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

Метки пакетов

Метка - это 32-битное число, которое ядро хранит вместе с пакетом. Правила файрвола ставят и проверяют её, ip rule выбирает по ней таблицу маршрутизации, а сокет может ставить её на каждый отправленный пакет. Вторую 32-битную метку conntrack хранит для каждого соединения. b4 с помощью меток отличает пакеты, которые отправил сам, от тех, что ещё предстоит обработать, направляет трафик сета в его маршрут или на свой слушатель и выводит собственные соединения из-под своих правил маршрутизации, а часть из них и из-под обработки пакетов.

Сервисы, которые занимаются policy-маршрутизацией или прозрачным проксированием, работают с теми же 32 битами: Xray и XKeen, sing-box и mihomo, XrayUI, podkop, Tailscale, WireGuard, mwan3. Если два сервиса используют один бит, один может принять пакеты другого за свои, а сервис, который пишет метку целиком, стирает биты, поставленные другими. На этой странице перечислены биты, которые b4 пишет и читает, правила маршрутизации, которые с ними связаны, и значения, которые используют некоторые другие сервисы на роутерах.

Как читать метку​

ЗаписьЗначение
0x5aef/0x27fffБиты под 0x27fff равны 0x5aef, остальные не сравниваются
0x8000/0x8000Бит 0x8000 установлен, что бы ни было в остальных битах
fwmark 0x5aef/0x27fff lookup 119 в ip ruleПакеты, чья метка совпадает с 0x5aef/0x27fff, маршрутизирует таблица 119
fwmark 0x111 lookup 111 в ip ruleМаски нет: вся 32-битная метка должна быть равна 0x111

Правило, которое пишет метку с маской, меняет только биты под маской и сохраняет остальные. В iptables это MARK --set-xmark 0x5aef/0x27fff или CONNMARK --save-mark --nfmask 0x27fff --ctmask 0x27fff. nftables выводит такую же запись как meta mark set meta mark & 0xfffddaef | 0x00005aef: AND сохраняет все биты вне 0x27fff (nft вписывает в эту константу и биты самого значения), OR записывает 0x5aef. Правило без маски, например meta mark set 0x00021546 в nftables или MARK --set-mark 0x111 в iptables, заменяет все 32 бита и стирает то, что туда записал другой сервис. nft list выводит каждое значение дополненным до восьми цифр: 0x00008000 вместо 0x8000.

ВидГде хранитсяГде видна
Метка пакета (fwmark)На одном пакете, от правила или сокета, который её поставил, до выхода пакета с роутераmeta mark в nftables, -m mark и MARK в iptables
Метка соединенияВ записи conntrack, общая для всех пакетов соединения в обе стороныct mark, -m connmark и CONNMARK, mark= в /proc/net/nf_conntrack
Метка сокета (SO_MARK)На сокете; каждый отправленный им пакет начинает с этой меткиfwmark: в выводе ss -e, запущенного от root на ядре 4.9 или новее (для raw-сокетов 4.10)

Какие биты использует b4​

Метка пакета​

БитыМаскаНазначениеЗначение
0-14, 170x27fffМаршрут сета с маршрутизациейСвоя у каждого сета; сеты с одним выходным интерфейсом, egress IP и аварийным отключением делят одну. См. сеты с выходным интерфейсом и прокси-сеты
15 по умолчанию0x8000 по умолчаниюМетка очереди: пакеты, которые b4 отправляет из raw-сокетов, кроме пакетов устройству в режиме TUN, DNS-запросы, которые он отправляет за клиентов и для своих сетов, и его проверки, которые идут мимо его обработкиМетка пакета в разделе Настройки, Основные, Движок пакетов, по умолчанию 0x8000 (32768)
180x40000Соединения, которые b4 открывает с upstream прокси-сета, Telegram, Хабом сообщества, ipinfo и RIPEstat, и его прозрачные слушатели; см. метки сокетовФиксирована
210x200000Собственные соединения b4, исходящие пакеты которых обработка пакетов не трогаетФиксирована, ставится вместе с битом 18 как 0x240000
240x1000000TCP-пакет прокси-сета, отправленный самим роутеромФиксирована, прибавляется к метке сета
280x10000000Режим TUN: пакеты, которые b4 отправляет обратноФиксирована, прибавляется к метке очереди
290x20000000Пакеты, которые b4 отправляет устройству в сетиФиксирована; в режиме NFQUEUE прибавляется к метке очереди, а у пакетов, которые поиск Дискавери отправляет обратно к своим проверочным соединениям, - к метке отправленных пакетов Дискавери
300x40000000Режим TUN: пакеты, направленные в b4tun0; не используется, когда в b4tun0 указывает сам маршрут по умолчаниюФиксирована
все0xffffffffДискавери, только во время поискаПо умолчанию метка очереди плюс 1 и плюс 2, 0x8001 и 0x8002; их заменяют system.checker.discovery_flow_mark и system.checker.discovery_injected_mark

С меткой очереди по умолчанию и вне поиска Дискавери b4 не ставит на пакеты другие биты, а его правила файрвола другие биты не проверяют: биты 16, 19, 20, 22, 23, 25, 26, 27 и 31 свободны. Правила, которые пишут метку целиком, у прокси-сетов в nftables и у Дискавери, стирают эти биты на пакетах, которые забирают. Бит 16 оставлен для 0x10000 от XrayUI.

Метка соединения​

БитыМаскаНазначение
300x40000000Соединение принадлежит сету с выходным интерфейсом
0-14, 170x27fffМетка этого сета, скопированная с первого пакета соединения
15 по умолчаниюМетка очереди, по умолчанию 0x8000Режим NFQUEUE, в iptables при наличии модуля connmark: в этом соединении с роутера ушёл пакет с меткой очереди, в том числе фейк или сегмент после разделения, который b4 отправил в соединение устройства. Правила очереди b4 для пакетов, входящих в роутер, такие соединения пропускают
все0xffffffffПроверочные соединения Дискавери во время поиска

Метки сокетов​

СокетыМетка
Raw-сокеты для фейков, сегментов после разделения и пакетов, которые b4 отправляет обратноМетка очереди, по умолчанию 0x8000; в режиме TUN метка очереди с добавленным 0x10000000, по умолчанию 0x10008000
Raw-сокеты для пакетов устройству: ответы DNS, которые собирает b4, сбросы, ICMP; в режиме TUN ещё и перехваченные ответы DNS и ответные пакеты, которые b4 отправляет обратноМетка очереди с добавленным 0x20000000, по умолчанию 0x20008000; в режиме TUN только 0x20000000
DNS-запросы, которые b4 отправляет за клиентов (DNS-редирект сета, DNS через TCP), и его запросы через резолвер сета, включая запрос имени хоста DoH-резолвера для нихМетка очереди
Проверки Детектора DPI, кроме запросов через b4 и запросов к системному резолверу; проверки закреплённых ответов DNS и недоступных адресов; запрос внешнего адреса роутера; запросы в обход b4 у MCP-инструмента b4_test_domain_now и у проверки применённого сета из Хаба сообществаМетка очереди
Прозрачные слушатели прокси-сетов и все соединения, которые они открывают, с upstream или, при Прямое подключение при недоступности upstream, напрямую; TCP-соединения SOCKS5-сервера b4 с доменами из целей прокси-сета, которые идут через upstream сета; соединения MTProto-прокси и Telegram через WebSocket с Telegram и загрузка ими списков адресов; пересылка MTProto-прокси на его домен для Fake SNI; запросы к Хабу сообщества, ipinfo и RIPEstat0x40000. Если синхронизация с Хабом не может соединиться, b4 повторяет её с меткой очереди; если этот повтор соединился, следующие запросы к Хабу идут с меткой очереди, пока синхронизация с ней не перестанет соединяться, а повтор с 0x40000 не соединится
Соединения через домены за Cloudflare-прокси или свой домен WebSocket, а также с Cloudflare Worker0x240000; 0x40000 для Worker, когда включено Обрабатывать соединения с Worker сетами
Проверочные соединения Дискавери и их запросы имён; пакеты, которые Дискавери отправляет самМетка потока; метка отправленных пакетов, с добавленным 0x20000000 у пакетов, которые уходят обратно к проверочным соединениям. По умолчанию метка очереди плюс 1 и плюс 2, и 0x20008002 в сторону проверочных соединений
Проверки мониторинга (Watchdog); запросы через b4 у Детектора DPI, b4_test_domain_now и проверки сета из Хаба; соединения, которые SOCKS5-сервер b4 открывает к остальным адресам; все остальные запросы к системному резолверу, в том числе имён остальных соединений выше и доменов сета, у которого нет своего резолвера или чей резолвер не ответил при выключенном Отдавать SERVFAIL, если резолвер недоступен; загрузка GeoIP и GeoSite, проверка и загрузка обновлений, база производителей устройств, запросы к AI-помощникуНет

Соединение без метки обрабатывается как любое соединение самого роутера: оно проходит обработку пакетов и все сеты, которые берут трафик роутера.

Что b4 не трогает​

Правила b4Пакет пропускается, если
Обработка пакетов, nftables (inet b4_mangle)b4_chain, правила для исходящих портов, пропускает его, если в его метке есть все биты метки очереди, его биты под 0x27fff равны 0x24bab или в метке есть бит 0x200000, а во время поиска Дискавери ещё и если его метка в точности равна метке потока или метке отправленных пакетов; output ещё до перехода туда принимает пакет со всеми битами метки очереди. prerouting с правилами DNS и правилами для ответов метку пакета не проверяет и пропускает соединения, в метке соединения которых есть все биты метки очереди
Обработка пакетов, iptables (B4, B4_PREROUTING)B4 пропускает его, если его биты под 0x27fff равны 0x24bab или метке прокси-сета или в метке есть бит 0x200000, а во время поиска Дискавери ещё и если его метка в точности равна метке потока или метке отправленных пакетов. Правила для метки очереди в B4 нет: mangle OUTPUT принимает пакет, который роутер отправляет со всеми битами метки очереди, раньше перехода в B4, но в B4 переходит и mangle POSTROUTING, а если фильтрация устройств выбирает устройства, то для их пакетов mangle FORWARD. Поэтому транзитный пакет с меткой очереди, а без фильтрации устройств и отправленный роутером, всё равно проходит правила очереди B4 для исходящих портов. B4_PREROUTING и правила DNS метку пакета не проверяют; при наличии модуля connmark B4_PREROUTING пропускает те же соединения, что и prerouting в nftables
Сама очередь, оба бэкендаb4 отпускает пакет без изменений, если в его метке есть бит 0x200000, под 0x27fff стоит 0x24bab или в ней есть все биты метки очереди, остальная часть лежит внутри 0x27fff, а сама метка не равна в точности ни одной из двух меток Дискавери
Сеты с маршрутизацией, кроме сетов блокировки, пакеты на входе в роутер (b4r_*_pre), включая пакеты самого роутера, которые прокси-сет возвращает через loВ его метке есть все биты метки очереди или бит 0x40000, или его биты под 0x27fff не равны нулю и, в цепочке прокси-сета, отличаются от собственной метки этого сета
Сеты с маршрутизацией, пакеты самого роутера (b4r_*_out)В его метке есть бит 0x40000 или любой бит под 0x27fff. Пакет со всеми битами метки очереди тоже пропускается - после того как сет с выходным интерфейсом поставит ему свою метку, если адрес назначения входит в сет; сет, который не берёт трафик самого роутера и задаёт устройства только IP-адресами, делает это только для пакетов с этих адресов
Отказ QUIC у прокси-сета с выключенным Маршрутизировать UDP через upstream (b4r_*_q)В его метке есть все биты метки очереди или бит 0x40000
Сеты блокировкиНикогда: метку они не проверяют, только адрес назначения и, если они заданы в сете, исходные интерфейсы и исходные устройства
Захват TUN (B4_TUN)В его метке есть все биты метки очереди, бит 0x20000000 или бит 0x200000, или его биты под 0x27fff равны 0x24bab; в iptables ещё и если адрес назначения входит в сет с маршрутизацией, кроме сетов блокировки. Пропускается и пакет в сеть, где у роутера есть собственный IPv4-адрес, если это не DNS по UDP и не TCP RST, который цепочка захватывает; пока b4 захватывает только соединения самого роутера, такой пакет пропускается всегда, кроме DNS-запроса по UDP к шлюзу внешнего интерфейса
TUN через весь маршрут по умолчаниюПравилами b4 уходят только пакеты с битом 0x10000000, а если ip принимает suppress_prefixlength, ещё и с битом 0x20000000; любой другой пакет, который идёт по маршруту по умолчанию, попадает в b4tun0
NAT Masquerade (b4_masq, B4_MASQ)В его метке есть бит 0x20000000. В iptables этот RETURN стоит в начале nat POSTROUTING, поэтому такой пакет пропускает все следующие там правила, в том числе правила других сервисов
Задать DSCP (B4_DSCP, inet b4_dscp)В его метке есть бит 0x20000000, он уходит через lo или идёт в ответном направлении своего соединения. В iptables переход в B4_DSCP стоит в начале mangle POSTROUTING; в nftables таблица inet b4_dscp работает в postrouting с приоритетом 150
Перенаправление DNS через TCPВ его метке есть все биты метки очереди
Дискавери во время поискаВ начале цепочки пакет, чья метка в точности равна метке отправленных пакетов, принимается, а пакет, чья метка или метка соединения в точности равна метке потока, уходит в очередь Дискавери; в обоих случаях он пропускает остаток цепочки. В iptables это встроенные mangle PREROUTING и OUTPUT, поэтому он пропускает все следующие там правила

Что b4 пишет в чужие пакеты​

Правила b4Что пишут
Сеты с выходным интерфейсомБиты метки пакета под 0x27fff; биты метки соединения под 0x27fff и бит 0x40000000. С маской, остальные биты остаются
Прокси-сеты, iptablesБиты метки пакета под 0x1027fff. С маской
Прокси-сеты, nftablesМетку пакета целиком
Обработка пакетовБиты метки очереди в метку соединения каждого соединения, в котором сам роутер отправляет пакет со всеми битами метки очереди, в том числе соединения устройства, в которое b4 отправляет фейки или сегменты после разделения. Только в режиме NFQUEUE; в nftables - не для пакетов, отправленных в lo, в iptables - только при наличии модуля connmark. С маской
Захват TUNБит 0x40000000 метки пакета. С маской
Дискавери во время поискаМетку пакета целиком, если метка его соединения в точности равна метке потока, и метку соединения целиком, если в соединении идёт пакет, чья метка в точности равна метке потока; обе получают значение метки потока

Метка очереди​

Метка очереди - это настройка Метка пакета в разделе Настройки, Основные, Движок пакетов, queue.mark в конфигурационном файле и --mark в командной строке. По умолчанию 0x8000 (32768); веб-интерфейс принимает значение в десятичном виде, а 0 означает значение по умолчанию. Каждый фейк, сегмент после разделения и пакет, который b4 отправляет обратно, уходит из raw-сокетов с этой меткой, в режиме TUN - с добавленным битом 0x10000000. Пакеты устройству в режиме TUN несут только 0x20000000, а пакеты поиска Дискавери - метку отправленных пакетов Дискавери, с добавленным 0x20000000 у пакетов, которые он отправляет обратно к своим проверочным соединениям. DNS-запросы, которые b4 отправляет за клиентов и для своих сетов, тоже несут метку очереди; запросы через резолвер самого роутера метки не несут. Каждое правило ниже проверяет все биты метки очереди сразу, поэтому другие биты на том же пакете её не скрывают.

Правилоnftablesiptables
Пакеты самого роутераoutput: meta mark & 0x8000 == 0x8000 ct mark set ct mark | 0x8000, затем ... acceptmangle OUTPUT: -m mark --mark 0x8000/0x8000 -j CONNMARK --save-mark --nfmask 0x8000 --ctmask 0x8000 (при наличии модуля connmark), затем ... -j ACCEPT
Цепочка очередиb4_chain: meta mark & 0x8000 == 0x8000 returnнет; b4 отпускает такой пакет из очереди без изменений, когда остальная часть его метки лежит внутри 0x27fff и метка не совпадает ни с одной из двух меток Дискавери
Пакеты на входе в роутерprerouting: ct mark & 0x8000 == 0x8000 returnB4_PREROUTING: -m connmark --mark 0x8000/0x8000 -j RETURN (при наличии модуля connmark)
Сеты с маршрутизацией, кроме сетов блокировкиmeta mark & 0x8000 == 0x8000 return-m mark --mark 0x8000/0x8000 -j RETURN
Сеты с выходным интерфейсом, пакеты самого роутераmeta mark & 0x8000 == 0x8000 ip daddr @<set> meta mark set ...-m mark --mark 0x8000/0x8000 -m set --match-set <set> dst -j MARK --set-xmark <mark>/0x27fff
Перенаправление DNS через TCP, пока оно включеноmeta mark & 0x8000 == 0x8000 returnB4_DNSTCP: -m mark --mark 0x8000/0x8000 -j RETURN
Захват TUN-B4_TUN: -m mark --mark 0x8000/0x8000 -j RETURN, пишется через iptables при любом бэкенде

Правило для сетов с выходным интерфейсом отправляет фейки и сегменты соединения, которое такой сет маршрутизирует, через тот же интерфейс, что и само соединение. Оно сверяет адрес назначения, а адрес источника - только у сета, ограниченного исходными устройствами, которые все заданы IP-адресами, поэтому так же поступает и с пакетами, которые b4 отправляет в соединения к адресам сета, которые сет не маршрутизирует, например с устройства вне его исходных интерфейсов. Адрес источника сверяется для каждого семейства адресов отдельно: в семействе, для которого такой сет не задаёт ни одного адреса устройства, правило сверяет только адрес назначения, поэтому при включённой Поддержке IPv6 сет, все устройства которого заданы IPv4-адресами, ставит свою метку каждому IPv6-пакету с меткой очереди к своим адресам.

Сохранение изменённой Метки пакета сразу переносит на новое значение правила обработки пакетов, правила сетов с маршрутизацией и перенаправление DNS через TCP и убирает правила со старым значением. Пока идёт поиск Дискавери, правила обработки пакетов и перенаправление ждут его окончания; если поиск закончится позже чем через пять минут после сохранения, в iptables они переходят на новое значение при следующей проверке монитора файрвола, а в nftables или при выключенном мониторе (system.tables.monitor_interval равен 0) - при следующем запуске b4. Пока они не перешли, b4 ставит в очередь собственные DNS-запросы, которые уже несут новое значение, как запросы устройства, поэтому DNS-редирект сета может перестать работать. Raw-сокеты, выпуск собственных пакетов b4 из очереди и в режиме TUN цепочка B4_TUN получают новое значение при следующем запуске b4, о котором просит веб-интерфейс. Обе метки Дискавери следуют за новым значением, если system.checker не задаёт для них значения, отличные от Метки пакета плюс 1 и плюс 2. До 1.84.0 веб-интерфейс отправлял их обратно при каждом сохранении, поэтому сохранение, которое меняло Метку пакета, или сделанное при действующем --mark, могло оставить их там со значениями, которые за ней больше не следуют, например равными старому значению плюс 1 и плюс 2. Если при остановленном b4 удалить discovery_flow_mark и discovery_injected_mark из system.checker, они снова следуют за ней.

b4 не принимает значение, которое:

  • состоит только из битов 0x240000, меток его собственных соединений;
  • состоит только из битов 0x27fff и 0x1000000, битов меток сетов;
  • пересекается с 0x70000000 в режиме TUN;
  • содержит бит 0x20000000 в режиме NFQUEUE при включённом NAT Masquerade или Задать DSCP;
  • имеет под 0x27fff биты 0x24bab, метку Telegram через WebSocket;
  • совпадает с меткой потока или меткой отправленных пакетов Дискавери;
  • больше 0xffffffff, либо, пока в конфигурации не задана хотя бы одна из меток Дискавери, больше 0xfffffffd или даёт такой метке (значение плюс 1 для метки потока, плюс 2 для метки отправленных пакетов) бит 0x200000 или значение другой метки Дискавери.

Пакет, который другой сервис пометил всеми битами метки очереди, b4 принимает за отправленный им самим. Прокси-сеты, Telegram через WebSocket и отказ QUIC его не трогают. Сет с выходным интерфейсом ставит ему свою метку, если его отправляет сам роутер на адрес из сета, а в метке нет битов под 0x27fff и бита 0x40000, если только сет не ограничен исходными устройствами, которые все заданы IP-адресами; сет блокировки отклоняет его по адресу назначения, как обычно. Цепочка очереди в nftables и захват TUN пропускают его, что бы ни лежало в остальной части метки. В режиме NFQUEUE, если его отправляет роутер, b4 ещё и копирует биты метки очереди в метку соединения (в nftables - не для пакетов, отправленных в lo, в iptables - только при наличии модуля connmark), и ответы тоже пропускаются. Пакет, который всё же попадает в очередь (в iptables через B4, а при обоих бэкендах через правила для пакетов на входе в роутер, которые проверяют только метку соединения), b4 отпускает без изменений, только если остальная часть его метки лежит внутри 0x27fff либо в метке есть бит 0x200000 или под 0x27fff стоит 0x24bab. У 51820 (0xca6c), которую wg-quick ставит на сокет WireGuard, когда пир маршрутизирует /0, бит 15 установлен, а остальная часть, 0x4a6c, лежит внутри 0x27fff.

Сеты с выходным интерфейсом​

Сет с выходным интерфейсом получает метку и таблицу маршрутизации по имени интерфейса, egress IP и аварийному отключению. Сеты, у которых все три совпадают, делят и метку, и таблицу.

ЧтоЗначение
МеткаПо хешу от трёх параметров, в диапазоне 0x100-0x7eff и никогда не равна битам метки очереди под 0x27fff; если заняты все кандидаты по хешу - по порядку, начиная с 0x66
Таблица100-249, кроме таблиц, названных в rt_tables, таблиц, на которые ссылается правило другого сервиса, и таблиц с маршрутами, которые добавил не b4
Правилоip rule add fwmark <метка>/0x27fff lookup <таблица> priority <10000 + таблица>, для IPv4 и, при включённой Поддержке IPv6, для IPv6
Содержимое таблицыМаршрут по умолчанию через интерфейс, при аварийном отключении ещё blackhole default metric 4096
Заданные вручнуюrouting.fwmark и routing.table в конфигурационном файле или через API; применяются, только если заданы оба, метка лежит внутри 0x27fff, не равна 0x24bab, не содержит всех битов метки очереди и не равна её битам под 0x27fff

Сет ставит метку на первый пакет каждого соединения к своим адресам и сохраняет её в метке соединения вместе с битом 0x40000000 - отметкой b4. Следующие пакеты соединения, идущие в направлении его первого пакета, получают метку обратно из метки соединения; ответные пакеты метку не получают. Цепочка сета для пакетов на входе в роутер, b4r_<set>_pre, по порядку:

  1. Пропускает пакеты с меткой очереди, с битом 0x40000 или с любым битом под 0x27fff.
  2. Пропускает пакеты, пришедшие с самого выходного интерфейса.
  3. Восстанавливает метку из метки соединения на следующих пакетах отмеченных соединений, идущих в направлении первого пакета.
  4. Ставит метку новым соединениям к адресам сета и сохраняет её вместе с отметкой.

Сет, исключающий исходные устройства, пропускает их пакеты перед шагом 2, в цепочку сета, ограниченного исходными устройствами, попадают только пакеты этих устройств, а сет, ограниченный исходными интерфейсами, применяет шаги 3 и 4 только к пакетам, пришедшим с них. Фильтрация устройств в разделе Настройки, Основные, Устройства сужает цепочку так же. b4r_<set>_out делает то же для соединений самого роутера, если сет их берёт, и ставит метку сета собственным пакетам b4 с меткой очереди, адресованным в сет; сет, ограниченный исходными устройствами, которые все заданы IP-адресами, делает это только для пакетов с их адресов. Маскарад выбирает пакеты по метке сета и выходному интерфейсу; если egress IP есть на интерфейсе, вместо маскарада работает SNAT на этот адрес, и он дополнительно требует, чтобы адрес назначения входил в сет.

На роутере, прошивка которого перезаписывает записанную b4 метку соединения, восстановление не срабатывает. b4 на iptables замечает это, пока работает монитор файрвола: если уже отмечено несколько соединений, восстановление не сработало ни разу и ни одно соединение с ответом в /proc/net/nf_conntrack не сохранило бит 0x40000000, и так две проверки подряд, b4 записывает 0 в .conntrack-mark рядом с конфигурационным файлом. С этого момента, а также при каждом следующем запуске с любым бэкендом, пока файл не удалён, сет ставит метку на каждый пакет к своим адресам, у которого нет битов под 0x27fff, а не только на первый.

Пока сет использует выходной интерфейс, у которого действующее значение rp_filter равно 1, b4 записывает 2 в net.ipv4.conf.<интерфейс>.rp_filter и возвращает прежнее значение, когда с этого интерфейса уходит последний сет.

На тестовой машине два сета на wg0 получили:

10119:  from all fwmark 0x5aef/0x27fff lookup 119
10123: from all fwmark 0x69cf/0x27fff lookup 123

Прокси-сеты и Telegram через WebSocket​

Сеты в режимах маршрутизации Вышестоящий прокси SOCKS5 и Telegram через WebSocket, а также переключатель Telegram через WebSocket, перенаправляют соединения на прозрачные слушатели b4 через TPROXY. У каждого есть метка, и метка задаёт порт слушателя.

ЧтоЗначение
Метка0x20000-0x27dff, по хешу от ID сета, а если хеш равен битам метки очереди под 0x27fff, - следующее за ним значение; routing.fwmark заменяет её, если лежит внутри 0x27fff, не равна 0x24bab и не равна битам метки очереди под 0x27fff
Переключатель «Telegram через WebSocket»0x24bab, порт 13443
Порт слушателя13000 + метка % 50000
Правило, приоритет 3fwmark <метка>/0x27fff lookup 252, для IPv4 и, при включённой Поддержке IPv6, для IPv6; в таблице 252 local default dev lo, она общая для всех прокси-сетов. Если 252 занята другим сервисом, b4 берёт 251, 250, затем 300-399
Правило, приоритет 2fwmark <метка>/0x1027fff iif lo lookup main, IPv4
Пакеты самого роутера<метка> + 0x1000000, только TCP в исходном направлении; у сета, ограниченного исходными устройствами или исходными интерфейсами, отсутствует

b4r_<set>_pre пропускает пакеты с меткой очереди, с битом 0x40000 или с битами под 0x27fff, отличными от собственной метки сета, а также пакеты на локальные, широковещательные и multicast-адреса и на link-local-адреса IPv6. Из пакетов к адресам сета он затем ставит метку TCP-пакетам соединений, которые уже принадлежат прозрачному сокету, и принимает их, а остальные TCP-пакеты, и UDP при включённом Маршрутизировать UDP через upstream, передаёт TPROXY с меткой сета; сет, ограниченный исходными интерфейсами, передаёт только пакеты, пришедшие с них. Исходные устройства ограничивают эту цепочку так же, как у сетов с выходным интерфейсом. iptables пишет метку под маской 0x1027fff, nftables - целиком.

Соединения самого роутера попадают в прокси-сет по петле, если сет не ограничен исходными устройствами или исходными интерфейсами. b4r_<set>_out ставит их TCP-пакетам исходного направления метку сета плюс бит 0x1000000, правило с приоритетом 3 отправляет их в lo, и они возвращаются через prerouting, где их забирает TPROXY. Когда новых соединений к адресам сета больше 200 в секунду (burst 400), b4r_<set>_out не ставит метку на первый пакет каждого следующего соединения, но последующие TCP-пакеты этого соединения в исходном направлении помечает как обычно.

Когда src_valid_mark равен 1 в net.ipv4.conf.all или на интерфейсе, через который пришло соединение, ядро проверяет источник каждого перенаправленного соединения в таблице, которую выбирает его метка, а таблица 252 отвечает на любой адрес самим роутером. Правило с приоритетом 2 отправляет эту проверку в main. Бит 0x1000000 не пускает под него пакеты самого роутера, и они по-прежнему идут петлёй через lo. net.ipv4.conf.all.src_valid_mark в 1 ставят XrayUI, когда в Xray есть исходящее подключение WireGuard, wg-quick и awg-quick, когда пир забирает маршрут IPv4 по умолчанию, и Tailscale в режиме netfilter по умолчанию.

Ещё b4 добавляет разрешение для каждой прокси-метки в начало входной цепочки: в iptables -I INPUT 1 -m mark --mark <метка>/<метка> -j ACCEPT, также через ip6tables и через варианты -legacy, если они установлены; в nftables meta mark & <метка> == <метка> accept в начало inet fw4 input, а без fw4 - в начало inet filter input, и никуда, если нет ни той, ни другой цепочки. При установке прокси-сета b4 записывает 0 в net.ipv4.conf.lo.rp_filter и 2 в net.ipv4.conf.all.rp_filter; прежние значения b4 не возвращает.

На тестовой машине переключатель «Telegram через WebSocket» и один прокси-сет получили следующее; второй прокси-сет и сет в режиме Telegram через WebSocket добавили такую же пару правил, каждый со своей меткой:

2:      from all fwmark 0x24bab/0x1027fff iif lo lookup main
2: from all fwmark 0x21546/0x1027fff iif lo lookup main
3: from all fwmark 0x24bab/0x27fff lookup 252
3: from all fwmark 0x21546/0x27fff lookup 252

Соединения самого b4​

С 0x40000 b4 открывает такие соединения: с upstream прокси-сета и прямые соединения, которые прокси-сет открывает вместо него, с Telegram, загрузку списков адресов и доменов для функций Telegram, пересылку MTProto-прокси на его домен для Fake SNI и запросы к Хабу сообщества, ipinfo и RIPEstat. Цепочки сетов с выходным интерфейсом, прокси-сетов и сетов Telegram через WebSocket пропускают пакеты с этим битом, поэтому ни один такой сет эти соединения не маршрутизирует и они не возвращаются петлёй на слушатели самого b4: они идут по остальным правилам маршрутизации роутера, обычно по основной таблице. Сеты блокировки их всё равно блокируют, а в режиме TUN они могут пройти через b4tun0.

Обработка пакетов 0x40000 не пропускает: сет, чьи цели совпадают с адресом назначения, применяет свою стратегию к собственным соединениям b4 так же, как к соединениям устройства. Сет в режиме прокси или Telegram через WebSocket, а также сет с выходным интерфейсом-туннелем TUN, TAP или WireGuard, который поднят, пропускает их без изменений, а поскольку его цепочки маршрутизации их тоже пропускают, они уходят по основному маршруту вовсе без стратегии.

0x240000 добавляет бит 0x200000, и обработка пакетов пропускает пакеты с этим битом. MTProto-прокси и Telegram через WebSocket ставят его на соединения через домены за Cloudflare-прокси или свой домен WebSocket, а также с Cloudflare Worker, пока не включено Обрабатывать соединения с Worker сетами; см. Обработка DPI.

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

В режиме TUN, когда в b4tun0 указывает сам маршрут по умолчанию, пакеты самого роутера с меткой очереди, 0x40000 или 0x240000 попадают в b4tun0, как и любые другие, если идут по маршруту по умолчанию. b4 читает их оттуда уже без метки, поэтому ни метка очереди, ни бит 0x200000 не выводят их из-под обработки пакетов; в режиме TUN они делают это только при захвате по портам, где такие пакеты пропускает B4_TUN.

Режим TUN​

В режиме TUN (queue.mode: "tun") пакеты попадают в b4 через TUN-устройство - b4tun0, если queue.tun.device_name не задаёт другое, - а не через очередь. Эти правила пишутся через iptables и при бэкенде nftables и касаются только IPv4.

ЧтоПравило
ЗахватЦепочка B4_TUN, в неё переходят из mangle OUTPUT и PREROUTING (из PREROUTING через B4_TUN_GATE, когда фильтрация устройств выбирает устройства), а пока b4 захватывает только соединения самого роутера (см. Движок пакетов) - только из OUTPUT: ставит 0x40000000/0x40000000 на запросы и ответы DNS по UDP, на первые пакеты соединений к портам захвата (без xt_connbytes - на все их пакеты), на каждый TCP-пакет к портам захвата на адреса сета для дублирования пакетов и на TCP RST с портов захвата, пока у сета включена Защита от RST-инъекций или задан сет для эскалации
Правилоfwmark 0x40000000/0x40000000 lookup <таблица> с приоритетом 10 либо на единицу меньше самого низкого правила другого сервиса в диапазоне 5-9, но не ниже 4
Таблицаdefault dev b4tun0; выбирается от 96 вниз до 61, кроме 77 и занятых таблиц, либо рядом с queue.tun.route_table
Пакеты, которые b4 отправляет обратноМетка сокета - метка очереди плюс 0x10000000, conntrack их не отслеживает (raw OUTPUT ... -j CT --notrack), если не включён system.tables.skip_setup и в ядре есть таблица raw и цель CT. Если system.tables.skip_setup выключен, а b4 не удалось поставить это правило, правило для пакетов устройству или SNAT в b4tun0, он захватывает только соединения самого роутера
Пакеты устройствуМетка сокета 0x20000000, conntrack их не отслеживает при тех же условиях

Если xt_connbytes недоступен, b4 сам считает пакеты каждого соединения и обрабатывает только первые, как это делал бы модуль. Пока b4 захватывает только соединения самого роутера, он сохраняет захват по портам, и B4_TUN ставит метку на все пакеты соединений к портам захвата; иначе b4 направляет в b4tun0 сам маршрут по умолчанию. Никакая настройка эти режимы не выбирает. Когда в b4tun0 направлен маршрут по умолчанию, собственные пакеты b4 уходят по правилам 88 и 89 (0x20000000) и 99 и 100 (0x10000000): первое правило каждой пары смотрит в main без маршрута по умолчанию, второе - в таблицу внешнего интерфейса с его маршрутом по умолчанию, выбранную так же от 97 вниз до 62, либо в саму queue.tun.route_table. Правилам 88, 89 и 99 нужен ip, который принимает suppress_prefixlength; без него добавляется только правило 100.

Дискавери​

Пока идёт поиск Дискавери, в том числе запущенный мониторингом или MCP-сервером, цепочка в начале цепочек prerouting и output таблицы inet b4_mangle (b4_discovery, nftables) или mangle PREROUTING и OUTPUT (B4_DISCOVERY, iptables и ip6tables) направляет его проверочные соединения в отдельную очередь с номером после основных (541 при настройках по умолчанию). Этой очередью Дискавери пользуется и в режиме TUN. Проверочные соединения несут метку потока, по умолчанию метку очереди плюс 1, пакеты, которые Дискавери отправляет сам, - метку отправленных пакетов, метку очереди плюс 2. Обе сравниваются как целые 32-битные значения, а метка потока копируется между пакетом и соединением целиком. Задают их system.checker.discovery_flow_mark и system.checker.discovery_injected_mark в конфигурационном файле. Значения по умолчанию содержат биты под 0x27fff, поэтому ни один сет с маршрутизацией трафик Дискавери не маршрутизирует. На время поиска цепочка очереди b4, b4_chain в nftables и B4 в iptables и ip6tables, тоже пропускает пакет, чья метка в точности равна метке потока или метке отправленных пакетов, поэтому обработка пакетов не трогает пакеты Дискавери на выходе с роутера.

Во время поиска соединение другого сервиса, чья метка в точности равна метке потока, тоже уходит в очередь Дискавери, а пакет с меткой, в точности равной метке потока или метке отправленных пакетов, пропускает остаток этих цепочек; в iptables это все правила ниже в mangle PREROUTING и OUTPUT, включая правила других сервисов.

Правила маршрутизации и таблицы​

ПриоритетПравилоТаблицаКогда есть
2fwmark <метка>/0x1027fff iif lomainПрокси-сеты и Telegram через WebSocket, IPv4
3fwmark <метка>/0x27fff252; 251, 250, 300-399Прокси-сеты и Telegram через WebSocket
4-10fwmark 0x40000000/0x40000000от 96 вниз до 61 либо рядом с queue.tun.route_tableРежим TUN с захватом по портам, IPv4
88, 89fwmark 0x20000000/0x20000000main без маршрута по умолчанию, затем таблица внешнего интерфейса: от 97 вниз до 62 либо queue.tun.route_tableРежим TUN через весь маршрут по умолчанию, IPv4
99, 100fwmark 0x10000000/0x10000000То жеРежим TUN через весь маршрут по умолчанию, IPv4
10000 + таблицаfwmark <метка>/0x27fff100-249 либо закреплённая routing.tableСеты с выходным интерфейсом

Ядро перебирает правила от меньшего номера приоритета к большему и останавливается на первом, которое дало маршрут. Правило, добавленное без приоритета, получает приоритет правила, следующего за local, минус один; на ядрах до 4.3 правило IPv6 вместо этого получает 16383. Добавленное после правила b4 с приоритетом 2, такое правило получает приоритет 1 и оказывается выше всех правил b4; в системе только со стандартными правилами оно получает 32765 и оказывается ниже них. XKeen, XrayUI и OpenClash вне режима TUN, MagiTrickle, mihomo в режиме iptables, руководства Xray, wg-quick и awg-quick добавляют свои правила именно так, поэтому их правила оказываются выше правил b4, если добавлены при работающем b4, в том числе при перезапуске этого сервиса. Добавленные до запуска b4, они оказываются ниже правил b4, только если других правил, кроме стандартных, тогда не было: рядом с правилом 5210 от Tailscale, например, такое правило получает 5209, то есть выше сетов b4 с выходным интерфейсом с приоритетами 10100-10249. На ядрах до 4.3 их правила IPv6 получают 16383 и в любом случае оказываются ниже правил b4.

Рядом с другими сервисами​

  • Метка с любым битом под 0x27fff, стоящая на пакете до цепочек маршрутизации b4, выводит пакет из-под сетов с выходным интерфейсом и прокси-сетов; только прокси-сет всё же забирает пакет, у которого биты под 0x27fff равны его собственной метке. Сеты блокировки и отказ QUIC у прокси-сета на эти биты не смотрят. Так вышестоящий прокси, работающий на роутере, остаётся вне сета, который совпадает с адресом его сервера, например при sockopt.mark равном 255 у Xray. Обработка пакетов к его соединениям при этом применяется, если метка не из следующего пункта и её биты под 0x27fff не равны 0x24bab, а в iptables - и метке прокси-сета.
  • Метку со всеми битами метки очереди b4 принимает за свою. Такой пакет, если он всё же попадает в очередь (в iptables через B4, а при обоих бэкендах через правила для пакетов на входе в роутер), обработка пакетов отпускает, только если остальная часть его метки лежит внутри 0x27fff. Метку с битом 0x200000 b4 принимает за признак пакета, который обработка пакетов не трогает.
  • В nftables цепочки маршрутизации b4 работают с приоритетом mangle - 1 (-151), раньше цепочек с приоритетом mangle (-150): b4 ставит метку первым, а если сервис после этого пишет метку целиком, метка b4 теряется и пакет идёт по правилу, которое совпадает с новым значением. Пакет самого роутера при этом меняет маршрут, только если метку переписала цепочка типа route (mangle OUTPUT в iptables как раз такая).
  • В iptables b4 вставляет свои переходы маршрутизации в начало mangle OUTPUT. В mangle PREROUTING он ставит их прямо над своим переходом B4_PREROUTING, который вставляет в начало при установке правил, или над стоящим раньше правилом другого сервиса, которое проверяет локальные сокеты; если нет ни того, ни другого, как в режиме TUN, он добавляет их в конец цепочки, а оказавшиеся ниже переходы возвращает на место. Правило, которое другой сервис вставит в начало позже, срабатывает первым, если только оно не проверяет локальные сокеты.
  • В iptables в режиме NFQUEUE пакет, который b4 выпустил из очереди, пропускает все следующие правила той встроенной цепочки mangle, из которой попал в очередь, поэтому правила другого сервиса ниже в этой цепочке его не видят. Это касается UDP-пакетов на порт 53 или с него, которые B4_PREROUTING и правила b4 ближе к началу mangle OUTPUT ставят в очередь, если метка очереди не стоит на самом пакете или его соединении (например, DNS, который руководства Xray забирают через TPROXY), и первых пакетов соединений на портах b4. Фейки и сегменты после разделения, которые отправляет b4, несут только метку очереди, и b4 принимает их близко к началу mangle OUTPUT, поэтому сервис, чьи правила стоят в этой цепочке ниже, например mwan3 или KVAS, их тоже не помечает: для соединения, которое такой сервис маршрутизирует по своей метке, они идут по основной маршрутизации роутера. В режиме TUN на фейках и сегментах стоит ещё бит 0x10000000, такого правила ACCEPT в mangle OUTPUT нет, и правила этих сервисов их видят.
  • Когда b4 выбирает таблицу сам, он пропускает ещё не занятую им таблицу, если она названа в rt_tables, на неё ссылается другое правило или в ней есть маршруты, которые добавил не b4. Таблица, заданная в routing.table, используется как есть только вместе с routing.fwmark, а занятую queue.tun.route_table b4 отвергает. Некоторые сервисы используют фиксированные номера таблиц из диапазонов b4 без такой проверки: XKeen 111, podkop 105, руководства Xray 100 и 106, XrayUI 250 в режиме TUN. Если такой сервис запускается, когда b4 уже занял одну из них, XKeen очищает таблицу и добавляет туда свои маршруты, а XrayUI заменяет в ней маршрут b4; podkop и руководства Xray не могут добавить свой маршрут (File exists), пока в таблице стоит маршрут по умолчанию b4. XKeen, podkop и XrayUI при остановке очищают таблицу, а XrayUI ещё и удаляет все правила, которые ссылаются на 250, в том числе правило b4 с приоритетом 3, если b4 использует эту таблицу.

Значения других сервисов, взятые из их исходного кода:

СервисМеткиПравила и таблицы
Xray-core 26.3.27streamSettings.sockopt.mark: метка сокета исходящего подключения целиком, только если задана; своих правил файрвола нет. Руководства по прозрачному прокси пишут 1 целиком вместе с TPROXY и на TCP и UDP самого роутера в OUTPUT, а собственный трафик Xray исключают только по точной метке 2 или 255Руководства: fwmark 1 lookup 100, для IPv6 fwmark 1 lookup 106, без маски, без приоритета
XKeen 2.0.1 BetaTPROXY и MARK 0x111 целиком в режиме TProxy и для UDP в режиме Hybrid; режим Redirect и TCP в режиме Hybrid используют nat REDIRECT без метки. CONNMARK сохраняет и восстанавливает метку целиком. С проксированием трафика роутера (proxy_router) так же забирает TCP и UDP самого роутера, кроме метки ровно 255, метки политики Keenetic и бита 0x40000000fwmark 0x111 lookup 111, без приоритета
XrayUI 0.70.20x10000/0x10000 в DIVERT, TPROXY и метке соединенияfwmark 0x10000/0x10000 lookup 77, без приоритета; режим TUN: 49 from <LAN> to <LAN> lookup main и 51 from <LAN> lookup 250, без метки
sing-box 1.14.2route.default_mark, routing_mark: метки сокетов. TUN auto_redirect: 0x2023 и 0x2024 целиком в метке пакета и соединения у UDP и ICMP, а если доступна NFQUEUE 100, то и у TCP-соединений, которые он оценивает по первому пакету; 0x2025 на первом TCP-пакете, который он сбрасывает; каждый исходящий сокет 0x2024TUN auto_route: 9000-9010 в таблицу 2022; с auto_redirect вместо них 9000 fwmark 0x2024, 9001 fwmark 0x2023 lookup 2022, 9002 и 32768 not fwmark 0x2024 lookup 2022
mihomo 1.19.32routing-mark: метка сокета, 2158, если включён режим iptables, а она не задана. Режим iptables: 0x2d0 (TPROXY под 0x2d0, MARK целиком). TUN auto-redirect пишет 0x2023 и 0x2024 и ставит 0x2024 на каждый исходящий сокет только с route-address-set или route-exclude-address-setTUN: 9000-9010 в таблицу 2022, а когда auto-redirect пишет метки, ещё 32768 в таблицу 2022; режим iptables: fwmark 0x2d0 lookup 720, только IPv4, без приоритета
OpenClash 0.47.1560x162 целиком: у UDP в режиме TPROXY по умолчанию, где TCP идёт через nat REDIRECT без метки, и у TCP, UDP и ICMP echo в режиме TUNfwmark 0x162 lookup 354, без приоритета; режим TUN: 1888
nikki 1.26.10x80/0xff для TPROXY, 0x81/0xff для TUN1024 в таблицу 80, 1025 в таблицу 81
podkop 0.7.220x100000 целиком105: fwmark 0x100000/0x100000 lookup podkop (таблица 105 с именем в rt_tables), только IPv4
zapret 72.13 и zapret2 1.0.5.2Сгенерированные пакеты: метка пакета из очереди плюс 0x40000000. При FILTER_TTL_EXPIRED_ICMP=1 (по умолчанию) 0x40000000 добавляется к метке соединения: в режиме nftables POSTNAT (тоже по умолчанию) - каждого соединения, пакеты которого уходят в nfqws, иначе - соединений, в которые nfqws отправил сгенерированные пакеты. В режиме POSTNAT к пакетам, которые уходят в очередь после NAT, добавляется 0x20000000. NFQUEUE 200 и 300Нет
MagiTrickle 0.8.20x4d616769 и дальше, по одной на группу, целиком, в метке пакета и соединенияfwmark <метка> lookup <метка>, без приоритета
KVAS 1.1.90xd1000 целиком, в метке пакета и соединения1778: fwmark 0xd1000/0xd1000 lookup 1001
Tailscale 1.102.5Собственные сокеты 0x80000; транзитные пакеты из tailscale0 получают 0x40000/0xff0000 и проходят маскарад; биты 0xff0000 новых соединений самого роутера сохраняются в метке соединения и восстанавливаются на следующих входящих пакетах, в iptables с маской, в nftables (по умолчанию в пакете OpenWrt) целиком5210, 5230, 5250 по 0x80000/0xff0000; 5270 в таблицу 52; на OpenWrt с mwan3 вместо них 1310-1370
wg-quick 1.0.20260223, awg-quick 3.1.20260812С пиром /0 и Table, не заданным или равным auto: 51820 (0xca6c) на сокете WireGuard, либо его FwMark, либо следующее число, если в таблице 51820 есть маршруты; метка соединения целиком копируется в метку пакета каждого UDP-пакета этого семейства адресов в preroutingnot fwmark 51820 lookup 51820, lookup main suppress_prefixlength 0, без приоритета
mwan3 2.12.2Интерфейс N как N << 8 под 0x3f00; метка соединения сохраняется и восстанавливается под той же маской1001-1060 по входному интерфейсу, 2001-2060 по метке, 3001-3060 unreachable по метке, 2061 и 2062 blackhole и unreachable
pbr 1.2.20x10000, 0x20000 и далее по интерфейсу под 0xff000030000, 29999 и ниже: fwmark <метка>/0xff0000

Где они встречаются с b4:

  • Xray, XKeen. 255 лежит под 0x27fff, поэтому сеты с маршрутизацией не трогают исходящие соединения Xray, а обработка пакетов к ним применяется. Отказ QUIC у прокси-сета с выключенным Маршрутизировать UDP через upstream, который проверяет только метку очереди и 0x40000, и сеты блокировки, которые метку не проверяют, отклоняют пакеты Xray к своим адресам тоже. XKeen пишет метки целиком и заменяет биты b4 на соединениях, которые забирает. С проксированием трафика роутера он забирает и собственные соединения b4: ни одно из его исключений не покрывает 0x40000. Вариант руководств Xray для nftables начинается с flush ruleset, который удаляет и таблицы nftables у b4, а служба iptables tproxyrules.service из руководства для IPv4 и IPv6 при остановке выполняет iptables -t mangle -F и ip6tables -t mangle -F, которые удаляют и правила b4 в mangle.
  • XrayUI. Его бит 16 лежит вне битов b4. Правило DIVERT и порядок двух сервисов в mangle PREROUTING описаны в b4 вместе с Xray или XrayUI.
  • sing-box, mihomo. Их метки по умолчанию лежат под 0x27fff; только outbound bridge у sing-box, когда переходит на iptables, использует бит 0x40000000 - бит захвата TUN у b4. auto_redirect (в mihomo только с route-address-set или route-exclude-address-set) пишет метки целиком после цепочек маршрутизации b4: у UDP и ICMP, а в sing-box ещё и у TCP-соединений, которые он оценивает через NFQUEUE. При auto_route правило в диапазоне 9000-9010 отправляет транзитный трафик в таблицу 2022 раньше сетов b4 с выходным интерфейсом, у которых приоритет от 10000. Соединения самого роутера, в том числе соединения b4, они тоже забирают: auto_redirect пропускает только метку ровно 0x2024.
  • nikki. Его маска 0xff лежит внутри меток сетов b4 с выходным интерфейсом. Сет, в метке которого младший байт равен 0x81 или, если nikki использует режим TPROXY, 0x80, первым совпадает с правилом nikki, потому что у того приоритеты меньше. Сам nikki меняет только биты 0-7, но они лежат под 0x27fff, поэтому на адресах, которые покрывают оба, побеждает маршрут nikki, в каком бы порядке они ни срабатывали. Опция nikki proxy.bypass_fwmark принимает пары метка/маска; значения 0x40000/0x40000 и 0x8000/0x8000 в ней выводят помеченные соединения и пакеты b4 из-под проксирования nikki, но не из-под перехвата DNS роутера, который срабатывает раньше этой проверки, и не соединения b4 без метки.
  • mwan3. Его маска 0x3f00 лежит внутри меток сетов b4 с выходным интерфейсом. Сет, в метке которого в битах 8-13 стоит номер активного интерфейса mwan3, первым совпадает с его правилом из 2001-2060; с числом 61 или 62 там он, пока работает mwan3, попадает под его правило blackhole или unreachable, 2061 или 2062. Метке сета без битов в 0x3f00 политика mwan3 добавляет номер интерфейса, и после этого с ней совпадает правило mwan3, а не b4.
  • zapret, zapret2. Биты 30 и 29 - это бит захвата TUN и бит пакетов устройству у b4, а бит 30 метки соединения - отметка b4. По метке ни один из сервисов не пропускает пакеты, которые сгенерировал другой. Но в nftables в режиме POSTNAT, который у zapret включён по умолчанию, zapret выводит свои сгенерированные пакеты из-под conntrack, и b4 ставит их в очередь только к адресам сета для дублирования пакетов: остальные его правила очереди считают пакеты соединения. В nftables пакеты, которые выбирают оба, ставят в очередь оба, b4 первым (приоритет -150 против 99 или 101 у zapret). Когда Задать DSCP включено, b4 не записывает значение в пакет с битом 0x20000000, поэтому в режиме POSTNAT пакеты, которые zapret ставит в очередь после NAT, и пакеты, которые он из них генерирует, уходят без значения DSCP. В iptables такие пакеты в mangle POSTROUTING забирает то правило NFQUEUE, которое стоит выше, и другое их не видит; пакеты самого роутера b4 ставит в очередь раньше, в mangle OUTPUT, а при фильтрации устройств транзитные пакеты - в mangle FORWARD, так что zapret может обработать их после b4. zapret отбрасывает ICMP time-exceeded для соединений, в метке соединения которых есть бит 0x40000000, а это каждое соединение, отмеченное сетом b4 с выходным интерфейсом. В режиме TUN с захватом по портам правило b4 fwmark 0x40000000/0x40000000 совпадает и со сгенерированными пакетами zapret и отправляет их в b4tun0.
  • MagiTrickle. В его метках, 0x4d616769 и следующих, есть бит 0x200000, поэтому в режиме NFQUEUE обработка пакетов пропускает его соединения. Есть в них и бит 0x40000000: в режиме TUN с захватом по портам правило b4 fwmark 0x40000000/0x40000000, только для IPv4, совпадает с каждым пакетом, который пометил MagiTrickle, и когда в ip rule оно стоит выше правила MagiTrickle fwmark <метка>, такие пакеты уходят в b4tun0, b4 их обрабатывает, и они выходят по маршрутизации самого роутера, а не по таблице MagiTrickle.
  • zapret, MagiTrickle и проверка метки соединения у b4. Оба ставят бит 0x40000000 в метку соединения. b4 считает любое соединение с ответом, у которого есть этот бит, доказательством того, что роутер сохраняет метку соединения, поэтому они могут скрыть прошивку, которая перезаписывает отметку b4.
  • KVAS. 0xd1000 содержит 0x40000: пакет, который уже несёт эту метку, когда срабатывают цепочки b4, выглядит для b4 как одно из его собственных соединений. С включённым ускорением KVAS помечает и соединения самого роутера к адресам из своего списка unblock, в том числе соединения b4, и его правило 1778 направляет их в таблицу 1001.
  • Tailscale. 0x40000 - метка Tailscale для пакетов из tailscale0. Его правило маскарада, включённое по умолчанию, совпадает с любым пакетом, у которого под 0xff0000 стоит это значение, поэтому собственные соединения b4 с меткой 0x40000 проходят маскарад на адрес исходящего интерфейса; соединения с 0x240000 - нет. Правило 5270 (1370 на OpenWrt с mwan3) стоит раньше сетов b4 с выходным интерфейсом, поэтому адрес, для которого в таблице 52 есть маршрут, уходит через Tailscale, даже если сет b4 поставил на пакет свою метку.
  • wg-quick, awg-quick. С меткой очереди по умолчанию в 0xca6c есть все её биты, поэтому b4 принимает собственные пакеты WireGuard за свои. Их правило в prerouting заменяет метку каждого UDP-пакета меткой соединения. Когда и они, и b4 работают через nftables, оно срабатывает после цепочек маршрутизации b4: пакеты сета с выходным интерфейсом по-прежнему совпадают с его правилом, потому что b4 сохранил метку сета в метке соединения, а UDP, который перенаправляет прокси-сет, теряет метку сета, и правило с приоритетом 3 больше не отправляет его слушателю b4. Поднятые после b4, их два правила оказываются выше всех правил b4, для IPv6 только на ядре 4.3 или новее.
  • pbr. 0x40000 - метка его четвёртого интерфейса, поэтому при четырёх интерфейсах и больше правило pbr направляет собственные соединения b4 с меткой 0x40000 в таблицу этого интерфейса. Политика pbr, которая совпала с пакетом, помеченным сетом b4 с выходным интерфейсом, добавляет свой байт интерфейса; если в этом байте есть бит 17, правило b4 больше не совпадает, и пакет маршрутизирует pbr.
  • OpenClash, podkop. Их запись заменяет метку b4: метки целиком, а у OpenClash в режиме по умолчанию для TCP ещё nat REDIRECT, поэтому на адресах, которые покрывают оба, побеждает их маршрут. OpenClash забирает соединения самого роутера, пока включено проксирование роутера (по умолчанию), а podkop всегда забирает те из них, что идут к адресам из его списков. Собственные соединения b4 ни один из них не исключает.
примечание

Значения в таблице взяты из указанных в ней версий и меняются от версии к версии. Что установлено на самом деле, показывают ip rule и список правил файрвола на роутере.

Как посмотреть метки на роутере​

# правила b4 с их метками
nft list table inet b4_mangle
nft list table inet b4_route
nft list table inet b4_dscp
iptables -t mangle -S
iptables -t nat -S

# правила маршрутизации всех сервисов и таблицы b4
ip rule
ip -6 rule
ip route show table 252

# метки сокетов собственных соединений b4
ss -tanpe | grep b4

# метки соединений в десятичном виде, если ядро их показывает
grep -o 'mark=[0-9]*' /proc/net/nf_conntrack | sort | uniq -c

«Информация о системе» в веб-интерфейсе показывает правила файрвола b4 и вывод ip rule.