把 VPN 客户端指向公司 HTTP 代理,第一个有用的事实是:代理并不说 VPN 的协议。它向您指定的地址打开一条普通 TCP 连接,然后退到一边,让客户端和服务器在那条流上自行交换。客户端需要的一切,从传输类型到服务器的监听,都必须与这种安排相符。两种不匹配解释了大多数失败:面向 CONNECT 代理的 UDP 配置文件,以及被误认为 VPN 错误的代理回复。

代理承载什么,不承载什么

代理只是一个传输跳点。它不会变成您的浏览器代理,不会缓存您通过隧道访问的网站,除非有人刻意配置检查,否则它看不到内部流量。它打开的隧道按设计对它是不透明的。

这也意味着代理无法修复没有对应监听器的服务器。获准到达某个目的地,与该目的地上有服务在监听,是两件不同的事,只有前者属于代理管理员。

载体在两端都必须是 TCP

常规 CONNECT 代理只转发字节流,因此客户端必须使用流式传输。该情形的客户端片段如下:

proto tcp-client
remote vpn.example.net 1194
http-proxy proxy.corp.example 3128

服务器端需要在 remote 行指定的端口上有一个真正的 TCP 监听器。在配置文件中把 proto udp 改成 proto tcp-client 只会创建一个期待流的客户端,并不会在对端创建流。如果同一台服务器在该端口上也通过 UDP 应答,那是另一个监听器,而不是同一个监听器的第二种模式。

存在独立 TCP 实例时,它的隧道设备、地址池和路由都是各自的资源。复制一份可用的配置并改动传输字样,会让这些资源仍指向原实例,于是产生一条认证成功却什么都不路由的连接。

先读代理回复,再看 VPN 结果

客户端的第一次交换是一条请求行,其中写明目标主机和端口。对这一行的回复告诉您究竟有没有字节流,而且它出现在任何证书或凭据被检查之前:

CONNECT vpn.example.net:1194 HTTP/1.1
Host: vpn.example.net:1194
Proxy replyWhat it meansWhere to look next
407 Proxy Authentication RequiredThe proxy wants its own credentialsThe client's proxy auth options, not the VPN account
403 ForbiddenThe destination or method is not permittedThe proxy's access policy for that host and port
503 Service UnavailableThe proxy could not complete the upstream connectionThe proxy's own logs and the server's listener

对 CONNECT 返回 200 类回复意味着流已存在。它并不说明网关证书是否受信任、共享密钥是否匹配,也不说明用户账号是否有效。这些检查稍后在流内部进行,失败时给出的是客户端自己的消息,而不是 HTTP 状态行。请在客户端日志中寻找代理握手之后的第一个 OpenVPN 事件,而不是窗口关闭前的最后一行。

代理凭据和 VPN 凭据往往是不同团队掌握的不同身份。407 不是 VPN 账号的密码错误,证书被拒也不是代理权限问题。

CONNECT 不暴露什么

显式的 CONNECT 隧道不是拦截。代理转发字节,并不终止 VPN 的 TLS 会话,所以客户端对服务器证书的验证仍然有意义,应当保持开启。为了通过代理而关闭验证,解决的是另一个问题。

也存在组织刻意终止并检查 TLS 的独立安排。那些需要各自的信任配置和各自的策略决定,并不是普通 http-proxy 行所要求的。

TCP 套 TCP 的代价

让隧道走 TCP,会让外层流保持有序并重传,而内层流量通常也是 TCP。两套恢复机制并不协调,因此一个丢失的段可能让共享这条外层流的一切停住,直到它被重传。这是为兼容性付出的真实交换,不是免费的升级。

当网络别无选择时使用代理路径,在策略允许的地方优先直连 UDP。无论如何,改动之后要确认同一个代理、目的地和配置文件能走到下一阶段;在那个地址加载页面的浏览器用的是另一种协议,并不能证明隧道的事。

相关文章