Iptables

iptables:MultiWAN 和埠轉發和埠重定向

  • February 14, 2021

我正在執行 Gentoo Linux,所以使用普通的 iptbales 來管理我的防火牆和網路。我通常將 wan0 用​​於我的所有流量,但由於我已經有一個網路伺服器,我希望我的第二個網路伺服器使用 wan1(綁定到另一個域)。

我有三個介面:

  • eth0 = 區域網路
  • wan0 = 主要使用的 WAN(預設網關)
  • wan1 = 輔助 WAN

關於網關的一些資訊

> route -n 

Kernel IP Routentabelle
Ziel Router          Genmask         Flags Metric Ref    Use Iface
0.0.0.0         80.108.x.x      0.0.0.0         UG    0      0        0 wan0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
80.108.x.0      0.0.0.0         255.255.254.0   U     0      0        0 wan0
84.114.y.0      0.0.0.0         255.255.255.0   U     0      0        0 wan1
127.0.0.0       127.0.0.1       255.0.0.0       UG    0      0        0 lo

NAT/MASQUEARDING 的預設初始化是

sysctl -q -w net.ipv4.conf.all.forwarding=1

iptables -N BLOCK
iptables -A BLOCK -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A BLOCK -m state --state NEW,ESTABLISHED -i eth0 -j ACCEPT
iptables -A BLOCK -m state --state NEW,ESTABLISHED -i lo -j ACCEPT

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -j MASQUERADE
iptables -t nat -A POSTROUTING -o wan0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o wan1 -j MASQUERADE

在這個網關後面我執行著幾個網路伺服器。在一台機器上,我在埠 8000 而不是 80 上執行 HTTP 伺服器。通常當我使用 wan0 作為傳入介面時,我使用以下規則:

lan_host1="192.168.0.200"
iptables -A FORWARD -i wan0 -p TCP -d $lan_host1--dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i wan0 -p TCP --dport 8000 -j DNAT --to-destination "$lan_host1":80
iptables -A FORWARD -i wan0 -p UDP -d $lan_host1--dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i wan0 -p UDP --dport 8000 -j DNAT --to-destination "$lan_host1":80

這很好用。現在我想使用 wan1,因為 wan0 與我通常用於其他用途的 IP/域相關聯。

我認為對 wan1 進行簡單的更改就可以了。

lan_host1="192.168.0.200"
iptables -A FORWARD -i wan1 -p TCP -d $lan_host1--dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i wan1 -p TCP --dport 8000 -j DNAT --to-destination "$lan_host1":80
iptables -A FORWARD -i wan1 -p UDP -d $lan_host1--dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i wan1 -p UDP --dport 8000 -j DNAT --to-destination "$lan_host1":80

但這不起作用。我想問題是 wan0 是預設的 GW。所以我猜 wan1 收到的包被轉發到 lan_host1,但是當被發送回網關時,它們是通過 wan0 而不是 wan1 發送的,或者至少使用來自 wan0 的 ip。

有什麼建議我可以如何管理嗎?

在此先感謝,羅布

由於答案與配置相關,我做了一些假設。您必須調整答案以適應實際配置。

  • wan1的 LAN 和 wan1 的網關任意選擇為84.114.7.0/24和 84.114.7.254。
  • 沒有考慮防火牆規則,但所有這些都不應該與它們互動。

在 Linuxip link上,應始終使用 and 而不是已棄用ip address的and 。可能無論如何都無法處理額外的路由表。ip routeifconfig``route``route

提醒一下,iptables或實際上netfilter不會路由,但它可以通過其操作更改 IP 路由堆棧做出的路由決策。此示意圖顯示了可能發生路由決策的位置。對於僅在一個地方的路由(而不是本地起源)流量,並且必須在之前發生更改:raw/PREROUTINGmangle/PREROUTINGnat/PREROUTINGraw通常不切實際,而nat僅適用於有限的情況,主要是離開mangle

一個基本的多宿主系統,要使用多條通往網際網路的路徑,通常需要策略路由,其中​​路由不僅可以像往常一樣隨目的地變化,還可以隨源或其他選擇器(如將在此處完成的那樣)在政策規則。在 Linux 上,附加規則ip rule可以選擇不同的路由表來選擇例如不同的預設路由(仍然只有一個預設路由,但每個路由表一個)。

所以這裡的原則是,在仍然保持有效的嚴格反向路徑轉發rp_filter)的同時,接受來自wan1的數據包,並像往常一樣使用備用表將它們路由到eth0(這將允許通過rp_filter)。此附加路由表應複製主路由表,但僅使用備用路徑 ( wan1 ) 所需的路由,因此不包括具有“正常”路徑 ( wan0 ) 的常用路由。如果其他路由(例如 VPN 等)必須參與通過wan1的流,很有可能他們的路線也必須添加,或者必須創建其他額外的規則和表格來應對這種情況。

由於 Linux 在核心 3.6 中停止使用路由記憶體,路由堆棧中的任何內容都不會告訴通過wan1將回複數據包從host1發送回客戶端,並且它們最終會使用通過wan0的主要預設路由出去, NATed此介面的 IP 錯誤(netfilter與路由無關,並且在接收連接的第一個數據包時已經選擇了要完成的 NAT),並且可能被 ISP 的下一個路由器丟棄,也執行嚴格的反向路徑過濾。有一個netfilter功能允許在 conntrack 的標記中複製數據包的標記並將其放回數據包中:這將充當連接的路由記憶體。所以iptablesnetfilterconntrack將用於兩個相關功能:標記數據包以更改路由決策,並在被辨識為同一連接的一部分的回複數據包上恢復此標記。

所有這些都轉化為這些命令:

  • 路由部分

用於標記的數據包(任意標記值 101)一個額外的路由表(不相關的任意值也是 101):

   ip rule add fwmark 101 lookup 101

用類似於路由表的條目填充表,減去wan0條目:

   ip route add table 101 192.168.0.0/16 dev eth0
   ip route add table 101 84.114.7.0/24 dev wan1
   ip route add table 101 default via 84.114.7.254 dev wan1
  • iptables / netfilter部分

以下命令中可能有各種優化,可能還可以改進。

恢復已保存的潛在先前標記,因此回複數據包將獲得與原始數據包相同的標記:

   iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark

標記來自wan1的數據包以更改上述路由決策:

   iptables -t mangle -A PREROUTING -i wan1 -j MARK --set-mark 101 

如果有標記,請將其保存在conntrack中(可以在nat表中完成,每個連接流只執行一次,而不是每個數據包):

   iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j CONNMARK --save-mark

實際上,這仍然無法通過嚴格的反向路徑轉發檢查,因為這個未記錄的功能是在 2010 年添加的。它必須在這裡使用:

sysctl -w net.ipv4.conf.wan1.src_valid_mark=1

引用自:https://unix.stackexchange.com/questions/573858