我有一台服务器,它有两个 IP 地址连接到一个接口:

2: enp27s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 30:9c:23:83:64:f6 brd ff:ff:ff:ff:ff:ff
    inet [IP_1]/32 scope global noprefixroute enp27s0
       valid_lft forever preferred_lft forever
    inet [IP_2]/32 scope global enp27s0
       valid_lft forever preferred_lft forever
    inet6 [IP6_1]/64 scope link
       valid_lft forever preferred_lft forever

我有几个虚拟机在其上运行,每当它们与外界通信时,它们的数据包都会IP_1作为源 IP。我还有一个特定的虚拟机,我想通过它进行“路由” IP_2。我不想将它完全连接到该 IP 地址,我仍然希望它留在虚拟网络内,但我希望从它发出的所有数据包都具有IP_2源 IP。

我尝试应用 SNAT 转换来实现这一点,但是并没有起到作用:

iptables -t nat -A POSTROUTING -s [VM_IP] -o enp27s0 -j SNAT --to-source [IP_2]

我猜是因为当数据包完成路由时,它们已经拥有IP_1源 IP,而-s [VM_IP]规则的一部分不匹配。将其更改为-s [IP_1]或仅设置IP_2为主 IP 可能有效,但我有点需要其他虚拟机将其传出流量路由通过IP_1

有什么方法可以实现这一点吗?我很确定以前有人问过类似的问题,但不幸的是,我的经验不足,无法想出关键词放在搜索栏中来找到它 🙁


更新:这是我的POSTROUTING表规则(不包括那条SNAT规则):

# iptables -t nat -S POSTROUTING
-P POSTROUTING ACCEPT
-A POSTROUTING -j LIBVIRT_PRT

# iptables -t nat -S LIBVIRT_PRT
-N LIBVIRT_PRT
-A LIBVIRT_PRT -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A LIBVIRT_PRT -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A LIBVIRT_PRT -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE

3

  • 顺序对 netfilter 规则很重要。您能向我们展示一下POSTROUTING表中的其他规则吗(iptables -t nat -S POSTROUTING)?


    – 

  • @larsks 当然可以,我已经将列表添加到问题中,尽管其中没有太多规则


    – 

  • 抱歉,您需要遵循这一点-j LIBVIRT_PRT。要么添加iptables -t nat -S LIBVIRT_PRT,要么只包含所有内容(iptables -t nat -S)。


    – 


最佳答案
1

鉴于您现有的规则集,当您运行…

iptables -t nat -A POSTROUTING -s [VM_IP] -o enp27s0 -j SNAT --to-source [IP_2]

…它会被附加到链的末尾POSTROUTING,因此最终会得到:

-P POSTROUTING ACCEPT
-A POSTROUTING -j LIBVIRT_PRT
-A POSTROUTING -s [VM_IP] -o enp27s0 -j SNAT --to-source [IP_2]

太晚了;此时,数据包已经遍历了MASQUERADE规则,不再匹配-s [VM_IP]。如果您将此规则移到规则前面,它可能会执行您想要的操作-J LIBVIRT_PRT

iptables -t nat -I POSTROUTING -s [VM_IP] -o enp27s0 -j SNAT --to-source [IP_2]

使用-I(没有明确的索引)将规则插入到链的顶部。

1

  • 哦,我明白了。现在可以了,谢谢。


    –