浏览器能打开公司内网,代理证书也被信任,但 SSTP 客户端仍在连接末尾附近断开。这一现象指向网页请求与隧道会话之间的差异,而不是密码错误。从 TCP 往上逐段检查,记录第一个失败的环节。判断代理是否为原因,靠的是环节,而不是错误码。

从客户端停下的位置开始

客户端依次经过固定顺序:TCP 连接 443 端口、TLS 握手、证书验证、SSTP 的 HTTP 交换、PPP 协商与认证,最后是 IP 配置。每个环节的失败都会留下不同特征,把它们混为一谈就会把你带到错误的配置页面。

TCP 失败是指在任何 TLS 字节出现之前的超时或重置。TLS 失败是指告警或握手超时。证书失败会产生关于证书链或名称的警告。HTTP 失败发生在握手成功之后,常表现为状态码或立即关闭。PPP 失败发生在隧道技术上建立之后,所以看起来像认证问题。

查看客户端日志时,找最后一个成功的环节,而不是第一行错误。错误行通常报告的是后果,而环节边界才指出拒绝的组件。

SSTP 要求网络承载什么

SSTP 运行在 TCP 443 的 TLS 之上,然后按照SSTP 规范中的定义,向形如 /sra_{GUID}/ 的路径发送一个名为 SSTP_DUPLEX_POST 的 HTTP 请求。请求声明实际上无限的内容长度,并在整个会话期间保持流双向打开。PPP 帧就在这条流中传输。

这就是为什么能处理普通浏览的代理仍会失败。内容长度有限的 GET 或 POST 可以被缓冲、检查并转发;永不结束的正文所构成的双向流则不能。等待正文结束的代理会永远等下去,客户端最终超时。

方法过滤和认证会带来各自的失败模式。如果代理要求请求提供凭据,浏览器会响应,VPN 客户端却可能不响应。如果代理删除或重写方法,网关会在 PPP 开始之前就拒绝请求。

为什么检测会改变身份

检测 TLS 的代理会终止客户端的 TLS 连接,并向网关另开一条连接。因此客户端验证的是代理的证书,而不是网关的证书,网关也把代理视为对端。当组织分发自己的根证书时,浏览器和 VPN 客户端都可能接受这条链,于是握手成功,问题转移到下一个环节。

验证成功并不代表代理能承载会话。它仍然必须在不缓冲的情况下转发无界的双向 POST,并让两条连接存活数小时。许多检测产品是为请求-响应流量设计的,对这种情况处理很差,甚至完全无法处理。

因此,添加未知根证书或关闭验证是错误的修复。它改变的是客户端接受哪张证书,对真正断开会话的流处理毫无作用。

改设置之前先确认签发者

询问端点它出示的是哪张证书、由谁签发。下面的命令无需启动 VPN 会话即可显示证书链和签发者:

openssl s_client -connect vpn.example.com:443 -servername vpn.example.com -showcerts
curl -vI https://vpn.example.com/

如果签发者是公共 CA,说明该主机的连接大概率没有被拦截,故障在别处。如果签发者是组织自己的 CA,说明检测正在生效,网关是通过代理到达的。在下结论之前,把指纹与网络团队预期值比对,不要只看名称。

对同一主机的浏览器测试只能证明代理接受 GET。它说明不了 SSTP 方法、请求 URI 或正文的存活时间,所以不要把能打开的内网页面当作隧道路径受支持的证据。

选择受支持的路径

向网络负责人问一个具体问题:代理是否允许向该网关 443 端口发送不缓冲的双向 POST?回答允许,就对应代理例外或为 VPN 主机记录的绕过方案。回答不允许,说明被检测的路径无法承载 SSTP,受支持的修复是换路径或换协议,而不是调整客户端。

选项通常包括为 VPN 网关设置不被检测的出口、只让公司流量经过代理的分流隧道设计,或组织在另一端口支持的替代协议。每一种都属于网络设计,并且都应当用同一台设备和同一配置文件测试,这样比较才能隔离路径因素。

记录结论:签发者、失败环节、代理规则和所选路径。下一个人看到同样的 98% 卡住时,就能核对一个事实,而不必重走整套流程。

相关文章