Pi-hole v6 принимает DNS-запрос на порту 53 и затем решает, можно ли ответить на пришедший пакет. На хосте WireGuard это второе решение обычно и объясняет, почему клиент получает тайм-аут, хотя резолвер выглядит здоровым из LAN. Порт открыт, FTL работает, но из 10.90.0.1 ничего не возвращается. Прежде чем ответ уйдёт, взаимодействуют три вещи: dns.interface, dns.listeningMode и межсетевой экран перед обоими.

Слушающий сокет не решает, кто получит ответ

FTL открывает UDP- и TCP-прослушиватели на порту 53. В конфигурации по умолчанию сокет часто wildcard, поэтому ss -lunp | grep :53 показывает 0.0.0.0:53 и [::]:53 независимо от того, обслуживаются ли клиенты VPN. Wildcard-сокет принимает пакет, затем FTL применяет свои правила интерфейса и источника, прежде чем ответить. Поэтому фраза «порт слушает» доказывает очень мало о клиенте туннеля.

Читайте работающую конфигурацию, а не файл, который вы считаете активным. pihole-FTL --config dns.interface и pihole-FTL --config dns.listeningMode печатают фактические значения, и они могут отличаться от файла хоста, когда настройкой владеет контейнер, переменная среды или менеджер развёртывания. Справочник по конфигурации Pi-hole FTL перечисляет режимы и то, какой из них опирается на интерфейс.

LOCAL спрашивает про подсеть, SINGLE — про интерфейс

LOCAL, режим по умолчанию, отвечает на запросы, адрес источника которых принадлежит подсети, настроенной на одном из интерфейсов хоста. Простой wg0 с 10.90.0.1/24 проходит эту проверку, потому что клиент на 10.90.0.2 находится внутри подсети туннеля. Клиент с маршрутизацией по другую сторону пира, или клиент, скрытый за NAT в другом префиксе, её не проходит, хотя пакет пришёл на wg0, и в журнале не появляется ни одного запроса.

SINGLE меняет вопрос. Он принимает запросы, приходящие на интерфейс, указанный в dns.interface, включая loopback, и игнорирует подсеть источника. Это режим, который выживает в цепочной или маршрутизируемой топологии VPN. Задайте оба ключа вместе, потому что режим без указанного интерфейса — не полная инструкция:

sudo pihole-FTL --config dns.interface "wg0"
sudo pihole-FTL --config dns.listeningMode "SINGLE"

BIND меняет сокет, и у этого есть цена

BIND не фильтрует wildcard-сокет; он привязывает порт 53 только к адресам, которые существуют на указанном интерфейсе, поэтому ядро отвергает пакеты, приходящие в другое место. Он строже SINGLE и не является его синонимом. Цена проявляется при загрузке: если wg0 не поднят, когда FTL стартует, привязывать может быть не к чему, и резолвер может работать без прослушивателя, пока интерфейс не появится и FTL не перезапустится.

Выбирайте BIND, когда вы контролируете порядок запуска, например модуль systemd, упорядоченный после интерфейса WireGuard, и когда хотите, чтобы ядро отбрасывало заблудшие пакеты до того, как их увидит FTL. Выбирайте SINGLE, когда туннель появляется и исчезает, или когда интерфейс создаёт инструмент, запускающийся после FTL.

Межсетевой экран — вторые ворота

Правильный режим FTL всё равно не сработает, если межсетевой экран хоста отбрасывает порт 53 на wg0. Разрешите диапазон источников VPN для обоих протоколов и держите интернет-сторону закрытой. В nftables, с существующей цепочкой input в таблице inet filter, правила выглядят так:

sudo nft add rule inet filter input iifname "wg0" ip saddr 10.90.0.0/24 udp dport 53 accept
sudo nft add rule inet filter input iifname "wg0" ip saddr 10.90.0.0/24 tcp dport 53 accept

Добавьте соответствующие правила IPv6, если туннель несёт IPv6, и поставьте их перед политикой отбрасывания цепочки. Если хост использует ufw или firewalld, выразите то же совпадение в этом менеджере, а не смешивайте инструменты. Не пробрасывайте порт 53 с интернет-маршрутизатора; клиенты должны достигать VPN-адреса резолвера через туннель.

Два пути остаются раздельными. Запросы клиентов завершаются на FTL. Собственные запросы FTL к вышестоящим выходят по таблице маршрутизации хоста, которая может использовать туннель, а может и нет, поэтому резолвер, который отвечает, но не возвращает ничего полезного, — это проблема вышестоящей стороны. Веб-админка и API слушают на своих портах и нуждаются в собственном ограничении.

Проверьте ответ и отказ

С клиента VPN опросите адрес резолвера по обоим протоколам: dig @10.90.0.1 example.com и dig +tcp @10.90.0.1 example.com. Затем проверьте журнал запросов в интерфейсе администратора, чтобы убедиться, что FTL записал запрос. Тайм-аут клиента без записи в журнале указывает на межсетевой экран или фильтр интерфейса; запись без ответа указывает на разрешение на вышестоящей стороне.

Проверьте отрицательный путь с хоста вне VPN. dig @10.90.0.1 example.com должен завершиться тайм-аутом, а ss -lunp на резолвере не должен показывать порт 53, привязанный к публичному адресу. Перезапустите службу один раз, затем перезагрузите хост и убедитесь, что резолвер по-прежнему отвечает после появления wg0. Запрос, который работает только до следующей перезагрузки, — не завершённое изменение.

Похожие статьи