Перейти к основному содержимому

DNS

Сет определяет, какой резолвер отвечает на домены, которые он нацеливает. Всё остальное продолжает уходить на тот резолвер, который выбрал клиент. На этой странице описано, что именно перехватывает b4, что сет делает с совпавшим запросом и какие общие настройки DNS действуют на все сеты.

Что перехватывает b4​

ТранспортКак попадает в b4Когда
UDP порт 53Правила очереди в PREROUTING и OUTPUT, для запросов (dport 53) и для ответов (sport 53)Всегда, пока b4 запущен
TCP порт 53REDIRECT в таблице nat на локальный слушатель, по умолчанию порт 5453Только пока хотя бы у одного включённого сета задан DNS-сервер или DoH-адрес и включён параметр Перехватывать DNS поверх TCP

В обоих случаях это касается и трафика, идущего с устройств сети, и запросов, которые роутер делает для себя. Запросы, которые b4 отправляет за клиента, и его запросы через резолвер сета несут метку очереди, а эти правила пропускают пакеты с ней, поэтому через них такой запрос обратно в очередь не попадает. Запросы, которые b4 делает через резолвер самого роутера, метки не несут.

b4 видит только незашифрованный DNS

Всё, что описано на этой странице, работает с DNS на порту 53. Если устройство само резолвит через DoH, DoT или DoQ, запрос уходит как TLS или QUIC на порт 443 или 853, и b4 его не прочитает: резолвер сета, его закрепления и его блокировки к этому имени не применяются, а маршрутизирующий сет не узнаёт из таких ответов ни одного адреса.

Обычные источники этого - браузер с включённым собственным защищённым DNS (Firefox, Chrome), Android Private DNS и резолвер, прописанный как DoH на самом устройстве. Чтобы работать с DNS через b4, выключите зашифрованный DNS на таких устройствах и оставьте им роутер.

Зашифрованный форвардер на самом роутере - это другое дело, и он не мешает. Устройства по-прежнему обращаются к роутеру на обычный порт 53, b4 перехватывает там, и до форвардера доходит только то, что b4 пропустил.

Как сет обрабатывает запрос​

Имя из запроса сверяется с целями сета так же, как SNI: запись домена покрывает его поддомены, поддерживаются записи regexp:. Обычные записи проверяются раньше регулярных выражений, поэтому домен, указанный в одном сете, не перехватывается заглушкой regexp:.* из другого.

Совпавший запрос b4 проводит по шагам в таком порядке:

  1. Блокировка. Если режим маршрутизации сета - block, запрос получает NXDOMAIN или отбрасывается, в зависимости от действия блокировки. См. Блокировка.
  2. Закреплённые адреса. Если для имени есть закрепление, b4 отвечает из него и на этом останавливается. Это работает независимо от того, включено ли перенаправление ниже.
  3. Резолвер. Если перенаправление включено и резолвер задан, b4 разрешает имя сам и отвечает клиенту напрямую. Иначе запрос уходит без изменений.
  4. Ответ. Адреса из ответа запоминаются для клиента и записываются в IP-сет сета, если включена маршрутизация. Ответ, пересланный или закреплённый, который приносит адреса, не записанные b4 в сет в последнее время, задерживается, пока b4 не закончит обновление сета для этих адресов, но не дольше 250 мс каждый раз, когда b4 его видит, поэтому следующее за ним соединение обычно идёт маршрутом сета. При движке TUN ответ не задерживается; см. Маршрутизация.

Типы резолверов​

Резолвер задаётся в Сеты → сет → DNS & Маршрутизация → Перенаправление DNS.

РежимПоле в конфигурацииЧто делает b4
Обычный DNS (UDP)dns.target_dnsСам отправляет запрос на этот IP, при необходимости фрагментируя его (Фрагментировать DNS-запросы), чтобы пройти DPI, который вычитывает доменные имена из запросов
DNS-over-HTTPSdns.doh_urlОтправляет запрос зашифрованным HTTPS-запросом: сначала POST, а если сервер его не принимает - GET

DoH-адрес имеет приоритет: если заполнены оба поля, используется DoH-адрес, а IP игнорируется. Адрес должен начинаться с https://, это проверяется при сохранении конфигурации.

Запрос с адреса собственного резолвера сета уходит без изменений, а не возвращается ему же, если b4 не блокирует этот запрос и не отвечает на него из закрепления. Резолвер в другом месте сети, который обращается к вышестоящему резолверу по обычному DNS, передаёт запрос клиента дальше через роутер, и если вернуть этот запрос ему же, он ждал бы весь таймаут запроса; любой другой запрос с этого адреса тоже уходит без изменений, в том числе запросы контейнеров и VPN-клиентов, которые выходят в сеть через NAT на хосте резолвера. DoH-адрес сравнивается так же, если сервер в нём указан IP-адресом. Сравнивается только адрес, указанный в сете: запрос, который резолвер отправляет с другого своего адреса, например запрос по IPv4 от резолвера, указанного в сете IPv6-адресом, всё равно возвращается к нему. Для резолвера на самом роутере сравнение не выполняется, чтобы собственные запросы роутера уходили к нему. Такой резолвер, а также резолвер роутера, когда резолвер в сети использует его как вышестоящий, должен обращаться к своему вышестоящему резолверу по протоколу, который b4 не перехватывает, например по DNS поверх HTTPS или TLS.

Перенаправление DNS в режиме DoH

Отправить один сервис на отдельный резолвер​

Частая причина перенаправить один сет - сервис, который отказывается работать из вашего региона. За этим стоят две разные вещи, и только одна из них про DNS.

Имя разрешается не туда. Какой адрес вы получите для имени, зависит от того, кто спросил: geo-DNS отдаёт ближайший к резолверу фронтенд, и резолвер из другого места получает другой ответ. Некоторые публичные резолверы идут дальше и держат собственные фронтенды для фиксированного списка сервисов: они отвечают адресом своего релея, который читает SNI и передаёт соединение дальше. И в том, и в другом случае соединение оказывается на пути, который сервис принимает, а остальной ваш DNS от такого сета не меняется.

Сервис смотрит на адрес, с которого вы подключаетесь. Ответ резолвера ваш собственный адрес не меняет, поэтому проверка, которая происходит уже после установки соединения (аккаунт, оплата, ключ API, привязанный к региону), от смены резолвера не зависит. Здесь нужен другой выход наружу: см. маршрутизацию трафика.

Для первого случая заведите сет, нацеленный только на домены этого сервиса, включите перенаправление и укажите DoH-адрес резолвера. Не добавляйте эти домены в сет-заглушку на всю сеть: смысл как раз в том, чтобы по-другому обрабатывался только этот сервис.

примечание

Резолвер, который отвечает адресами собственных релеев, видит, какие из этих имён вы запрашиваете, и дальше несёт этот трафик через себя. Это осознанное решение о доверии. Направляйте на такой резолвер только те домены, которым это нужно, а обычный просмотр оставьте резолверу, который выбрали бы сами по себе.

Закреплённые адреса​

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

157.240.0.174 www.instagram.com
157.240.205.63 scontent.cdninstagram.com scontent-a.cdninstagram.com
  • Сначала адрес, затем имена, для которых им нужно отвечать.
  • Закрепление действует на каждое имя и его поддомены, побеждает самая длинная подходящая запись.
  • Закрепление работает только для имени, которое сет уже нацеливает. Закрепление имени, не покрытого целями сета, не даёт ничего: интерфейс предупреждает об этом и предлагает добавить имя в домены сета.
  • Список закреплений - это весь адресный ответ для имени. Запросы A и AAAA получают закреплённые адреса соответствующего семейства; запрос AAAA к имени, закреплённому только за IPv4, а также запросы CNAME, SVCB, HTTPS и ANY получают пустой ответ, а не ответ резолвера, потому что такие ответы несли бы CNAME сайта, и системный кэш уходил бы по нему мимо закреплений, как только истекал ответ с закреплёнными адресами. Запрос A к имени, закреплённому только за IPv6, по-прежнему уходит на резолвер, потому что клиенту только с IPv4 больше взять адрес неоткуда; туда же уходят остальные типы записей, среди них MX, TXT и SRV.
  • В сете без маршрутизации закреплённый адрес, до которого роутер не достучался по TCP на порт 443, в ответ не попадает. b4 подключается к каждому такому адресу при старте, при сохранении сета и каждые system.ip_health.retest_interval_sec секунд (по умолчанию 300), а переставший отвечать адрес перепроверяется с тем же интервалом. Закрепления сета с маршрутизацией не проверяются: проверка подключается напрямую с роутера, а соединения сета уходят через его маршрут, поэтому адрес, недоступный напрямую, может оказаться правильным. Раунд, в котором не ответил ни один адрес, как при обрыве аплинка, ничего не доказывает и вердиктов не меняет. Когда недоступны все адреса семейства, закрепления всё равно отдаются в ответ, так что закреплённый хост, который просто не слушает порт 443, своё закрепление сохраняет; только при включённом обнаружении блокировки по IP такой запрос уходит на резолвер.
  • Закреплённые ответы отдаются с TTL 60 секунд.
  • Закрепления читаются, даже когда Включить перенаправление DNS выключено, так что сет может закрепить несколько имён и оставить всё остальное резолверу клиента.

В файле конфигурации те же данные хранятся наоборот - как dns.pins, где имени сопоставлены его адреса.

Когда резолвер не отвечает​

Резолвер, который не ответил вовремя или вернул ошибку, не обрывает разрешение имени. b4 отвечает последним удачным ответом, который хранит для этого имени, а если такого нет - отправляет запрос тому резолверу, к которому обращался сам клиент, и отдаёт полученный ответ. Три неудачи подряд выводят заданный резолвер из цепочки на 30 секунд, поэтому пропавший резолвер стоит одного таймаута, а не одного на каждый запрос.

Сет может потребовать обратного переключателем Отдавать SERVFAIL, если резолвер недоступен (dns.strict). С ним резолвер, который не ответил, даёт SERVFAIL, b4 не откатывается на обычный DNS, и имя, которое b4 взял на себя, либо разрешается через заданный резолвер, либо не разрешается вовсе.

warning

Fail-closed вместе с недоступным резолвером означает, что в сете не резолвится ничего. На цензурируемом подключении сам DoH-сервер является мишенью, поэтому резолвер, отвечавший на момент сборки сета, может перестать отвечать позже, и вместе с ним ляжет каждый домен сета, хотя стратегия обхода под ним продолжает работать.

Запросы, которые b4 делает сам​

Некоторые имена сета b4 разрешает и для себя. Он заранее разрешает домены сета с включённой маршрутизацией, а для сета в режиме прокси ищет адрес имени, когда клиент его SOCKS5-прокси запрашивает это имя при выключенной опции Передавать имя домена в upstream, когда upstream отклоняет имя и когда соединение уходит в прямое. Если перенаправление включено и резолвер задан, эти запросы тоже идут к нему, а не к собственному резолверу роутера, а после изменения настроек резолвера домены сета разрешаются заново.

Ответ резолвера сета окончательный, что бы в нём ни было, так же как при передаче клиенту через перенаправление: имени нет, адреса нет, SERVFAIL или REFUSED. Если резолвер не ответил вовремя или недоступен, запрос уходит к резолверу роутера, а при включённом Отдавать SERVFAIL, если резолвер недоступен завершается ошибкой. Собственные запросы роутера к доменам сета тоже проходят через перенаправление, поэтому, пока не началась пауза, описанная ниже, такой откат может занять два таймаута запроса. Эти запросы учитываются в общем с перенаправлением счёте неудач: после трёх подряд резолвер пропускается на 30 секунд, запросы сразу идут к резолверу роутера, а сет с включённым fail-closed в это время не разрешает свои домены заранее. Последний удачный ответ для них не используется, а обычный DNS отправляется без фрагментации.

Откат на IPv4​

Пока в разделе Настройки, Основные, Движок пакетов не включена Поддержка IPv6, b4 обрабатывает только IPv4. Сайт с двойным стеком, на который нацелен сет, иначе открывался бы по IPv6, где у b4 нет никаких правил, и сет обходился бы стороной, при этом внешне ничего бы не сломалось.

Чтобы закрыть самый частый путь туда, b4 убирает IPv6-адреса из DNS-ответов для доменов, совпавших с сетом, оставляя клиенту IPv4-адреса, которые b4 действительно защищает. Ответ переписывается, а не отклоняется: записи A остаются, записи AAAA убираются, и клиент сам откатывается на IPv4.

  • Это касается только имён, совпавших с сетом. Все остальные имена получают полный ответ, а IPv6 в сети никак не затрагивается.
  • Как только поддержка IPv6 включена, переписывание прекращается само: обходить становится нечего.
  • Сет, чьи цели закреплены за IPv6 через targets.ip_version со значением 6, сохраняет свои IPv6-ответы: ради IPv6 такой сет и существует.
  • Переписанные ответы видны как dns-ipv6-stripped в результате.

Переключатель называется Форсировать IPv4 для совпавших доменов и находится в карточке IPv4 / IPv6 раздела Настройки, Основные, Движок пакетов, по умолчанию он включён. Выключить его - то же самое, что поставить system.dns.keep_ipv6_answers в true: записи AAAA будут проходить как есть. Пока включена Поддержка IPv6, переключатель неактивен.

Достаёт только до того DNS, который b4 видит

Здесь то же ограничение, что и во всём остальном на этой странице. Клиент, который резолвит через собственный DoH, DoT или DoQ, ответа b4 не показывает, поэтому сохраняет IPv6-адреса и всё равно доходит до сайта по IPv6. То же касается адреса, который уже лежит в кеше клиента или прописан в hosts. Откат сужает щель, но не закрывает её: полное решение - включить поддержку IPv6, чтобы у b4 были правила в обоих семействах.

Общие настройки DNS​

Карточка DNS в разделе Настройки, Основные, DNS содержит перехват DNS поверх TCP и таймауты, которые действуют на все сеты.

Карточка DNS

Зачем здесь DNS поверх TCP​

Обычно DNS ходит по UDP. Резолвер, у которого ответ не влезает в UDP-пакет, помечает его усечённым, и клиент повторяет запрос по TCP - так бывает с длинными списками адресов, записями DNSSEC и передачей зон. Некоторые stub-резолверы предпочитают TCP сразу, а клиент, который хочет обойти то, что следит за UDP, может уйти в TCP намеренно.

Это обычные DNS-запросы, и без перехвата они доходят до резолвера, выбранного клиентом, то есть резолвер сета, его закрепления и его блокировки для них не работают. Параметр Перехватывать DNS поверх TCP закрывает этот путь: TCP-порт 53 заворачивается в b4, и дальше применяется та же обработка сетом, что и для UDP.

ПараметрПоле в конфигурацииПо умолчаниюЗначение
Перехватывать DNS поверх TCPsystem.dns.tcp_disabledвключено (false)Если выключить, клиент, откатившийся на TCP, доходит до апстрим-резолвера, а DNS-сервер сета не используется
Порт слушателяsystem.dns.tcp_port5453На этом локальном порту b4 слушает DNS поверх TCP, а правило файрвола отправляет туда соединения, идущие на порт 53. Снаружи роутера этот порт не используется, клиенты как обращались к порту 53, так и обращаются. Меняйте, только если 5453 уже занят другой программой
Таймаут запросаsystem.dns.query_timeout_sec5Сколько ждать резолвер сета, прежде чем уйти на запасной путь, или прежде чем ответить SERVFAIL, если сет настроен на fail-closed. Одинаково для UDP и TCP
Таймаут простояsystem.dns.tcp_idle_sec30Сколько держать открытым простаивающее TCP-соединение в ожидании следующих запросов
Таймаут чтения/записиsystem.dns.tcp_io_sec10Предельное время на один запрос или ответ в установленном соединении
Таймаут пересылкиsystem.dns.tcp_dial_sec5Сколько ждать при пересылке несовпавшего TCP-запроса на резолвер, выбранный клиентом
Форсировать IPv4 для совпавших доменовsystem.dns.keep_ipv6_answersвключено (false)Находится в карточке IPv4 / IPv6 раздела Настройки, Основные, Движок пакетов. Переключатель и поле инвертированы: включённый переключатель означает, что keep_ipv6_answers равно false и IPv6-адреса вырезаются из ответов для совпавших доменов. Выключенный оставляет записи AAAA на месте. См. Откат на IPv4

В файле конфигурации хранятся только значения, отличающиеся от умолчаний, поэтому блок system.dns обычно отсутствует, пока ничего из этого не менялось.

примечание

Перехват TCP требует REDIRECT в таблице nat. Там, где ядро его не предоставляет, b4 пишет предупреждение, и DNS поверх TCP для этого семейства адресов остаётся на резолвере клиента. На перехват UDP это не влияет.

Отправить весь DNS в DoH​

Сет, который нацелен на все домены, превращает перенаправление внутри сета в перенаправление для всей сети. Импортируйте его через Сеты → Импорт/Экспорт:

{
"b4_version": "dev",
"name": "all DOH",
"tcp": { "dport_filter": "53" },
"udp": { "dport_filter": "53" },
"fragmentation": { "strategy": "none" },
"faking": { "sni": false },
"targets": { "sni_domains": ["regexp:.*"] },
"enabled": true,
"dns": {
"enabled": true,
"doh_url": "https://wikimedia-dns.org/dns-query"
}
}

regexp:.* совпадает с любым именем, поэтому каждый запрос, который не забрал другой сет, разрешается через DoH - для всех устройств сети и для самого роутера. Стратегии обхода здесь выключены: этот сет существует, чтобы отвечать на DNS, а не чтобы менять трафик.

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

Про два поля dport_filter

Они действительно ограничивают сет: с udp.dport_filter в значении 53 сет не применяется к QUIC на порту 443, а все порты, перечисленные в любом сете, дополнительно попадают в то, что b4 забирает в очередь.

Чего они не делают - так это не включают обработку DNS. Порт 53 разбирается раньше, чем читается любой фильтр портов, поэтому перенаправление работает и с двумя пустыми полями. Оставить их здесь всё же разумно: так сет с regexp:.* не забирает себе заодно все TLS-соединения. Единственная плата - tcp.dport_filter со значением 53 заводит TCP-порт 53 в очередь ради стратегий обхода, которыми этот сет не пользуется.

Что при этом меняется​

  • Локальные имена перестают разрешаться. Имена роутера, имена в .lan и всё прочее, что отдаёт собственный резолвер роутера, попадает на публичный резолвер, который про них не знает. Закрепите нужные имена или нацельте заглушку на более узкое выражение.
  • Один резолвер тянет на себе весь catch-all. Пока DoH-сервер недоступен, каждое имя сета отвечается из кеша или собственным резолвером клиента, а не тем, ради которого сет создавался. В режиме fail-closed тот же отказ означает, что эти имена не разрешаются вовсе. Доступность резолвера с вашего подключения здесь важнее списка его возможностей.
  • DNS поверх TCP подтягивается следом. Как только такой сет появляется, TCP-порт 53 тоже заворачивается в b4, и клиент, повторяющий запрос по TCP, получает тот же ответ, а не проскакивает мимо.

Как посмотреть результат​

Каждое решение b4 по запросу видно на странице Трафик и в логах - вместе с протоколом, сетом, доменом и клиентом.

РезультатЗначение
dns-doh-><хост>Разрешено через DoH на этом сервере
dns-forward-><ip>Разрешено самим b4 на этом обычном DNS-сервере
dns-passthroughСовпало с сетом, но резолвер в сете не задан, поэтому запрос ушёл без изменений
dns-pinОтвечено закреплённым адресом
dns-pin-emptyУ закреплённого имени спросили тип записи, которого в списке закреплений нет, поэтому ответ пустой
dns-healВ ответе заменены недоступные адреса, работой детектора блокировки IP в сете
dns-sinkholeОтвечено NXDOMAIN блокирующим сетом
dns-blockОтброшено блокирующим сетом
dns-servfailРезолвер сета не ответил, и запасного ответа тоже не нашлось, либо сет настроен на fail-closed
dns-fallback-cacheРезолвер сета не ответил, поэтому повторно отданы последние удачные адреса для этого имени
dns-fallback-upstreamРезолвер сета не ответил и в кеше ничего не было, поэтому запрос ушёл тому резолверу, к которому обращался клиент
dns-bad-targetВ поле DNS-сервера сета не корректный IP-адрес, поэтому запрос ушёл без изменений
dns-from-targetЗапрос пришёл с адреса собственного резолвера сета, поэтому ушёл без изменений, а не вернулся к нему. См. Типы резолверов
dns-ipv6-disabledЗапрос, пришедший по IPv6, совпал с сетом при выключенной поддержке IPv6, поэтому ушёл без изменений, а не был обработан сетом
dns-ipv6-strippedИз ответа убраны IPv6-адреса, клиенту оставлен IPv4-путь, который защищает b4. См. Откат на IPv4
dns-heal+ipv6-strippedС одним ответом произошло и то, и другое: недоступные адреса заменены, а IPv6-адреса убраны
примечание

В режиме TUN запросы на порт 53 перехватываются, а ответы видны только тогда, когда b4 держит весь маршрут по умолчанию. Перенаправления и закрепления работают в любом случае, потому что эти ответы b4 формирует сам. Если b4 не может поставить правило NOTRACK, TUN захватывает только трафик самого устройства, поэтому DNS других хостов доходит до b4, только когда его обрабатывает резолвер на этом устройстве, см. Движок пакетов.