/----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:两条可能的互联网路线
简而言之:H有多条可能的互联网路线.
当该链路启动时,H应该只通过GW2访问互联网,因此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来防止这种情况吗?基本上,一个iptables友好版本的“如果数据包来自GW2,但来自H1,放弃它”
>注1:最好不要改变GW2上的任何内容.
>注2:H1需要能够与GW1和GW2通话,反之亦然,但只有GW2才能通向互联网
TLDR; H1应仅允许通过GW2进行互联网访问,但仍需要能够与GW1和GW2通信.
编辑:GW1的接口是’99’网络的br0.105和’111’网络的br0.111.解决方案可能会或可能不会很简单,但我自己无法生成正确的iptables语法,所以非常感谢帮助.
PS:这是this question的后续问题
解决方法
让:
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
将导致ICMP目的地不可达消息发送到< ip-h1>在来自< ip-h1>的数据包的情况下从GW2返回到GW1.这里的想法是通过MAC地址进行过滤,因为您似乎通过此接口有多条路由到不同的路由器,您需要区分原始路由器.
您可以通过查看其接口配置获取GW2的MAC地址,或者,如果您无权访问它,可以查看GW1的ARP缓存表 – 只需运行arp -n查看缓存中的当前条目.
请注意,如果GW1正在为通过< int2>离开的流量执行NAT然后< ip-h1>需要是< int2>的IP地址,而不是H1的IP地址.
当你想要一种通配符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