使用兩個路由器防止無休止轉發
問題中的網路看起來基本上是這樣的:
/----Inet1 / H1---[111.0/24]---GW1---[99.0/24] \----GW2-----Inet2
設備說明
- H1:IP 為 192.168.111.47 的主機
- GW1:具有 IP 192.168.111.1 和 192.168.99.2 的 Linux 機器,以及它自己的網際網路路由。
- GW2:具有 IP 192.168.99.1 和自己的網際網路路由的通用無線路由器。
- Inet1 和 Inet2:兩種可能的 Internet 路由
簡而言之:H 有不止一種可能的通往網際網路的途徑。
H 應該僅在該連結啟動時通過 GW2 訪問 Internet,因此 GW1 具有一些僅針對 H1 的基於策略的路由:
ip rule add from 192.168.111.47 table 991 ip route add default via 192.168.99.1 table 991
儘管只要 GW2 與 Internet 有直接連結,此方法就可以工作,但當該連結斷開時,就會出現問題。然後發生的事情是 GW2 將數據包轉發回 GW1,GW1 再次轉發回 GW2,從而創建了 TCP-pingpong 的無限循環。首選結果是數據包剛剛被丟棄。
GW1 上的 iptables 可以做些什麼來防止這種情況發生嗎?*基本上, “如果數據包來自 GW2,但源自 H1,則丟棄它”*的 iptables 友好版本
- 注意 1:最好不要在 GW2 上進行任何更改。
- 注2:H1 需要能夠與 GW1 和 GW2 通話,反之亦然,但只有 GW2 才能連接到網際網路
**TLDR;**H1 應該只允許通過 GW2 訪問網際網路,但仍需要能夠與 GW1 和 GW2 通話。
編輯: GW1 的介面對於“99”網路是 br0.105,對於“111”網路是 br0.111。解決方案可能非常簡單,也可能不簡單,但我自己無法生成正確的 iptables 語法,因此非常感謝您的幫助。
PS:這是this question的後續問題
如果可能的話,你真的應該修復你的路由
GW2
。如果不是,您可以設置一個解決方法。讓:
br0.105 = interface at GW1 in the 99.0/24 network facing GW2 <mac-gw2> = the MAC address of GW2's interface in the 99.0/24 network facing GW1 <ip-h1> = IP address of H1 from the 111.0/24 network
然後添加規則
iptables -A FORWARD -i br0.105 -s <ip-h1> -m mac --mac-source <mac-gw2> -j REJECT
<ip-h1>
如果數據包 from<ip-h1>
曾經從GW2
to返回,將導致發送到的 ICMP 目標不可達消息GW1
。這裡的想法是按 MAC 地址過濾,因為您似乎有多個通過此介面到不同路由器的路由,您需要區分始發路由器。您可以通過查看其介面配置來獲取 MAC 地址
GW2
,或者,如果您無權訪問它,則可以查看 ARP 記憶體表GW1
- 只需執行arp -n
以查看記憶體中的目前條目。請注意,如果
GW1
對通過的流量進行 NAT,<int2>
則<ip-h1>
需要是 的 IP 地址<int2>
,而不是 的IP 地址H1
。正如您要求使用萬用字元 MAC 地址的方法 - 沒有,iptables mac 模組需要完全匹配。但是您顯然可以編寫腳本(快速而骯髒,在投入生產之前添加符合您的偏執水平的檢查):
#!/bin/bash # variables # the IP address of GW2 IP_GW2=192.168.99.1 # the IP address of H1 IP_H1=192.168.111.47 # the configuration file containing GW2's MAC address CONFIG_MAC_GW2="/etc/default/iptables-mac-gw2" # the "arping" utility (used to resolve an IP address to a MAC address) ARPING=/usr/sbin/arping # include $CONFIG_MAC_GW2, if exists test -f $CONFIG_MAC_GW2 && source $CONFIG_MAC_GW2 # test if $MAC_GW2 is empty or undefined if [ ! -n "$MAC_GW2" ]; then MAC_GW2=`$ARPING $IP_GW2 -c 1 -r` if [ $? == 1 ]; then echo \$MAC_GW2 has not been configured and could not be detected using "$ARPING $IP_GW2 -c 1 -r" exit 1 fi # write the discovered MAC address into $CONFIG-MAC-GW2 so we don't have # to resolve it on succeeding runs echo MAC_GW2=${MAC_GW2} > $CONFIG_MAC_GW2 fi # [...] iptables -A FORWARD -i br0.105 -s $IP_H1 -m mac --mac-source $MAC_GW2 -j REJECT