菜单栏报告已连接,而扩展列表仍把该组件标记为未激活。两种读数来自同一台 Mac,谁都没有说谎:它们描述的是不同的事实。macOS 至少为 VPN 客户端保留三种相互独立的状态,而求助帖常把它们混成一句话,这正是建议在重装和重配之间来回摇摆的原因。弄清楚你真正缺的是哪一种状态,能把一个下午的猜测变成两分钟的核对。

这些状态不仅位置不同,所属方也不同。一种属于操作系统的扩展注册表,一种属于设备所服从的策略,还有一种属于客户端自身的会话。因为所属方不同,对其中一种所做的修复很少能改变另外两种。

被同一个说法概括的三种状态

StateWhere it livesWhat it does not prove
installed and activatedthe system extension registrythat any tunnel exists
permitted by policya configuration profile or a one-time user approvalthat the vendor's profile is configured
connectedthe client's own session statethat traffic takes the intended route

读取顺序比列表本身更重要:先从注册表开始,因为从未激活的组件不可能处于连接状态,然后看策略,它决定激活是否根本可行,最后看客户端,三者中只有它描述会话。顺序靠上的不匹配可以解释下方所有症状,而靠下的不匹配则不影响上面两项。

一个具体的例子:注册表显示已激活,客户端却连不上,问题指向配置文件或服务器,而不是扩展。反过来,客户端已激活,旁边的注册表却什么都没显示,通常意味着你看到的这个应用并不是承载流量的那个。动手之前,先记下你观察到的是哪种组合。

不轻信图标,自己找出扩展

当前版本把网络扩展列在系统设置的“通用”→“登录项与扩展”中。找到以产品名或发布者命名的条目,读它旁边的开关,而不是菜单栏上的图标。标签和位置在 macOS 各版本之间发生过变动,所以请按厂商针对你所使用版本的说明操作,而不是照抄旧文章的截图。条目完全不存在意味着该组件从未安装,改配置文件也不会让它凭空出现。

systemextensionsctl list
log show --last 10m --predicate 'subsystem == "com.apple.networkextension"' --style compact

第一条命令是查看装了什么、每个扩展是否自报已激活的最快方式。第二条显示激活为何被拒,因为拒绝通常以策略或签名问题的形式出现,根本到不了用户界面。改动之前先读拒绝文本:日志行会写出组件名,往往还有原因,而这正是支持工单需要的。复制整行而不是你认为重要的那个短语,因为版本号和标识符分别位于两端。

客户端承认、而列表不承认的事

扩展确认之后,再问客户端是否持有配置文件和会话,因为保存了配置却没有连接是配置问题,而连接了却不走流量是路由或策略问题。把三者当成一回事,只会让你回头重装一个一直正常工作的组件。

scutil --nc list
scutil --nc status "Work VPN"

列表显示已配置的服务及其连接状态;状态调用则显示某个具名服务的状态和它最后的错误。重装之前先把那段文本和 macOS 版本记下来,因为重装会毁掉证据,而且经常把同样的故障再演一遍。

当开关归策略所有

在受管理的 Mac 上,配置文件可以把扩展固定在某个状态,开关随之按设计变灰。开关不可用是一种策略声明,而不是需要绕过的缺陷。为了够到它而删除配置文件或管理注册,会改变设备的安全态势,在下一次签入时被还原,并留下一台自称合规、却缺少使其合规的那些控制项的机器。这个结果比原来的问题更糟,因为它把原因和症状一起藏了起来。

把请求连同扩展标识符、准确的拒绝文本和版本一起交给管理员。受管理的部署通常可以在几分钟内集中批准一个网络扩展,既比绕路更快,事后也可审计。

在真实应用上验证修复

任何受支持的修正之后,重新连接,并测试 VPN 存在的那个应用,而不是菜单栏上的标记。然后确认本应留在隧道之外的流量仍然留在外面,因为悄悄把一切都路由进去的修复,和你原本想要做的改动并不相同。在真实应用上做两分钟测试,比一个你无法复现的标记更有价值。

还在这份列表里时,有一点要当心:内容过滤器也是一种网络扩展。当单个站点失败时,把面板里每个扩展都关掉是粗暴的做法,会破坏其他应用无关的过滤,也让你把本该用来对比的组件提前拆掉,使下一次诊断更难。动手之前先按发布者和角色认出这个扩展,并记下三种状态中究竟哪一种出了错。

相关文章