iptables:接口上的 DROP 不执行任何操作,但如果我不指定接口,它就会起作用

iptables:接口上的 DROP 不执行任何操作,但如果我不指定接口,它就会起作用

设置:

Ubuntu 20.04 安装在一个有 5 个物理以太网端口(我们称之为 eth1 - eth5)的盒子上。

我已使用 brctl 将它们全部连接到网桥 (“br0”),并且它们都可以互相 ping 通。

我想要做的是:允许 eth2 - eth5 继续自由地相互聊天,同时限制通过 eth1 进入的内容。(最终,eth1 将成为特定入站流量的“外部连接”,而其他接口可以自由通信。)

iptables -A FORWARD -j DROP

预期:每个人都会失明。效果很好。网桥正在使用来自 iptables 的规则。测试成功,撤消该操作。

iptables -F
iptables -A FORWARD -i eth1 -j DROP

预期:eth1 失明,但其他一切正常。现实:什么都没发生我仔细检查了 iptables -L,其中唯一的东西就是 Chain FORWARD 下面的单个“DROP all -- anywhere anywhere”。

iptables -F
iptables -A FORWARD -i br0 -j DROP

这似乎产生了影响。连接的笔记本电脑仍然可以 ping 通网桥本身,但无法互相 ping 通。

为什么当我删除特定接口时它不起作用?

我也乐意接受诸如“你完全用错方法了”之类的建议。另请注意:我试图避免任何形式的 IP 过滤。我想通过接口(物理以太网端口)进行过滤,而不是通过插入其中的 IP 地址进行过滤。

答案1

iptables在路由层工作。它在桥接层不起作用。一旦eth1设置为桥接端口,它就不再参与路由。这意味着不会看到数据包通过路由eth1,并且通常不会穿越iptables一点儿也不。

br_netfilter,桥接和iptables

有一个问题:当br_netfilter模块加载(通常通过 Docker),iptables也会过滤桥接IPv4 帧。OP 的问题暗示模块已加载。下图中绿色方框显示了这种情况(iptables蓝色区域(以太网桥接)中填写“处理 IPv4”字段:

Netfilter 和常规网络中的数据包流

在这种情况下,任何桥接帧看起来都iptables通过处理此帧的桥接器(br0)进行传输。eth1仍然不能像路由接口一样被引用。相反,这需要特殊的physdev模块(也会触发 的加载br_netfilter)来指定桥接端口。必须注意区分桥接流量和路由流量,因为iptables会看到两者。此文档可帮助处理更复杂的规则集:基于 Linux 的网桥上的 ebtables/iptables 交互第 7 节

因此,最后,当模块br_netfilter被加载时,或者无论如何通过以下规则加载时,为了实现目标,下面非常简单的示例就可以了。由于我没有来自 OP 的有关 Docker 或其他任何内容的背景信息,我必须强制 FORWARD 的策略为 ACCEPT 并首先插入规则,因为如果默认策略是 DROP 并且 Docker 加载了自己的规则,那么这个简单的例子就远远不够了:

iptables -P FORWARD ACCEPT
iptables -F FORWARD

iptables -I FORWARD 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -I FORWARD 2 -m physdev --physdev-in eth1 -j DROP

nftables

这需要内核 >= 5.3。

请注意,如果没有理由加载br_netfilter(例如运行 Docker),则不要使用iptables为此,可以使用nftables直接在适当的位置:家庭,因为nftables可以使用连接跟踪桥接系列中直接提供状态防火墙的功能,没有这个临时解决方案(最初是因为ebtables不能用连接跟踪)。

因此,我们可以将这个br_netfilter模块全部删除:

rmmod br_netfilter

这样做会破坏 Docker。

或者仅br_netfilter在当前网络命名空间和当前桥(默认情况下未启用,但为了彻底起见)中加载时禁用功能(失败的测试意味着未加载模块):

if sysctl -n net.bridge.bridge-nf-call-iptables 2>/dev/null; then
    sysctl -qw net.bridge.bridge-nf-call-iptables=0
    ip link set dev br0 type bridge nf_call_iptables 0
fi

每个命名空间的切换或者桥接切换足以激活该功能:必须同时禁用两者才能禁用它。

否则仍会影响iptables并且nftables在 ip 家族中(nftables没有工具可以正确处理这个问题)。如果 Docker 正在运行并且位于同一个网络命名空间(主机)中,这样做也会破坏 Docker,除非它实际上是在另一个网络命名空间中运行的 Docker-in-Docker。

等效nftables 桥接系列中直接的规则集是(使用 加载nft -f ...):

table bridge t {
    chain forward { type filter hook forward priority filter; policy accept;
        ct state established,related accept
        iif eth1 drop
    }
}

相关内容