Dan*_*der 5 routing iptables port-forwarding
鉴于以下安装:
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
Run Code Online (Sandbox Code Playgroud)
目前,我的服务的 DNS 条目指向旧路由器的外部地址。路由器将流量端口转发到 Web 服务器,Web 服务器将响应返回给旧网关。
为了无缝迁移到新路由器(使用另一个外部 IP),我想先设置一个新路由器,在两个连接都处于活动状态的情况下测试整个过程,然后将 DNS IP 更改为新的外部地址。
现在,通过上述设置,旧路由器仍然可以工作。但是寻址到新路由器的 tcp 连接也会响应无法处理它们的旧路由器。
我想过将 nat 与伪装一起使用,但随后所有发送到新路由器的流量看起来都像本地流量。这会欺骗基于服务器 ip 的过滤器和日志记录。
现在,我的计划是使用带有 Debian 和 iptables 的辅助 PC 作为临时解决方案:
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
Run Code Online (Sandbox Code Playgroud)
helper pc 现在负责寻找正确的网关:
我在互联网上发现了很多输入,尤其是 serverfault.com(尤其是这个),但所有这些都只涵盖了这个问题的一个部分。我猜它需要结合基于 mac 地址的过滤规则-m mac --mac-source <mac>、NAT、状态和 rt_tables --set-mark/ ip rule add fwmark(Debian 似乎不支持 --gw)。
根据具体情况,有两种有效的解决方案。
首先,确保/etc/iproute2/rt_tables包含以下行:
201 gw1
202 gw2
Run Code Online (Sandbox Code Playgroud)
其次,填充表格
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
Run Code Online (Sandbox Code Playgroud)
第三,创建两个 iproute2 规则以将处理“分流”到这些自定义表:
ip rule add prio 100 from all fwmark 1 lookup gw1
ip rule add prio 110 from all fwmark 2 lookup gw2
Run Code Online (Sandbox Code Playgroud)
最后,创建一组 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
Run Code Online (Sandbox Code Playgroud)
该解决方案与之前的解决方案非常相似。区别在于 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
Run Code Online (Sandbox Code Playgroud)
仍然与上面相同,但添加:
ip rule add prio 10 to 192.168.1.0/24 lookup main
Run Code Online (Sandbox Code Playgroud)
这可以确保发往本地网络(我假设192.168.1.0/24)的数据包不会由网关处理。
另外,添加另一条iptables规则:
-t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10
Run Code Online (Sandbox Code Playgroud)
最后,让两个网关将端口 80 转发到“辅助电脑”;这将节省大量尝试解决“半开放”连接故障的麻烦(因为,在您当前的计划中,“辅助电脑”只能看到来自网络服务器的流量,而不是双向的流量)。