我有一台主机,它将数据包发送到虚拟机,例如 192.168.0.1/24,目标 IP 为 192.168.0.11 或 192.168.0.12。我试图将虚拟机设置为 NAT。它会路由数据包,根据原始目标 IP 更改目标 IP,因此我无法仅使用 SNAT,因为原始 IP 已在 PREROUTING 中切换。我一直试图使用 --set-mark 标志来用 11 或 12 标记数据包,这样 POSTROUTING 规则就会知道要使用什么 SNAT 规则。以下是我的规则:
iptables -t mangle -A PREROUTING --destination 192.168.0.11 -j MARK --set-mark 11
iptables -t nat -A PREROUTING -m mark --mark 11 -i eth0 -j DNAT --to 20.0.21.11
iptables -t nat -A POSTROUTING -m mark --mark 11 -o eth1 -j SNAT --to-source 20.0.1.1
和
iptables -t mangle -A PREROUTING --destination 192.168.0.12 -j MARK --set-mark 12
iptables -t nat -A PREROUTING -m mark --mark 12 -i eth0 -j DNAT --to 20.0.21.11
iptables -t nat -A POSTROUTING -m mark --mark 12 -o eth1 -j SNAT --to-source 20.0.1.2
如果我观察 iptables -t mangle/nat -nvL,我的前两个规则就会增加,但 POSTROUTING 规则从未匹配。有人知道为什么会这样吗?
我在写这篇文章时想到了这一点。第一个网络是 /24 子网,而我的第二个网络目前设置为 /8 子网。这会对此产生任何影响吗?
编辑
让事情更清楚一点。
第一步是主机将 192.168.0.11/24 或 192.168.0.12/24 从 192.168.0.1/24 发送到虚拟机,如下所示。
Destination IPs
HOST ================
=============== +--* 192.168.0.11 *--+ ======
* 192.168.0.1 *--- ================ ---* VM *
=============== +--* 192.168.0.12 *--+ ======
================
然后,我希望虚拟机转发这些数据包,并将两个目标 IP 更改为 20.0.21.11/8。然后,根据原始目标 IP 的不同,将源 IP 更改为 20.0.21.1/8 或 20.0.21.2/8。就像这样。
Source IPs w/ 20.0.21.11 as Destination IP
==============
====== +--* 20.0.21.1 *--+ ============
* VM *--- ============== ---* Test rig *
====== +--* 20.0.21.2 *--+ ============
==============
另外要明确的是,这是私有网络上的 NAT。这里没有互联网连接。只是Host <--> VM <--> Test rig
编辑2
再画一张图让它更清晰一些。
Destination IPs Source IPs
HOST ============== =============== Test rig
============= +--*192.168.0.11*-+ | 20.0.21.1 *--+ ==============
*192.168.0.1*--- ============== +--* VM | +--* 20.0.21.11 *
============= +--*192.168.0.12*-+ | 20.0.21.2 *--+ ==============
============== ===============
答案1
您的规则看起来正确,请检查您是否设置了网桥,这些网桥可能会使数据包的输入/输出接口混乱。您还可以添加 -j LOG 规则来查看日志中匹配的内容。
答案2
您是否已在主机上启用 IP 转发?如果没有,那么您的第二条规则将永远不会匹配,因为转发的数据包将被内核忽略。
你可以用 来检查cat /proc/sys/net/ipv4/ip_forward
。如果输出为零,你可以尝试echo 1 > /proc/sys/net/ipv4/ip_forward
看看这是否能解决你的问题。如果能,echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf
将使设置在重启后继续有效。
我想把这个评论发上去,但我的声誉太低了。很抱歉发了这么明显的答案,但这个答案已经让我困惑很多次了,所以值得发一下!