从 OpenWrt 22.03 开始默认使用了基于 nftables 的 fw4,不再默认包含 iptables,因此 tproxy 配置方法有变。
依赖软件包 kmod-nft-tproxy。
/etc/config/network 添加路由规则
1 2 3 4 5 6 7 8 9
| config route option interface 'loopback' option target '0.0.0.0/0' option type 'local' option table '100'
config rule option mark '0x1' # 与后面防火墙mark对应 option lookup '100'
|
/etc/config/firewall 添加 IP 集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| config ipset option name 'chnroute-ipv4' option loadfile 'chnroute cidr文件路径' option family 'ipv4' list match 'dest_net'
config ipset option name 'bypass-ipv4' option loadfile '不代理cidr文件路径' option family 'ipv4' list match 'dest_net'
config ipset option name 'forward-ipv4' option loadfile '强制代理cidr文件路径' option family 'ipv4' list match 'dest_net'
|
新建文件 /etc/nftables/20-tproxy.nft
假设本地端口为 1234,TCP 使用 DNAT 转发,UDP 使用 TPROXY 转发,配置如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| set ss_special_bypass { type ipv4_addr flags interval
elements = { 0.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/4, 255.255.255.255 } }
chain ss_tproxy_cntrl { ct mark 1 goto ss_proxy_udp ct state related,established return ip daddr @forward-ipv4 goto ss_proxy_udp_pre ip daddr @ss_special_bypass return ip daddr @bypass-ipv4 return ip daddr @chnroute-ipv4 return goto ss_proxy_udp_pre }
chain dstnat { type nat hook prerouting priority dstnat iifname br-lan jump ss_dnat_cntrl }
chain mangle_prerouting { type filter hook prerouting priority mangle iifname br-lan ip protocol udp jump ss_tproxy_cntrl }
chain ss_proxy_tcp { ip protocol tcp redirect to 1234 }
chain ss_proxy_udp_pre { udp dport 53 return udp dport 443 reject # drop quic ct mark set 1 jump ss_proxy_udp }
chain ss_proxy_udp { ip protocol udp tproxy ip to :1234 meta mark set ct mark }
chain ss_dnat_cntrl { meta nfproto ipv4 udp dport 53 redirect ip daddr @forward-ipv4 goto ss_proxy_tcp ip daddr @ss_special_bypass return ip daddr @bypass-ipv4 return ip daddr @chnroute-ipv4 return goto ss_proxy_tcp }
|
重启 firewall 和 network 后生效。
1 2
| service network restart service firewall restart
|