我有一个装有两块网卡的盒子,设置为桥接。ebtables 将 http 流量重定向到 iptables。br0 的 IP 地址是 10.10.10.10。Stunnel 设置为 transparent = source。它接受 127.1.1.1:8080 上的连接,并始终连接到端口 80 上的同一 IP 地址 (10.10.20.20)。
我已经制定了以下 iptables 规则:
iptables -t nat -I PREROUTING -p tcp --dport 80 -i ens192 -j DNAT --to-destination 127.1.1.1:8080
iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
路由也已设置。如果客户端通过端口 80 连接到盒子本身,则一切正常。Stunnel 连接到目标 (10.10.20.20)。但如果客户端的目标地址不同,stunnel 仍会尝试连接到 10.10.20.20,但无法连接。
因此,当我将原始数据包追踪到 10.10.20.20 时,我可以看到不同的行为。预期的行为:
trace id 71a8325b ip raw OUTPUT packet: oif "br0" ip saddr 10.10.10.10 ip daddr 10.10.20.20 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 28971 ip length 60 tcp sport 51408 tcp dport 80 tcp flags == syn tcp window 64240
trace id 71a8325b ip raw OUTPUT rule meta l4proto tcp ip daddr 10.10.20.20 counter packets 37 bytes 3265 meta nftrace set 1 (verdict continue)
trace id 71a8325b ip raw OUTPUT verdict continue
trace id 71a8325b ip raw OUTPUT policy accept
trace id 71a8325b ip filter OUTPUT packet: oif "br0" ip saddr 10.10.10.10 ip daddr 10.10.20.20 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 28971 ip length 60 tcp sport 51408 tcp dport 80 tcp flags == syn tcp window 64240
trace id 71a8325b ip filter OUTPUT verdict continue
trace id 71a8325b ip filter OUTPUT policy accept
trace id 71a8325b inet filter output packet: oif "br0" ip saddr 10.10.10.10 ip daddr 10.10.20.20 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 28971 ip protocol tcp ip length 60 tcp sport 51408 tcp dport 80 tcp flags == syn tcp window 64240
trace id 71a8325b inet filter output verdict continue
trace id 71a8325b inet filter output policy accept
意外的是,stunnel无法连接:
trace id fd9543bc ip raw OUTPUT packet: oif "br0" ip saddr 10.10.10.10 ip daddr 10.10.20.20 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 26448 ip length 60 tcp sport 34188 tcp dport 80 tcp flags == syn tcp window 64240
trace id fd9543bc ip raw OUTPUT rule meta l4proto tcp ip daddr 10.10.20.20 counter packets 52 bytes 4540 meta nftrace set 1 (verdict continue)
trace id fd9543bc ip raw OUTPUT verdict continue
trace id fd9543bc ip raw OUTPUT policy accept
trace id fd9543bc ip filter OUTPUT packet: oif "br0" ip saddr 10.10.10.10 ip daddr 127.1.1.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 26448 ip length 60 tcp sport 34188 tcp dport 8080 tcp flags == syn tcp window 64240
trace id fd9543bc ip filter OUTPUT verdict continue
trace id fd9543bc ip filter OUTPUT policy accept
trace id fd9543bc inet filter output packet: oif "br0" ip saddr 10.10.10.10 ip daddr 127.1.1.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 26448 ip protocol tcp ip length 60 tcp sport 34188 tcp dport 8080 tcp flags == syn tcp window 64240
trace id fd9543bc inet filter output verdict continue
trace id fd9543bc inet filter output policy accept
似乎目标地址被目标地址转换了。但我不知道为什么以及何时。我只在 nat 表 PREROUTING 中进行了 DNAT。据我了解,此数据包无论如何都不应再次触及此规则。为什么只有当原始目标不是盒子自己的 IP 地址时才会发生这种情况?我在想,也许 stunnel 会更改数据包本身?
以下是完整的 iptables-save 输出
# Generated by iptables-save v1.8.7 on Thu Nov 18 22:40:01 2021
*nat
:PREROUTING ACCEPT [14:1295]
:INPUT ACCEPT [14:1295]
:OUTPUT ACCEPT [2:196]
:POSTROUTING ACCEPT [4:316]
-A PREROUTING -i ens192 -p tcp -m tcp --dport 80 -j DNAT --to-destination 127.1.1.1:8080
COMMIT
# Completed on Thu Nov 18 22:40:01 2021
# Generated by iptables-save v1.8.7 on Thu Nov 18 22:40:01 2021
*mangle
:PREROUTING ACCEPT [15:1154]
:INPUT ACCEPT [172:24172]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [222:44999]
:POSTROUTING ACCEPT [222:44999]
:DIVERT - [0:0]
-A PREROUTING -p tcp -m socket -j DIVERT
-A DIVERT -j MARK --set-xmark 0x1/0xffffffff
-A DIVERT -j ACCEPT
COMMIT
# Completed on Thu Nov 18 22:40:01 2021
有什么想法吗,我该如何继续?