据我所知,Linux(netfilter)的 NAT 不会重用 TIME_WAIT 状态下的 TCP 端口,但似乎 Linux >= 6.5 会重用 TIME_WAIT 状态下的 TCP 端口,即使目的地相同。
例如我添加了这个iptables规则。
sudo iptables -t nat -A POSTROUTING -p tcp --dport 3478 -j SNAT --to-source :10000
现在,仅使用端口 10000 来连接 TCP 中的 *:3478。我使用了 stunclient (https://www.stunprotocol.org/) 进行测试(stunserver.stunprotocol.org 在端口 3478 上提供 TCP STUN 服务器)。
在 Linux 6.5 之前的版本中,一旦我使用 stunclient,任何后续请求都会在 120 秒内继续失败(= 的默认值net.netfilter.nf_conntrack_tcp_timeout_time_wait
)。但是,在 Linux 6.5 或更新版本中,后续请求有时会在第一个请求后不久成功。奇怪的是,它们不一定会成功,但成功的概率为 20-30%。
我用以下内核版本对此进行了测试。
5.19.0-50
6.2.0-39
6.3 (mainline)
6.4 (mainline)
6.5 (mainline)
6.5.0-14
6.5.0-27
6.8.6 (mainline)
我的所有测试都是在 Linux Mint 21.3 上进行的,使用的是 iptables v1.8.7 (nf_tables)、nft 1.0.2、libnftnl 1.2.1。有人知道这种行为的原因吗?我猜这种行为不符合 TIME_WAIT 的目的。