iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -d 172.16.1.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j MASQUERADE
上面,第一条规则没有多大意义,因为同一 LAN 中地址之间的数据包不在 IP 层转发(即路由),而是在以太网层作为帧转发(桥接/交换),因此该规则永远不匹配,因为它们不被视为路由但被桥接,并且iptables预计只能在第 3 层工作:IPv4。但是当br_netfilter加载这些类型的“无用规则”时变得需要,否则仅用于路由的操作将在桥接路径的第 2 层发生(如这里:NAT 将由同一 LAN 中的两个节点之间的桥接完成,无需第一条规则)。
正在努力(多年来)摆脱br_netfilter,但这需要功能奇偶校验。对于 IP 和 IPv6(我猜是 ARP),内核 5.3、nftables和内核模块或多或少地实现了nf_conntrack_bridge这一点,这些模块允许系列中的nftablesbridge(不在ip,ip6或inet类似br_netfilter触发器的系列中)使用conntrack:
此功能允许通过在网桥路径中使用iptables来增加ebtables的使用,以实现有状态的防火墙网桥(而不是路由器)。它已经存在了很长时间(2002 年),最初没有切换并且是桥代码的一部分:如果启用了桥和网络过滤器支持,那么它也是。
然后在 2003 年添加了切换。当然,出于兼容性原因,默认设置为启用。
然后在内核 3.18中,该功能被分离到它自己的内核模块
br_netfilter
,因为它可能导致问题。存在对兼容性的担忧,并且已经针对nftables弃用它的目标:现在必须加载内核模块才能使该功能正常工作。但是,它的主要已知客户通常会在任何桥接状态防火墙设置中找到,它将是出于兼容性原因再次自动加载的iptables目标。
physdev
br_netfilter
所以在一个简单的系统上,
br_netfilter
不应该加载,也不应该有任何可用的sysctl在net.bridge
:bridge-nf-call-arptables
,bridge-nf-call-ip6tables
,bridge-nf-call-iptables
(以及bridge-nf-filter-pppoe-tagged
,bridge-nf-filter-vlan-tagged
,bridge-nf-pass-vlan-input-dev
)中根本不应该出现。但是现在,这个内核模块有了一个新的主要客户:Docker。遇到此问题的通常方式是在运行 Docker 时,因为Docker 显式加载
br_netfilter
以能够控制容器之间的内部通信,同时默认情况下过滤和丢弃转发的数据包。因此,人们往往会发现它在使用中,即使在没有预料到它的情况下,或者认为这种行为是预期的行为,但它不应该再出现了。由于默认设置是系统范围的,除了 Docker 管理的网桥之外,它还会影响系统上的所有其他网桥:不仅是初始主机名称空间中的网桥,还包括任何其他网络名称空间中的网桥。
同样,iptables的
physdev
自动加载br_netfilter
仅在它自己的模块 ( ) 本身被加载时(在此补丁xt_physdev
之前它曾经比这更频繁)。请注意在补丁描述中是如何写的:所有这一切使得这个问题的答案是:
这是出于向后兼容性的原因。
补充说明。
在当前未加载内核模块的系统上
xt_physdev
,仅允许运行用户命名空间的普通用户可以执行以下操作:br_netfilter
并且可能已经破坏了系统上安装的任何其他技术(虚拟机、容器......)的 LAN 连接,这些技术没有使用特殊和仅外观无用的规则来保护自己免受
此 Netfilter 文档页面中描述了这些效果,解释了桥接路径、路由路径、ebtables 和 iptables 之间的交互: 基于 Linux 的桥接上的 ebtables/iptables 交互。第7 部分特别有用,因为它描述了应该添加什么样的保护,例如:
上面,第一条规则没有多大意义,因为同一 LAN 中地址之间的数据包不在 IP 层转发(即路由),而是在以太网层作为帧转发(桥接/交换),因此该规则永远不匹配,因为它们不被视为路由但被桥接,并且iptables预计只能在第 3 层工作:IPv4。但是当
br_netfilter
加载这些类型的“无用规则”时变得需要,否则仅用于路由的操作将在桥接路径的第 2 层发生(如这里:NAT 将由同一 LAN 中的两个节点之间的桥接完成,无需第一条规则)。正在努力(多年来)摆脱
br_netfilter
,但这需要功能奇偶校验。对于 IP 和 IPv6(我猜是 ARP),内核 5.3、nftables和内核模块或多或少地实现了nf_conntrack_bridge
这一点,这些模块允许系列中的nftablesbridge
(不在ip
,ip6
或inet
类似br_netfilter
触发器的系列中)使用conntrack:但是其他涉及 VLAN 封装/解封装或特别是 PPPoE 协议的功能还没有准备好。
此外,从内核 5.3 开始,可以停用网络名称空间范围的功能,并使其仅在每个网络名称空间甚至每个网桥上都处于活动状态。但这要求创建的每个新命名空间(包括初始网络命名空间就是这样的需要)在其内部早期运行,例如:
然后对于需要它的手工挑选的桥梁,在桥梁创建(
ip link add ...
)或以后(ip link set ...
):具有默认iptables设置的 Docker 无法处理此问题,因此 Docker 无法在具有此类设置的主机上同时运行,但是 Docker-in-Docker(实际上是在其他容器技术中,如 LXC 而不是 Docker原因)可能会很好,因为每个新命名空间中的默认值仍然向后兼容。