我对路由/iptables 管道中的事件顺序有疑问。我先解释一下我的设置。问题在这篇文章的末尾。
我在 Linux 4.4 上使用策略路由和 iptables。
我有两个接口:wan0(面向我的 ISP)和 vpn-crypto(面向 vpn 提供商的 tun 设备)
我想有选择地将一些流量路由到 vpn,其他一切都通过 wan0
我实现策略路由如下:
在 mangle OUTPUT 表中,我为匹配某种模式的新流量设置了一个标记 0xC。出于测试目的,我将流量标记为指向特定 IP 地址 (37.9.239.33)。当然,我还有其他 iptables 的东西,比如 MASQUEARADE,但这与这个问题无关。
我有一个 iproute2 规则,它将所有“标记”的数据包发送到 vpn:
0: from all lookup local 190: from all fwmark 0x4/0x4 lookup vpn 400: from all fwmark 0x8/0x8 oif wan0 unreachable 32766: from all lookup main 32767: from all lookup default
vpn 表仅包含一条规则,并通过 vpn 发送所有内容:
default via 10.33.0.1 dev vpn-crypto proto static src 10.33.148.125
我使用命令进行测试,ping -c3 37.9.239.33
其中 37.9.239.33 是标记为 vpn 的 IP 地址。连接到 wan0 和 vpn-crypto 的两个 tcpdump 会话显示数据包有效地通过 vpn-crypto 发出并返回,正如预期的那样!到目前为止一切顺利,一切正常。
然而,当记录数据包流经 iptables 时,我观察到一个我不理解的奇怪行为:我在 FILTER.OUTPUT 表和 MANGLE.POSTROUTING 表中插入日志跟踪。
我观察到这一系列事件:
FILTER.OUTPUT: IN= OUT=wan0 SRC=59.189.21.112 DST=37.9.239.33 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=26960 DF PROTO=ICMP TYPE=8 CODE=0 ID=9649 SEQ=1 MARK=0xc
MANGLE.POSTROUTING: IN= OUT=vpn-crypto SRC=59.189.21.112 DST=37.9.239.33 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=26960 DF PROTO=ICMP TYPE=8 CODE=0 ID=9649 SEQ=1 MARK=0xc
MANGLE.POSTROUTING: IN= OUT=wan0 SRC=59.189.21.112 DST=37.9.239.33 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27049 DF PROTO=ICMP TYPE=8 CODE=0 ID=9649 SEQ=2
FILTER.OUTPUT: IN= OUT=wan0 SRC=59.189.21.112 DST=37.9.239.33 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27100 DF PROTO=ICMP TYPE=8 CODE=0 ID=9649 SEQ=2 MARK=0xc
MANGLE.POSTROUTING: IN= OUT=vpn-crypto SRC=59.189.21.112 DST=37.9.239.33 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27100 DF PROTO=ICMP TYPE=8 CODE=0 ID=9649 SEQ=2 MARK=0xc
MANGLE.POSTROUTING: IN= OUT=wan0 SRC=59.189.21.112 DST=37.9.239.33 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27193 DF PROTO=ICMP TYPE=8 CODE=0 ID=9649 SEQ=3
FILTER.OUTPUT: IN= OUT=wan0 SRC=59.189.21.112 DST=37.9.239.33 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27237 DF PROTO=ICMP TYPE=8 CODE=0 ID=9649 SEQ=3 MARK=0xc
MANGLE.POSTROUTING: IN= OUT=vpn-crypto SRC=59.189.21.112 DST=37.9.239.33 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27237 DF PROTO=ICMP TYPE=8 CODE=0 ID=9649 SEQ=3 MARK=0xc
我预计由于 MANGLE.OUTPUT 中的标记而导致的重新路由决定发生在 FILTER.OUTPUT 之前,但它似乎发生在之后!事实上,所有 FILTER.OUTPUT 数据包仍然通过 wan0 路由,表明尚未发生重新路由决定。关于这一点,网络上可用的文档分为 50/50。例如:
https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html,第 6 章,表 6-2,说明重新路由决定发生在 filter.output 之前
http://www.aptalaska.net/~jclive/IPTablesFlowChart.pdf,声明重新路由决定发生在 filter.output 之后
两者哪一个是正确的?有人可以对此有所了解吗?
在 3 次 ping 的上下文中,在 MANGLE.POSTROUTING 表中,我看到 2 个通过wan0路由的意外数据包,这些数据包“未标记”并且似乎与通过vpn-crypto路由的数据包重复。为什么是这样?此外,根据 tcpdump,这些数据包永远不会到达接口(这是正确的)。
有人可以阐明这种行为吗?