Linux

使用兩個路由器防止無休止轉發

  • October 12, 2012

問題中的網路看起來基本上是這樣的:

                    /----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>曾經從GW2to返回,將導致發送到的 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

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