Transportes seguros para DNS

Las consultas y respuestas de DNS tradicionales se envían a través de UDP o TCP sin encriptación, por lo que están sujetas a vigilancia, falsificación de identidad y filtrado de Internet basado en DNS. Las respuestas a clientes de agentes de resolución públicos, como el DNS público de Google, son especialmente vulnerables a esto, ya que los mensajes pueden pasar por muchas redes, mientras que los mensajes entre los agentes de resolución recursivos y los servidores de nombres autorizados suelen incorporar protecciones adicionales.

Para abordar estos problemas, en 2016 lanzamos DNS por HTTPS (ahora denominado DoH) que ofrecía una resolución de DNS encriptada con validación de DNSSEC mediante HTTPS y QUIC. Además, en 2019, agregamos compatibilidad con el estándar DNS por TLS (DoT) que usa la función DNS privado de Android.

DoH y DoT mejoran la privacidad y seguridad entre los clientes y agentes de resolución, y complementan la validación de DNSSEC del DNS público de Google para proporcionar DNS autenticado de extremo a extremo en dominios con firma de DNSSEC. Con el DNS público de Google, nos comprometemos a proporcionar una resolución de DNS rápida, privada y segura para los clientes DoH y DoT.

Versiones de TLS y paquetes de criptomonedas compatibles

El DNS público de Google es compatible con TLS 1.2 y TLS 1.3 para DoH y DoT. No se admiten versiones anteriores de TLS o SSL. Solo se admiten conjuntos de cifrado con seguridad directa y encriptación autenticada con datos adicionales (AEAD). Qualys SSL Labs muestra el conjunto actual de conjuntos de algoritmos de cifrado admitidos.

Extremos

El DNS público de Google usa los siguientes extremos para DoH y DoT:

DoT (puerto 853) dns.google

DoH (puerto 443) Plantillas de URI

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

    • Para POST, la URL es solo https://dns.google/dns-query y el cuerpo de la solicitud HTTP es la carga útil de DNS UDP binaria con el tipo de contenido application/dns-message.
    • Para GET es https://dns.google/dns-query?dns=BASE64URL_OF_QUERY.
  • API de JSON: https://dns.google/resolve{?name}{&type,cd,do,…}

    • En la página de la API de JSON se describen más parámetros GET. Solo se requiere el parámetro name.

Clientes

Hay varias aplicaciones cliente que utilizan DoT o DoH

  • Función "Navegación privada" de Android 9 (Pie) – DoT
  • Intra (app para Android): DoH

El sitio web dnsprivacy.org enumera muchos otros clientes para DoT y DoH, pero estos generalmente requieren una configuración moderadamente técnica.

Ejemplos de la línea de comandos

Los siguientes ejemplos de la línea de comandos no están diseñados para usarse en un cliente real y son solo ilustraciones en las que se usan herramientas de diagnóstico comúnmente disponibles.

DoT

Los siguientes comandos requieren Knot DNS kdig 2.3.0 o una versión posterior. Con 2.7.4 o una versión posterior, quita el comentario de +tls‑sni para enviar SNI según lo requiera 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

La string codificada Base64Url en este comando es el mensaje DNS que envía dig +noedns example.test A con el campo del ID de DNS establecido en cero, como se recomienda en la sección 4.1 de RFC 8484. El comando de shell envía esa consulta de DNS como el contenido del cuerpo de los datos binarios mediante el application/dns-message de tipo de contenido.

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 de RFC 8484

La string codificada Base64Url en este comando es el mensaje DNS que envía dig +noedns example.com A con el campo del ID de DNS establecido en cero. En este caso, se pasa de forma explícita en la 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

Se usará la API de JSON para el 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 y SNI para URLs de direcciones IP

TLS 1.3 requiere que los clientes proporcionen identificación del nombre del servidor (SNI).

La extensión SNI especifica que la información de SNI es un dominio DNS (y no una dirección IP):

“HostName” contiene el nombre de host DNS completamente calificado del servidor, según lo entienda el cliente. El nombre de host se representa como una string de bytes mediante la codificación ASCII sin un punto final. Esto permite la compatibilidad de nombres de dominio internacionalizados mediante el uso de etiquetas A definidas en RFC5890. Los nombres de host de DNS no distinguen mayúsculas de minúsculas. El algoritmo para comparar nombres de host se describe en la sección 2.3.2.4 de RFC 5890.

No se permiten las direcciones IPv4 e IPv6 literales en “HostName”.

Estos requisitos pueden ser difíciles de cumplir para las aplicaciones DoH o DoT que desean aprovechar las mejoras de seguridad en TLS 1.3. Actualmente, el DNS público de Google acepta conexiones TLS 1.3 que no proporcionan SNI, pero es posible que debamos cambiar esto por motivos operativos o de seguridad en el futuro.

Nuestras recomendaciones para las aplicaciones de los DoT o DoH en relación con el SNI son las siguientes:

  1. Envía el nombre de host dns.google como SNI para cualquier conexión a los servicios de Google Public DNS DoT o DoH.
  2. Si no hay un nombre de host disponible (por ejemplo, en una aplicación que ejecuta DoT oportunista), es mejor enviar la dirección IP en la SNI en lugar de dejarla en blanco.
  3. Las direcciones IPv6 deben aparecer entre corchetes [2001:db8:1234::5678] en el encabezado Host, pero sin corchetes en la SNI.

Truncamiento de respuesta de DNS

Aunque el DNS público de Google por lo general no trunca las respuestas a las consultas de DoT y DoH, hay dos circunstancias en las que lo hace:

  1. Si el DNS público de Google no puede obtener respuestas completas y sin truncar de los servidores de nombres autorizados, establece la marca de TC en la respuesta.

  2. En los casos en que la respuesta DNS (en formato de mensaje DNS binario) exceda el límite de 64 KiB para mensajes DNS de TCP, el DNS público de Google puede establecer la marca TC (truncación) si los estándares de RFC así lo requieren.

Sin embargo, en estos casos, no es necesario que los clientes vuelvan a intentarlo con TCP sin formato o con cualquier otro transporte, ya que el resultado será el mismo.