我正在尝试使用 iptables 来:
- 标记发往目标 IP 的数据包
- 检测该标记以更改目标 IP
- 检测该标记以更改源 IP
这些是我用来实现该目的的命令:
sudo iptables -t mangle -A PREROUTING --destination 192.0.2.0 -j MARK --set-mark 11
sudo iptables -t nat -A PREROUTING -m mark --mark 11 -j DNAT --to-destination ${DESTINATION_IP}
sudo iptables -t nat -A POSTROUTING -m mark --mark 11 -j SNAT --to-source ${SOURCE_IP}
看起来第一个 MARK 命令没有拾取任何数据包来标记它们:
sudo iptables -vL -t mangle
Chain PREROUTING (policy ACCEPT 11892 packets, 1184K bytes)
pkts bytes target prot opt in out source destination
0 0 MARK all -- any any anywhere 192.0.2.0 MARK set 0xb
此后,后面的规则就看不到任何标记要修改的数据包了。
我是否正确地认为,pkts
符合0
该规则意味着它没有匹配任何数据包?
我应该如何标记数据包以便稍后识别和修改?
答案1
本地发起的数据包不通过PREROUTING
chain,而是通过OUTPUT
。因此,如果您尝试从同一主机测试规则,则应将MARK
规则添加到mangle/OUTPUT
chain 中,并将DNAT
规则添加到nat/OUTPUT
chain 中。
结果你的规则将如下所示:
sudo iptables -t mangle -A OUTPUT --destination 192.0.2.0 -j MARK --set-mark 11
sudo iptables -t nat -A OUTPUT -m mark --mark 11 -j DNAT --to-destination ${DESTINATION_IP}
sudo iptables -t nat -A POSTROUTING -m mark --mark 11 -j SNAT --to-source ${SOURCE_IP}
另外,还有一种方法可以避免标记并引用原始(转换之前)的地址和端口号。
sudo iptables -t nat -A OUTPUT --dst 192.0.2.0 -j DNAT --to ${DESTINATION_IP}
sudo iptables -t nat -A POSTROUTING -m conntrack --ctstate DNAT --ctorigdst 192.0.2.0 -j SNAT --to ${SOURCE_IP}
要获取 iptables 匹配或 iptables 目标的选项列表,您可以使用简短的内置帮助。例如:
iptables -m connmark --help
iptables -j DNAT --help
当您排除 nat 规则故障时,您应该知道只有新连接的第一个数据包会通过该nat
表。
其他用于解决问题的工具是tcpdump
和conntrack
。