问题中的网络基本上是这样的:
/----Inet1
/
H1---[111.0/24]---GW1---[99.0/24]
\----GW2-----Inet2
设备说明
- H1:IP 为 192.168.111.47 的主机
- GW1:Linux 机,IP 为 192.168.111.1 和 192.168.99.2,有自己的互联网路由。
- 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 直接连接到互联网,这种方法就行得通,但当该链接断开时,问题就出现了。然后,GW2 将数据包转发回 GW1,GW1 又将数据包转发回 GW2,从而形成无限的 TCP 乒乓循环。理想的结果是数据包被丢弃。
GW1 上的 iptables 有什么办法可以防止这种情况发生吗?基本上,一个 iptables 友好版本的“如果数据包来自 GW2,但源自 H1,则丢弃它”
- 注1:最好不要对 GW2 进行任何更改。
- 注 2:H1 需要能够与 GW1 和 GW2 通信,反之亦然,但只有 GW2 应该连接到互联网
TLDR;H1 只应被允许通过 GW2 访问互联网,但仍然需要能够与 GW1 和 GW2 通信。
编辑:GW1 的接口是 br0.105(用于“99”网络)和 br0.111(用于“111”网络)。解决方案可能非常简单,也可能不太简单,但我自己无法生成正确的 iptables 语法,因此非常希望得到帮助。
PS:这是来自这个问题
答案1
你真的如果可能的话,应该修复您的路由 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>
如果数据包来自<ip-h1>
从 返回到 ,GW2
则会导致向 发送 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
答案2
既然 G1 是 Linux 机器,为什么不直接用 ping 测试 G2 的外部接口,并在它没有响应时更改默认路由呢?而且,如果你做得对,当 ping 再次开始工作时,你可以自动恢复。