
我的伺服器位於兩個不同的公共 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 時,連線才有效。流量到達到伺服器,但它是透過路由器 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
您目前的設定將無法如預期般運作。您需要有一個可以浮動在Router-A
和上的虛擬IP Router-B
。這也將簡單地實現兩個路由器之間的負載平衡。在這個例子中,我將使用行業標準VRRP在 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
浮動在上面的Router-A
虛擬IP ( )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 連線的路由器進行路由。