只处理 NEW 的防火墙规则关不住所有 WAN 通路
拒绝 NEW 连接不会动已建立的流和回包。在宣称策略已封闭之前,请先读 conntrack 状态、规则顺序和例外。
在 WAN 上拒绝新的出站连接看起来像是失败即关闭的策略,但它给出的承诺比表面更窄。属于既有流的报文不会命中它,许多回包也不会。这个缺口很容易被忽略,因为规则读起来像是在覆盖接口,而不是接口上的某一种连接状态。把状态匹配当成结论来读,正是虚假封闭感的来源。
状态是匹配条件,不是结论
连接跟踪依据防火墙已经看到的内容给报文分类,而不是依据应用的判断。双向都观察到的流算已建立,即使它下方的路由从隧道换成普通上行链路,其后续报文仍保持已建立。对入站连接的回应也可能属于已建立流量。这些报文永远不会重新变成 NEW。
因此,只针对新连接的规则无法证明 每个受保护的报文都被阻断。它把其他状态留给规则集的其余部分处理,而那里可能有一条更早放置的放行。
把规则放回它的上下文里读
放在阻断之前、针对已建立和相关流量的宽泛放行,会让报文在阻断被评估之前就通过。从后面的规则里去掉状态条件并不能改变这一点,因为评估根本到不了那里。顺序决定结果,而状态匹配决定哪些报文能走到那个顺序。
要检查实际生效的规则集,而不是你编辑过的文件,包括跳到其他链的规则以及平台生成的一切。在由 iptables 管理的路由器上,列出链会显示规则定义,它引用的链也必须一并追查。原生 nftables 系统则需要检查它自己的规则集和钩子优先级,因为固件很少生成完全相同的链。
计数器会告诉你哪条规则真正命中,它们通常比决策之后抓的包更有信息量。计数为零的规则没有被命中过,无论它的位置暗示了什么。
把禁止表达成与状态无关
如果一组客户端绝不能经隧道之外访问互联网,就直说这一点,而不是用一种状态去近似。规则必须按源、出口和目的地选择,不依赖连接状态,并且要放在任何更早的放行都无法绕过的地方。这样管理访问和本地网络例外各自拥有明确的规则,意图在策略里就看得见。
选 reject 而不是 drop 改变的是命中流量失败的方式,并不会扩大规则所选择的报文集合。连接被拒绝和静默超时是两种不同症状,指向同一个选择。
有意允许回应对 WAN 上由外部发起的访问,这样的策略是站得住的。只是必须照实这样描述,而不是把它呈现成只经隧道的完全隔离。
确认到底谁在这个组里
示例覆盖的是从一个接口发出、来自一个前缀的转发 IPv4 流量。它对 IPv6、第二条上行链路,以及路由器自身产生的流量只字未提。充当 DNS 解析器的路由器会发出自己的上游查询,而这些查询根本不会经过 forward 链。
确认受保护的客户端地址仍在所选前缀之内,因为已经移出该前缀的设备是意外直连,而不是策略允许。不审查例外设计就把阻断扩大到整个 LAN,往往也会拆掉你自己的管理通路。
iptables -S FORWARD
iptables -L FORWARD -v -n
cat /proc/net/nf_conntrack | grep -c ESTABLISHED
然后把一条旧流和一条新流放在一起试。新的连接尝试和已经活跃的双向传输在这条规则下表现不同,只有两者都测过,才知道你真正拥有的是哪种策略。