iptables:MultiWAN 和埠轉發和埠重定向
我正在執行 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。
- 沒有考慮防火牆規則,但所有這些都不應該與它們互動。
在 Linux
ip link
上,應始終使用 and 而不是已棄用ip address
的and 。可能無論如何都無法處理額外的路由表。ip route
ifconfig``route``route
提醒一下,iptables或實際上netfilter不會路由,但它可以通過其操作更改 IP 路由堆棧做出的路由決策。此示意圖顯示了可能發生路由決策的位置。對於僅在一個地方的路由(而不是本地起源)流量,並且必須在之前發生更改:raw/PREROUTING、mangle/PREROUTING或nat/PREROUTING,raw通常不切實際,而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 的標記中複製數據包的標記並將其放回數據包中:這將充當連接的路由記憶體。所以iptables和netfilter的conntrack將用於兩個相關功能:標記數據包以更改路由決策,並在被辨識為同一連接的一部分的回複數據包上恢復此標記。
所有這些都轉化為這些命令:
- 路由部分
用於標記的數據包(任意標記值 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