Linux kernel Iptables:离开桥接接口的匹配数据包

Linux kernel Iptables:离开桥接接口的匹配数据包,linux-kernel,iptables,netfilter,Linux Kernel,Iptables,Netfilter,抱歉,如果您已经在serverfault上看到了这一点,但它已经在那里播放了好几天了,而且我完全没有牵引力 我正在构建一个基于iptables的防火墙配置工具,并试图让一个“线中碰撞”的场景正常工作 给定桥接器br0中带有eth0和eth1的设置,以及第三个接口eth2: | | | eth0 eth1 eth2 | == br0== | | | |

抱歉,如果您已经在serverfault上看到了这一点,但它已经在那里播放了好几天了,而且我完全没有牵引力


我正在构建一个基于iptables的防火墙配置工具,并试图让一个“线中碰撞”的场景正常工作

给定桥接器
br0
中带有
eth0
eth1
的设置,以及第三个接口
eth2

    |          |         |
   eth0       eth1      eth2
    | == br0== |         |
          |              |
          |              |
         --- linux node ---
在这个场景中,假设我希望TCP端口80流量在连接到
eth0
的网络时被丢弃,但允许它
eth1

因此,我试图可靠地匹配通过特定接口发出的数据包
eth0

如果我在
过滤器
表中添加以下iptables规则:

-A FORWARD -o br0 --physdev-out eth0 -j LOG
给定一个来自
eth1
(网桥的另一半)的数据包,则规则匹配得很好,记录:

... IN=br0 OUT=br0 PHYSIN=eth2 PHYSOUT=eth1 ...
但是,如果数据包源自
eth2
,则规则不再匹配

我发现路由算法无法确定要选择哪个桥接接口,因此数据包通过桥接中的两个接口发送

如果我添加另一个更混乱的日志规则,那么我将获得该数据包的以下日志输出:

... IN=eth2 OUT=br0 ...
我的猜测是,在第一种情况下,路由算法可以选择网桥上的另一个接口,因为该数据包不应该按它来的方式发送。在第二种情况下,它没有选择一个特定的接口,因此您根本无法获得physdev信息

但是,如果网桥已经识别了目标MAC地址(如
brctl showmacs br0
所示),那么它可以确定正确的接口,并且您可以再次获得physdev informatino

(还有第三种情况:如果网桥包含三个似乎适用的接口,那么它仍然无法建立一个单独的接口来发送数据包,而只是排除了源接口。)

因此,问题是,我如何能够可靠地匹配通过
eth0发出的数据包


考虑到我在开始时给出的示例,仅匹配将通过多个接口路由出去的数据包是不够的,其中一个接口是
eth0
(尽管这在其他场景中很有用)。我希望能够以不同的方式处理
eth0
eth1
的流量,允许流量
eth1
,但不允许
eth0

观察到的行为的原因

当数据包从非桥接接口到达时,iptables无法获得物理网桥信息的原因是,数据包从未靠近桥接机制,即使此时我们知道它是在网桥上发送的

如果数据包确实通过网桥端口到达,但它是一个N>2的网桥,那么问题在于iptables PHYSDEV扩展只为“out”提供一个值,因此它不需要告诉我们是否有两个值

解决方案

使用ebtables而不是iptables。ebtables
OUTPUT
链将知道它在哪个物理桥接接口上发送数据包

在上面的场景中,如果要过滤通过特定桥接接口(
eth0
)离开的数据包,无论数据包是如何到达系统的,请按照以下行添加ebtables规则:

-A OUTPUT -o eth0 -j <target>
这将标记来自
eth2
并绑定到网桥的任何数据包。然后我们将此规则添加到ebtables

-A FORWARD -i eth2 -o br0 -j MARK --set-mark 1234
-A OUTPUT -o eth0 --mark 1234 -j DROP
它将
丢弃任何由iptables标记的数据包(来自
eth2
),该数据包通过特定网桥端口
eth0

感谢

感谢netfilter iptables邮件列表上的Pascal Hambourg,感谢他帮助我们提出了这个解决方案