Jam*_*ieB 5 networking firewall iptables
设置:
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
Run Code Online (Sandbox Code Playgroud)
预期:eth1 失明,但其他一切都很好。现实:什么也没有发生。我仔细检查了 iptables -L,其中唯一的东西是 Chain FORWARD 下的一个“DROP all - Anywhere”。
iptables -F
iptables -A FORWARD -i br0 -j DROP
Run Code Online (Sandbox Code Playgroud)
这似乎有影响。连接的笔记本电脑仍然可以 ping 网桥本身,但无法相互 ping 通。
为什么当我删除特定接口时它不起作用?
我也愿意接受诸如“你以完全错误的方式处理这件事”之类的建议。另请注意:我试图避免任何类型的 IP 过滤。我想按接口(物理以太网端口)进行过滤,而不是按插入其中的 IP 地址进行过滤。
A.B*_*A.B 12
iptables
工作在路由层。它在桥接层不起作用。一旦eth1
设置为桥接端口,就不再参与路由。这意味着不会有数据包被路由通过,并且通常它根本eth1
不会遍历iptables 。
br_netfilter
、桥接和iptables有一个问题:当br_netfilter
模块加载时(通常由 Docker加载),iptables
还将过滤桥接的IPv4 帧。OP的问题暗示模块已加载。这种情况如下图所示,蓝色字段中的绿色框(处理 IPv4 的iptables)(以太网桥接):
在这种情况下,任何桥接帧都将通过处理该帧 ( ) 的桥出现在iptablesbr0
中。eth1
仍然无法像路由接口一样被引用。相反,这需要特殊physdev
模块(它也会触发 的加载br_netfilter
)来指定桥接端口。必须注意区分桥接流量和路由流量,因为iptables会看到两者。本文档可以帮助处理更复杂的规则集:基于 Linux 的桥接器上的 ebtables/iptables 交互第 7 节。
所以最后,当模块br_netfilter
被加载时,或者无论如何通过以下规则加载时,为了实现目标,下面这个非常简单的例子就可以了。由于我没有来自 OP 的有关 Docker 或其他任何内容的上下文,因此我必须首先强制 FORWARD 的策略接受并插入规则,因为如果默认策略是 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
Run Code Online (Sandbox Code Playgroud)
这需要内核 >= 5.3。
请注意,如果没有理由加载br_netfilter
(例如运行 Docker),则可以在适当的位置直接使用nftables ,而不是使用iptables :网桥系列,因为nftables可以直接在网络中使用状态防火墙的conntrack设施。 Bridge 系列,没有这个拼凑(最初是因为ebtables不能使用conntrack)。
因此,我们可以br_netfilter
完全删除该模块:
rmmod br_netfilter
Run Code Online (Sandbox Code Playgroud)
这样做会扰乱 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
Run Code Online (Sandbox Code Playgroud)
每个命名空间切换或桥接切换足以激活该功能:必须禁用两者才能禁用它。
否则它仍然会影响iptables以及ip 系列中的nftables ( nftables没有工具可以正确处理这个问题)。如果 Docker 正在同一网络命名空间(主机)中运行,那么这样做也会中断 Docker,除非它实际上是在其他网络命名空间中运行的 Docker-in-Docker。
桥系列中直接等效的nftablesnft -f ...
规则集是(使用 加载):
table bridge t {
chain forward { type filter hook forward priority filter; policy accept;
ct state established,related accept
iif eth1 drop
}
}
Run Code Online (Sandbox Code Playgroud)