
服务器上的数据库只监听内网地址,本地怎么都连不上。查资料,答案是要建一条 SSH 隧道。
用 Xshell 配置时容易卡住:本地转发和远程转发,名字看着差不多,方向却正好相反。
配反了,连不上;配对了,一次就通。
这篇把 Xshell 里的三种隧道说清楚。
SSH 不只是给你一个命令行。
它在客户端和服务器之间建立的那条连接,本身是一条加密通道。既然通道已经通了,就可以往里塞别的东西——不只是你敲的命令。
端口转发就是把这条通道"接"到某个端口上。
数据从一个端口进去,穿过加密通道,从另一头出来。整个过程对使用者透明——你只管连本地端口,剩下的交给 SSH。
场景:数据库跑在服务器内网,只监听 127.0.0.1:3306,不对外开放。你本地的客户端连不上。
思路:让本机开一个端口,所有发到这个端口的请求,都经由服务器转发给内网的数据库。
命令形式:
ssh -L 3307:127.0.0.1:3306 user@跳板机参数拆开看:
流程:
这里最容易搞混的一点:目标地址里的 127.0.0.1 指的是跳板机自己,不是你的电脑。
因为发请求的是跳板机——它连自己本地的 3306,正好就是数据库。
场景:反过来了。你本机跑着一个服务,想让外面的人访问,但你的机器在内网,没有公网 IP。
思路:让远程服务器开一个端口,把请求反向送回你的本地。
命令形式:
ssh -R 8080:127.0.0.1:80 user@公网服务器流程:
注意:这次 127.0.0.1 指的是你自己的电脑。
同样的写法,含义完全相反——因为发起连接的那一方换了。
前两种都要事先说清楚:请求最终要去哪里。
动态转发不需要。
命令形式:
ssh -D 1080 user@跳板机它在本地开一个 SOCKS5 代理端口。之后所有走这个代理的请求,都由跳板机根据目标地址动态转发。
代价:动态转发的规则更宽泛,转发的是"任意目标"。所以它的配置更需要谨慎——范围越大,越要想清楚是不是真的需要。
三种转发记混,多半是因为在看"端口在哪一头"。
换个角度,看是谁主动发起请求,就清楚了:
-L 和 -R 的关系,就是互为镜像。
一个把远端的服务拉到本地,一个把本地的服务推到远端。方向相反,所以 127.0.0.1 的含义也正好对调。
命令行讲完了,说下图形界面的位置。
会话属性 → SSH → 隧道 → 点「添加」。
在弹出的规则窗口里:
对应的就是前面命令行里的那几个参数。
一个实用点:规则可以保存成多条,连上会话后自动全部生效。所以经常用的隧道配置一次就够了,不用每次手动敲命令。
隧道建好了,用着用着断了。这是另一个常见困扰。
原因通常不在 SSH 本身。
你和服务器之间的链路上,可能有防火墙、NAT 网关这类设备。它们会清理长时间没有数据传输的连接——因为它们无法判断这是"空闲"还是"已经死掉",干脆回收资源。
所以需要定期发点东西,证明连接还活着。
SSH 提供了两个层面的保活:
关键差别在"带不带数据"。
TCP 层的空包只有包头,没有内容。有些中间的设备会直接丢弃这种包,或者不当回事。
而 SSH 应用层的心跳是一个正常的加密请求——服务端必须响应。链路两端的设备都会看到真实流量,自然就不会判定它空闲。
会话属性 → 连接 → 勾选「保持活动状态」,间隔设为较小值(如 30 秒)。
如果有服务器权限,可以在 /etc/ssh/sshd_config 里加:
ClientAliveInterval 60ClientAliveCountMax 3含义是:服务端每 60 秒探测一次客户端,连续 3 次没响应才断开。
改完重启 SSH 服务生效。
保活只能防止"连接因空闲被清理"。
如果你本地断网、进程崩溃、或者合盖休眠——连接照样断,只是断的原因不同。
如果跑的是长时间任务,光靠保活不够。正确做法是让任务脱离 SSH 会话运行,比如用 tmux 或 screen。
这样即使连接断了,任务还在服务器上跑着,重新连上后 tmux attach 就能找回现场。
保活解决的是"连接别断",tmux 解决的是"断了也不怕"。两者要一起用。
SSH 隧道的方向,取决于谁发起连接。
想清楚"请求是从哪一头出发的",127.0.0.1 指的是谁就自然清楚了,-L 和 -R 也不会再记反。
至于 Xshell 里连接老断开,多半是中间设备在回收空闲连接——用应用层心跳告诉它们"还活着"就行。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。