Sichere Übertragungen für DNS

Herkömmliche DNS-Abfragen und -Antworten werden unverschlüsselt über UDP oder TCP gesendet und unterliegen daher Überwachung, Spoofing und DNS-basierter Internetfilterung. Antworten an Clients von öffentlichen Resolvern wie Google Public DNS sind hier besonders anfällig, da Nachrichten viele Netzwerke passieren können, während Nachrichten zwischen rekursiven Resolvern und autoritativen Nameservern häufig zusätzliche Schutzmaßnahmen enthalten.

Um diese Probleme zu beheben, haben wir 2016 DNS über HTTPS (jetzt DoH) eingeführt und bieten eine verschlüsselte DNSSEC-validierende DNS-Auflösung über HTTPS und QUIC. 2019 haben wir außerdem den Support für den DoT-Standard (DNS over TLS) hinzugefügt, der von der Android-Funktion Privates DNS verwendet wird.

DoH und DoT verbessern den Datenschutz und die Sicherheit zwischen Clients und Resolvern und ergänzen die Google Public DNS-Validierung von DNSSEC, um ein Ende-zu-Ende-authentifiziertes DNS für DNSSEC-signierte Domains bereitzustellen. Mit Google Public DNS haben wir uns zum Ziel gesetzt, eine schnelle, private und sichere DNS-Auflösung für DoH- und DoT-Clients bereitzustellen.

Unterstützte TLS-Versionen und Krypto-Suites

Google Public DNS unterstützt TLS 1.2 und TLS 1.3 sowohl für DoH als auch für DoT; frühere Versionen von TLS oder SSL werden nicht unterstützt. Es werden nur Cipher Suites mit Forward Security und Authenticated Encryption with Zusätzliche Daten (AEAD) unterstützt. Qualys SSL Labs zeigt den aktuellen Satz unterstützter Chiffresammlungen.

Endpunkte

Google Public DNS verwendet die folgenden Endpunkte für DoH und DoT:

DoT (Port 853) dns.google

DoH (Port 443) URI-Vorlagen

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

    • Für POST lautet die URL nur https://dns.google/dns-query und der Text der HTTP-Anfrage ist die binäre UDP-DNS-Nutzlast mit dem Inhaltstyp „application/dns-message“.
    • Für GET ist das https://dns.google/dns-query?dns=BASE64URL_OF_QUERY.
  • JSON API – https://dns.google/resolve{?name}{&type,cd,do,…}

    • Weitere GET-Parameter werden auf der Seite JSON API beschrieben. Nur der Parameter name ist erforderlich.

Im Namen der Kunden meines Arbeitgebers

Es gibt eine Reihe von Clientanwendungen, die DoT oder DoH verwenden.

  • Funktion „Privates Surfen“ für Android 9 (Pie) – DoT
  • Intra (Android-App) – DoH

Auf der Website dnsprivacy.org sind mehrere andere Clients für DoT und DoH aufgeführt, diese erfordern jedoch in der Regel eine mäßig technische Konfiguration.

Befehlszeilenbeispiele

Die folgenden Befehlszeilenbeispiele sind nicht für die Verwendung in einem tatsächlichen Client vorgesehen und dienen lediglich zur Darstellung gängiger Diagnosetools.

DoT

Für die folgenden Befehle ist Knot DNS kdig 2.3.0 oder höher erforderlich. Entfernen Sie bei Version 2.7.4 oder höher die Kommentarzeichen von +tls‑sni, um gemäß TLS 1.3 SNI zu senden.

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

RFC 8484-POST

Der Base64Url-codierte String in diesem Befehl ist die von dig +noedns example.test A gesendete DNS-Nachricht, wobei das DNS-ID-Feld auf null gesetzt ist, wie in RFC 8484-Abschnitt 4.1 empfohlen. Der Shell-Befehl sendet diese DNS-Abfrage als Binärdatentextinhalt mit dem Inhaltstyp 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"

RFC 8484 GET

Der Base64Url-codierte String in diesem Befehl ist die von dig +noedns example.com A gesendete DNS-Nachricht, wobei das DNS-ID-Feld auf null gesetzt ist. In diesem Fall wird sie explizit in der URL übergeben.

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"

JSON-GET

Dabei wird die JSON API für DoH verwendet.

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 und SNI für IP-Adress-URLs

TLS 1.3 erfordert, dass Clients die Server Name Identification (SNI) angeben.

Die SNI-Erweiterung gibt an, dass die SNI-Informationen eine DNS-Domain und keine IP-Adresse sind:

„HostName“ enthält den voll qualifizierten DNS-Hostnamen des Servers, so wie er vom Client verstanden wird. Der Hostname wird als Bytestring mit ASCII-Codierung ohne abschließenden Punkt dargestellt. Dies ermöglicht die Unterstützung internationalisierter Domainnamen durch die Verwendung von A-Labels, die in RFC5890 definiert sind. Bei DNS-Hostnamen wird die Groß-/Kleinschreibung nicht berücksichtigt. Der Algorithmus zum Vergleichen von Hostnamen wird in RFC5890, Abschnitt 2.3.2.4 beschrieben.

Literale IPv4- und IPv6-Adressen sind in „HostName“ nicht zulässig.

Für DoH- oder DoT-Anwendungen, die von Sicherheitsverbesserungen in TLS 1.3 profitieren möchten, können diese Anforderungen schwer zu erfüllen sein. Google Public DNS akzeptiert derzeit TLS 1.3-Verbindungen, die kein SNI bereitstellen. Wir müssen dies jedoch in Zukunft möglicherweise aus Betriebs- oder Sicherheitsgründen ändern.

Unsere Empfehlungen für DoT- oder DoH-Anwendungen im Zusammenhang mit SNI lauten wie folgt:

  1. Senden Sie den dns.google-Hostnamen als SNI für alle Verbindungen zu den Google Public DNS DoT- oder DoH-Diensten.
  2. Wenn kein Hostname verfügbar ist (z. B. in einer Anwendung mit opportunistischem DoT), ist es besser, die IP-Adresse im SNI zu senden, anstatt sie leer zu lassen.
  3. IPv6-Adressen sollten im Host-Header in geklammerter [2001:db8:1234::5678]-Form, im SNI jedoch ohne Klammern angezeigt werden.

Abkürzung von DNS-Antworten

Obwohl Google Public DNS Antworten auf DoT- und DoH-Anfragen in der Regel nicht kürzt, gibt es zwei Situationen:

  1. Wenn das Google Public DNS keine vollständigen und nicht abgeschnittenen Antworten von autoritativen Nameservern erhalten kann, wird das TC-Flag in der Antwort festgelegt.

  2. In Fällen, in denen die DNS-Antwort (im binären DNS-Nachrichtenformat) das Limit von 64 KiB für TCP-DNS-Nachrichten überschreiten würde, kann Google Public DNS das TC-Flag (Truncation) setzen, sofern dies gemäß RFC-Standards erforderlich ist.

In diesen Fällen müssen Clients es jedoch nicht mit einfachem TCP oder einem anderen Transport wiederholen, da das Ergebnis das gleiche ist.