NetworkManager 里丢失的 VPN 路由:配置文件策略还是脚本?
隧道连上了,但有一个前缀始终不出现。在添加辅助脚本之前,先判断问题出在配置文件策略、插件数据,还是第二个路由所有者。
你连上了,隧道接口出现了,可你需要的一个前缀就是不在表里。下一步通常是去找一个能把它加进去的脚本。这样的搜索会落到那些把 OpenVPN 辅助程序粘进配置文件的回答上,而其中一半会让情况更糟而不是更好,因为一条缺失的路由有三个可能的所有者,其中只有一个是缺失的脚本。
在写任何东西之前,先判断该由哪个所有者负责。
三个所有者,一个缺失的前缀
前缀可能缺席,是因为没人提供它,是因为配置文件拒绝了它,或者是因为它被安装在你没有查看的地方。这些是不同的故障,修法也不同。
第一个最容易检查:服务器或插件到底有没有提供过这条路由?从未收到前缀的后端无法安装它,辅助脚本也无法凭空造出对端从未描述过的可达性。第二个是配置文件策略,它可以抑制连接本会走的路由。第三个是表或规则,它可以把路由放在默认查找从不查看的地方。
第四个所有者是你自己,在之后:一个在连接时添加路由、却在断开时不删除它的脚本。这会留下一个比隧道活得更久、指向已死接口的前缀,并让下一个调试这台机器的人困惑。
添加任何东西之前,先读配置文件
从已保存连接自身的属性开始。读取时不要泄露机密,如果配置文件名称有歧义,就用 UUID。
nmcli -f vpn.service-type,ipv4.never-default,ipv4.ignore-auto-routes,ipv4.route-table,ipv4.routes connection show office
vpn.service-type 会告诉你哪个后端拥有这条连接,这一点很重要,因为插件数据是后端专用的。某个插件接受的键并不是另一个插件支持的指令,所以从别的客户端文档里抄来的片段证明不了任何事。
ipv4.ignore-auto-routes 和 ipv4.never-default 回答的是不同的问题。前者可以拒绝连接本会自动走的路由,后者控制配置文件能否成为默认路由。一个忽略自动路由、又不依赖其他东西的配置文件会连得很干净,却几乎什么都不安装。
ip -4 rule show
ip -4 route show table all
这两条命令能厘清第三种可能。在每一张表里查找你的前缀,而不只是 main,并检查是否有策略规则把相关查找送到别处。如果前缀在另一张表里而没人去查它,那就不是缺路由,而是有一条永远到不了它的查找。
脚本修不了的东西
加一个辅助脚本,是给 NetworkManager 的 vpn.data 一个可执行的程序。这是真实存在的机制,但对这些情况大多不合适,因为脚本拿到控制权时,配置文件自身的策略已经决定接受什么了。
OpenVPN 的 script-security 是另一个反复出现的混淆。它是一项 OpenVPN 设置,规定客户端可以执行哪些脚本、可以在它们的环境里放什么;级别 3 允许通过环境传递凭据,这属于机密处理的决定,而不是路由修复。把它粘进一个后端不是 OpenVPN 的配置文件,或在没有脚本需要时提高它,只会增加暴露面,不会增加路由。
然后是重启反射。重启 NetworkManager 服务会拆掉并重建每一条受管链路,如果你在远程工作,其中也包括你正连着的这一条。这是破坏性操作,不是无害诊断;在服务器上,它可能决定会话能否存活。
决定,按顺序来
按顺序问三个问题。对端提供过这个前缀吗,后端的日志或它自己的状态输出会显示?如果提供过,配置文件是配置成接受并安装路由,还是在抑制它们?如果路由确实存在于某处,那么你正在测试的流量所走的查找路径正确吗?
只有第一个答案是肯定的、第二个也是肯定的、第三个也正确时,补充脚本才站得住脚;即便如此,也该先问后端是否原生支持这条路由。VPN 设置参考记录了 service-type 和插件专用的数据字典,在假设某个键存在之前,应当从这里查起。
在获得批准的修正之后,重新连接,先按地址、再按名称测试目标,然后断开再重连,确认状态可重复。一个所有者、一张表、以及一条随隧道消失的路由,才是值得要的结果。