Implementação de DNS sobre QUIC para proxy UDP e cliente.
2019—2023 © NS1
Este código é lançado sob a licença Apache 2.0. Você pode encontrar os termos e condições no arquivo LICENSE.
A implementação segue RFC 9250: DNS sobre conexões QUIC dedicadas.
A compatibilidade do protocolo QUIC depende da biblioteca quic-go.
Crie o proxy DoQ e o cliente de teste.
go build ./cmd/proxy
go build ./cmd/client
Gere a chave de teste e o certificado autoassinado para o servidor proxy.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out server.key
openssl req -x509 -days 30 -subj "/CN=DNS-over-QUIC Test" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1" -key server.key -out server.crt
Inicie o proxy. Por padrão, o servidor carrega a chave TLS e o certificado dos arquivos gerados acima, usará 8.8.4.4 (DNS público do Google) como servidor back-end e escutará na porta UDP 853 (porta experimental do rascunho). Use opções de linha de comando para modificar o comportamento padrão. Observe que o uso da porta padrão requer iniciar o proxy como superusuário.
sudo ./proxy
Consulte o proxy usando o utilitário de teste. O cliente estabelece uma sessão QUIC para o servidor e envia cada consulta através de um fluxo dedicado. Upstream, as solicitações XFR são enviadas por TCP, todas as outras são enviadas por UDP. As respostas são impressas na ordem de preenchimento:
./client ns1.com A ns1.com AAAA
;; opcode: QUERY, status: NOERROR, id: 25849
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;ns1.com. IN AAAA
;; ANSWER SECTION:
ns1.com. 195 IN AAAA 2606:4700:10::6814:31b6
ns1.com. 195 IN AAAA 2606:4700:10::6814:30b6
ns1.com. 195 IN RRSIG AAAA 13 2 200 20190325121641 20190323121641 44688 ns1.com. m17G7sGkXNhBiKINI2LuQLvUL0Qb+l6LMUmKSoVo2TP5sw3Yd27L44QOZhVU1GS//tD1e6YVOVsMrW3arlk/bQ==
;; ADDITIONAL SECTION:
;; OPT PSEUDOSECTION:
; EDNS: version 0; flags: do; udp: 512
;; opcode: QUERY, status: NOERROR, id: 26044
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;ns1.com. IN A
;; ANSWER SECTION:
ns1.com. 25 IN A 104.20.49.182
ns1.com. 25 IN A 104.20.48.182
ns1.com. 25 IN RRSIG A 13 2 26 20190325121645 20190323121645 44688 ns1.com. xJK5DhMiFqxWx/gC7gHQXM8wkVFDyocIF3Zuehqa+S92zAq3yOtZMrqVRXxsKNw2lfCMQXLHr7hVUDm5H4B5eA==
;; ADDITIONAL SECTION:
;; OPT PSEUDOSECTION:
; EDNS: version 0; flags: do; udp: 512
O servidor proxy suporta autenticação de certificado de cliente. Para ativar o recurso, forneça o pacote de certificados CA no formato PEM como parâmetro de proxy -mtls_ca_certs
.
Gere um certificado CA de teste:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out ca.key
openssl req -x509 -days 30 -subj "/CN=DNS-over-QUIC Test CA" -addext "basicConstraints=critical,CA:true,pathlen:0" -key ca.key -out ca.crt
Gere certificados de servidor e cliente e assine-os com o certificado CA:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out server.key
openssl req -x509 -CA ca.crt -CAkey ca.key -days 30 -subj "/CN=server" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1" -key server.key -out server.crt
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out client.key
openssl req -x509 -CA ca.crt -CAkey ca.key -days 30 -subj "/CN=client" -key client.key -out client.crt
Execute o proxy e ative o mTLS fornecendo o certificado CA como um pacote CA:
./proxy -mtls_ca_certs ca.crt
Execute a consulta fornecendo certificados de cliente. O pacote CA permite a validação do certificado do servidor:
./client -ca_certs ca.crt -cert client.crt -key client.key ns1.com. AAAA
Observe que este é um código experimental construído sobre um protocolo experimental.
O servidor e o cliente neste repositório usam a mesma biblioteca QUIC e, portanto, devem ser compatíveis. Porém, se um cliente diferente for utilizado, o handshake poderá falhar na negociação da versão. Sugerimos verificar primeiro a captura de pacotes quando o cliente não conseguir se conectar.
O proxy também registra informações sobre conexões e fluxos aceitos que podem ser usados para inspecionar a sequência de eventos:
$ sudo ./proxy -listen 127.0.0.1:853 -cert cert.pem -key key.pem -backend 8.8.4.4:53
ts=2019-03-24T10:31:32.408891Z msg="listening for clients" addr=127.0.0.1:853
ts=2019-03-24T12:16:45.048583Z client=127.0.0.1:52212 msg="session accepted"
ts=2019-03-24T12:16:45.050231Z client=127.0.0.1:52212 stream_id=0 msg="stream accepted"
ts=2019-03-24T12:16:45.050278Z client=127.0.0.1:52212 stream_id=4 msg="stream accepted"
ts=2019-03-24T12:16:45.091568Z client=127.0.0.1:52212 stream_id=4 msg="stream closed"
ts=2019-03-24T12:16:45.104623Z client=127.0.0.1:52212 stream_id=0 msg="stream closed"
ts=2019-03-24T12:16:45.110261Z client=127.0.0.1:52212 msg="session closed"
Este projeto está mantido.
Solicitações pull e problemas são bem-vindos. Consulte as Diretrizes de Contribuição NS1 para obter mais informações.