卸载 VPN 客户端、重启,然后发现浏览器什么都打不开,这在 Ubuntu 上很常见。隧道没了,但把流量指向它的策略还在,而这些残留通常留在 NetworkManager 里,而不是在软件包里。运行时创建的连接配置文件和虚拟接口不属于任何软件包,所以卸载软件包并不会删掉它们。

隧道没了,策略还在

终止开关的原理是让没有隧道的网络无法使用。如果在这种状态生效时移除客户端,就没有任何东西去解除它。结果看起来完全像网卡坏了,通常是一个占着路由的配置文件。

这就是重装有时能恢复联网的原因:它重建了那个知道如何撤销自身策略的进程。在开关生效时被移除的客户端,留下了一个没人来清理的状态。

先读清软件包从未拥有的对象

改动之前先读状态。列出设备、活动连接和两张路由表,然后找一台报告已连接的虚拟设备,或者一条指向它的默认路由。IPv4 和 IPv6 是分别失效的,所以对一个名称解析已损坏的地址能 ping 通,指向的是另一个对象,而不是路由已死。一台占着默认路由的虚拟设备本身就足以解释整次断网。

nmcli device status
nmcli connection show --active
ip -4 route
ip -6 route

把看到的东西记下来,因为修复方法是删除某一个具体对象而不是全部重置。任何范围更大的操作都可能造成第二次断网。这就是修复和猜测的区别。

路由表为空但设备已连接,是另一种故障,它指向 DHCP 而不是残留的配置文件。动任何东西之前先读租约。

删配置文件,而不是密钥文件

通过 NetworkManager 删除配置文件,而不是删掉密钥文件。删文件会让内存中的配置一直有效到下次重启,这会让正确的修复看起来不可靠。然后重启服务,再读一遍设备列表。真正让删除生效的是重启。

sudo nmcli connection delete pvpn-killswitch
sudo systemctl restart NetworkManager

如果虚拟链路还在,就把那条链路也删掉,然后分别测试地址和名称。路由干净但名称解析失败,指向 DNS;地址失败则指向路由或防火墙。

在它重演之前检查开机钩子

有些残留会在每次开机时把自己重新装回去。手写的 unit 或添加防火墙规则的 if-up 脚本在软件包消失后仍然这么做,于是断网再次出现,之前那次修复看起来像运气。再重启之前,搜一遍 unit 文件和网络钩子。unit 的名字通常就是线索。

systemctl list-unit-files | grep -i vpn
grep -rl -i vpn /etc/systemd/system /etc/network/if-up.d

删除或屏蔽那个具体文件,然后重启一次,确认没有隧道的状态正是你要的。最后这次重启才是检验,因为只能撑到下次开机的修复不算修复。之后把记录留在机器上。nmcli 参考涵盖了上文用到的设备和连接命令。

相关文章