Skip to content

DNS ​

DNS сообщает, какой IP-адрес у сайта. В режиме VPN на DNS-запросы программ отвечает ядро, используя DNS-серверы из настроек приложения. Адреса нужны и самому ядру: чтобы проверить правила по IP, соединиться с сайтом напрямую и найти ваш сервер.

ПрограммаЯдроСервер VPNРезолверyoutube.comобычный сайт1.1.1.1настоящий адрес, запрос шёл через VPNvpn.exampleадрес вашего сервера1.1.1.1напрямую – через сам сервер его адрес не узнатьyoutube.comс Fake IPядро сразу отвечает 198.18.0.7
Три запроса, когда «Всё остальное» идёт через VPN, а DNS-серверы стоят по умолчанию. Пустой кружок – запрос проходит мимо этой точки.

Перехват ​

В режиме VPN ядро перехватывает все DNS-запросы программ и отвечает на них само. В режиме Прокси перехвата нет: программа либо сама узнаёт адрес, либо передаёт прокси имя сайта, и тогда адрес узнаёт ядро.

Частный DNS на Android ​

В режиме «Автоматически» Android проверяет, поддерживает ли DNS-сервер сети DoT, и если да, переключается на него. Ядро перехватывает только обычный DNS, поэтому приложение указывает системе DNS-сервер внутри туннеля, где DoT нет. Иначе весь системный DNS шёл бы мимо ядра, и свои DNS-серверы из настроек не работали бы совсем.

Если в «Частном DNS» указано имя сервера, Android подключается к нему по DoT сам, через туннель, как к обычному сайту. Свои DNS-серверы из настроек тогда не используются, но маршруты по доменам работают: имя сайта ядро видит в самом соединении.

Куда ядро ходит за ответом ​

По умолчанию это DoH от Cloudflare и Google: https://1.1.1.1/dns-query и https://8.8.8.8/dns-query.

«Всё остальное»Как идут DNS-запросы ядра
через VPNчерез ваш сервер; провайдер видит только соединение с сервером
напрямую или в блокс устройства напрямую

Xray опрашивает серверы по очереди: если один не ответил за 2,5 с, он спрашивает следующий. Последним идёт системный DNS. Там, где провайдер режет DoH, без него ядро не нашло бы даже адрес вашего сервера. mihomo опрашивает все серверы сразу и берёт первый ответ.

Как это выглядит в конфиге ядра

Для маршрутов из примера на странице Маршрутизация:

json
"dns": {
  "servers": [
    {"address": "localhost", "domains": ["domain:direct.example"], "skipFallback": true},
    {"address": "https://1.1.1.1/dns-query"},
    {"address": "https://8.8.8.8/dns-query"},
    {"address": "localhost"}
  ],
  "queryStrategy": "UseIPv4"
}
yaml
dns:
  enable: true
  ipv6: false
  nameserver: [https://1.1.1.1/dns-query, https://8.8.8.8/dns-query]
  proxy-server-nameserver: [https://1.1.1.1/dns-query, https://8.8.8.8/dns-query]
  direct-nameserver: [https://1.1.1.1/dns-query, https://8.8.8.8/dns-query, 1.1.1.1, 8.8.8.8]
  respect-rules: true

Домены из «Напрямую» ​

CDN выдаёт узел, ближайший к тому, кто спрашивает. Если узнать адрес сайта из «Напрямую» через VPN, вернётся узел рядом с сервером, хотя соединение пойдёт из дома. Поэтому адреса доменов из «Напрямую» тоже узнаются напрямую.

Xray. За это отвечает настройка «Отдельный резолвер для direct-доменов», по умолчанию она включена. Домены из «Напрямую» резолвит системный DNS, поэтому находятся и имена из домашней или рабочей сети. Если заданы свои DNS-серверы, их резолвит первый из них. Это не касается сайта из маршрута, который поднят выше «Напрямую»: его адрес узнаётся так же, как у остальных сайтов.

mihomo. Делает так всегда. Для этого к DoH добавлен обычный DNS на тех же адресах: часть провайдеров режет DoH, и сайты из «Напрямую» открывались с задержкой в 5 секунд (issue #9). Для остальных сайтов обычный DNS не используется, потому что в нём провайдер подменяет адреса заблокированных доменов.

Адрес вашего сервера ​

Если сервер указан именем, ядро всегда узнаёт его адрес напрямую: туннеля в этот момент ещё нет.

Свои DNS-серверы ​

Один адрес на строку или несколько через запятую.

ЗаписьXraymihomo
https://dns.example/dns-queryDoHDoH
tls://1.1.1.1нетDoT
quic://dns.exampleDoQ, всегда напрямуюDoQ
9.9.9.9, udp://9.9.9.9обычный DNSобычный DNS
tcp://9.9.9.9обычный DNS по TCPобычный DNS по TCP
localhostсистемный DNSсистемный DNS
h2c://dns.example/dns-queryDoH без TLSнет
dhcp://en0нетDNS из настроек сети
https+local://…напрямую, мимо маршрутовнапрямую, мимо маршрутов

Запись, которую текущее ядро не понимает, пропускается. sdns:// не понимает ни одно из них.

Свои адреса для доменов ​

Записи hosts – это имя и адрес через пробел, по одной на строку. Адрес может быть IPv4 или IPv6. Порядок «адрес имя», как в файле hosts, тоже подходит. Вместо адреса можно указать другое имя.

nas.home 192.168.1.10, fd00::10
*.dev.example 10.0.0.5
old.example new.example

«Резолвер для отдельных доменов» задаёт, какой DNS-сервер отвечает за конкретный домен:

home.lan 192.168.1.1
*.corp.example https://dns.corp.example/dns-query

В этих двух полях имя без маски совпадает только с самим доменом, для поддоменов нужна маска *.. В маршрутах наоборот: там vk.com уже включает поддомены.

IPv4 и IPv6 ​

СтратегияКакие адреса запрашивает ядро
UseIPv4, по умолчаниютолько IPv4
UseIPIPv4 и IPv6
UseIPv6только IPv6

PreferIPv4 и PreferIPv6 есть только у Xray: ядро узнаёт адреса обоих видов, но подключается сначала по IPv4 (или по IPv6), а по другому протоколу – только если таких адресов у сайта нет. У mihomo есть только UseIPv4 и UseIP, причём UseIPv4 отключает у него IPv6 полностью, а не только в DNS.

Fake IP ​

Обычно программа ждёт, пока ядро узнает настоящий адрес сайта, а когда «Всё остальное» идёт через VPN, это запрос через сервер. С Fake IP ядро сразу отвечает подставным адресом из 198.18.0.0/16 и запоминает, для какого сайта его выдало. Когда программа подключается к этому адресу, ядро отправляет на сервер имя сайта, и настоящий адрес ищет уже сервер. Первое открытие сайта становится быстрее на один запрос до сервера и обратно.

  • Работает только в режиме VPN.
  • Подставной адрес живёт 1 секунду, поэтому после отключения VPN он не остаётся в кэше системы.
  • Проверки связи и локальные имена всегда получают настоящий адрес: *.lan, *.local, *.home.arpa, localhost, connectivitycheck.gstatic.com, *.msftconnecttest.com, captive.apple.com, *.ntp.org и подобные. Если система получит подставной адрес для проверки связи, она покажет «нет интернета», хотя VPN работает.

Тест на утечку показывает чужой резолвер ​

Тесты вроде dnsleaktest показывают Google или Cloudflare, хотя в приложении указан, например, Quad9. Это не утечка.

Ядро узнаёт адрес через свой DNS, чтобы проверить маршруты, но серверу отправляет имя сайта, а не найденный адрес. Сервер узнаёт адрес заново через свой резолвер, и тест видит именно его. Изменить это можно только в настройках сервера.

Ещё один частый источник лишнего резолвера – DoH в самом браузере. Firefox по умолчанию ходит к Cloudflare, и ядро не видит такой запрос как DNS.

Готовый конфиг провайдера ​

Если в готовом конфиге Xray или Clash есть свой DNS, работает он. Пункт «DNS» в «Не учитывать от провайдера» на экране маршрутизации заменяет его на DNS из настроек приложения.