家里服务器没公网 IP 想在外面访问、数据库不想暴露 3306 端口、公司内网要跳板机中转——这些都能用 SSH 隧道(端口转发)解决。SSH 隧道把数据加密地"钻"过一条通道,安全又不需要额外装软件。这篇文章把三种转发方式(本地、远程、动态)一次讲透。
一、SSH 隧道是什么?
SSH 端口转发就是把某个端口的流量,通过 SSH 加密通道转发到另一台机器。三种模式:
| 模式 | 命令参数 | 用途 |
|---|---|---|
| 本地转发 | -L |
把远程服务的端口映射到本地 |
| 远程转发 | -R |
把本地服务的端口暴露到远程 |
| 动态转发 | -D |
建立 SOCKS5 代理,浏览器全局走隧道 |
二、本地转发(-L):访问内网服务
场景:数据库只在服务器内网监听,你想在本地电脑用 Navicat 连接。
# 把服务器的 3306 端口映射到本地 3306
ssh -L 3306:localhost:3306 root@服务器IP
此时本地 localhost:3306 就等于服务器内网的 3306,Navicat 直接连 127.0.0.1:3306 即可,数据库不用暴露公网,安全组只需放行 22。
转发到其他内网机器(跳板机场景):
# 服务器 A 是跳板机,把内网机器 B 的 80 端口映射到本地 8080
ssh -L 8080:B的IP:80 root@A的IP
本地访问 http://localhost:8080 就等价于访问内网 B 的 80 端口。
三、远程转发(-R):内网穿透
场景:家里/办公室的机器没有公网 IP,想让外网通过服务器访问家里的服务。
在内网机器上执行:
# 把内网机器的 80 端口,暴露到服务器的 8080 端口
ssh -R 8080:localhost:80 root@公网服务器IP
外网访问 公网服务器IP:8080 就等同于访问内网机器的 80 端口。
限制:默认只监听服务器的 127.0.0.1(本地才能访问)。要让公网都能访问,需在服务器 /etc/ssh/sshd_config 开启:
GatewayPorts yes
改完重启 sshd:sudo systemctl restart sshd。注意:开启后 8080 暴露公网,确认无风险再用。
四、动态转发(-D):SOCKS5 代理
场景:临时给浏览器挂代理,所有流量加密走服务器中转(国内访问海外服务、隐藏本机 IP)。
ssh -D 1080 root@服务器IP
然后在浏览器/系统代理设置里把 SOCKS5 指向 127.0.0.1:1080,所有上网流量就走服务器出口了。
五、常用参数组合
# 后台运行 + 防断开(-N 不执行远程命令,-f 后台,-o 保活)
ssh -Nf -L 3306:localhost:3306 root@服务器IP -o ServerAliveInterval=60
# 压缩加速(传大文件时)
ssh -C -L 8080:localhost:8080 root@服务器IP
# 指定密钥和端口
ssh -i ~/.ssh/id_ed25519 -p 2222 -L 3306:localhost:3306 root@服务器IP
# 同时建立多条隧道
ssh -L 3306:localhost:3306 -L 8080:localhost:80 root@服务器IP
-N:只建隧道不执行命令(纯转发必备,防止开一个 shell);-f:后台运行,断开终端隧道仍在;ServerAliveInterval=60:每 60 秒发心跳,防运营商/防火墙踢掉空闲连接。
长期使用推荐配置:把隧道写进 ~/.ssh/config:
Host tunnel
HostName 服务器IP
User root
LocalForward 3306 localhost:3306
ServerAliveInterval 60
ServerAliveCountMax 3
以后一条 ssh tunnel 就建立隧道。
六、常见问题排查
bind: Address already in use:本地端口被占用,换一个本地端口(-L 3307:...);remote port forwarding failed for listen port:远程端口被占用,或GatewayPorts未开启;- 连上后隧道不通:目标服务是否监听在对应地址(MySQL 要
bind-address允许)、防火墙是否放行; - 隧道经常断开:加
ServerAliveInterval=60,配合 autossh 自动重连(autossh -M 0 -Nf -L ...); - 建立隧道后没有 shell:加了
-N是正常的,隧道就在后台工作,ss -tlnp | grep 3306可验证; - 每次都要输密码:配置 SSH 密钥免密(ssh-keygen + ssh-copy-id),隧道才能无人值守。
总结:SSH 隧道三种模式对应三种需求——本地转发 -L 把远程服务拉到本地(访问内网数据库)、远程转发 -R 把本地服务暴露到公网(内网穿透)、动态转发 -D 建 SOCKS5 代理。生产环境常配合 -Nf 后台运行 + ServerAliveInterval 保活,再配个密钥免密,一条隧道稳稳跑几个月。



