故障之后打开 Windows 的 VPN 对话框,它会给你一个编号和一句话,而那句话多半是较不有用的那一半。编号指出连接在哪一阶段失败,阶段则决定下一步该看哪个日志、哪项设置、找哪个团队。按顺序走完这些阶段大约要十分钟,也能避免那套熟悉的流程:重装网卡、切换协议、重置协议栈,只为修一个本来就没被允许拨入的账户。

把编号读成阶段

原生连接要过四道关口。它抵达服务器并建立链路,协商安全,认证用户,然后应用地址分配与路由。每一处的失败留下的证据都不同,而属于某一阶段的代码,对其它阶段毫无帮助。

要避免的错误是把代码当成严重程度。链路失败和授权失败读起来都是“无法连接”,除此之外毫无共同点。严重程度说明有多急,阶段说明该打开什么。

Code familyStageWhere the evidence lives
829, 703Link or dial completionClient event log, remote listener reachability
720PPP negotiation and miniport bindingAdapter state, bindings, client log detail
691, 649, 812Identity and authorizationGateway or authentication server decision
Connected, no trafficAddressing, routing and resolutionRoute table and resolver configuration

第一阶段:链路与拨号尝试

829 表示底层链路掉线。它并不说明是对端停止应答、中间设备掐断会话,还是客户端策略把它关闭了。像 703 这样的拨号完成代码还要更早:尝试根本没走到有链路的地步,这通常指向配置文件、服务状态或本地策略。

Get-VpnConnection -Name 'Corp' | Select-Object Name,ServerAddress,TunnelType,AuthenticationMethod,ConnectionStatus
Test-NetConnection -ComputerName vpn.example.net -Port 443
Get-WinEvent -LogName Application -MaxEvents 200 | Where-Object ProviderName -match 'RasClient' | Select-Object -First 15 TimeCreated,Id,Message

事件查询是人人都跳过的那一步。一条带时间戳和接口名的客户端记录,比对话框更有价值,因为它说明这次尝试究竟有没有离开本机。既没有记录、监听端也没有回应,那就是可达性问题,在客户端上怎么改都没用。

如果同一个配置文件在别的网络上能用,就停在这里。代码描述的是路径条件,不是配置错误,下一次有用的比较是两份抓包,而不是再装一遍。

第二阶段:PPP 与微型端口绑定

720 位于链路与用户之间。隧道已经建立,随后 PPP 层却没能协商出地址或控制协议,这往往是客户端上的绑定问题,而不是凭据被拒。正是这个区别构成了代码的全部价值:它说明根本没走到凭据那一步,所以账户不是嫌疑人。

Get-NetAdapter -IncludeHidden | Where-Object InterfaceDescription -match 'WAN Miniport' | Select-Object Name,Status,ifIndex
Get-NetAdapterBinding | Where-Object ComponentID -match 'ms_pptp|ms_l2tp|ms_sstp|ms_agile' | Select-Object Name,ComponentID,Enabled

读那两段输出,比重置任何东西都更有信息量。微型端口存在却没有启动,或者协议绑定被别的软件禁用,产生的正是这一阶段的失败。两者都能在不动协议栈其余部分的前提下修好。相反,彻底重置会连带清掉与故障无关的地址和筛选状态。

第三阶段:身份与授权

691 表示凭据被拒绝了。649 表示该账户没有拨入权限,812 表示远程访问策略拒绝了这次连接。这些是决定,不是传输故障,客户端只能如实上报。

证据在另一侧。请网关管理员调出那个时间点的尝试和匹配到的策略,向目录管理员确认账户是否有拨入权限、是否在策略要求的组里。更改隧道类型或重装客户端,都改不了针对一个身份作出的决定。

这一阶段有个有用的习惯:把账户字符串原样写进工单,包括任何域前缀。数量惊人的 691 案例是给错域保存的凭据,而这在账户字符串里就能看出来,不在协议设置里。

第四阶段:已连接,却什么都不通

连接可以建立完成,却依然没用。它拿到了地址,客户端报告成功,而应用的每个请求都超时。对话框对此毫无反映,也没有代码可查。到那时对话框已经帮不上忙,有用的证据在别处。

Get-NetRoute -DestinationPrefix 10.24.0.0/16 | Select-Object DestinationPrefix,NextHop,InterfaceAlias
Resolve-DnsName files.corp.example.internal
Test-NetConnection -ComputerName 10.24.6.15 -Port 445

如果缺少路由,要么服务器没下发,要么客户端把它丢了。路由在、域名解析失败,问题就在解析。两者都正常而应用仍然失败,那已经越过隧道,进入应用自身的配置。

每次测试只改一层。你在下一次尝试之前做的任何改动都会成为下一个代码的背景,而一个描述你上次改动的代码,比没有代码更糟。

一次尝试、一处改动、一条记录

不论处在哪个阶段,记录里都该有代码、消息、配置文件名、时间戳,以及你当时所在的网络。五个字段,而且每一个都已经在对话框或客户端日志里摆在你面前。这组信息小到能贴进工单,具体到别人可以复现。

然后把这个时间戳放到另一侧那条记录的旁边。本页上方的表格说明每种不一致归哪个阶段。没有第二条记录,代码只能缩小范围;有了它,阶段就定了。正是这次对照,把编号变成诊断,而不是猜测。

这个习惯覆盖了 Windows 上几乎所有原生 VPN 故障,而每一条分支都不需要重装任何东西。对话框一直在告诉你遇到的是哪一种,真正的工作是不肯把它们都当成同一个问题。

相关文章