我有一个已经在很多情况下使用的配方,但这次不适用于 Debian 11(内核 5.10.0-10-amd64)
我的设置基本上是一个用于 RFC1918 LAN 的内部接口 eth0,以及连接到某些 ISP 盒子的两个外部接口:
ISP1 的 eth1 作为默认路由器,地址为 10.0.0.254,公共 IP 为 1.2.3.4(象征性的)
ISP2 的 eth2 有一个路由器,地址为 10.0.3.254,公共地址为 2.3.4.5
我有不同的可能路线。我想控制我的数据包采用的路由,因此我创建了一些规则和 fwmark。首先我2<tab>secondrouter
附加/etc/iproute2/rt_tables
ip rule add fwmark 0x3 lookup secondrouter
ip route add default via 10.0.3.254 table secondrouter
一切都很好关于ip route list table secondrouter
和ip rule list
此时我能够做到:
curl -4 ifconfig.me
1.2.3.4 #<- public ip address of my default route
那我就做
iptables-legacy -t mangle -A OUTPUT -d 34.117.59.81 -j MARK --set-mark 0x3
现在如果我这样做
curl -4 ifconfig.me
<timeout>
我期望 2.3.4.5 作为公共 IP。很明显,标记的数据包不会从 ip 路由表中获取路由,更糟糕的是,它会超时。
如果我在旧版 Debian 上以完全相同的方式执行此操作,则它可以完美运行。
注意:如果我做一个
ip route add 34.117.59.81 via <second router IP>
我的卷曲测试按预期完美运行
curl -4 ifconfig.me
2.3.4.5 #<- Pub ip address of my second router
当使用iptables
或iptables-legacy
来标记要路由的数据包时,会出现我的问题。顺便说一句,我有很多运行良好的 iptables 规则,所以它看起来不像 iptables 问题。
编辑:解决方案:在表的输出添加一些伪装纳特
答案1
当数据包离开机器时,它会被赋予与默认输出接口相对应的源 IP 地址。
因此需要在输出接口上添加 MASQUERADE 规则,因为标记规则为我们的数据包提供了与计划目的地不同的另一个目的地。
iptables-legacy -t nat -A POSTROUTING -o eth2 -j MASQUERADE
为了理解 netfilter 的处理顺序:(通过普劳夫)
(input interface)
|
v
/-------+-------\
| sanity checks |
\-------+-------/
|
v hook NF_IP_PRE_ROUTING
+------+------+
| conntrack |
| defrag. |
+-------------+
| mangle |
| PREROUTING |
+-------------+
| nat (dst) |
| PREROUTING |
+------+------+
|
v
local delivery /----+----\ forward
+---------------+ route +---------------+
| \---------/ |
v v
/-----+-----\ /-----+-----\
| defrag. | | TTL check |
\-----+-----/ | dec. TTL |
| \-----+-----/
v hook NF_IP_LOCAL_IN |
+------+------+ |
| mangle (1) | |
| INPUT | |
+-------------+ |
| filter | v
| INPUT | /-----+-----\
+-------------+ | DF check |
| nat (src)(2)| \-----+-----/
+-------------+ |
| conntrack | |
| confirm | |
+------+------+ hook v NF_IP_FORWARD
| +------+------+
v | mangle (1) |
/------+--------\ | FORWARD |
| local process | +-------------|
\------+--------/ | filter |
| | FORWARD |
v +------+------+
/-----+-----\ |
| route | |
| frag. | |
\-----+-----/ |
| |
v hook NF_IP_LOCAL_OUT |
+------+------+ |
| conntrack | |
| defrag. | |
+-------------+ |
| mangle | |
| OUTPUT | |
+-------------+ v
| nat (dst)(3)| /-----+-----\
| OUTPUT | | frag. |
+-------------+ \-----+-----/
| filter | |
| OUTPUT | |
+------+------+ |
| |
v |
/-----+-----\ |
| reroute | |
\-----+-----/ |
| |
+------------------+ +------------------+
| |
v v hook NF_IP_POST_ROUTING
+---+-----+---+
| mangle (1) |
| POSTROUTING |
+-------------+
| nat (src) |
| defrag. |
| POSTROUTING |
+-------------+
| conntrack |
| confirm |
| frag. |
+------+------+
|
v
(output interface)