我有两个不同公共 IP 后面的服务器,并执行 DNAT 以根据端口将流量发送到不同的内部服务器。
------------------------- -----------------------
| server a (port 80/tcp)| | router A |
| (eth0) 192.168.1.123|..................|192.168.1.1 (eth1) |
------------------------- : | (eth0) 1.2.3.4|............
: ----------------------- :
: :
: ----------------------- :.... INTERNET
------------------------- : | router B | :
| server a (port 25/tcp)| : | (eth0) 2.3.4.5|...........:
| (eth0) 192.168.1.234|..................|192.168.1.2 (eth1) |
------------------------- -----------------------
在路由器 A 和 BI 上启用转发和以下 iptables:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A PREROUTING -d ${externalIP} -i eth0 -p tcp --dport 25 -j DNAT --to 192.168.1.234
iptables -t nat -A PREROUTING -d ${externalIP} -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.1.123
实际上我在服务器A和B上添加了以下路由:
route add default gw 192.168.1.1
因此,所有到互联网的内部流量都经过路由器 A,并且所有到端口 25 和 80 的流量都正确地发送到服务器 A 和 B,但只有流量通过路由器 A 时连接才有效。事实上,通过路由器 B 的流量到达服务器,但它通过路由器 A 而不是 B 返回,因此连接不起作用。
我在服务器上添加了一条新路线:
route add default fw 192.168.1.2
route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
0.0.0.0 192.168.1.2 0.0.0.0 UG 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
但连接仍然不起作用。
我该如何解决呢?
平衡内部 -> 外部的流量并不重要,但我希望正确建立来自互联网与外部 IP 的所有传入连接。
注意:我也尝试在其中一个路由器上针对另一个路由器的外部 IP 进行 DNAT,但它们位于不同的网络上,所以不起作用:
iptables -t nat -I PREROUTING -p tcp --dport 25 -d ${ExternalIPA} -i eth0 -j DNAT --to ${ExternalIPB}
答案1
您当前的设置将无法按预期工作。您需要一个可以浮动的虚拟 IP Router-A
。Router-B
这还将轻松地在两个路由器之间实现负载平衡。在此示例中,我将使用行业标准虚拟专用网络备份组在 Linux 路由器(Ubuntu-16)上。
具体步骤如下:
在 LinuxRouter-A
和 上Router-B
,执行以下命令:
$ sudo echo "net.ipv4.ip_nonlocal_bind=1" >> /etc/sysctl.conf
$ sudo sysctl -p
在两个路由器上安装 keepalived
$ sudo apt-get update
$ sudo apt-get install keepalived -y
然后转到Router-A
将充当的。使用以下条目MASTER
创建一个新的配置文件:/etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
interface eth1
state MASTER
virtual_router_id 50
priority 101
authentication {
auth_type AH
auth_pass pass123
}
virtual_ipaddress {
192.168.1.99
}
}
然后转到Router-B
将充当的角色BACKUP
,并对新的配置文件执行相同的操作/etc/keepalived/keepalived.conf
:
vrrp_instance VI_1 {
interface eth1
state BACKUP
virtual_router_id 50
priority 100
authentication {
auth_type AH
auth_pass pass123
}
virtual_ipaddress {
192.168.1.99
}
}
解释:
net.ipv4.ip_nonlocal_bind=1
告诉内核虚拟 IP 不能绑定到任何物理接口。
vrrp_instance VI_1
必须在两个路由器上匹配。这是一个标识符,因为您可以在同一个路由器上运行多个 VRRP。
interface eth1
是面向 LAN(面向内部服务器)的接口。
state MASTER
一遍Router-A
又 state BACKUP
一遍Router-B
是不言自明的。
virtual_router_id 50
必须在两个路由器上匹配。这是一个标识符。
priority 101
继续(在这种情况Router-A
下priority 100
,Router-B
路由器 A 具有更高的优先级)。
authentication
必须在两个路由器上匹配。在本例中,我使用了预共享密钥passw123
virtual_ipaddress
是 VRRP 将使用的浮动 IP 地址。此 IP 必须在两个路由器上匹配。此 IP 不得由 LAN 段上的任何设备使用。在本例中,我选择了192.168.1.99
启用 keepalived 服务
$ sudo systemctl enable keepalived
启动 keepalived 服务
$ sudo systemctl start keepalived
是时候操作两个路由器上的 iptables 规则了。
清除两个路由器上的所有 NAT 规则(删除损坏的 NAT 规则)
$ sudo iptables -t nat -F
$ sudo iptables -t mangle -F
然后添加正确的 NAT 规则:
路由器-A
$ sudo iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to 192.168.1.99
$ sudo iptables -t nat -A PREROUTING -d ${externalIP} -i eth0 -p tcp --dport 25 -j DNAT --to 192.168.1.234
路由器-B
$ sudo iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to 192.168.1.99
$ sudo iptables -t nat -A PREROUTING -d ${externalIP} -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.1.123
这就是路由器端所需的全部内容。现在跳转到服务器(服务器 A 和服务器 B),删除现有默认网关 ( 192.168.1.1
) 并分配新网关 ( 192.168.1.99
)
$ sudo ip route del 0/0
$ sudo route add default gw 192.168.1.99
当从互联网建立连接时,两台服务器(服务器 A 和服务器 B)将流量返回到192.168.1.99
浮动在上方的虚拟 IP( )Router-A
,Router-B
答案2
最后我设法让它在不使用虚拟 IP 的情况下工作,基本上使用 CONNNMARK 并添加不同的路由:
笔记:
- 路由器 A eth1 MAC = AA:AA:AA:AA:AA:AA
- 路由器 B eth1 MAC = BB:BB:BB:BB:BB:BB
我必须在所有使用非对称路由的服务器上添加以下路由和 iptables:
# add the two routing tables
ip route add to default table 11 via 192.168.1.1 dev eth0
ip route add to default table 33 via 192.168.1.2 dev eth0
# add the mark to the routing tables
ip rule add priority 99 table 11 fwmark 11
ip rule add priority 99 table 33 fwmark 33
# mark the packets that came from the different routes
iptables -t mangle -A OUTPUT ! -d 192.168.1.0/24 -m addrtype --dst-type UNICAST -j CONNMARK --restore-mark
iptables -A INPUT -i eth0 ! -s 192.168.1.0/24 -m addrtype --src-type UNICAST -m mac --mac-source AA:AA:AA:AA:AA:AA -j CONNMARK --set-mark 33
iptables -A INPUT -i eth0 ! -s 192.168.1.0/24 -m addrtype --src-type UNICAST -m mac --mac-source BB:BB:BB:BB:BB:BB -j CONNMARK --set-mark 11
现在一切正常。从互联网到任何外部 IP 地址的所有连接都通过管理 DNAT 连接的路由器进行路由。