在 VPN 接口出现时保持 nftables 策略稳定
基于名称的 nftables 规则能在隧道反复出现与消失时继续生效,但路由和已有流不会自动跟随。请把各自的负责方分开。
隧道是一次性的,策略不该如此。在 Linux 网关上,按名称匹配隧道接口的 nftables 规则只需加载一次,之后每次该接口出现都会继续适用。接口仍然有自己的生命周期:它被创建、消失,周围的路由与转换按各自的节奏走。把这几方负责的东西分开,才能在重连期间保持访问稳定。
按名称匹配比接口活得更久
nftables 提供数字接口索引匹配以及按名称的动态匹配 iifname 和 oifname。使用这些名称的规则即使在隧道设备尚未创建时也能干净加载,这正是启动时的规则集所需要的。接口被改名后匹配会停止,新接口接管该名称后又会恢复。数字索引没有这一特性,因此隧道通常选择名称形式。
名称只是匹配用的键,不是对端是谁的证据。对端认证仍然是 VPN 的工作。
添加规则前先读链
看看规则集当前包含什么、新规则会落在哪里,因为顺序决定结果。
nft list ruleset
nft -c -f /etc/nftables.conf列表会显示链、规则和句柄,检查模式会在不加载的情况下校验候选文件。针对同一条流,放在先前放行之后的仅隧道放行不会改变任何结果,因为第一条匹配的规则获胜。正因如此,一条迟到的规则可能看起来正确却毫无作用。按顺序读链,并确认禁止客户端到上行链路流量的规则仍然排在一切更宽泛的规则之前。
路由、转换和流各有其他负责方
接口存在并不会创建路由,也不会认证对端。那些属于 VPN 管理器,而转换有第三条生命周期。
conntrack -L -s 10.20.0.0/24 | head
ip route show dev vpn0conntrack 列表会显示已有流及其原始值与转换后的值,路由列表则显示管理器为该接口安装了什么。NAT 规则在第一个包上就建立连接跟踪状态,因此已建立的流在规则改变后仍保留其转换。所以规则正在更新与有流正在使用新路径是两件事。决定哪些会话必须重连,其余不相关的流不要动。
接受冷启动、丢失与恢复
在启动时没有隧道、随后有隧道、以及在断开与回归之后分别测试网关。确认隧道缺失时被禁止的转发仍被拒绝,对端认证后新的允许流能工作,而恢复不需要清空无关状态。不要把整条 POSTROUTING 链或每一条 conntrack 记录当作某一个配置文件的停止动作来清空,因为其他服务也在共用它们。记录是哪个组件改动了接口、路由和策略,而不只是启动钩子以零退出。
能在重连中存活的策略,其负责方是明确的,其规则也在隧道断开与连通两种情况下都测试过。报告成功的钩子只能证明钩子运行过。