iptables:匹配桥接接口的数据包

我正在构build一个基于iptables的防火墙configuration工具,并试图得到一个“在线”情况下工作。

给定一个在br0和第三个接口eth2使用eth0eth1的设置:

  | | | eth0 eth1 eth2 | == br0== | | | | | | --- linux node --- 

在这种情况下,假设我想让TCP端口80stream量被删除,如果它要连接到eth0的networking,但是允许它到eth1

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

如果我在filter表中添加下面的iptables规则:

 -A FORWARD -o br0 --physdev-out eth0 -j LOG 

给定一个来自eth1 (桥的另一半)的数据包,那么规则匹配就好,logging:

 ... IN=br0 OUT=br0 PHYSIN=eth2 PHYSOUT=eth1 ... 

但是,如果数据包来自eth2 ,则规则不再匹配。

我看来,路由algorithm无法确定select哪个桥接接口,所以数据包通过网桥中的两个接口发出。

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

 ... IN=eth2 OUT=br0 ... 

我的猜测是,在第一种情况下,路由algorithm可以select桥上的另一个接口,因为这个数据包不应该出现问题。 在第二种情况下,它没有select一个特定的接口,然后你根本没有得到任何physdev信息!

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

(还有第三种情况:这个桥包含三个接口,这似乎适用于这个接口,那么它仍然不能build立一个接口来发送数据包,只是排除了源接口。)

那么问题是,我怎样才能可靠地匹配eth0数据包?

考虑到我在开始时给出的例子,仅仅匹配将通过多个接口路由出去的数据包是不够的,其中之一是eth0 (尽pipe在其他情况下这将是有用的)。 我希望能够以不同的方式处理eth0eth1的stream量,使stream量达到eth1 ,而不是eth0

观察到的原因

当数据包从非桥接接口到达时,iptables没有得到物理网桥信息的原因是数据包从来没有接近过桥机制,尽pipe在这一点上我们知道我们正在发送桥接。

在数据包确实通过网桥端口到达的情况下,它是一个N> 2的桥接,问题在于,iptables PHYSDEV扩展只提供了它们作为“out”的一个值,所以它不会告诉我们如果有两个。

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

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

 -A OUTPUT -o eth0 -j <target> 

在更复杂的情况下,如果要过滤从特定接口到达的数据包,并通过桥接接口离开,则会变得越来越困难。 假设我们要从eth2 (非桥接)到eth0 (桥接为br0一部分)中删除所有stream量,我们需要将此规则添加到iptables中

 -A FORWARD -i eth2 -o br0 -j MARK --set-mark 1234 

这将标记来自eth2并绑定到网桥的任何数据包。 然后我们将这个规则添加到ebtables中

 -A OUTPUT -physdev-out eth0 --m mark --mark 1234 -j DROP 

这将DROP任何通过特定网桥端口eth0出口的由iptables标记的数据包(来自eth2 )。

致谢

感谢Pascal Hambourg在netfilter iptables邮件列表中提供这个解决scheme的帮助。