системный резолвер что это
Особенности резолвера DNS в Windows 10 и DNS Leak
TL;DR: DNS-резолвер в Windows 10 отправляет запросы на все известные системе адреса DNS-серверов параллельно, привязывая запрос к интерфейсу, и использует тот ответ, который пришел быстрее. В случае, если вы используете DNS-сервер из локального сегмента, такое поведение позволяет вашему провайдеру или злоумышленнику с Wi-Fi-точкой подменять записи DNS, даже если вы используете VPN.
Современные версии Windows добавляют головные боли активным пользователям VPN. DNS-резолвер до Windows 7 включительно имел предсказуемое поведение, совершая запросы к DNS-серверам в порядке очереди и приоритета DNS-серверов, в общем-то, как и все остальные ОС. Это создавало так называемый DNS Leak (утечка DNS-запроса через внешний интерфейс при подключенном VPN) только в том случае, если DNS-сервер внутри VPN-туннеля не ответил вовремя, или ответил ошибкой, и, в целом, не являлось такой уж вопиющей проблемой.
Windows 8
С выходом Windows 8, Microsoft добавила весьма интересную функцию в DNS-резолвер, которая, как я могу судить по Google, осталась совершенно незамеченной: Smart Multi-Homed Name Resolution. Если эта функция включена (а она включена по умолчанию), ОС отправляет запросы на все известные ей DNS-серверы на всех сетевых интерфейсах параллельно, привязывая запрос к интерфейсу. Сделано это было, вероятно, для того, чтобы уменьшить время ожидания ответа от предпочитаемого DNS-сервера в случае, если он по каким-то причинам не может ответить в отведенный ему таймаут (1 секунда по умолчанию), и сразу, по истечении таймаута, отдать ответ от следующего по приоритету сервера. Таким образом, в Windows 8 и 8.1 все ваши DNS-запросы «утекают» через интернет-интерфейс, позволяя вашему провайдеру или владельцу Wi-Fi-точки просматривать, на какие сайты вы заходите, при условии, что ваша таблица маршрутизации позволяет запросы к DNS-серверу через интернет-интерфейс. Чаще всего такая ситуация возникает, если использовать DNS-сервер внутри локального сегмента, такие DNS поднимают 99% домашних роутеров.
Данную функциональность можно отключить, добавив в ветку реестра:
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\DNSClient
Параметр типа DWORD с названием:
DisableSmartNameResolution
и любым значением, отличным от нуля, что возвращало старое поведение резолвера.
Windows 10
Хоть Windows 8 и 8.1 отправляли все ваши запросы без вашего ведома через публичный интерфейс, совершить подмену DNS-ответа таким образом, чтобы перенаправить вас на поддельный сайт, было проблематично для злоумышленника, т.к. ОС бы использовала подмененный ответ только в том случае, если не удалось получить правильный ответ от предпочитаемого DNS-сервера, коим является сервер внутри шифрованного туннеля.
Все изменилось с приходом Windows 10. Теперь ОС не только отправляет запрос через все интерфейсы, но и использует тот ответ, который быстрее пришел, что позволяет практически всегда вашему провайдеру перенаправить вас на заглушку о запрещенном сайте или злоумышленнику на поддельный сайт. Более того, способ отключения Smart Multi-Homed Name Resolution, который работал в Windows 8.1, не работает на новой версии.
Единственный приемлемый (хоть и не самый надежный) способ решения проблемы — установить DNS на интернет-интерфейсе вне локального сегмента, например, всем известные 8.8.8.8, однако, он не поможет в случае с OpenVPN. Для OpenVPN единственным (и некрасивым) решением является временное отключение DNS на интернет-интерфейсе скриптами.
UPD: ранее в статье рекомендовалось использовать параметр redirect-gateway без def1 для OpenVPN. Оказывается, Windows возвращает маршрут по умолчанию от DHCP-сервера при каждом обновлении IP-адреса, и через какое-то время весь ваш трафик начинал бы ходить в обход VPN. На данный момент, красивого решения не существует.
UPD3: Windows 10, начиная с Creators Update, теперь отправляет DNS-запросы на все известные адреса DNS-серверов по порядку, а не параллельно, начиная со случайного интерфейса. Чтобы повысить приоритет конкретного DNS, необходимо уменьшить метрику интерфейса. Сделал патч для OpenVPN, надеюсь, его включат в 2.4.2: https://sourceforge.net/p/openvpn/mailman/message/35822231/
UPD4: Обновление вошло в OpenVPN 2.4.2.
Что такое DNS? Введение в систему доменных имён
Авторизуйтесь
Что такое DNS? Введение в систему доменных имён
Если вы хоть немного имели дело с интернетом и компьютерными сетями, то наверняка слышали о системе доменных имён (DNS). Прочитав статью узнаете, как это всё работает.
Само имя хоста не даст никакой информации о нахождении конкретной машины, с которой вы собираетесь связаться, поскольку все соединения происходят по IP-адресам.
Сервер доменных имён — это устройство, которое сопоставляет имя хоста с IP-адресом конкретной машины/железа.
В этой статье будет рассказано о деталях различных DNS-запросов, типах DNS-серверов и о разновидностях DNS-записей.
DNS-резолвер
Это компьютеры, которые провайдеры используют для поиска в их базе данных конкретного узла, запрашиваемого пользователем. Когда данные получены, пользователь перенаправляется на соответствующий IP-адрес. Резолверы играют крайне важную роль в DNS.
13–15 декабря, Онлайн, Беcплатно
Время, в течение которого запись хранится в резолвере, называется TTL (time to live).
Его можно установить в панели управления сервиса, на котором приобретался домен.
Типы DNS-серверов
Корневой DNS-сервер
Это DNS-сервер, который хранит в себе адреса всех TLD-серверов (TLD — top-level domain, домен верхнего уровня). По пути от имени хоста до IP-адреса запрос сначала попадает на корневой DNS-сервер.
Существует 13 корневых DNS-серверов:
Организации, управляющие корневыми DNS-серверами
Это не означает, что существует только 13 машин, которые обрабатывают все запросы со всего мира — существуют и второстепенные серверы, по которым распределяется трафик.
TLD-серверы
Эти серверы связаны с доменами верхнего уровня (TLD). Обычно они идут после корневых DNS-серверов. В TLD-серверах содержится информация о домене верхнего уровня конкретного хоста.
Теперь возникает вопрос — откуда TLD-серверы знают адрес авторитативных серверов? Ответ прост — после того, как вы покупаете любой домен у регистраторов вроде Godaddy или Namecheap, регистраторы привязывают авторитативные серверы к TLD-серверу.
Сейчас некоторые провайдеры предоставляют возможность использовать сторонние авторитативные серверы. Вы можете выбрать конкретный авторитативный сервер имён у регистратора.
Авторитативный DNS-сервер
Запрос на эти серверы поступает в самую последнюю очередь. Эти серверы хранят фактические записи типа A, NS, CNAME, TXT, и т. п.
Авторитативные DNS-серверы по возможности возвращают IP-адреса хостов. Если сервер этого сделать не может — он выдаёт ошибку, и на этом поиск IP-адреса по серверам заканчивается.
Типы DNS-запросов
Существует 3 типа DNS-запросов:
Попробуем рассмотреть этот процесс на рисунке:
Разберём рисунок выше:
Что в итоге?
Даже если вы измените запись у регистраторов, внесение изменений на резолверах всего мира займёт какое-то время. Этот процесс может длиться от 24 до 72 часов, но обычно завершается быстрее, т. к. за это время TTL-записи у провайдеров успевает истечь.
Решаем проблему перехвата и подмены DNS-запросов. DNSCrypt в Яндекс.Браузере
Когда речь заходит о защите веб-трафика от перехвата и подмены, то на ум в первую очередь приходят протокол HTTPS или даже собственный VPN-сервер. К сожалению, многие забывают еще об одной незащищенной стороне, а именно о DNS-запросах. Сегодня я еще раз привлеку внимание к этой проблеме и расскажу о том, как мы решаем ее в Яндекс.Браузере с помощью технологии DNSCrypt.
Архитектура системы доменных имен (DNS) за редким исключением остается неизменной с 1983 года. Каждый раз, когда вы хотите открыть сайт, браузер отправляет запрос с указанием домена на DNS-сервер, который в ответ отправляет необходимый IP-адрес. И запрос, и ответ на него передаются в открытом виде, без какого-либо шифрования. Это значит, что ваш провайдер, администратор сети или злоумышленник c MITM могут не только хранить историю всех запрошенных вами сайтов, но и подменять ответы на эти запросы. Звучит неприятно, не правда ли?
Предлагаю вспомнить несколько реальных историй перехвата и подмены DNS-запросов.
Перехват DNS-запросов (DNS hijacking) это не какая-то редкая страшилка, а вполне распространенная практика. Например, среди провайдеров. Обычно это работает следующим образом. Если пользователь пытается перейти на несуществующий сайт, то провайдер перенаправляет его на свою страницу с рекламой. А может и не на свою.
Американский провайдер Earthlink в 2006 году стал перенаправлять пользователей и информацию об их запросах рекламному партнеру Barefruit. Особенно плохо это выглядело в том случае, если пользователь запрашивал несуществующий домен известного сайта, например, webmale.google.com. Пользователь видел рекламу и контент, которые не имели ничего общего с google.com в адресной строке.
Подобная практика явно нарушает стандарт RFC для DNS-ответов и делает пользователей уязвимыми для XSS-атак. К примеру, исследователь Дэн Камински продемонстрировал уязвимость, которая позволяла встраивать в Facebook или PayPal мошеннические фреймы.
Вы, конечно же, можете отказаться от использования DNS-сервера провайдера и прописать в настройках роутера сторонние решения (например, Google Public DNS или Яндекс.DNS). Но при отсутствии шифрования это никак не решит проблему. Провайдер вполне может вмешаться и здесь, подменив ответ на свой.
Масштабы трояна DNSChanger впечатляют, но бразильцы его переплюнули. 4,5 млн DSL-модемов было взломано в одной только Бразилии в 2011-2012 годах. Для этого было достаточно разослать спам со ссылкой на вредоносную страницу, которая взламывала модем и прописывала новый адрес DNS-сервера. Причем в этот раз мошенники не стали мелочиться с рекламой. На своих подставных DNS-серверах они подменяли адреса для всех крупнейших банков Бразилии.
С домашними и офисными WiFi-роутерами дело обстоит так же печально, как и с бразильскими модемами. Пользователи нередко оставляют заводские логин и пароль на админку, да и за выходом свежих прошивок с исправленными уязвимостями не следит почти никто (кроме читателей Хабра, конечно же). В прошлом году исследователи из Sentrant в своем докладе рассказали о новых случаях взлома роутеров. Мошенники перехватывали обращения к Google Analytics и благодаря этому встраивали на сайты рекламу.
Думаю, с примерами перехвата можно закончить. Вывод тут простой: DNS перехватывают много, на разных этапах и с разной целью.
Разработчики популярного сервиса OpenDNS предложили решение проблемы еще несколько лет назад. Они создали опенсорсную утилиту DNSCrypt и одноименный протокол, который играет для DNS-запросов такую же роль, как и SSL для HTTP.
Во-первых, DNSCrypt зашифрует с помощью стойкой эллиптической криптографии сообщения между вашим компьютером и DNS-сервером. Это защитит их от прослушки и MITM.
Во-вторых, вы больше не привязаны к серверу провайдера или настройкам своего роутера. DNSCrypt обращается за адресами напрямую на указанный вами сервер.
До сих пор для применения DNSCrypt пользователям было необходимо установить на компьютер отдельную утилиту. Это не сложно, но без широкого распространения знаний об угрозе и способах ее решения вряд ли стоит рассчитывать на массовое применение технологии.
Поддержка DNSCrypt в Яндекс.Браузере
Наша команда считает шифрование DNS не менее важным, чем переход на HTTPS, поэтому мы решили поддержать DNSCrypt на уровне Яндекс.Браузера. И сегодня мы начинаем тестирование новой бета-версии Яндекс.Браузера 16.4, пользователи которой могут включить в настройках защиту DNS-запросов.
При этом все запросы в зашифрованном виде будут отправляться на быстрый DNS-сервер Яндекса, который также получил поддержку протокола DNSCrypt. Ограничивать пользователей только одним сервером мы не хотим, поэтому уже в ближайшее время добавим в этом месте возможность выбрать альтернативный DNS-сервер (например, тот же OpenDNS).
И еще кое-что. Подменить IP-адрес на фишинговый можно не только через перехват запроса, но и через самый обычный системный host-файл. Поэтому мы сейчас экспериментируем с запретом использовать системный резолвер в случае недоступности DNS-сервера. Мы понимаем, что включение этой опции по умолчанию может навредить пользователям корпоративных и локальных ресурсов, поэтому пока только наблюдаем и собираем отзывы.
Resolve IP адресов в Linux: понятное и детальное описание
Настройка сетевого взаимодействия сервисов не самая простая задача и часто осуществляется без глубокого понимания как требуется настраивать систему и какие настройки на что влияют. После миграции сервисов в docker контейнерах с centos 6 на centos 7 я столкнулся со странным поведением вебсервера: он пытался присоединиться к сервису по IPv6, а сервис же слушал только IPv4 адрес. Стандартный совет в такой ситуации — отключить поддержку IPv6. Но это не поможет в ряде случаев. Каких? В этой статье я задался целью собрать и детально объяснить как приложения resolve ‘ят адреса.
Публикация будет полезна начинающим администраторам и разработчикам.
Прочитав эту статью, вы узнаете:
А еще я веду телеграм канал Об IT без галстуков и блог. На канале рассказываю о проблемах менеджмента и как их решать, пишу о принципах мышления при решении бизнес задач, о том как стать эффективным и высокоплачиваемым специалистом.
Теперь, когда у разработчика есть возможность вызвать функцию семейства getaddrinfo из glibc для определения адреса, то возникает потребность конфигурировать возвращаемые значения. Например, использовать ли сперва /etc/hosts или запрос к DNS-серверу. В glibc подобное конфигурирование производится с помощью схемы под названием Name Service Switch (NSS).
Если объяснять на пальцах, то NSS позволяет задавать базы данных и очередность поиска в этих базах для предоставления сервиса. В нашем случае, сервис — это поиск по hostname, а базой данных может выступать /etc/hosts или DNS сервер. Это не единственный сервис настраиваемый посредством NSS, предоставляются сервисы mail алиасов, сервис поиска пользователей и групп. Ознакомится со списком можно в руководстве.
Можно отметить, что для localhost имеются две записи: IPv4 и IPv6 адрес. Это может сыграть злую шутку и в конце материала я расскажу почему.
В мануале еще пишут про особую логику с обработкой хостнейма _gateway, но видимо это какой-то патч, так как с Centos 7 у меня он не завелся.
База mdns4_minimal или же mdns_minimal требуется для корректной работы Avahi. При необходимости можно обратиться к документации Arch по Avahi, где коротко и понятно дана информация
по использованию.
Теперь, когда дана информация по базам и принципам их работы стоит отметить отличия в определении адресов в разных инструментах, что приводит к проблемам в рантайме.
Обычно администраторы проверяют хостнейм используя команду host. Это некорректно, так host, как и dig, используют только DNS резолвинг, но не используют NSS. Nginx, например, использует функцию getaddrinfo, а она использует NSS. Это приводит к тому, что вбитый в /etc/hosts хостнейм может работать с nginx, но не резолвится иными способами. Куда хуже, когда в /etc/hosts вбиты IPv6 адрес для хостнейма, а в настройках DNS возвращается только IPv4 адрес. В этом случае, администратор может проверить что команда host возвращает только IPv4 адрес и успокоится, а потом приложение использующее getaddrinfo из glibc запустится и найдет для того же хостнейма IPv4 и IPv6 адрес. Источник ошибок…
Для проверки результатов возвращаемой каждой из баз документация рекомендует воспользоваться утилитой getent.
Ниже немного примеров работы с getent с включенным IPv6.
В /etc/nsswitch.conf содержится следующая цепочка баз:
В /etc/hosts содержится следующее инфо
Команда getent ahosts покажет список всех адресов которые удалось найти. С такими настройками она выведет следующее:
Команда позволяет точечно опросить конкретную базу и выяснить что срезолвит база. Рассмотрим для каждой базы возвращаемые значения:
Если убрать из /etc/hosts строки для localhost, то вывод видоизменится:
Теперь база dns и myhostname возвращает ответы, а база files не содержит данных. Для DNS запросов используется неймсервер конфигурируемый в /etc/resolv.conf в моем контейнере, например
На хост машине установлен dnsmasq который проксирует и кэширует ответы DNS серверов. Ответ от DNS будет зависеть от настроек DNS сервера к которому поступил запрос. RFC 1912 рекомендует в пункте 4.1 сконфигурировать DNS сервера таким образом, чтобы localhost указывал на 127.0.0.1.
Certain zones should always be present in nameserver configurations:
These are set up to either provide nameservice for «special»
addresses, or to help eliminate accidental queries for broadcast or
local address to be sent off to the root nameservers. All of these
files will contain NS and SOA records just like the other zone files
you maintain, the exception being that you can probably make the SOA
timers very long, since this data will never change.
The «localhost» address is a «special» address which always refers to
the local host. It should contain the following line:
В моем случае, dnsmasq из коробки содержит записи для localhost, как и рекомендует RFC.
Статус IPv6 на сервере можно получить из параметров ядра. Значение 0 возвращается при включенном IPv6, а 1 при выключенном.
В выводе ifconfig интерфейсы слушающие IPv6 содержат строчку inet6. Ниже пример вывода с выключенным и включенным IPv6 соответственно:
Выключить IPv6 можно вызовом
Воу, в первом выводе у нас дублируется адрес 127.0.0.1. Чтобы разобраться почему так происходит стоит обратиться к исходному коду glibc и к коду утилиты getent. Ниже кусок кода утилиты getent.
Флаг AI_V4MAPPED функции getaddrinfo производит маппинг IPv6 адресов на IPv4 если не были найдены IPv6 адреса в результате опроса базы. Флаг AI_ADDRCONFIG вынудит getaddrinfo проверить наличие IPv6/IPv4 адресов сконфигурированных в системе и в случае отсутствия хотя бы одного IPv6/IPv4 адреса не будет возвращаться IPv6/IPv4 независимо от того что ответит конкретная база.
Чтобы лучше понять эту концепцию, приведу примеры с выводом getaddrinfo на той же системе, с разными настройками ai_flags и ai_family. В /etc/hosts включены для localhost IPv4 и IPv6 адреса.
Исходный код можно найти на моем github.
Осталось проверить как ведет себя getaddrinfo для dns базы. Для этого оставлю в /etc/nsswitch.conf для hosts только dns базу и порезолвлю google.com. Вывод ниже с включенным IPv6.
А вот вывод с выключенным IPv6:
Как видно, ситуация с AI_ADDRCONFIG очень похожа.
Напоследок приведу пример как не учитывая все вышесказанное вляпаться в проблемы. IPv6 включен, /etc/nsswitch.conf стандартный.
Какой можно сделать вывод из всего написанного?
dxdt.ru: занимательный интернет-журнал
Техническое: DNSCrypt на примере “Яндекс.Браузера”
Нередко спрашивают, что такое DNSCrypt и зачем это нужно. Некоторое время назад я уже писал про DNSCrypt, применительно к “Яндекс.Браузеру”, тогда речь шла о поддержке в бета-версии браузера. В этот раз посмотрим на технологию в подробностях, а “Яндекс.Браузер” послужит примером и источником лабораторных данных. Разбор пакетов я провожу в Wireshark, для которого написал небольшой парсер DNSCrypt (в терминологии Wireshark – это dissector, на языке Lua; штатного парсера DNSCrypt в Wireshark-е мне выявить не удалось).
DNSCrypt – это прокси-сервис, создающий защищённый канал между клиентским резолвером DNS и рекурсивным DNS-резолвером, исполняемым на сервере. У DNSCrypt, соответственно, две части: клиентская и серверная. Через трафик DNS, который штатно передаётся в открытом виде, могут утекать сведения о посещаемых сайтах. Кроме того, запросы DNS – распространённый вектор атак для подмены адресов. Замена адреса системного резолвера DNS на адрес подставного сервера является общим местом троянских программ уже много лет. То же самое относится к атакам на домашние роутеры. DNSCrypt позволяет зашифровать (а также – ограниченно защитить от подмены) и запросы, и ответы DNS. Предусмотрена возможность аутентификации сервера и клиента, но эта возможность не всегда используется. Вообще, тема сокрытия DNS-трафика (DNS Privacy) сейчас набрала заметную популярность. Кроме DNSCrypt, существует, например, протокол “DNS через TLS” (DNS over TLS – свежий RFC 7858, который, несмотря на некоторую “перевёрнутость”, выглядит не хуже DNSCrypt). Есть и другие разработки.
DNSCrypt. Протокол может использовать в качестве транспорта как TCP, так и UDP. На практике, предпочтение отдаётся UDP, если он доступен, но спецификация строго требует поддержки именно TCP (не UPD, поддержка которого опциональна). TCP, естественно, привлекает сессионной природой. Но UDP – гораздо быстрее, особенно для нагруженных сервисов. Из-за проблем с DDoS-атаками и некоторых других вопросов обеспечения безопасности, сейчас наметилось модное движение в сторону перевода максимального числа сервисов на TCP, это особенно касается DNS. Тем не менее, ниже я рассматриваю работу DNSCrypt только по UDP, так как это традиционный для DNS вариант. Рекомендованный номер (серверного) порта DNSCrypt – 443 (он обычно открыт в корпоративных сетях; практика использования 443/udp, например, является стандартной для целого ряда VPN и других сервисов; 443/tcp – это TLS/HTTPS, фундамент веб-сервисов). Впрочем, “Яндекс” в своей реализации DNSCrypt использует непривилегированный номер: 15353, вероятно, это связано с какими-то идеями по преодолению разнообразных сетевых барьеров.
Чуть подробнее о барьерах: никаких проблем с блокированием трафика DNSCrypt, при наличии такого желания у провайдера канала, не возникнет. Как будет ясно из описания ниже, этот протокол никак не пытается скрыть сам факт своего использования. В трафик данного протокола включаются стандартные маркеры, которые позволят обнаружить и зафильтровать пакеты даже на самом примитивном маршрутизаторе, с помощью нехитрого правила “в две строчки”. При этом, например, доступ для других TCP-сессий, работающих на 443 порту, сохранится.
В DNSCrypt установление сессии между клиентом и сервером начинается с обычного DNS-запроса, отправленного на адрес и соответствующий номер порта узла, который будет предоставлять функции резрешения (резолвинга) имён. Это запрос TXT-записи для имени специального вида (то есть, запрос уже можно легко зафильтровать). Например, в случае с сервисом “Яндекса”: 2.dnscrypt-cert.browser.yandex.net. Это специальное имя может быть не делегировано. Значение 2 – соответствует версии DNSCrypt. Актуальная версия – вторая. В ответ сервер должен прислать один или несколько сертификатов DNSCrypt (подчеркну: они не имеют никакого отношения к SSL-сертификатам).
На скриншоте – пакет с сертификатом от сервера DNSCrypt “Яндекса”.
Сертификат представляет собой набор из нескольких полей: версия сертификата, значение подписи, открытый ключ сервера, magic-байты для клиента (они послужат идентификатором клиентских запросов – сервер сможет понять, какой ключ использовать при ответе), серийный номер и срок действия.
Спецификация предполагает, что в составе сертификата сервер передаёт кратковременный открытый ключ. (Впрочем, в случае с сервером “Яндекса”, данный ключ не меняется, как минимум, с конца марта, когда была запущена бета-версия браузера с поддержкой DNSCrypt.) Подпись на сертификате должна генерироваться от другой пары ключей. Открытый ключ этой пары известен клиенту – он необходим для проверки подписи. Очевидно, подписывать сертификат тем же ключом, который используется в рамках сессии – бессмысленно. Я не проверял, проводит ли валидацию серверного сертификата “Яндекс.Браузер”. Дело в том, что в модели угроз, на которую ориентировано использование DNSCrypt в “Яндекс.Браузере”, валидация сертификата особого смысла не имеет, как и сравнение значения ключа с сохранённой копией (я вернусь к этому моменту ниже).
В качестве криптографических примитивов DNSCrypt использует конструкции из шифра Salsa20 (XSalsa20), хеш-функции Poly1305 (для реализации аутентифицированного шифрования) и алгоритм X25119-hsalsa20 для выработки общего сеансового ключа (алгоритм использует эллиптическую кривую Curve25119 и хеш-функцию hsalsa20). Эти конструкции разработаны Даниэлем Бернштейном (Daniel J. Bernstein) и давно получили признание как весьма добротные. Алгоритм получения общего секрета (сеансового ключа) математически родственен алгоритму Диффи-Хеллмана. Отмечу, что общий секрет в данном случае можно восстановить постфактум, если станет известен соответствующий секретный ключ из пары серверных (или клиентских) ключей, это позволит расшифровать ранее записанный трафик, именно поэтому спецификация рекомендует использовать кратковременные ключи.
Шифр XSalsa20 в режиме аутентифицированного шифрования требует nonce длиной 192 бита (24 байта). Повторное использование одного и того же сочетания ключа и nonce не допускается. Это связано с архитектурой шифра XSalsa20 – повторное использование nonce приведёт к утечке: прослушивающей стороне станет известно значение XOR от пары соответствующих открытых текстов. Поэтому nonce должно быть каждый раз новым, но не обязательно случайным. Параметр nonce в DNSCrypt присутствует в двух воплощениях: клиентской и серверной.
Посмотрим на зашифрованный клиентский запрос, отправляемый “Яндекс.Браузером”.
Первое поле запроса – это клиентское значение magic (Client query magic bytes): здесь используется часть открытого ключа сервера, полученная ранее. При необходимости, данные “магические байты” могут служить сигнатурой, позволяющей выбирать в трафике запросы, отправляемые к DNSCrypt;
Следующее поле – кратковременный клиентский открытый ключ (Client public key);
Клиентское значение nonce – 96 бит (12 байтов), половина от требуемого значения nonce для шифра XSalsa20 (согласно спецификации DNSCrypt, дополняется байтами со значением 0). Можно использовать тот или иной счётчик, “Яндекс.Браузер” так и поступает: cудя по всему, здесь передаётся 64-битное значение миллисекундного таймстемпа (время формирования запроса), к которому дописываются четыре байта псевдослучайных значений. На случай, если это действительно точное время, передаваемое в открытом виде, отмечу, что параметры дрейфа системных часов служат неплохим признаком, идентифицирующим конкретное аппаратное устройство, – то есть, могут быть использованы для деанонимизации;
Последнее поле – это сам зашифрованный запрос. Для шифрования используется общий секретный ключ, который вычисляется сторонами на основании переданных открытых ключей. В случае с клиентом – открытый ключ передаётся в пакете DNS-запроса (см. выше). “Яндекс.Браузер” следует стандартной практике и генерирует новую пару ключей (открытый/секретный) для X25119-hsalsa20 при каждом старте барузера. Для выравнивания данных на границу 64-байтового блока, как предписывает спецификация, используется стандартное дополнение (ISO/IEC 7816-4: 0x80 и нулевые байты в требуемом количестве).
Блок зашифрованных данных – это, скорее всего, результат использования функции crypto_box из библиотеки libsodium (либо NaCl, на которую ссылается спецификация DNSCrypt; libsodium – это форк NaCl). Я предположил, что 16-байтовый код аутентификации (MAC), который используется для проверки целостности сообщения перед расшифрованием, находится, вероятно, в начале блока. Впрочем, так как расшифровать данные я не пытался, то и определение расположения кода не столь важно. Для расшифрования можно использовать секретный ключ, который содержится в памяти во время работы браузера, но чтобы его извлечь – нужно некоторое время повозиться с отладчиком и дизассемблером.
Зашифрованный ответ, полученный от сервера:
(Нетрудно заметить, что ответ, представленный на скриншоте, поступил почти через пять секунд после запроса, почему так получилось – видимо, тема для отдельной записки.)
Пакет открывается magic, в данном случае, это байты, содержащие маркер ответа DNSCrypt (опять же, хорошая сигнатура для обнаружения трафика). Эти байты определены протоколом и должны присутствовать в начале всякого ответа сервера на запрос DNS-резолвинга;
Следующее поле – nonce (Response nonce). Поле содержит значение nonce, использованное сервером при шифровании данного ответа. Поле строится из двух равных частей, по 12 байтов: nonce из соответствующего клиентского запроса и серверное дополнение;
Заключительная часть пакета – зашифрованные данные ответа, формат аналогичен запросу.
Теперь вернёмся к модели угроз, на примере “Яндекс.Браузера”. Если в настройках браузера включено использование DNSCrypt, например, через серверы “Яндекса”, но доступ к соответствующему серверу заблокирован, то браузер (как и бета-версия) прозрачно, без предупреждений, переходит к использованию системного резолвера. Почему это лишает смысла необходимость валидации сертификатов серверов DNSCrypt? Потому что активная атакующая сторона, которая может подменять пакеты на уровне IP, для отключения DNSCrypt в браузере может просто заблокировать доступ к серверу, вместо того, чтобы тратить ресурсы на поделку ответов. Из этого можно сделать вывод, что модель угроз “Яндекса” не включает активную подмену пакетов на пути от сервера DNSCrypt к клиенту.
В качестве завершения, пара слов о том, как DNSCrypt относится к DNSSEC. DNSSEC – не скрывает данные DNS-трафика, но защищает их от подмены, вне зависимости от канала обмена информацией. В случае с DNSSEC – не имеет значения, по какому каналу получены данные из DNS, главное, чтобы ключи были на месте. DNSCrypt – скрывает трафик и ограниченно защищает его от подмены на пути от рекурсивного резолвера (сервиса резолвинга) до клиента. Если данные были подменены на пути к резолверу (или на самом сервере резолвера), а он не поддерживает DNSSEC, то клиент получит искажённую информацию, хоть и по защищённому DNSCrypt каналу. Серверы, предоставляющие DNSCrypt, могут поддерживать и DNSSEC.