你连上了错误的 VPN,客户端报告了失败。这件事是否要紧,取决于失败之前线上究竟送出去了什么,而这个词本身并不告诉你。有些握手根本不携带任何秘密,另一些则把口令交给应答该地址的任何一方。在吊销任何东西之前,先分清是这两种情况中的哪一种。

先停下,保住证据

保留客户端日志、所选配置、你输入的地址以及大致时间。把它们写在客户端之外,因为改配置或重装会毁掉你之后需要的记录。在通过你自己掌握的路径确认端点之前,暂停一切后续尝试。

在询问这次尝试是否安全时,绝不要把未脱敏的配置或日志贴到公开论坛。这类文件常常含有私钥路径、内部主机名或令牌,所以先脱敏,再交给拥有该端点的管理员。

什么能越过边界

大部分混乱来自把每次失败都当成同一类事件。能到达对面的是四种不同的东西:公开证书、证明某个私钥被用过的签名、口令或一次性验证码,以及你自己选中的文件。每种都有各自的后果和各自的补救。给痕迹分类,是决定之后一切的那一步。

证书这一类最轻,因为随请求发出的东西本来就是公开的,它的标识字段对任何发起连接的人都可见。针对挑战的签名只说明私钥被用过,不说明私钥被发出。口令正好相反:拿到它的人可以在别处试,而专门用来校验口令的服务,恰恰就是那个值的预期接收方。

私钥的证明不是私钥的上传

现代 TLS 有意把这两件事分开。RFC 8446 定义了 CertificateVerify 消息:客户端用与其证书匹配的私钥对挑战签名。签名只证明持有,不携带私钥,所以一次经证书认证的尝试并不自动等于私钥泄露。

这份安心有边界,值得说明。证明只说明私钥参与了那次交换,对机器上本地程序此前读过什么一无所知。它也不说明一次不明尝试究竟走到了哪一步,所以日志仍然比理论重要。

口令遵循完全不同的信任模型。配置了外部校验器的集中器可能把提交的值转发出去,因此收到它就是预期功能,而错误的去处是真实的暴露,不是理论上的暴露。

用日志复原那次尝试

四个事实可以复原尝试:实际被联系的地址、服务器身份是否被校验、选了哪种认证方式、进程停在哪里。每一项都出现在客户端日志里,每一项都排除一种不同的说法。关于路由或所分配地址的错误并不说明线上已经送出过什么,因为认证可能在隧道建立失败之前就已完成。

这些事实要从客户端自己的日志里取,而不是凭记忆。把过滤范围收窄,输出才短到可以脱敏和分享:

grep -n -i -E 'verify|authentication|certificate|error|timeout' client.log | tail -30

不要用主机名替代上述任何一项。一个熟悉的名字、当前的 DNS 应答、以及软件弹出的证书警告,描述的是此刻而不是先前那次连接。口令提示同样不能证明发出过什么,因为客户端可能在提交之前就失败了。

判断,再行动

判断来自痕迹,而不是失败看起来有多吓人。把四行对着你复原的事实读一遍:

DecisionEvidence that puts you hereEvidence that rules it out
Change the password nowA password was submitted and a server reply arrivedThe log stops before any submission
Review active sessionsA one-time code was accepted by the wrong endpointThe code was never sent, or was rejected before use
Revoke and reissueThe file you selected contained key material, not just settingsThe upload was a profile with no embedded key
No further actionThe attempt ended before any authentication value was offeredYou later find an earlier attempt you had forgotten

如果口令到达了非预期的服务,请通过账号管理渠道更换,并检查它还在哪里被复用。已过期的一次性验证码能关上那条路,但用它建立的会话不会自己关闭,所以请身份管理员复核会话。如果密钥文件确实被上传,请按签发机构的吊销流程处理,而不是等出现滥用证据。

然后把有边界的结果写下来:发出了什么、还有什么未知、哪一项凭据需要处理。之后复核要的正是这份记录,它比两种舒服的结论中任何一种都有用。

相关文章