Автор: Редакция «VPN не работает»

DNS не работает через VPN

Если DNS не работает через VPN, сам канал обычно исправен: рукопожатие прошло, трафик идёт, а превратить имя сайта в адрес некому. Разводит эти два случая пара запросов — по IP-адресу и по имени. Пакеты по адресу ходят, а по имени нет — ни шифрование, ни маршруты трогать не надо.

Коротко. Убедитесь, что туннель жив: wg show печатает latest-handshake и счётчики transfer. Дальше три причины. На Linux строка DNS = не применяется без resolvconf — в Debian пакет лежит в Suggests. На Android строгий «Приватный DNS» ходит по DoT на порт 853 и отката на порт 53 не имеет. Третья — размер: по UDP всё длиннее 512 байт усекается с битом TC, а буфер EDNS с 2020 года равен 1232 байтам.

Как отличить сбой резолвинга от пропажи сети?

Тремя командами:

  1. ping 1.1.1.1 — проходимость канала по адресу, без участия имён.
  2. nslookup example.com — получение адреса по имени.
  3. wg show — состояние туннеля.

Первая отвечает, вторая молчит — виноват DNS. Свежий latest-handshake в выводе wg show значит, что пакеты доходят в обе стороны. Растущий transfer-tx при нулевом transfer-rx — уже не про имена, а про отсутствие ответов вообще: этот случай разобран в статье «подключён, но сайты не открываются».

Почему поле DNS в конфиге не применяется на Linux?

Потому что применяет его внешняя утилита, а не сам wg-quick. По man-странице wg-quick(8) строка DNS в секции [Interface] задаёт и резолверы, и поисковые домены — различаются они по формату значения. При подъёме скрипт вызывает resolvconf -a tun.<интерфейс> -m 0 -x, при опускании — resolvconf -d ..., а список подаёт на stdin строками nameserver .... Нет resolvconf — применять нечем: интерфейс поднимется, а резолвер останется прежним. В Debian wireguard-tools предлагает «openresolv | resolvconf | systemd-resolved» в Suggests, а не в Recommends: по умолчанию не ставится ничего.

Флаг -x не косметика: он отображается в дополнительный поисковый домен ~., после чего запросы преимущественно уходят на резолверы этого интерфейса — кроме доменов, явно закреплённых за другими линками; без -x они разъезжаются по всем линкам. Сама поддержка -x в systemd-resolvconf реализована частично. Без resolvconf DNS навешивают через PostUp и PostDown — man называет их обычным местом для таких настроек.

Чем смотреть реальные резолверы вместо resolv.conf?

Командой resolvectl status: она показывает глобальные и по-интерфейсные настройки DNS, действующие сейчас. Рядом — resolvectl query <имя> и resolvectl flush-caches. Привычный cat /etc/resolv.conf при systemd-resolved бесполезен: /run/systemd/resolve/stub-resolv.conf держит единственным сервером заглушку 127.0.0.53, и дальнейший маршрут запроса не виден.

Что делать с приватным DNS на Android?

На время диагностики перевести его в «Автоматически» или «Выключено» — менять хост бесполезно. Функция появилась в Android 9 (API level 28): Settings → Network & internet → Private DNS. Строгий режим (вписано имя хоста) требует TLS-соединения на порт 853; невозможность его установить — жёсткая ошибка, при которой служба DNS не работает вовсе, отката на порт 53 нет. Оппортунистический режим при неудаче возвращается на порт 53 без защиты.

Обратная половина: javadoc VpnService.Builder.addDnsServer говорит, что при незаданном сервере используются DNS-серверы сети по умолчанию. При пустом поле DNS туннель работает, а имена уходят к резолверу оператора или Wi-Fi — это и есть утечка. Остальное — в разборе VPN не работает на Android.

Откуда берётся утечка DNS на Windows?

Из механизма Smart Multi-Homed Name Resolution: система шлёт параллельные запросы DNS, LLMNR и NetBIOS по всем сетям и при нескольких ответах выбирает по порядку привязки. Отключает его политика «Turn off smart multi-homed name resolution»; в реестре — Software\Policies\Microsoft\Windows NT\DNSClient, значение DisableSmartNameResolution.

Клиент WireGuard для Windows закрывает это фаерволом, но только когда у интерфейса ровно один пир и у него в AllowedIPs есть префикс /0 (0.0.0.0/0 или ::/0): тогда пакеты на порт 53 пропускаются лишь к резолверам из конфигурации. Замена маршрута парой 0.0.0.0/1 и 128.0.0.0/1 выглядит эквивалентно, но документация предупреждает: фаервольная семантика не активируется. Проверка — nslookup mydomain.com 1.1.1.1 (первый параметр имя, второй сервер), set vc переводит на TCP; в PowerShell — Resolve-DnsName с -Server, -TcpOnly, -DnsOnly.

Почему большие ответы DNS теряются в туннеле?

Потому что размер ответа упирается в MTU. RFC 1035 ограничивает сообщения по UDP 512 байтами; длиннее — усечение и бит TC в заголовке. RFC 7766 (март 2016) сделал TCP обязательным транспортом DNS, а не аварийным.

EDNS(0) (RFC 6891) даёт объявить буфер больше, но предупреждает: слишком большое значение гарантирует фрагментацию на уровне IP, а потеря одного фрагмента убивает весь ответ. DNS Flag Day 2020 зафиксировал дефолт 1232 байта — MTU 1280 из спецификации IPv6 минус 48 байт заголовков (edns-buffer-size: 1232 в Unbound).

Режет и сам туннель: wg-quick вычитает из MTU пути ровно 80 байт, при обычных 1500 интерфейс получает 1420. Клиент для Windows делает так же, а Android-приложение WireGuard без поля MTU ставит 1280 — поэтому совет «поставьте 1280» на телефоне часто не меняет ничего. Симптом: короткие A-записи разрешаются, а DNSSEC и длинные TXT виснут.

Симптом, причина и команда проверки

Что наблюдаетеВероятная причинаЧем проверить
По IP-адресу открывается, по имени нетРезолвер недоступен из туннеляnslookup example.com 1.1.1.1
wg-quick не нашёл команду resolvconfПакет в Suggests, не установленtype -P resolvconf пусто → openresolv или PostUp
/etc/resolv.conf показывает 127.0.0.53Заглушка systemd-resolvedresolvectl status, блок нужного интерфейса
Android: туннель есть, имена не разрешаютсяСтрогий приватный DNS без откатаПриватный DNS → «Автоматически»
Windows: отвечает домашний резолверSmart Multi-Homed Name ResolutionResolve-DnsName example.com -DnsOnly
TXT и DNSSEC виснут, A-записи приходятУсечение больших ответовdig +tcp example.com, буфер 1232

Сколько признаков страны видит сайт?

Как минимум четыре, и расходятся они независимо: адрес выхода туннеля, резолвер, WebRTC и часовой пояс. Резолвер попал в список из-за EDNS Client Subnet (RFC 7871): иначе авторитетный сервер видит адрес рекурсивного резолвера, а не источника запроса, и CDN подбирают узел по нему. Про WebRTC то же говорит RFC 8828 (январь 2021): раскрыться может и адрес туннеля, и адрес провайдера. Поэтому утечка DNS и «не та страна» — разные последствия одного дефекта; что видно снаружи, разобрано на странице про безопасность VPN.

Частые вопросы

Короткие ответы на типовые вопросы про разрешение имён собраны ниже.

Как понять, что виноват именно DNS, а не туннель?

Двумя запросами подряд: `ping 1.1.1.1` идёт по адресу, `nslookup example.com` — по имени. Если по адресу пакеты ходят, а по имени нет, сеть и шифрование исправны. Состояние канала подтверждает `wg show`: свежий latest-handshake означает, что пакеты доходят в обе стороны, и чинить надо только разрешение имён.

Почему строка DNS в конфиге WireGuard не работает на Linux?

Потому что wg-quick применяет её через внешнюю утилиту: при подъёме интерфейса он вызывает `resolvconf -a tun.<интерфейс> -m 0 -x`. В Debian пакет resolvconf идёт в Suggests, а не в Recommends, поэтому на чистой системе его просто нет и применять DNS нечем. Ставится openresolv, либо резолвер навешивается через `PostUp` и `PostDown`. Симлинк resolvectl под именем resolvconf — плохая замена: wg-quick проверяет, что бинарник не символическая ссылка, и иначе не добавляет префикс tun.

Нужно ли отключать приватный DNS на Android при диагностике?

На время проверки — да, режим «Автоматически» или «Выключено». Строгий режим работает по DNS over TLS на порту 853 и при недоступном резолвере отката на порт 53 не имеет вовсе: служба DNS просто перестаёт работать. Плюс само имя хоста (`dns.google` у Google, `one.one.one.one` у Cloudflare) нужно чем-то разрешить в момент старта туннеля.

Какой MTU ставить, чтобы не терялись большие ответы DNS?

Универсального числа нет. wg-quick и официальный клиент для Windows вычитают из MTU пути 80 байт, поэтому при обычных 1500 интерфейс получает 1420. Android-приложение WireGuard без явного поля MTU ставит 1280, и совет «поставьте 1280» там ничего не меняет. Со стороны резолвера ориентир другой: DNS Flag Day 2020 зафиксировал буфер EDNS в 1232 байта.

Чем утечка DNS отличается от неверной страны на сайте?

Это разные последствия одного дефекта. При утечке запросы имён уходят к резолверу провайдера, и он видит, какие домены вы запрашиваете. При геонесовпадении CDN выбирает узел по расположению резолвера: механизм EDNS Client Subnet (RFC 7871) появился именно потому, что иначе авторитетный сервер видит адрес рекурсивного резолвера, а не источника запроса.

Что проверить с DNS в Amnezia, если имена не разрешаются?

Проверьте, установлен ли AmneziaDNS и включён ли он: без него подключение использует адреса из настройки DNS-серверов, и сбой ищется там же, где на любом другом клиенте. По документации служба поднимает DNS-резолвер внутри серверной Docker-сети, клиенты шлют запросы через туннель вместо DNS-серверов локального провайдера, а домены по умолчанию разрешаются по шифрованному соединению к Cloudflare DNS.

Поделиться: Telegram ВКонтакте