这里叠着三层传输,每一层都有自己的封装。VPN 载荷走在 TLS 会话里,该 TLS 会话走在一条通往环回端口的 TCP 连接里,而这条连接的字节又走在 SSH 里通往中继主机,中继主机再打开真正通往 VPN 监听端的 TCP 连接。这套安排并不改变 OpenVPN 所认证的内容,也不会让 UDP 监听端变得可以经 TCP 访问。请把余下内容当作字节路径的说明,而不是绕过网络管控的配方。

本地转发实际搬运的是什么

SSH 客户端在本地端口上监听。当本地进程发起连接时,客户端把这些字节装进自己的加密通道,服务器一侧则向转发请求里指定的目的地打开新的 TCP 连接。

这个目的地由中继解析,而不是由你的机器解析,所以只存在于远端网络内部的名字依然可用。这也意味着中继必须能到达 VPN 监听端,并且有返回它的路由。一个能在你的笔记本上解析的名字,并不能说明中继能看见什么。

启动 SSH 会话只能证明中继可达且已通过认证。它不能说明下一跳监听端是否在运行,中继与监听端之间的防火墙是否放行,也不能说明 VPN 是否会接受你的配置文件。

把客户端指向本地监听端

一个明确给出的例子:中继可以到达 gw.internal.example:443 上的 TCP 监听端,而一个高位本地端口只把这路径开放给本机。

ssh -N -L 127.0.0.1:24011:gw.internal.example:443 [email protected]

OpenSSH 手册 把本地转发描述为在本地接受 TCP 连接、并从远端发起后续连接。请把监听端绑定到环回地址而不是所有网卡,因为从网络可达的转发就是一个挂着你名字的开放中继。通配绑定还会把这个端口开放给共享机器上的其他任何本地账户。

然后把 VPN 客户端设为 TCP 模式,并指向 127.0.0.1:24011。如果配置文件使用 UDP,这套设计帮不上忙:转发承载的是字节流,其中没有数据报的通路。

把两种认证分开

SSH 负责认证中继主机。OpenVPN 仍然认证 VPN 对端,环回目的地并不改变这一要求。因为套接字现在指向 localhost 就关闭证书校验,是这套设计里最糟的捷径。它把传输安排变成了信任安排,而第二种安排并没有人批准。

保持配置文件的信任锚、服务器角色校验和名称验证不被改动。如果你的客户端拿服务器名称与它拨号的地址作比较,环回可能需要的是一项明确的名称设置,而不是关掉校验;要确认比较的是哪个字段,应查配置文件文档。

把中继当作信任关系里的第二方:它的管理员能看到连接元数据,配置一旦改动也能把转发改向别处。这套安排需要中继和 VPN 服务所有者双方批准,而不只是今天需要它的那个人。

不要在隧道下面搭环路

VPN 一旦安装路由,承载它的 SSH 连接仍然需要一条不经过隧道的、通往中继的路径。如果默认路由切到 VPN,而中继只能经同一条隧道到达,传输就会崩溃,VPN 也跟着断。这种故障看起来像隧道掉线,而不像路由错误,因此常被误判。

通常的修法是在隧道拉起之前,把通往中继地址的主机路由钉在物理网卡上,并检查这条路由能否在重连后保留。请用针对中继地址的路由查询来验证,而不是假定顺序正确。

还要预期这套叠加比直连更慢、更脆弱,因为现在有两层有序传输,还多了一个需要维护的端点。它是穿越网络边界的一种办法,不是性能技巧。

完成后关闭监听端

不再需要隧道时就停掉 SSH 会话,并确认本地端口已经释放。一个被遗忘的转发,会让一条已认证的路径在可能共享的机器上继续敞开。

也要复核中继允许的转发目的地,因为宽松的配置会把任何被攻陷的账户变成通用跳板。把端口、中继和目的地一起记录,好让下一个人知道这条转发是做什么用的、是否仍然获批。

相关文章