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

Перехват пакетов

Движок пакетов - часть b4, которая видит трафик. Он читает первые пакеты каждого соединения, сопоставляет их с сетами и применяет стратегии. Пакеты попадают в него одним из двух режимов захвата, NFQUEUE или TUN, который выбирается в разделе Настройки > Основные > Движок пакетов. Оба режима зависят от правил файрвола, которые b4 ставит и поддерживает.

NFQUEUE​

В режиме NFQUEUE правила iptables или nftables передают пакеты в очереди netfilter, а b4 их читает. На каждый рабочий поток приходится одна очередь, номера идут подряд от значения Начальный номер очереди: при значениях по умолчанию 537-540.

В очередь попадает только начало каждого соединения. Сколько пакетов, задают Лимит TCP пакетов соединения и Лимит UDP пакетов соединения, по умолчанию 19 и 8. С iptables счёт ведёт match connbytes. Фейки и сегменты после разделения, которые b4 отправляет в соединение, тоже учитываются в лимите. Лимит меньше этих значений при сохранении конфигурации поднимается до них, а сет не может превысить глобальное значение.

Где стоят правила​

ТрафикХукИнтерфейс, который сравнивают Интерфейсы захвата
Пересылаемый роутеромpostrouting, после решения о маршрутеИнтерфейс, через который пакет уходит
Пересылаемый, если включена Фильтрация устройств и выбраны устройства из таблицы ARPforward, с проверкой MAC-адреса источникаИнтерфейс, через который пакет уходит
Соединения самого роутераpostrouting; output, если включена Фильтрация устройств и выбраны устройстваИнтерфейс, через который пакет уходит
Обратное направление и DNSpreroutingИнтерфейс, через который пакет пришёл

Правила для TCP выбирают пакеты по направлению conntrack. В postrouting, forward и output они берут пакеты в направлении первого пакета соединения, в prerouting - ответы. Направление TCP-пакета b4 определяет по хуку, из которого пакет попал в очередь. Если ядро не умеет выбирать по направлению, см. Когда b4 определяет направление по портам.

Пакеты, в метке которых есть все биты метки очереди b4 и нет других битов вне 0x73027fff, проходят мимо очереди. На ядрах 3.14 и новее b4 также без изменений отпускает из очереди пакет, который сокет на роутере отправил со всеми битами метки очереди. Метка очереди описана в разделе Метки пакетов.

С iptables семейство адресов, где iptables не принимает цель NFQUEUE или match connbytes, остаётся без правил захвата. Если их не принимают ни IPv4, ни IPv6, движок не запускается.

Пакеты, уходящие другим маршрутом​

Пакет, который уходит через поднятый интерфейс WireGuard или AmneziaWG или через устройство TUN или TAP, стратегии не получает: совпавший с ним сет не отправляет фейков, ничего не разделяет и не трогает ни его QUIC, ни ответы его соединения. Сеты блокировки его по-прежнему блокируют. Соединение такого пакета, с которым совпал сет, на странице Логи заканчивается пометкой [tunnel->wg0], а на странице Трафик его находит фильтр flags:tunnel.

DPI на внешнем интерфейсе видит только собственные пакеты туннеля. Сервис, который маршрутизирует по метке, например MagiTrickle, отправляет в туннель собственные пакеты соединения. Пакеты, которые отправляет b4, несут метку очереди вместо метки этого сервиса. Они идут по основной маршрутизации роутера и могут уйти мимо туннеля.

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

Пакет с меткой другого сервиса так же не получает стратегии, если пакеты b4 на его адрес ушли бы не через тот интерфейс, что сам пакет, или, для IPv4, не нашли бы маршрута вовсе. b4 спрашивает у ядра, через какой интерфейс уходит на этот адрес пакет с меткой пакетов b4, то есть с меткой очереди и добавленным битом 0x2000000. Это касается VPN поверх PPP, туннельного интерфейса IPsec и второго внешнего канала, которые сервис выбирает по своей метке. Такое соединение на странице Логи заканчивается пометкой [reroute->ppp1], а на странице Трафик его находит фильтр flags:reroute. Если пакет несёт метку маршрута одного из сетов самого b4, который маршрутизирует через его интерфейс, b4 задаёт вопрос с этой меткой, поэтому соединение, которое маршрутизирует сам сет, сохраняет стратегию. Пакет, в метке которого есть все биты метки очереди, как у устройств хотспота KeeneticOS, тоже не получает стратегии, пока включённый сет отправляет адреса через другой интерфейс, а не тот, которым уходит пакет. Правило такого сета отправляет пакеты b4 к своим адресам через свой интерфейс, а b4 не может знать, есть ли среди них адрес пакета. Сет с включённым Только по домену без IP-адресов и сет без адресов назначения ничего не маршрутизируют и не учитываются. Для любой метки b4 делает эту проверку только с iptables legacy, пока ни у одного другого сервиса на роутере нет таблиц nftables, а параметр Пропустить настройку IPTables/NFTables выключен. Такие таблицы b4 ищет при установке своих правил и при каждой их проверке с интервалом из поля Интервал мониторинга файрвола (секунды). В остальных случаях цепочки output других сервисов по-прежнему видят пакеты b4 и могут поставить им свою метку. Тогда b4 проверяет только метку, в которой есть все биты метки очереди.

Сет, который b4 сам маршрутизирует в такой туннель, сохраняет свои правила, см. Изменение пакетов при туннельном выходе.

Интерфейсы захвата подробно​

Интерфейсы захвата - фильтр на правилах выше, а не список интерфейсов, к которым подключается b4, и направление он не выбирает. Для пересылаемого трафика сравнивается интерфейс, через который пакет уходит, а его определяет таблица маршрутизации. Поэтому VPN-клиент или прозрачный прокси, сдвинувший маршрут по умолчанию, уводит все пакеты на другой интерфейс, и сделанный до этого выбор перестаёт совпадать.

Пока выбор ни с чем не совпадает, пакеты по-прежнему попадают в очередь b4, с тем же расходом, и каждый принимается без изменений. Ни один сет не применяется, ни одна стратегия не работает. Карточка Движок пакетов тогда называет интерфейс, через который уходит трафик, а если часть трафика ещё совпадает - долю, которую b4 не разбирает. Счётчики по интерфейсам для этого предупреждения есть в отчёте диагностики как packets_leaving и packets_arriving. Раздел Какой интерфейс за что отвечает сравнивает это поле с интерфейсами сета.

TUN​

В режиме TUN целевой трафик маршрутизируется через виртуальный интерфейс, по умолчанию b4tun0, который читает b4. Каждый обработанный пакет b4 отправляет дальше через raw-сокет в аплинк, который следует маршруту по умолчанию, если Аплинк-интерфейс его не закрепляет. Режим TUN работает только с IPv4.

Что захватывает TUN​

ЯдроЧто захватываетсяСтрока Захват в окне «Диагностика системы»
С match connbytesПервые пакеты каждого соединения на порты захватаports
Без connbytesВесь маршрут по умолчанию идёт через TUN-устройствоdefault

Порты захвата - это TCP и UDP 443, порты из фильтров портов сетов и TCP 80, если в сете включена Пустая строка перед методом HTTP.

В режиме ports при наличии match xt_conntrack правила захвата TCP берут только пакеты в направлении первого пакета соединения, а захват сбросов - только сбросы в обратном направлении. Если Пропустить настройку IPTables/NFTables выключено, направление TCP-пакета, прочитанного из TUN-устройства, b4 определяет по первому подходящему пункту:

  • В режиме ports при наличии xt_conntrack каждый пакет, кроме сброса, считается пакетом устройства.
  • Если b4 сам считает пакеты, без connbytes, направление определяет первый пакет соединения, который видел b4: после SYN его пакеты считаются пакетами устройства, после SYN-ACK - ответами.
  • В остальных случаях направление определяется по портам: для сброса в режиме ports с connbytes, для каждого пакета в режиме ports с connbytes, но без xt_conntrack, и для соединения, первого пакета которого b4 не видел. См. Когда b4 определяет направление по портам.

Пересылаемый трафик и таблица raw​

Роутер пересылает пакеты для других хостов, например клиентов LAN или Docker-контейнеров в сети bridge. TUN отправляет такой пакет дальше копией, и эта копия должна миновать отслеживание соединений. b4 обеспечивает это правилом NOTRACK в таблице raw iptables. Без него NAT ядра даёт копии новый порт источника, и ответ до клиента не доходит.

На ядре без таблицы raw (iptable_raw) или цели CT (xt_CT), например на ядре Synology DSM, такое правило поставить нельзя. Если не удалось поставить SNAT в TUN-устройство, b4 поступает так же. В обоих случаях он захватывает только соединения самого роутера, в том числе его SOCKS5- и MTProto-прокси:

  • пересылаемый трафик не получает стратегий обхода, и его DNS-запросы b4 не видит;
  • сеты маршрутизации и блокировки на пересылаемый трафик действуют;
  • если нет ещё и connbytes, через TUN-устройство идут все пакеты захваченных соединений, а b4 сам считает их и обрабатывает только первые.

Об этом сообщает лог при запуске, а окно Диагностика системы показывает Только это устройство в строке Захватываемый трафик раздела Движок. Если включено Пропустить настройку IPTables/NFTables, b4 не ставит ни одно из этих правил и продолжает захватывать пересылаемый трафик.

Трансляция адресов​

Адрес источника у захваченных пакетов TUN-движок сам заменяет на адрес аплинка и держит это правило выше любого правила маскарада без выходного интерфейса. NAT Masquerade не трогает TUN-устройство. Если TUN захватывает только трафик самого роутера, вместо этого правила стоит исключение из NAT, -o <устройство> -j ACCEPT, и адрес источника не меняется.

Когда b4 определяет направление по портам​

По портам b4 определяет направление TCP-пакета, если включено Пропустить настройку IPTables/NFTables. В режиме NFQUEUE так же бывает для семейства адресов, ядро которого не умеет выбирать пакеты по направлению conntrack: нет xt_conntrack для iptables или ct direction из nft_ct для nftables. Случаи в режиме TUN перечислены в разделе Что захватывает TUN. Пакет с одного из TCP-портов, которые b4 ставит в очередь, то есть 443, портов из фильтров TCP-портов сетов и 80, если в сете включена Пустая строка перед методом HTTP, считается ответом сервера. Правила, добавленные вручную при включённом Пропустить настройку IPTables/NFTables, должны ставить в очередь пакеты устройства по порту назначения, а ответы - по порту источника.

Порты источника для своих соединений устройства берут из диапазона 32768-60999 (Linux, Android) или 49152-65535 (Windows, macOS, iOS). В этом режиме соединения с таких портов проходят мимо b4 без обработки, если фильтр TCP-портов сета охватывает эти порты. В разделе Последние изменения на дашборде тогда появляется запись Фильтры TCP-портов охватывают порты источника клиентских соединений с этими портами. Фильтр ниже 32768 этого не допускает.

Отброшенные QUIC-соединения​

b4 видит только первые пакеты соединения. Когда сет отбрасывает или отклоняет QUIC-соединение, режимом действия UDP или как сет блокировки, b4 не пропускает и последующие пакеты этого соединения:

ДвижокКакЧто нужно
NFQUEUE, nftablesАдреса и порты соединения на 2 минуты попадают в набор b4_udp_drop4 или b4_udp_drop6 в inet b4_mangle, а правило в b4_chain отбрасывает его пакеты. Кроме того, b4 удаляет запись conntrack соединения, и когда набор отпускает соединение, его пакеты снова попадают в b4nf_conntrack_netlink для удаления записи
NFQUEUE, iptablesb4 удаляет запись conntrack соединения. Последующие пакеты заводят новую запись, попадают в b4 и снова отбрасываютсяnf_conntrack_netlink
TUN с xt_connbytesb4 удаляет запись conntrack соединения, и последующие пакеты снова направляются в TUN-устройствоnf_conntrack_netlink
TUN без xt_connbytesb4 обрабатывает каждый последующий пакет соединенияНичего

Без nf_conntrack_netlink iptables и TUN с xt_connbytes отбрасывают только пакеты, которые видит b4, по умолчанию первые 8 (Лимит UDP пакетов соединения). С nftables набор всё равно держит соединение, 2 минуты или до тех пор, пока b4 не перестроит свои правила. В OpenWrt модуль входит в пакет kmod-nf-conntrack-netlink, который рекомендует установщик. Строка Блокировка QUIC действует на всё соединение в разделе Возможности ядра окна Информация о системе показывает, удерживает ли роутер такую блокировку. Другой UDP, который отбрасывает сет, например трафик игры, отбрасывается только в пределах пакетов, которые видит b4.

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

Набор отбрасывания держит соединение по его адресам и портам. Новое QUIC-соединение, которое устройство откроет с того же порта к тому же адресу и порту сервера в течение этих 2 минут, тоже отбрасывается, какое бы имя в нём ни было.

Что нужно от ядра​

ФункцияЧто нужно
NFQUEUE с iptablesnfnetlink_queue, цель xt_NFQUEUE и match xt_connbytes. xt_conntrack для выбора TCP-пакетов по направлению
NFQUEUE с nftablesnfnetlink_queue и nft_queue. nft_ct для лимитов пакетов и для выбора TCP-пакетов по направлению
TUN/dev/net/tun и команда iptables или прослойка iptables-nft. xt_connbytes для захвата по портам, xt_conntrack для выбора TCP-пакетов по направлению, iptable_raw и xt_CT для пересылаемого трафика
Удержание отброшенного QUIC-соединенияnf_conntrack_netlink с iptables и в режиме TUN с xt_connbytes; с nftables - для удаления записи conntrack и для того, чтобы отпустить удерживаемые соединения после изменения настроек, см. Отброшенные QUIC-соединения
DSCP с iptablesМодуль xt_DSCP, в OpenWrt из пакетов kmod-ipt-ipopt и iptables-mod-ipopt. Для значений сетов ещё команда ipset и модуль xt_set
DSCP с nftablesНичего дополнительно
Перехват DNS поверх TCPЦель REDIRECT в таблице nat

Разделы Модули ядра и Возможности ядра в окне Информация о системе показывают, что из этого есть, и пакеты, которые дают недостающее.

Запуск движка и повторные попытки​

b4 запускает движок пакетов раньше веб-интерфейса. Если движок не запустился, b4 удаляет уже поставленные правила и продолжает работать без него:

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

Причина пишется в лог на уровне ERROR, видна на дашборде и на карточке Движок пакетов. Например, на ядре без модулей очереди iptables отвергает цель NFQUEUE. TUN-движок с автоматическим аплинком не находит маршрута по умолчанию, пока WAN или VPN ещё не поднялись.

Повторяя запуск, b4 перезапускается на месте: завершается так же, как по сигналу остановки, и запускается снова с той же командной строкой, заново читая файл конфигурации. Идентификатор процесса не меняется, и среда контейнера или супервизор не видят завершения.

ПопыткаЧерез
Первая15 секунд
Вторая30 секунд
Третья60 секунд

Причину, которая устраняется сама, например WAN-подключение, поднявшееся позже b4, подхватывает одна из этих попыток. После третьей неудачной попытки b4 остаётся без движка до перезапуска из веб-интерфейса или менеджером сервиса, который начинает отсчёт заново. Если веб-сервер выключен, порт 0, b4 вместо этого завершается с ошибкой.

Поддержка правил​

Прошивка роутера перестраивает файрвол при событиях вроде поднятия интерфейса или смены проброса портов и удаляет при этом правила b4. С интервалом из поля Интервал мониторинга файрвола (секунды) b4 проверяет свои правила и возвращает пропавшие. SIGUSR1 запускает проверку сразу.

  • В режиме NFQUEUE 0 отключает проверку, и удалённые правила не возвращаются.
  • В режиме TUN интервал не меньше 10 секунд, и 0 ничего не отключает. TUN-движок проверяет свою цепочку захвата B4_TUN и переходы в неё, а монитор - правила маскарада, MSS clamping, DSCP и сетов маршрутизации. Если включено Пропустить настройку IPTables/NFTables, проверяются только правила захвата.

Когда TUN захватывает по портам, строка Правила захвата окна Диагностика системы сравнивает число правил в цепочке захвата с числом, поставленным b4. После первого восстановления строка Правила захвата восстановлены и, в любом режиме движка, строка Правила восстановлены монитором показывают число восстановлений и время последнего. Растущий счётчик указывает на другой сервис на роутере, который переписывает файрвол.

Правила подвкладки «Файрвол»​

Правилоiptablesnftables
NAT MasqueradeЦепочка B4_MASQ в таблице nat, переход в неё в конце POSTROUTINGТаблица ip b4_nat
DSCPЦепочка B4_DSCP в таблице mangle, переход в неё в начале POSTROUTING, выше перехода захвата b4Таблица inet b4_dscp
MSS clampingПравила TCPMSS в начале mangle OUTPUT, FORWARD и B4_PREROUTING; в режиме TUN - в начале mangle PREROUTING вместо B4_PREROUTINGПравила в начале prerouting, output и forward в inet b4_mangle

Маскарад работает для IPv4, а для IPv6 - только с iptables в режиме NFQUEUE, пока включена Поддержка IPv6. Пакеты, которые b4 отправляет клиентам в LAN, сохраняют свой адрес источника.

Переход DSCP стоит выше перехода захвата, потому что пакет, который разбирает b4, покидает mangle POSTROUTING на этом переходе, и правило ниже его уже не видит. Если ядро отвергает правило DSCP с iptables, b4 один раз пишет об этом в лог и оставляет это семейство адресов без значения. С nftables отвергнутая таблица оставляет без значения оба семейства. Как сеты записывают собственные значения, описано в разделе DSCP.

Правила MSS стоят выше правил очереди b4 по той же причине: SYN-ACK или SYN самого роутера, который разбирает b4, до правила ниже них не доходит.

С iptables устройство в столбце MSS, сопоставленное по MAC-адресу, распознаётся только в пакетах, которые оно отправляет. Поэтому, пока глобальный MSS clamping выключен, b4 ещё и ставит наименьшее из таких значений на каждый SYN-ACK с порта 443, который пересылает, к какому бы устройству он ни шёл. Устройство, добавленное вручную, сопоставляется по IP-адресу в обоих направлениях.

Правила «Доступ из интернета»​

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

  • iptables. Цепочка B4_EXPOSE в таблице filter содержит разрешающие правила, а в неё ведёт один переход в INPUT. Переход ставится сразу под последним правилом бан-листа в INPUT, а если таких правил нет - в начало, поэтому забаненный там адрес остаётся забаненным и на портах b4. Правила бан-листа - это переходы в цепочки fail2ban f2b-*, CrowdSec, sshguard или ufw-before-input, а также DROP и REJECT по ipset адресов источника. Правила IPv4 ставятся через iptables, IPv6 - через ip6tables, там, где у этого варианта уже есть таблица filter.
  • nftables. accept ставится в начало каждой filter-цепочки на хуке input в таблицах, которые b4 не принадлежат, например inet fw4 input в OpenWrt. Его комментарий имеет вид b4-expose:mtproto. Цепочка с политикой accept и приоритетом ниже filter правила не получает: там свои цепочки держат fail2ban, CrowdSec и banIP, поэтому забаненные ими адреса остаются забаненными. В nftables accept завершает путь пакета только по одной базовой цепочке. drop в любой другой цепочке на том же хуке всё равно окончателен, поэтому правило в собственной таблице b4 оставило бы порт закрытым.

Если на хосте нет ни одной такой цепочки, соединение отбросить нечему, и b4 правила не добавляет. Слушатель, привязанный к одному адресу, получает правило только для этого адреса, слушатель на loopback не получает правила, как и слушатель, который не запустился.

Правила проверяются вместе с остальными правилами b4, с интервалом из поля Интервал мониторинга файрвола (секунды) и по SIGUSR1, что бы ни происходило с движком пакетов. В цепочку input, появившуюся после прошлой проверки, правило добавляется. Сохранение удаляет правила закрываемых портов раньше, чем слушатели получают новые настройки. Выключение переключателя, остановка b4 или b4 --clear-tables удаляют правило. При запуске b4 удаляет правила, оставшиеся от работы, завершившейся без уборки, если не включено Пропустить настройку IPTables/NFTables.

firewalld 2.2 и новее помечает свою таблицу nftables как принадлежащую ему там, где это поддерживают Linux 6.9 и nftables 1.1, например в Fedora 42, RHEL 10 и Debian 13. Ядро тогда отклоняет изменения от других программ. b4 распознаёт отказ, повторяет попытку для этой таблицы раз в 10 минут, а не при каждой проверке, и пишет в лог команды firewall-cmd, которые открывают порт в самом firewalld. NftablesTableOwner=no в /etc/firewalld/firewalld.conf отключает владение. Тогда правило стоит в начале цепочки filter_INPUT firewalld, выше его зон, и адрес, заблокированный в зоне, всё равно может дойти до открытых портов.

У слушателя DNS поверх TCP и прозрачных слушателей прокси-сетов и Telegram через WebSocket переключателя нет. Они существуют только как цели правил перенаправления и отвода трафика самого b4.