DNS sur QUIC vers proxy UDP et implémentation client.
2019—2023 © NS1
Ce code est publié sous licence Apache 2.0. Vous pouvez trouver les termes et conditions dans le fichier LICENCE.
L'implémentation suit la RFC 9250 : DNS sur des connexions QUIC dédiées.
La compatibilité du protocole QUIC dépend de la bibliothèque quic-go.
Créez le proxy DoQ et le client de test.
go build ./cmd/proxy
go build ./cmd/client
Générez une clé de test et un certificat auto-signé pour le serveur 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
Démarrez le proxy. Par défaut, le serveur charge la clé TLS et le certificat à partir des fichiers générés ci-dessus, utilisera 8.8.4.4 (Google Public DNS) comme serveur backend et écoutera sur le port UDP 853 (port expérimental du brouillon). Utilisez les options de ligne de commande pour modifier le comportement par défaut. Notez que l'utilisation du port par défaut nécessite le démarrage du proxy en tant que superutilisateur.
sudo ./proxy
Interrogez le proxy à l’aide de l’utilitaire de test. Le client établit une session QUIC vers le serveur et envoie chaque requête via un flux dédié. En amont, les requêtes XFR sont envoyées sur TCP, toutes les autres sont envoyées sur UDP. Les réponses sont imprimées dans l'ordre d'achèvement :
./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
Le serveur proxy prend en charge l'authentification par certificat client. Afin d'activer la fonctionnalité, fournissez un ensemble de certificats CA au format PEM en tant que paramètre proxy -mtls_ca_certs
.
Générez un certificat CA de test :
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
Générez des certificats serveur et client et signez-les avec le certificat 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
Exécutez le proxy et activez mTLS en fournissant le certificat CA sous forme de bundle CA :
./proxy -mtls_ca_certs ca.crt
Exécutez la requête en fournissant des certificats clients. Le bundle CA permet la validation des certificats de serveur :
./client -ca_certs ca.crt -cert client.crt -key client.key ns1.com. AAAA
Notez qu'il s'agit d'un code expérimental construit sur un protocole expérimental.
Le serveur et le client de ce référentiel utilisent la même bibliothèque QUIC et doivent donc être compatibles. Cependant, si un autre client est utilisé, la négociation peut échouer lors de la négociation de version. Nous suggérons de vérifier d'abord la capture des paquets lorsque le client ne parvient pas à se connecter.
Le proxy enregistre également des informations sur les connexions et les flux acceptés qui peuvent être utilisées pour inspecter la séquence d'événements :
$ 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"
Ce projet est maintenu.
Les demandes de tirage et les problèmes sont les bienvenus. Consultez les directives de contribution NS1 pour plus d’informations.