端口 443 有响应,SSTP 仍然失败:哪一环节断了?
有东西接受了连接,隧道却依旧建不起来。把传输、证书、SSTP 协商和 PPP 认证分开看。
隧道始终建不起来,而到端口 443 的 TCP 握手却能完成,这只能证明一件小事。该地址上有什么东西在监听,并愿意接受连接。它既不能说明那是什么服务,也不能说明它会出示什么证书,更不能说明收到最初几个字节之后会发生什么。
从这次握手到一条可用的隧道,中间还隔着四个环节,每个环节失败的报错都不一样。
端口开放只描述一层
能接受 TCP 连接,只说明某个进程占着套接字、路径允许握手通过。它看不出那个进程是不是 SSTP 服务器,看不出它有没有与你配置文件中域名匹配的证书,也看不出它会不会批准你的账号。同一地址上的 Web 服务器同样能完美完成握手,然后拿一个 HTTP 错误来回应你的 SSTP 请求。这次握手之上的部分,全都还没被检验。
把端口测试当成最便宜的过滤器,而不是判决书。它的价值在于排除掉整整一类故障,而不在于确认它之上的所有事情。
把两者混为一谈,才会有人在一次根本没触及客户端真正问题的测试之后,去重装客户端。
用证据把四个环节分开
这四个环节是传输可达性、TLS 校验、HTTPS 上的 SSTP 交换,以及隧道内部的 PPP 认证。过了第一环却卡在第四环,要修的是凭据;卡在第二环,要修的是证书或域名。这两种修理毫无共同之处,选错了只会白白耗掉故障时间。
nc -vz vpn.example.net 443
openssl s_client -connect vpn.example.net:443 -servername vpn.example.net -brief
curl -sS -o /dev/null -w '%{http_code}\n' https://vpn.example.net/
第三条命令值得细读。普通网页返回 200,只说明那里有 Web 服务,并不说明它听得懂 SSTP 请求。同一地址返回 404,对 VPN 而言同样说明不了什么。只有客户端日志才能告诉你,它究竟走到了四个环节中的哪一个。
留意每条命令用的是哪个域名。证书是按你送出的域名来选的,所以配置文件和测试脚本之间的域名不一致,是你自己引入的不一致。把域名记在结果旁边,后面的困惑就能避免。
按正确方向解读“部分成功”
中间设备可以放行普通浏览,却拒绝后面的交换,这正是“能上网的代理未必能建隧道”的原因。同样的情形也出现在证书只对浏览器域名有效、对配置文件里配置的域名无效时:浏览器满意了,客户端却不满意,而两边对自己检查过的东西都没说错。
排查期间请保持服务器校验开启。一旦关掉,证书不匹配就会伪装成握手成功,而唯一能解释故障的证据也被藏了起来。
如果同一个配置在另一个网络里能用,差异就是路径相关的。这把范围缩小到中间设备,却没说清是哪一台,但仍然是有效的一步。请记下当时用的网络,没有它,这个对比毫无价值。
然后再测应用,而不只是会话
会话建立之后,要从真正需要它的客户端去验证预期路由、域名解析和服务权限。隧道连上了,远端仍可能缺少转发,或根本不存在回程路由,而在等待的人看来,这些故障和应用本身出问题一模一样。
让每个结论都挂在产出它的那个环节上。把开放端口说成 VPN 可用,就是这样把五分钟的证书检查拖成一整天的重装软件。