iptables数据包转发到两个网关之一取决于来源

鉴于以下安装:

old router 192.168.1.1 with NAT forward of tcp port 80 to 192.168.1.10:80 new router 192.168.1.2 with NAT forward of tcp port 80 to 192.168.1.10:80 web server 192.168.1.10 with default gateway 192.168.1.1 

目前,我的服务的DNS条目指向旧路由器的外部地址。 路由器将stream量端口转发给networking服务器,networking服务器将答案返回给旧网关。

为了无缝迁移到新的路由器(使用另一个外部IP),我想先设置一个新的路由器,testing两个连接都处于活动状态的整个事件,然后将DNS IP更改为新的外部地址。

现在,用上面的设置,旧的路由器仍然工作。 但是发往新路由器的tcp连接,也回答不能处理它们的旧路由器。

我想过用伪装来使用nat,但是发往新路由器的所有stream量看起来就像是本地stream量。 这会欺骗服务器基于ip的filter和日志logging。

现在,我的计划是使用一个Debian和iptables的帮助程序来获得一个临时解决scheme:

 old router 192.168.1.1 with NAT forward of tcp port 80 to 192.168.1.10:80 new router 192.168.1.2 with NAT forward of tcp port 80 to 192.168.1.20:80 web server 192.168.1.10 with default gateway 192.168.1.20 helper pc 192.168.1.20 

帮手PC现在负责find正确的网关:

  • 保持192.168.1.2转发的连接状态,并转发它们而不修改为192.168.1.10(我想通过它们的源MAC地址和SYN来标识它们)
  • 将跟踪连接的数据包转发到192.168.1.2
  • 将未跟踪连接的数据包转发到192.168.1.1

我在互联网上发现了很多input,特别是serverfault.com( 尤其是这个 ),但是它们都只包含了这个问题的一个部分。 我想它需要一个基于MAC地址的filter规则的组合 – MAC -m mac --mac-source <mac> ,NAT,状态和rt_tables --set-mark / ip rule add fwmark (-gw似乎不被支持由Debian)。

有两种有效的解决scheme,取决于情况。

解决scheme1:networking服务器是Linux 完全在你的控制之下。

首先,确保/etc/iproute2/rt_tables包含以下几行:

 201 gw1 202 gw2 

其次,填写表格

 ip route add table gw1 default via $GW1_IP dev $ETH metric 100 ip route add table gw2 default via $GW2_IP dev $ETH metric 100 

第三,创build两个iproute2规则来“分stream”处理这些自定义表格:

 ip rule add prio 100 from all fwmark 1 lookup gw1 ip rule add prio 110 from all fwmark 2 lookup gw2 

最后,创build一组iptables命令来正确标记相应的数据包:

 # Make sure mark exists before routing happens # The first handles incoming packets -t mangle -A PREROUTING -j CONNMARK --restore-mark # The second handles outgoing packets -t mangle -A OUTPUT -j CONNMARK --restore-mark # Mark packets and save the mark -t mangle -A INPUT -m mac --mac-source $GW1_MAC -j MARK --set-mark 1 -t mangle -A INPUT -m mac --mac-source $GW2_MAC -j MARK --set-mark 2 -t mangle -A INPUT -j CONNMARK --save-mark 

解决scheme2:networking服务器不是 Linux和/或它完全在你的控制之下

这个解决scheme与以前的解决scheme非常相似。 不同之处在于iptables规则集合:

 # Make sure mark exists before routing happens -t mangle -A PREROUTING -j CONNMARK --restore-mark # Mark packets and save the mark -t mangle -A FORWARD -m mac --mac-source $GW1_MAC -j MARK --set-mark 1 -t mangle -A FORWARD -m mac --mac-source $GW2_MAC -j MARK --set-mark 2 -t mangle -A POSTROUTING -j CONNMARK --save-mark 

编辑:修改的解决scheme2

还是像上面一样,但是加上:

 ip rule add prio 10 to 192.168.1.0/24 lookup main 

这确保了目的地为本地networking的数据包(我假定为192.168.1.0/24 )将不会被网关处理。

另外,添加另一个iptables规则:

 -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10 

最后, 两个网关都将端口80转发给'helper pc'。 它会节省很多头痛,试图解决“半开放”的连接问题(因为在目前的计划中,“帮手PC”只能看到来自networking服务器的stream量,而不是双向的stream量)。

如果仅用于本地testing,则只能使用iptables的-s选项告诉旧的路由器,如果stream量来自该源IP,则将其转发给新路由器。 然后,您的新路由器将转发您的请求到Web服务器(根据您提供的configuration)。

即使你从外面testing你的设置,你仍然可以用-s过滤你的源地址ip。

例:

 iptables -I PREROUTING -i eth0 -s xxxx -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80