SSH 本地转发如何承载 TCP OpenVPN 会话
一个本地端口,两段经过认证的关系,三层传输。SSH 转发搬运的是什么,以及环路与证书校验仍在哪些环节生效。
这里叠着三层传输,每一层都有自己的封装。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 会话,并确认本地端口已经释放。一个被遗忘的转发,会让一条已认证的路径在可能共享的机器上继续敞开。
也要复核中继允许的转发目的地,因为宽松的配置会把任何被攻陷的账户变成通用跳板。把端口、中继和目的地一起记录,好让下一个人知道这条转发是做什么用的、是否仍然获批。