报错说“版本不对”,于是很容易先去换 TLS 版本。有代理时,先查更靠前的一种可能:客户端是不是把 TLS 握手发到了等待明文 HTTP 的端口上?

像 https://example.com/ 这样的目标,配上像 http://proxy.example:8080 这样的代理,是常见的组合。把第二个 URL 改成 HTTPS,意思是让客户端与代理本身之间的对话加密;它并不是“允许访问 HTTPS 网站”的指令。

定位第一段 TLS 对话

使用 HTTP 代理时,客户端可以先发 CONNECT 并收到 HTTP 响应,之后才在隧道内开始与目标建立 TLS。使用 HTTPS 代理时,先建立的是到代理本身的独立 TLS 连接。

TLS 解析器收到 HTTP 错误页或其他明文时,可能报出协议错误。这句话并不能说明网站支持哪些 TLS 版本,甚至不能说明是否真的连到过该网站。

  1. 记录代理 URL(连同其 scheme)以及端点文档中规定的协议。
  2. 查清失败发生在 CONNECT 响应之前、目标 TLS 过程中,还是校验代理自身证书时。
  3. 对照旧的绕行方案时,核对实际的客户端与依赖版本。早期的代理实现有时对 scheme 的处理并不相同。

若干“修复”可能因不同原因而出错。HTTP 代理列表为允许经该路径发出的公开请求提供普通 HTTP 端点候选。普通 HTTP 端点需要 HTTP 代理 scheme;真正启用 TLS 的端点则应保留 HTTPS 及其证书校验。拒绝 CONNECT 的代理需要受支持的服务或策略,而不是随意降级库。

保留最早可观察到的失败。关闭证书校验不会让只讲 HTTP 的监听端改说 TLS,选择旧密码套件策略也解释不了在站点握手之前就发出的 HTTP 拒绝。

相关文章