使用基于策略的路由转发来自环回接口的数据包

使用基于策略的路由转发来自环回接口的数据包

我有以下 iptables 规则:

iptables -t mangle -A PREROUTING -p udp -m udp --dport 10000 -j MARK --set-xmark 0x4/0xffffffff

它在目标端口 10000 的所有 udp 数据包上设置 fwmark 4。我使用基于策略的路由将其转发到隧道(没有任何 nat):

[root@localhost ~]# ip rule
0:  from all fwmark 0x4/0x4 lookup 87 
32765:  from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 
[root@localhost ~]# ip route show table 87
default dev tunnel  scope link 

如果数据包来自普通 NIC(eth0等),则一切正常,但在环回接口上传输的数据包(lo例如使用 生成的数据包socat -u - UDP:localhost:10000)似乎会跳过PREROUTING链后的路由决策,并被本地主机接收(实际上它通过lo接口回复 ICMP 端口不可达数据包)。

这是预期的行为吗?如果是这样我该如何解决这个问题?我需要数据包对于不同的输入设备没有不同的路径,因为我想用它lo来测试更复杂的 iptables 规则集(也就是说,带有 nat 的额外规则对我来说不是一个解决方案)。

答案1

这里涉及到一些事情。

本地框的输出使用OUTPUT表,而不是PREROUTING.PREROUTING用于流经盒子的流量。

iptables 规则仅在数据包发送时匹配。当客户端打开连接时,它必须在生成单个数据包之前绑定到一个地址。当它绑定时,它根据路由规则选择源地址,而不咨询 iptables。

当您测试使用127.0.0.1作为目的地并发送数据包时,它会尝试使用127.0.0.1作为源地址发送,默认情况下内核不允许路由。

如果解决了这个问题,当数据包离开接口并且具有远程系统不知道如何返回的源地址时,您将遇到另一个问题。

因此解决方案是三件事:

1)将规则添加到OUTPUT表中:

iptables -t mangle -A OUTPUT -p udp -m udp --dport 10000 -j MARK --set-xmark 0x4/0xffffffff

2) 启用本地网络路由:

sysctl -w net.ipv4.conf.$iface.route_localnet=1

$iface你的隧道接口在哪里。

3) 添加一条MASQUERADE规则,以便重写离开接口的流量的源地址:

iptables -t nat -A POSTROUTING -o $iface -m addrtype --src-type LOCAL -j MASQUERADE

 

但请注意,在测试将流量发送到 时127.0.0.1,您仍然可能会遇到问题。没有任何东西会重写目标地址,因此它会被路由出去,$iface目的地为127.0.0.1。远程系统可能会拒绝此流量。

相关内容