Метки пакетов
Метка - это 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, 17 | 0x27fff | Маршрут сета с маршрутизацией | Своя у каждого сета; сеты с одним выходным интерфейсом, egress IP и аварийным отключением делят одну. См. сеты с выходным интерфейсом и прокси-сеты |
| 15 по умолчанию | 0x8000 по умолчанию | Метка очереди: пакеты, которые b4 отправляет из raw-сокетов, кроме пакетов устройству в режиме TUN, DNS-запросы, которые он отправляет за клиентов и для своих сетов, и его проверки, которые идут мимо его обработки | Метка пакета в разделе Настройки, Основные, Движок пакетов, по умолчанию 0x8000 (32768) |
| 18 | 0x40000 | Соединения, которые b4 открывает с upstream прокси-сета, Telegram, Хабом сообщества, ipinfo и RIPEstat, и его прозрачные слушатели; см. метки сокетов | Фиксирована |
| 21 | 0x200000 | Собственные соединения b4, исходящие пакеты которых обработка пакетов не трогает | Фиксирована, ставится вместе с битом 18 как 0x240000 |
| 24 | 0x1000000 | TCP-пакет прокси-сета, отправленный самим роутером | Фиксирована, прибавляется к метке сета |
| 28 | 0x10000000 | Режим TUN: пакеты, которые b4 отправляет обратно | Фиксирована, прибавляется к метке очереди |
| 29 | 0x20000000 | Пакеты, которые b4 отправляет устройству в сети | Фиксирована; в режиме NFQUEUE прибавляется к метке очереди, а у пакетов, которые поиск Дискавери отправляет обратно к своим проверочным соединениям, - к метке отправленных пакетов Дискавери |
| 30 | 0x40000000 | Режим 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.
Метка соединения
| Биты | Маска | Назначение |
|---|---|---|
| 30 | 0x40000000 | Соединение принадлежит сету с выходным интерфейсом |
| 0-14, 17 | 0x27fff | Метка этого сета, скопированная с первого пакета соединения |
| 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 и RIPEstat | 0x40000. Если синхронизация с Хабом не может соединиться, b4 повторяет её с меткой очереди; если этот повтор соединился, следующие запросы к Хабу идут с меткой очереди, пока синхронизация с ней не перестанет соединяться, а повтор с 0x40000 не соединится |
| Соединения через домены за Cloudflare-прокси или свой домен WebSocket, а также с Cloudflare Worker | 0x240000; 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 отправляет за
клиентов и для своих сетов, тоже несут метку очереди; запросы через резолвер самого роутера
метки не несут. Каждое правило ниже проверяет все биты метки очереди сразу, поэтому другие
биты на том же пакете её не скрывают.
| Правило | nftables | iptables |
|---|---|---|
| Пакеты самого роутера | output: meta mark & 0x8000 == 0x8000 ct mark set ct mark | 0x8000, затем ... accept | mangle 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 return | B4_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 return | B4_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, по порядку:
- Пропускает пакеты с меткой очереди, с битом
0x40000или с любым битом под0x27fff. - Пропускает пакеты, пришедшие с самого выходного интерфейса.
- Восстанавливает метку из метки соединения на следующих пакетах отмеченных соединений, идущих в направлении первого пакета.
- Ставит метку новым соединениям к адресам сета и сохраняет её вместе с отметкой.
Сет, исключающий исходные устройства, пропускает их пакеты перед шагом 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 |
| Правило, приоритет 3 | fwmark <метка>/0x27fff lookup 252, для IPv4 и, при включённой Поддержке IPv6, для IPv6; в таблице 252 local default dev lo, она общая для всех прокси-сетов. Если 252 занята другим сервисом, b4 берёт 251, 250, затем 300-399 |
| Правило, приоритет 2 | fwmark <метка>/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, включая правила других сервисов.
Правила маршрутизации и таблицы
| Приоритет | Правило | Таблица | Когда есть |
|---|---|---|---|
| 2 | fwmark <метка>/0x1027fff iif lo | main | Прокси-сеты и Telegram через WebSocket, IPv4 |
| 3 | fwmark <метка>/0x27fff | 252; 251, 250, 300-399 | Прокси-сеты и Telegram через WebSocket |
| 4-10 | fwmark 0x40000000/0x40000000 | от 96 вниз до 61 либо рядом с queue.tun.route_table | Режим TUN с захватом по портам, IPv4 |
| 88, 89 | fwmark 0x20000000/0x20000000 | main без маршрута по умолчанию, затем таблица внешнего интерфейса: от 97 вниз до 62 либо queue.tun.route_table | Режим TUN через весь маршрут по умолчанию, IPv4 |
| 99, 100 | fwmark 0x10000000/0x10000000 | То же | Режим TUN через весь маршрут по умолчанию, IPv4 |
| 10000 + таблица | fwmark <метка>/0x27fff | 100-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. Метку с битом0x200000b4 принимает за признак пакета, который обработка пакетов не трогает. - В nftables цепочки маршрутизации b4 работают с приоритетом
mangle - 1(-151), раньше цепочек с приоритетом mangle (-150): b4 ставит метку первым, а если сервис после этого пишет метку целиком, метка b4 теряется и пакет идёт по правилу, которое совпадает с новым значением. Пакет самого роутера при этом меняет маршрут, только если метку переписала цепочка типаroute(mangleOUTPUTв iptables как раз такая). - В iptables b4 вставляет свои переходы маршрутизации в начало mangle
OUTPUT. В manglePREROUTINGон ставит их прямо над своим переходомB4_PREROUTING, который вставляет в начало при установке правил, или над стоящим раньше правилом другого сервиса, которое проверяет локальные сокеты; если нет ни того, ни другого, как в режиме TUN, он добавляет их в конец цепочки, а оказавшиеся ниже переходы возвращает на место. Правило, которое другой сервис вставит в начало позже, срабатывает первым, если только оно не проверяет локальные сокеты. - В iptables в режиме NFQUEUE пакет, который b4 выпустил из очереди, пропускает все
следующие правила той встроенной цепочки mangle, из которой попал в очередь, поэтому
правила другого сервиса ниже в этой цепочке его не видят. Это касается UDP-пакетов на порт
53 или с него, которые
B4_PREROUTINGи правила b4 ближе к началу mangleOUTPUTставят в очередь, если метка очереди не стоит на самом пакете или его соединении (например, DNS, который руководства Xray забирают через TPROXY), и первых пакетов соединений на портах b4. Фейки и сегменты после разделения, которые отправляет b4, несут только метку очереди, и b4 принимает их близко к началу mangleOUTPUT, поэтому сервис, чьи правила стоят в этой цепочке ниже, например mwan3 или KVAS, их тоже не помечает: для соединения, которое такой сервис маршрутизирует по своей метке, они идут по основной маршрутизации роутера. В режиме TUN на фейках и сегментах стоит ещё бит0x10000000, такого правила ACCEPT в mangleOUTPUTнет, и правила этих сервисов их видят. - Когда b4 выбирает таблицу сам, он пропускает ещё не занятую им таблицу, если она названа в
rt_tables, на неё ссылается другое правило или в ней есть маршруты, которые добавил не b4. Таблица, заданная вrouting.table, используется как есть только вместе сrouting.fwmark, а занятуюqueue.tun.route_tableb4 отвергает. Некоторые сервисы используют фиксированные номера таблиц из диапазонов 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.27 | streamSettings.sockopt.mark: метка сокета исходящего подключения целиком, только если задана; своих правил файрвола нет. Руководства по прозрачному прокси пишут 1 целиком вместе с TPROXY и на TCP и UDP самого роутера в OUTPUT, а собственный трафик Xray исключают только по точной метке 2 или 255 | Руководства: fwmark 1 lookup 100, для IPv6 fwmark 1 lookup 106, без маски, без приоритета |
| XKeen 2.0.1 Beta | TPROXY и MARK 0x111 целиком в режиме TProxy и для UDP в режиме Hybrid; режим Redirect и TCP в режиме Hybrid используют nat REDIRECT без метки. CONNMARK сохраняет и восстанавливает метку целиком. С проксированием трафика роутера (proxy_router) так же забирает TCP и UDP самого роутера, кроме метки ровно 255, метки политики Keenetic и бита 0x40000000 | fwmark 0x111 lookup 111, без приоритета |
| XrayUI 0.70.2 | 0x10000/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.2 | route.default_mark, routing_mark: метки сокетов. TUN auto_redirect: 0x2023 и 0x2024 целиком в метке пакета и соединения у UDP и ICMP, а если доступна NFQUEUE 100, то и у TCP-соединений, которые он оценивает по первому пакету; 0x2025 на первом TCP-пакете, который он сбрасывает; каждый исходящий сокет 0x2024 | TUN 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.32 | routing-mark: метка сокета, 2158, если включён режим iptables, а она не задана. Режим iptables: 0x2d0 (TPROXY под 0x2d0, MARK целиком). TUN auto-redirect пишет 0x2023 и 0x2024 и ставит 0x2024 на каждый исходящий сокет только с route-address-set или route-exclude-address-set | TUN: 9000-9010 в таблицу 2022, а когда auto-redirect пишет метки, ещё 32768 в таблицу 2022; режим iptables: fwmark 0x2d0 lookup 720, только IPv4, без приоритета |
| OpenClash 0.47.156 | 0x162 целиком: у UDP в режиме TPROXY по умолчанию, где TCP идёт через nat REDIRECT без метки, и у TCP, UDP и ICMP echo в режиме TUN | fwmark 0x162 lookup 354, без приоритета; режим TUN: 1888 |
| nikki 1.26.1 | 0x80/0xff для TPROXY, 0x81/0xff для TUN | 1024 в таблицу 80, 1025 в таблицу 81 |
| podkop 0.7.22 | 0x100000 целиком | 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.2 | 0x4d616769 и дальше, по одной на группу, целиком, в метке пакета и соединения | fwmark <метка> lookup <метка>, без приоритета |
| KVAS 1.1.9 | 0xd1000 целиком, в метке пакета и соединения | 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-пакета этого семейства адресов в prerouting | not 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.2 | 0x10000, 0x20000 и далее по интерфейсу под 0xff0000 | 30000, 29999 и ниже: fwmark <метка>/0xff0000 |
Где они встречаются с b4:
- Xray, XKeen.
255лежит под0x27fff, поэтому сеты с маршрутизацией не трогают исходящие соединения Xray, а обработка пакетов к ним применяется. Отказ QUIC у прокси-сета с выключенным Маршрутизировать UDP через upstream, который проверяет только метку очереди и0x40000, и сеты блокировки, которые метку не проверяют, отклоняют пакеты Xray к своим адресам тоже. XKeen пишет метки целиком и заменяет биты b4 на соединениях, которые забирает. С проксированием трафика роутера он забирает и собственные соединения b4: ни одно из его исключений не покрывает0x40000. Вариант руководств Xray для nftables начинается сflush ruleset, который удаляет и таблицы nftables у b4, а служба iptablestproxyrules.serviceиз руководства для IPv4 и IPv6 при остановке выполняетiptables -t mangle -Fиip6tables -t mangle -F, которые удаляют и правила b4 в mangle. - XrayUI. Его бит 16 лежит вне битов b4. Правило
DIVERTи порядок двух сервисов в manglePREROUTINGописаны в 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, в каком бы порядке они ни срабатывали. Опция nikkiproxy.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 такие пакеты в manglePOSTROUTINGзабирает то правилоNFQUEUE, которое стоит выше, и другое их не видит; пакеты самого роутера b4 ставит в очередь раньше, в mangleOUTPUT, а при фильтрации устройств транзитные пакеты - в mangleFORWARD, так что zapret может обработать их после b4. zapret отбрасывает ICMP time-exceeded для соединений, в метке соединения которых есть бит0x40000000, а это каждое соединение, отмеченное сетом b4 с выходным интерфейсом. В режиме TUN с захватом по портам правило b4fwmark 0x40000000/0x40000000совпадает и со сгенерированными пакетами zapret и отправляет их вb4tun0. - MagiTrickle. В его метках,
0x4d616769и следующих, есть бит0x200000, поэтому в режиме NFQUEUE обработка пакетов пропускает его соединения. Есть в них и бит0x40000000: в режиме TUN с захватом по портам правило b4fwmark 0x40000000/0x40000000, только для IPv4, совпадает с каждым пакетом, который пометил MagiTrickle, и когда вip ruleоно стоит выше правила MagiTricklefwmark <метка>, такие пакеты уходят в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.