Linux

兩個路由器的埠轉發

  • December 14, 2020

我有兩個不同的公共 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

因此,所有到 Internet 的內部流量都通過路由器 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}

最後我設法讓它在不使用虛擬 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 連接的路由器進行路由。

您目前的設置將無法按預期工作。您需要有一個可以浮動的虛擬 IPRouter-ARouter-B. 這也將簡單地在兩個路由器之間進行負載平衡。在此範例中,我將在 Linux 路由器 (Ubuntu-16) 上使用行業標準VRRP 。

這是程序:

在 LinuxRouter-ARouter-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 MASTERonRouter-Astate BACKUPonRouter-B是不言自明的。

virtual_router_id 50必須在兩個路由器上匹配。這是一個標識符。

priority 101onRouter-Apriority 100on Router-B(在這種情況下,Router-A 具有更高的優先級)。

authentication必須在兩個路由器上匹配。在這種情況下,我使用了一個預共享密鑰passw123

virtual_ipaddress是 VRRP 將使用的浮動 IP 地址。此 IP 必須在兩個路由器上匹配。LAN 段上的任何設備都不得使用此 IP。在這種情況下,我選擇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

這就是路由器端所需的一切。現在跳到伺服器(Server-A 和 Server-B),刪除現有的預設網關 ( 192.168.1.1) 並分配新網關 ( 192.168.1.99)

$ sudo ip route del 0/0
$ sudo route add default gw 192.168.1.99

當從 Internet 建立連接時,兩台伺服器(伺服器 A 和伺服器 B)將流量返回到192.168.1.99浮動在上面的虛擬 IP ( )Router-ARouter-B

參考:https ://www.keepalived.org/manpage.html

引用自:https://serverfault.com/questions/1045816