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

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

我正在构建一个基于 iptables 的防火墙配置工具,并尝试使“线路碰撞”场景发挥作用。

eth0给定一个带有eth1桥接器br0和第三个接口的设置eth2

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

在这种情况下,假设我想丢弃 TCP 端口 80 的流量(如果它要流向连接到的网络)eth0,但允许它流向eth1

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

如果我在表中添加以下 iptables 规则filter

-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 信息。

(还有第三种情况:这似乎适用于桥接器包含三个接口的情况,但仅通过排除源接口,它仍然无法建立单个接口来发送数据包。)

所以,问题是,无论如何我怎样才能可靠地匹配发出的数据包eth0

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

答案1

观察到的行为的原因

当数据包从非桥接接口到达时,iptables 没有获取物理桥接信息的原因是,数据包从未靠近桥接机制,即使此时我们知道我们正在桥接上将其发送出去。

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

解决方案

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

在上述场景中,您想要过滤通过特定桥接接口(eth0)离开的数据包,而不管它如何到达系统,请添加如下 ebtables 规则:

-A OUTPUT -o eth0 -j <target>

在更复杂的场景中,如果你想过滤从特定接口到达并通过桥接接口离开的数据包,事情会变得更加困难。假设我们想丢弃所有从eth2(非桥接)到eth0(桥接为 的一部分br0)的流量,我们需要将此规则添加到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任何被 iptables 标记为来自 的数据包都将eth2通过特定的桥接端口传出eth0

致谢

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

相关内容