Безопасный транспорт для DNS

Традиционные DNS-запросы и ответы отправляются через UDP или TCP без шифрования, что делает их объектами слежки, подмены и интернет-фильтрации на основе DNS. Ответы клиентам от общедоступных преобразователей, таких как Google Public DNS, особенно уязвимы для этого, поскольку сообщения могут проходить через множество сетей, а сообщения между рекурсивными преобразователями и авторитетными серверами имен часто включают дополнительную защиту .

Чтобы решить эти проблемы, в 2016 году мы запустили DNS over HTTPS (теперь он называется DoH), предлагая зашифрованное разрешение DNS с проверкой DNSSEC через HTTPS и QUIC . А в 2019 году мы добавили поддержку стандарта DNS over TLS (DoT), используемого функцией Android Private DNS .

DoH и DoT повышают конфиденциальность и безопасность между клиентами и преобразователями, дополняя проверку DNSSEC на общедоступном DNS Google для обеспечения сквозной аутентификации DNS для доменов, подписанных DNSSEC. С помощью Google Public DNS мы стремимся обеспечить быстрое, конфиденциальное и безопасное разрешение DNS для клиентов DoH и DoT.

Поддерживаемые версии TLS и криптопакеты

Google Public DNS поддерживает TLS 1.2 и TLS 1.3 как для DoH, так и для DoT; более ранние версии TLS или SSL не поддерживаются. Поддерживаются только наборы шифров с прямой защитой и шифрованием с проверкой подлинности и дополнительными данными (AEAD). Qualys SSL Labs показывает текущий набор поддерживаемых наборов шифров.

Конечные точки

Google Public DNS использует следующие конечные точки для DoH и DoT:

DoT (порт 853) dns.google

DoH (порт 443) Шаблоны URI

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

    • Для POST URL-адрес — это просто https://dns.google/dns-query , а тело HTTP-запроса — это двоичная полезная нагрузка UDP DNS с типом контента application/dns-message.
    • Для GET это https://dns.google/dns-query?dns= BASE64URL_OF_QUERY .
  • JSON API – https://dns.google/resolve{?name}{&type,cd,do,…}

    • Дополнительные параметры GET описаны на странице JSON API . Обязателен только параметр name .

Клиенты

Существует ряд клиентских приложений, использующих DoT или DoH.

  • Android 9 (Pie) Функция «Частный просмотр» — DoT
  • Intra (приложение для Android) – DoH

На веб-сайте dnsprivacy.org перечислено несколько других клиентов для DoT и DoH, но они обычно требуют умеренной технической настройки.

Примеры командной строки

Следующие примеры командной строки не предназначены для использования в реальном клиенте и представляют собой просто иллюстрации с использованием общедоступных инструментов диагностики.

ДоТ

Для следующих команд требуется Knot DNS kdig 2.3.0 или новее; в версии 2.7.4 или более поздней раскомментируйте +tls‑sni , чтобы отправить SNI , как того требует 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

RFC 8484 ПОСТ

Строка в кодировке Base64Url в этой команде представляет собой DNS-сообщение, отправленное dig +noedns example.test A с нулевым значением поля DNS ID, как рекомендовано в разделе 4.1 RFC 8484 . Команда оболочки отправляет этот DNS-запрос как содержимое тела двоичных данных, используя Content-Type 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 ПОЛУЧИТЬ

Строка в кодировке Base64Url в этой команде представляет собой DNS-сообщение, отправленное dig +noedns example.com A с нулевым значением поля DNS ID. В этом случае он явно передается в 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"

ПОЛУЧИТЬ JSON

При этом используется JSON API для 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 и SNI для URL-адресов IP-адресов

TLS 1.3 требует, чтобы клиенты предоставляли идентификацию имени сервера (SNI).

Расширение SNI указывает, что информация SNI представляет собой домен DNS (а не IP-адрес):

«Имя хоста» содержит полное DNS-имя хоста сервера, как его понимает клиент. Имя хоста представляется в виде байтовой строки в кодировке ASCII без завершающей точки. Это позволяет поддерживать интернационализированные доменные имена за счет использования A-меток, определенных в RFC5890 . Имена хостов DNS нечувствительны к регистру. Алгоритм сравнения имен хостов описан в RFC5890, раздел 2.3.2.4 .

Буквальные адреса IPv4 и IPv6 не допускаются в «HostName».

Эти требования могут быть трудновыполнимыми для приложений DoH или DoT, которые хотят воспользоваться преимуществами улучшений безопасности в TLS 1.3. Google Public DNS в настоящее время принимает соединения TLS 1.3, которые не предоставляют SNI, но в будущем нам может потребоваться изменить это по соображениям эксплуатации или безопасности.

Наши рекомендации для приложений DoT или DoH в отношении SNI следующие:

  1. Отправьте имя хоста dns.google в качестве SNI для любых подключений к службам Google Public DNS DoT или DoH.
  2. Если имя хоста недоступно (например, в приложении, выполняющем оппортунистический DoT), лучше отправить IP-адрес в SNI, а не оставлять его пустым.
  3. Адреса IPv6 должны отображаться в формате [2001:db8:1234::5678] в скобках в заголовке Host , но без скобок в SNI.

Усечение ответа DNS

Хотя общедоступный DNS Google обычно не усекает ответы на запросы DoT и DoH, это происходит в двух случаях:

  1. Если Google Public DNS не может получить полные и несокращенные ответы от авторитетных серверов имен, в ответе устанавливается флаг TC.

  2. В тех случаях, когда ответ DNS (в форме двоичного сообщения DNS) превышает ограничение в 64 КиБ для сообщений TCP DNS, Google Public DNS может установить флаг TC (усечения), если этого требуют стандарты RFC.

Однако в этих случаях клиентам не нужно повторять попытку использования простого TCP или любого другого транспорта, поскольку результат будет тот же.