TPROXY's different behavior in different kernel
Q: 某代理软件如果不关闭
A: 摘录聊天记录如下
silver: tproxy
这个其实还是防火墙 防火墙这个就 …… tm 麻烦了 你看你有
iptables 还有 , nft 然后
iptables 还有 iptables-legacy 和 iptables-netfilter 用户机器上有可能是个
iptables-legacy 的 binary 但他内核实现是 , netfilter 的 也有可能用户机器上既有
nft 又有 iptables-netfilter 然后他两个都配了规则 , ( 如果是
nft 有可能用户同时配了 , table ip/table ip6/table inet tl; dr: linux firewall is messy
群友提到其他软件的用户会使用
exactly but
如果想跑在路由器上 那对应版本的内核有没有 , namespace uname -a: linux 2.6.32
gg
所以我觉得你的问题其实是在挂掉的时候怎么优雅处理
tproxy
于是吃了个晚饭后翻源码
silver: 调研了下
这个 , case 是这样的 。
- Linux <=3.x
的版本 这个功能只有一个实现 , 也就是 , xftables 项目的 xt_TPROXY.c - =4.x
的版本 因为 , nftables 也来了 所以有两个实现 , nft_tproxy.c , 和 xt_TPROXY.c - 5.x+的版本
xftables , 彻底被干掉了 就剩下 , nftables 的实现了 。 所以在一个
4.x 的内核上你就能体验到两种不同实现的差异 如果 。 tproxy 重定向到的那个端口上没有一个 listening socket :
- 如果走了
nftables 的实现 那么规则无效 , 继续执行其他规则 , 换句话说网络是正常的: , nft_tproxy.c#L143
- 如果走的是
xftables 的老实现 那么丢包: , xt_TPROXY.c#L184
我搞了个测试环境复现了下
换句话说你必须用 , nftables 不能用 , iptables-nat iptables-nat ( 出于兼容性还是用了 xftables 的实现 ) 也不能用 , iptables-legacy 这样就算 , tproxy 背后的 socket 没了 网络也正常 , so tl; dr: blame upstream
群乌贼: 草
silver: 讲道理你想
tproxy 就是把一个应该丢到网络设备的包丢到了 socket 上 ( 所以
socket 没了内核肯定是知道的 ( 所以肯定内核做了什么操作才会丢包
( 群友
A: 云理解就是做没做的问题 吧 ( silver: 对
老内核就是看到 , socket 不存在就丢包 新内核就是看到 , socket 不存在就当这条规则不存在 继续执行下一跳规则 , 所以如果你用
4.x 的话 用 , nft 写规则 或者你用 ; 5.x+的内核就好了
当然这个事情解法很多
Per-device
或者说在路由层面通过两个路由
可能在一个不能直接互联的网里