Transports sécurisés pour DNS

Les requêtes et les réponses DNS traditionnelles sont envoyées via UDP ou TCP sans chiffrement, et sont donc soumises à la surveillance, au spoofing et au filtrage Internet basé sur le DNS. Les réponses aux clients de résolveurs publics tels que le DNS public de Google sont particulièrement vulnérables, car les messages peuvent transiter par de nombreux réseaux, tandis que les messages entre les résolveurs récursifs et les serveurs de noms primaires intègrent souvent des protections supplémentaires.

Pour résoudre ces problèmes, nous avons lancé le DNS sur HTTPS (désormais appelé DoH) en 2016, qui propose une résolution DNS chiffrée de validation DNSSEC sur HTTPS et QUIC. En 2019, nous avons ajouté la prise en charge de la norme DNS sur TLS (DoT) utilisée par la fonctionnalité DNS privé d'Android.

DoH et DoT améliorent la confidentialité et la sécurité entre les clients et les résolveurs, en complément de la validation du DNS public Google de DNSSEC pour fournir un DNS authentifié de bout en bout pour les domaines signés DNSSEC. Avec le DNS public de Google, nous nous engageons à fournir une résolution DNS rapide, privée et sécurisée aux clients DoH et DoT.

Versions et suites de chiffrement compatibles avec TLS

Le DNS public de Google est compatible avec TLS 1.2 et TLS 1.3 pour DoH et DoT. Les versions antérieures de TLS ou SSL ne sont pas acceptées. Seules les suites de chiffrement dotées de la sécurité persistante et du chiffrement authentifié avec des données supplémentaires (AEAD) sont compatibles. Les ateliers SSL de Qualys présentent les suites de chiffrement actuellement compatibles.

Points de terminaison

Le DNS public de Google utilise les points de terminaison suivants pour DoH et DoT:

DoT (port 853) dns.google

Modèles d'URI DoH (port 443)

  • RFC 8484 – https://dns.google/dns-query{?dns}

    • Pour POST, l'URL est simplement https://dns.google/dns-query et le corps de la requête HTTP est la charge utile DNS UDP binaire avec le type de contenu application/dns-message.
    • Pour GET, il s'agit de https://dns.google/dns-query?dns=BASE64URL_OF_QUERY.
  • API JSON – https://dns.google/resolve{?name}{&type,cd,do,…}

    • D'autres paramètres GET sont décrits sur la page de l'API JSON. Seul le paramètre name est obligatoire.

Clients

De nombreuses applications clientes utilisent DoT ou DoH

  • Fonctionnalité "Navigation privée" d'Android 9 (Pie) – DoT
  • Intra (application Android) – DoH

Le site Web dnsprivacy.org répertorie plusieurs autres clients pour DoT et DoH, mais ceux-ci nécessitent généralement une configuration relativement technique.

Exemples de ligne de commande

Les exemples de ligne de commande suivants ne sont pas destinés à être utilisés dans un client réel. Ils ne sont que des illustrations utilisant des outils de diagnostic courants.

DoT

Les commandes suivantes nécessitent Knot DNS kdig 2.3.0 ou version ultérieure. À partir de la version 2.7.4, annulez la mise en commentaire de +tls‑sni pour envoyer le SNI conformément aux exigences de TLS 1.3.

kdig -d +noall +answer @dns.google example.com \
  +tls-ca +tls-hostname=dns.google # +tls-sni=dns.google
;; DEBUG: Querying for owner(example.com.), class(1), type(1), server(dns.google), port(853), protocol(TCP)
;; DEBUG: TLS, imported 312 system certificates
;; DEBUG: TLS, received certificate hierarchy:
;; DEBUG:  #1, C=US,ST=California,L=Mountain View,O=Google LLC,CN=dns.google
;; DEBUG:      SHA-256 PIN: lQXSLnWzUdueQ4+YCezIcLa8L6RPr8Wgeqtxmw1ti+M=
;; DEBUG:  #2, C=US,O=Google Trust Services,CN=Google Internet Authority G3
;; DEBUG:      SHA-256 PIN: f8NnEFZxQ4ExFOhSN7EiFWtiudZQVD2oY60uauV/n78=
;; DEBUG: TLS, skipping certificate PIN check
;; DEBUG: TLS, The certificate is trusted.

;; ANSWER SECTION:
example.com.            2046    IN      A       93.184.216.34
kdig -d +noall +answer @dns.google example.com \
  +tls-pin=f8NnEFZxQ4ExFOhSN7EiFWtiudZQVD2oY60uauV/n78= \
  # +tls-sni=dns.google
;; DEBUG: Querying for owner(example.com.), class(1), type(1), server(dns.google), port(853), protocol(TCP)
;; DEBUG: TLS, received certificate hierarchy:
;; DEBUG:  #1, C=US,ST=California,L=Mountain View,O=Google LLC,CN=dns.google
;; DEBUG:      SHA-256 PIN: lQXSLnWzUdueQ4+YCezIcLa8L6RPr8Wgeqtxmw1ti+M=
;; DEBUG:  #2, C=US,O=Google Trust Services,CN=Google Internet Authority G3
;; DEBUG:      SHA-256 PIN: f8NnEFZxQ4ExFOhSN7EiFWtiudZQVD2oY60uauV/n78=, MATCH
;; DEBUG: TLS, skipping certificate verification

;; ANSWER SECTION:
example.com.            5494    IN      A       93.184.216.34

DoH

POST RFC 8484

Dans cette commande, la chaîne encodée en base64Url correspond au message DNS envoyé par dig +noedns example.test A avec le champ "ID DNS" défini sur zéro, comme recommandé dans la section 4.1 du document RFC 8484. La commande shell envoie cette requête DNS en tant que contenu du corps des données binaires, à l'aide du type de contenu application/dns-message.

echo AAABAAABAAAAAAAAB2V4YW1wbGUEdGVzdAAAAQAB | base64 --decode |
 curl -is --data-binary @- -H 'content-type: application/dns-message' \
   https://dns.google/dns-query
HTTP/2 200
strict-transport-security: max-age=31536000; includeSubDomains; preload
access-control-allow-origin: *
date: Wed, 29 May 2019 19:37:16 GMT
expires: Wed, 29 May 2019 19:37:16 GMT
cache-control: private, max-age=19174
content-type: application/dns-message
server: HTTP server (unknown)
content-length: 45
x-xss-protection: 0
x-frame-options: SAMEORIGIN
alt-svc: quic=":443"; ma=2592000; v="46,44,43,39"

GET RFC 8484

Dans cette commande, la chaîne encodée en Base64Url correspond au message DNS envoyé par dig +noedns example.com A avec le champ d'ID DNS défini sur zéro. Dans ce cas, elle est explicitement transmise dans l'URL.

curl -i https://dns.google/dns-query?dns=AAABAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE
HTTP/2 200
strict-transport-security: max-age=31536000; includeSubDomains; preload
access-control-allow-origin: *
date: Wed, 29 May 2019 19:37:16 GMT
expires: Wed, 29 May 2019 19:37:16 GMT
cache-control: private, max-age=19174
content-type: application/dns-message
server: HTTP server (unknown)
content-length: 45
x-xss-protection: 0
x-frame-options: SAMEORIGIN
alt-svc: quic=":443"; ma=2592000; v="46,44,43,39"

GET JSON

Cette approche utilise l'API JSON pour DoH.

curl -i 'https://dns.google/resolve?name=example.com&type=a&do=1'
HTTP/2 200
strict-transport-security: max-age=31536000; includeSubDomains; preload
access-control-allow-origin: *
date: Thu, 30 May 2019 02:46:46 GMT
expires: Thu, 30 May 2019 02:46:46 GMT
cache-control: private, max-age=10443
content-type: application/x-javascript; charset=UTF-8
server: HTTP server (unknown)
x-xss-protection: 0
x-frame-options: SAMEORIGIN
alt-svc: quic=":443"; ma=2592000; v="46,44,43,39"
accept-ranges: none
vary: Accept-Encoding

{"Status": 0,"TC": false,"RD": true,"RA": true,"AD": true,"CD": false,"Question":[ {"name": "example.com.","type": 1}],"Answer":[ {"name": "example.com.","type": 1,"TTL": 10443,"data": "93.184.216.34"},{"name": "example.com.","type": 46,"TTL": 10443,"data": "a 8 2 86400 1559899303 1558087103 23689 example.com. IfelQcO5NqQIX7ZNKI245KLfdRCKBaj2gKhZkJawtJbo/do+A0aUvoDM5A7EZKcF/j8SdtyfYWj/8g91B2/m/WOo7KyZxIC918R1/jvBRYQGreDL+yutb1ReGc6eUHX+NKJIYqzfal+PY7tGotS1Srn9WhBspXq8/0rNsEnsSoA="}],"Additional":[]}

TLS 1.3 et SNI pour les URL d'adresse IP

TLS 1.3 exige que les clients fournissent une identification de nom de serveur (SNI, Server Name Identification).

L'extension SNI indique que les informations SNI correspondent à un domaine DNS (et non à une adresse IP):

"HostName" contient le nom d'hôte DNS complet du serveur, tel qu'il est compris par le client. Le nom d'hôte est représenté par une chaîne d'octets utilisant l'encodage ASCII sans point final. Cela permet la prise en charge des noms de domaine internationalisés via l'utilisation des étiquettes A définies dans le document RFC5890. Les noms d'hôte DNS ne sont pas sensibles à la casse. L'algorithme de comparaison des noms d'hôte est décrit dans le document RFC5890, section 2.3.2.4.

Les adresses IPv4 et IPv6 littérales ne sont pas autorisées dans "HostName".

Ces exigences peuvent être difficiles à répondre pour les applications DoH ou DoT qui souhaitent bénéficier des améliorations de sécurité dans TLS 1.3. Le DNS public de Google accepte actuellement les connexions TLS 1.3 qui ne fournissent pas de SNI. Toutefois, nous devrons peut-être modifier ce paramètre à l'avenir pour des raisons opérationnelles ou de sécurité.

Nos recommandations pour les applications DoT ou DoH concernant SNI sont les suivantes:

  1. Envoyez le nom d'hôte dns.google en tant que SNI pour toutes les connexions aux services Google Public DNS DoT ou DoH.
  2. Si aucun nom d'hôte n'est disponible (par exemple, dans une application effectuant un DoT opportun), il est préférable d'envoyer l'adresse IP dans la SNI plutôt que de la laisser vide.
  3. Les adresses IPv6 doivent apparaître entre crochets [2001:db8:1234::5678] dans l'en-tête Host, mais sans crochets dans le SNI.

Troncation de réponse DNS

Bien que le DNS public de Google ne tronque généralement pas les réponses aux requêtes DoT et DoH, il existe deux cas de figure:

  1. Si le DNS public de Google ne peut pas obtenir de réponses complètes et non tronquées des serveurs de noms primaires, il définit l'indicateur TC dans la réponse.

  2. Dans les cas où la réponse DNS (sous forme de message DNS binaire) dépasse la limite de 64 Kio pour les messages DNS TCP, le DNS public de Google peut définir l'indicateur TC (troncation) si les normes RFC l'exigent.

Toutefois, dans ces cas, il n'est pas nécessaire que les clients effectuent une nouvelle tentative à l'aide du TCP simple ou de tout autre transport, car le résultat sera le même.