为什么你的 VPN 接口总是脱离它的 firewalld 区域
区域能维持到隧道重新连接,然后就消失了。在粘贴命令之前,先弄清楚是 NetworkManager 还是 firewalld 拥有那个接口。
你把 tun0 加进正确的区域,应用开始正常工作,而下次重连时修复就蒸发了。再执行同一条命令又能用,于是看起来像是 firewalld 忘了。它没有忘;是某个对那个接口拥有更强主张的东西把它重新分配了。
区域会一直保留到接口被重新创建
给接口指定 firewalld 区域是一种绑定,而绑定依附于接口对象当前的存在形式。一个先拆掉设备再重建的 VPN 客户端会产生一个新对象,而新对象从分配组件所说的内容开始。这就是症状每次重连都复现、而不是每个数据包都复现的原因。
同样的逻辑也解释了重启时的行为:运行时绑定挺不过重启,而永久绑定只适用于 firewalld 认为自己拥有的设备。
在改动任何东西之前,先弄清楚是哪个组件在分配区域。
在改动任何东西之前,先读三样东西
记录接口当前的区域、带各自接口的活动区域,以及你打算使用的区域的永久接口列表。分别在改动前、一次重连后和一次重启后执行这些查询。比较三个结果就能看出绑定是被替换、被忽略,还是只是应用得太晚。如果永久列表已经写上了该设备,而运行时的区域却不一致,那就是有东西盖过了你的修改。
每一步还要记录真实的设备名,因为今天落在 tun0 上的隧道,明天可能落在 tun1 上。
把绑定保存到一个通用名称并不是身份校验,两分钟的记录能省下一小时的猜测。
当 NetworkManager 拥有连接时
如果由 NetworkManager 管理 VPN 连接,它的配置文件就携带区域,并在连接激活时把它交给 firewalld。此时针对同一设备的 firewalld 永久接口绑定可能被忽略,因为所有者是 NetworkManager。把区域设在连接上,并确认你改的是 VPN 配置文件,而不是一条无关的物理连接或一条临时记录。
改动这个属性可能立刻影响一条活动的连接。
保留一条可用的管理通道,并在应用之前先读目标区域的策略。只有在 ifcfg 文件仍是配置来源的地方,改它的 ZONE 字段才是对的。
当 firewalld 拥有绑定时
对于接口名被刻意保持稳定的独立隧道,永久接口改动才是合适的工具。通过你的部署所用的重载或生命周期来应用它,然后再检查运行时状态,因为只改永久配置描述的是意图,而不是当前生效的东西。两者可能在整个重载期间一直对不上。
如果接口名是动态的,就在连接的整个生命周期里维护分配,而不是去和先抢到名字的那条隧道赛跑。
不要为了让应用能用,就把接口 丢进 trusted。
测试重载、重连和重启
只有三种情况都挺过去,改动才算完成。
先重载,因为只在运行时生效的修改正是在那里消失。然后重连隧道,因为被替换的接口正是在那里丢掉绑定。然后重启,因为所有者不一致正是在那里最终暴露。每个阶段都记录区域,并与你写下的意图对比,记下是哪一步造成了差异。
如果区域正确而应用仍然失败,问题就在区域规则或基于来源的分类上,而不在成员关系上。firewalld 关于连接与接口的文档 是所有权应当如何工作的参考。
把所有者、取值和预期结果写进 runbook,下一次重新分配就会是可解释的。