Не получается tproxy в xray на OpenWRT

Привет! Делаю на OpenWRT 23.05.5 по инструкции. Inbound в xray:

  {
    "tag": "dokoproxy",
    "listen": "127.0.0.1",
    "port": 10199,
    "protocol": "dokodemo-door",
    "settings": {
      "network": "tcp,udp",
      "followRedirect": true
    },
    "sniffing": {
      "enabled": true,
      "destOverride": [
        "http",
        "tls",
        "quic"
      ]
    }
  }

Фаервол в OpenWRT большой и сложный, заменил ручками максимально простым с одним правилом маскарадинга:

#!/usr/sbin/nft -f

flush ruleset

table inet fw4 {
  chain prerouting {
    type nat hook prerouting priority dstnat; policy accept;
  }
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    ip saddr 192.168.69.0/24 oifname "br-wan" counter masquerade
  }
 chain mangle_prerouting {
  type filter hook prerouting priority mangle; policy accept;
 }
}

Добавил 198 proxy в /etc/iproute2/rt_tables, маршруты:

ip rule add fwmark 0x198 table proxy priority 100
ip route add local 0.0.0.0/0 dev lo table proxy
ip -6 rule add fwmark 0x198 table proxy priority 100
ip -6 route add local ::/0 dev lo table proxy

и непосредственно правило nft 'add rule inet fw4 mangle_prerouting iifname "br-lan" meta l4proto { tcp, udp } counter log meta mark set 0x198 tproxy ip to 127.0.0.1:10199 accept'

В логе есть записи Fri Dec 27 11:30:00 2024 IN=br-lan OUT= PHYSIN=lan1 MAC=36:07:b2:f1:59:d4:00:0c:29:3e:13:46:08:00 SRC=192.168.69.229 DST=188.40.167.81 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=12060 DF PROTO=TCP SPT=36362 DPT=80 WINDOW=64240 RES=0x00 SYN URGP=0, а в логе xray ничего. При telnet 127.0.0.1 10199 это подключение в логе xray видно. Без правила с tproxy интернет через маскарадинг, разумеется, работает

Та же самая конфигурация на обычном Debian 12 работает с полпинка. В логе xray видно подключение, запрос и detour. Снимите, пожалуйста, с ручника! Что ещё можно подкрутить на OpenWRT? Крутится оно на железке BPI-R3

может здесь найдется подсказка OpenWrt-mihomo/mihomo/files/nftables/hijack.nft at 11383113b9340310994a39e6f77f1c9079e0e75e · morytyann/OpenWrt-mihomo · GitHub

Накатал небольшой тест, который принимает соединения по образцу исходников xray и выводит на экран. На обычном линуксе соединения в него прилетают и показываются, а на OpenWRT, увы пусто. Попробую сбросить конфигурацию и смотреть что из этого получится

Ещё интересно, если в правило добавить второй log, то в лог выводит две строчки без метки и с меткой: nft 'add rule inet fw4 mangle_prerouting ip saddr 192.168.69.229/32 meta l4proto { tcp, udp } counter log meta mark set 0x198 tproxy ip to 127.0.0.1:12345 log accept'. В тестовой слушалке всё равно пусто

mihomo нагуглился почти сразу, изучал, но ничего особо не нашёл

Глянь тут настройки nft и маршруты

У меня все работает

А где вы ставите марку 198 на пакеты, чтобы rule работало?

UPD: увидел.
Во-первых, надо исключить из маркировки как минимум 127.0.0.1 (поставить перед правилом mark)

  ip daddr { 127.0.0.0/8, 224.0.0.0/4, 240.0.0.0/4, 255.255.255.255 } counter return

Также желательно исключить dst ip сервера, чтобы otbound не заворачивался обратно в tproxy

Также я не уверен за OpenWrt (нет возможности проверить), но полновесный nftables имеет трассировку пакетов.

Для этого можно включить метки трейса, например там же в самом начале цепочки mangle_prerouting

  <любое условие> meta nftrace set 1

И затем можно получать в реальном времени полный путь пакета через

nft -nn monitor trace

Пока все предложения были мимо, но я, кажись, накопал причину. После удаления пачки зависимостей на легаси iptables заработало:

[2024-12-28 12:25:32] opkg remove docker
[2024-12-28 12:25:36] opkg remove docker-compose
[2024-12-28 12:25:45] opkg remove dockerd
[2024-12-28 12:26:18] opkg remove kmod-ipt-nat6
[2024-12-28 12:26:37] opkg remove kmod-ipt-physdev
[2024-12-28 12:26:44] opkg remove kmod-ipt-nat6
[2024-12-28 12:26:48] opkg remove kmod-ipt-nat
[2024-12-28 12:26:54] opkg remove kmod-ipt-extra
[2024-12-28 12:27:14] opkg remove iptables-mod-extra
[2024-12-28 12:28:00] opkg remove kmod-ipt-extra
[2024-12-28 12:30:11] opkg remove kmod-ipt-conntrack
[2024-12-28 12:31:25] opkg remove ip6tables-zz-legacy
[2024-12-28 12:31:30] opkg remove kmod-ip6tables
[2024-12-28 12:33:33] opkg remove kmod-nf-ipvs
[2024-12-28 12:33:36] opkg remove kmod-ip6tables
[2024-12-28 12:34:24] opkg remove kmod-ipt-conntrack
[2024-12-28 12:35:07] opkg remove xtables-legacy
[2024-12-28 12:35:17] opkg remove iptables-zz-legacy
[2024-12-28 12:41:17] opkg remove fail2ban
[2024-12-28 12:41:23] opkg remove iptables-zz-legacy
[2024-12-28 12:41:37] opkg remove xtables-legacy
[2024-12-28 12:41:53] opkg remove kmod-ipt-conntrack
[2024-12-28 12:42:22] opkg remove kmod-br-netfilter
[2024-12-28 12:42:25] opkg remove kmod-ipt-conntrack
[2024-12-28 12:42:33] opkg remove kmod-ipt-core
[2024-12-28 12:44:06] opkg remove jool-tools-netfilter
[2024-12-28 12:44:11] opkg remove kmod-jool-netfilter
[2024-12-28 12:45:00] opkg remove kmod-nf-ipt6
[2024-12-28 12:45:01] opkg remove kmod-nf-ipt

Теперь осталось выяснить, что конкретно мешало. Хотелось бы оставить как минимум fail2ban – там правила для dropbear и luci


upd
Нашёл виновного: br_netfilter. Достаточно выключить его и troxy начинает работать. Бридж сетка в докере при этом работать перестаёт. В режиме --network=host работает нормально, так что пережить можно