Linux

NAT 倍數伺服器

  • June 9, 2019

我需要一個專家來配置 NAT 重定向(iptables)來維護客戶端的源地址。目前我的伺服器正常工作,但所有客戶端都顯示為我的 vLAN 的私有 IP。

我的伺服器重定向的操作範例:

VPS 1 (Public IP) redirect traffic to VPS 5 (Private IP)
VPS 2 (Public IP) redirect traffic to VPS 5 (Private IP)
VPS 3 (Public IP) redirect traffic to VPS 5 (Private IP)
VPS 4 (Public IP) redirect traffic to VPS 5 (Private IP)

但是在重定向流量時,客戶端的 IP 會更改為客戶端訪問的公共伺服器的私有 IP。

TCPDUMP:

IP 10.0.1.130.61570> 10.0.1.138.85: UDP, length 35
IP 10.0.1.132.63112> 10.0.1.138.85: UDP, length 35
IP 10.0.1.133.63435> 10.0.1.138.85: UDP, length 35
IP 10.0.1.136.63432> 10.0.1.138.85: UDP, length 35

這是重定向完成後所有客戶端都分配了私有IP的問題,我需要維護客戶端的真實IP。

如果我刪除規則“iptables -t nat -A POSTROUTING -j MASQUERADE”

然後維護客戶端的IP,但伺服器將帶有私有IP的數據包響應到客戶端的IP。

TCPDUMP:

IP 10.0.1.138.85> client1.isp.net.61570: UDP, length 45
IP 10.0.1.138.85> client2.isp.net.63112: UDP, length 45
IP 10.0.1.138.85> client3.isp.net.63435: UDP, length 45
IP 10.0.1.138.85> client4.isp.net.63432: UDP, length 45

我想保留客戶端的真實 IP,但(VPS 5)沒有將數據包路由回網際網路。

我知道兩種方法可以解決您的問題:

簡單的方法

DNAT您可以在沒有規則的 VPS 主機上使用規則中的附加埠範圍SNAT。並且基於這些埠號,VPS-5路由通過正確的主機返回回复。

簡短的例子:

  • VPS-5計劃其他主機將來自客戶端的數據包轉發到的附加埠號。讓我們猜測VPS-1轉發數據包到VPS-5 tcp/10001VPS2- 到VPS-5 tcp/10002等等。
  • 在每台VPS主機上,您只需要一條規則即可將流量轉發到VPS-5. 因此,VPS-1規則將如下所示:
# vps-1 host
iptables -t nat -A PREROUTING \
        --dst <vps-1-pub-ip> -p udp --dport <srv-port> \
   -j DNAT --to-destination <vps-5-ip>:10001
  • VPS-5你需要更複雜的配置。訣竅在於,VPS5接收轉發請求的埠號也指向 VPS 主機,應通過該主機路由回复。
  • VPS-5你需要單獨的路由表和每個其他VPS主機的路由規則。VPS-1和的例子VPS-2
# vps-5 host
ip route add <connected-subnet> dev <iface> table 1
ip route add 0/0 via <VPS-1-INT-IP> dev <iface> table 1
ip rule add fwmark 1 lookup 1 pref 10001

ip route add <connected-subnet> dev <iface> table 2
ip route add 0/0 via <VPS-2-INT-IP> dev <iface> table 2
ip rule add fwmark 2 lookup 2 pref 10002
  • 標記來自 VPS 主機的傳入連接並將其保存到 conntrack 條目中:
# vps-5 host
iptables -t mangle -A PREROUTING \
        -m conntrack --ctstate NEW \
        -p udp --dport 10001 \
   -j CONNMARK --set-mark 0x1
  • 將請求重定向到服務埠:
# vps-5 host
iptables -t nat -A PREROUTING \
        --dst <vps-5-ip> -p udp --dport 10001:10004 \
   -j REDIRECT --to-ports 85
  • 在回複數據包上設置防火牆標記以將它們路由回正確的 VPS 主機:
# vps-5 host
iptables -t mangle -A OUTPUT \
        -m conntrack --ctstate DNAT --ctdir REPLY \
   -j CONNMARK --restore-mark

這種方式僅適用於主機直接相互連接的情況。否則你應該使用下一種方式。

隧道模式

在某些情況下,伺服器不是直接相互連接,而是通過一些路由器連接。在這些情況下,如上所述的方式將無濟於事,因為每個中間路由器都獨立地做出有關路由的決定。

據我所知,保存客戶端的源地址並將數據包從前端主機(VPS-1- VPS-4)重定向到目標主機(VPS-5)的唯一方法是使用隧道。

簡化的解決方案: * 規劃額外的 ip 定址以供隧道內使用。* 在每台前端主機 ( VPS-1- VPS-4) 上創建隧道到VPS-5. 你可以你想要的任何類型的隧道。以最簡單的方式,您可以使用靜態 GRE 隧道,但它有一些限制,例如避免 NAT。* 在每台前端主機上,您只需一條規則即可將流量轉發到VPS-5. 範例VPS-

# vps-1 host
iptables -t nat -A PREROUTING \
        --dst <vps-1-pub-ip> -p udp --dport <srv-port> \
   -j DNAT --to-destination <vps-5-tun-ip>
  • 您還應該配置額外的VPS-5路由表和路由規則以通過右前主機進行回复:
# vps-5 host
ip route add 0/0 dev <vps-1-tun-iface> table 1
ip rule add fwmark 1 lookup 1 pref 10001
  • 根據輸入介面標記傳入的連接,並將其保存到 conntrack 條目中:
iptables -t mangle -A PREROUTING \
        -m conntrack --ctstate NEW \
        -i <vps-1-tun-iface> \
   -j CONNMARK --set-mark 0x1
  • 如果您的應用程序不偵聽隧道 IP 地址,則應將來自前端主機的傳入數據包重定向到偵聽地址:
iptables -t nat -A PREROUTING \
        -i <vps-1-tun-iface> \
        -p udp --dport <srv-port> \
   -j DNAT --to-destination <srv-listen-ip>
  • 在回複數據包上設置防火牆標記:
iptables -t mangle -A OUTPUT \
   -j CONNMARK --restore-mark
  • 不要忘記在過濾表中允許這些數據包:
iptables -t filter -A INPUT \
        -m conntrack --ctstate ESTABLISHED,RELATED
   -j ACCEPT
...
iptables -t filter -A INPUT \
        -p udp --dport <srv-port>
   -j ACCEPT

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