这里有很多关于 iptables DNAT/SNAT 设置的问题,但我还没有找到一个可以解决我当前问题的方法。
我有绑定到 eth0 的 IP 地址(例如 192.168.0.20)的服务,并且我在 eth0:0 上还有一个 IP 地址(192.168.0.40),该地址与另一台服务器共享。只有一台服务器处于活动状态,因此这个别名接口的出现和消失取决于哪台服务器处于活动状态。为了让服务接受流量,使用 DNAT 规则来更改目标 IP。
iptables -t nat -A PREROUTING -d 192.168.0.40 -p udp --dport 7100 -j DNAT --to-destination 192.168.0.20
我还希望此服务的所有出站流量都看起来来自共享 IP,以便在发生主动备用故障转移时返回响应能够起作用。
iptables -t nat -A POSTROUTING -p udp --sport 7100 -j SNAT --to-source 192.168.0.40
我的问题是 SNAT 规则并不总是运行。入站流量会导致出现这样的连接跟踪条目。
[root]# conntrack -L -p udp
udp 17 170 src=192.168.0.185 dst=192.168.0.40 sport=7100 dport=7100 src=192.168.0.20 dst=192.168.0.185 sport=7100 dport=7100 [ASSURED] mark=0 secmark=0 use=2
这意味着 POSTROUTING 链未运行,并且出站流量以真实 IP 地址作为源。
我正在考虑在原始表中设置一个 NOTRACK 规则来阻止该端口号的连接跟踪,但是有没有更好或更有效的方法来实现这一点?
编辑-替代问题:有没有办法(在 CentOS/Linux 中)拥有一个可以绑定但不能使用的接口,以便当在服务器之间交换共享 IP 地址时它可以连接到网络或断开连接?
答案1
我找到了解决问题的方法。
通过使用内核参数net.ipv4.ip_nonlocal_bind=1
,我可以让我的服务绑定到尚不存在的地址。
当 eth0:0 接口启动时,服务将接受流量。ARP 等由 ucarp/networking 处理。有了这个,根本不需要 DNAT/SNAT 规则。
答案2
我可以建议两种替代方案,您可以选择其中一种或您自己的方案。
您可以设置服务来监听通配符地址,从而完全避免 DNAT 规则。然后,SNAT 规则将应用于传出数据包。
或者,根据您使用的 HA 解决方案,您可以将其配置为在迁移时启动在浮动 IP(192.168.0.40)上监听的服务。
不太相关的注意,但这种滋扰并不存在OpenBSD CARP。使用 CARP,您可以在所有节点上配置虚拟 IP,但仅在一个节点上处于活动状态。这当然意味着您可以让您的服务在所有节点上监听虚拟 IP。
这不是很好,但您可以在所有节点上配置虚拟 IP(甚至启动它)并用于arptables
禁用该 IP 的 ARP 回复或公告。然后,当节点成为主节点或从节点时,您可以让 ucarp 启用或禁用 ARP 规则。