SSH 本地端口转发:用 localhost 访问远程服务
服务器上的 Web 服务只监听 127.0.0.1:8080,自己的电脑如何访问?不必把应用端口开放到公网,可以通过 SSH 建立一条加密通道。
本文统一使用示例地址
203.0.113.10和示例用户名user。使用时替换成自己的 SSH 服务器地址和账号。
1. 先理解:两个 127.0.0.1 不是同一台机器
127.0.0.1 是回环地址,表示"当前这台电脑自己"。
- 在自己的电脑访问
127.0.0.1,连接的是自己的电脑。 - 在服务器访问
127.0.0.1,连接的是服务器自己。
SSH 本地端口转发会在自己的电脑创建一个监听端口,再把收到的连接通过 SSH 送到服务器,由服务器连接指定的目标。
text
本机浏览器:http://127.0.0.1:18080
│
▼
本机 SSH 客户端:监听 127.0.0.1:18080
│
│ SSH 加密连接(通常走服务器的 22 端口)
▼
远程 SSH 服务器
│
▼
服务器上的应用:127.0.0.1:8080
2. 一条命令建立隧道
前提:你能通过 SSH 登录服务器,SSH 服务端允许端口转发,并且服务器能访问目标应用。
在自己的电脑上执行,Windows 可用 PowerShell,macOS/Linux 可用终端:
bash
ssh -N -L 127.0.0.1:18080:127.0.0.1:8080 user@203.0.113.10
完成 SSH 认证后,保持终端打开。因为使用了 -N,没有远程命令行提示符、暂时没有输出通常是正常的。
现在在本机浏览器打开:
text
http://127.0.0.1:18080
看到的就是远程服务器上 8080 端口的 Web 服务。
3. 命令怎么读
通用格式:
text
ssh -N -L 本地监听地址:本地端口:目标地址:目标端口 用户名@SSH服务器
| 部分 | 含义 |
|---|---|
-N |
不执行远程命令,只进行端口转发 |
-L |
本地转发,在运行 SSH 客户端的电脑上创建入口 |
127.0.0.1:18080 |
本机监听的地址和端口 |
127.0.0.1:8080 |
SSH 服务器要连接的目标地址和端口 |
user@203.0.113.10 |
SSH 登录账号和服务器地址 |
目标地址是从 SSH 服务器的角度看的。 右侧的 127.0.0.1 指 SSH 服务器自身,不是你的电脑。
两边端口不必相同。本机 18080 被占用时,可以改成 28080,然后访问 http://127.0.0.1:28080,服务器应用不需要改动。
4. 它为什么不需要开放应用的公网端口
浏览器先连接本地 SSH 客户端,数据通过已经建立的 SSH 连接到达服务器,再由服务器连接应用。因此,公网一般只需要允许 SSH 端口,不需要额外放行应用的 8080 端口。
显式绑定左侧的 127.0.0.1,可让这个入口仅供本机访问。如果改成 0.0.0.0,则可能让其他设备也能连接,具体取决于网络和防火墙设置。
隧道不会取消应用的登录验证。管理面板仍需 Token,数据库仍需数据库账号密码。
5. 几个常用变体
SSH 使用自定义端口
例如 SSH 监听 2222:
bash
ssh -p 2222 -N -L 127.0.0.1:18080:127.0.0.1:8080 user@203.0.113.10
-p 是 SSH 连接端口,不是应用端口。
同时转发多个服务
重复添加 -L 即可:
bash
ssh -N -L 127.0.0.1:18080:127.0.0.1:8080 -L 127.0.0.1:13306:127.0.0.1:3306 user@203.0.113.10
| 本机入口 | 远程目标 | 使用工具 |
|---|---|---|
127.0.0.1:18080 |
服务器 127.0.0.1:8080 |
浏览器 |
127.0.0.1:13306 |
服务器 127.0.0.1:3306 |
数据库客户端 |
端口转发不转换协议:数据库端口不能用浏览器当网页打开,HTTPS 服务也仍需使用 HTTPS,并正确处理证书与访问主机名的匹配。
添加保活和失败检查
bash
ssh -N -L 127.0.0.1:18080:127.0.0.1:8080 -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 user@203.0.113.10
ExitOnForwardFailure=yes:转发监听建立失败时退出,例如本地端口被占用。ServerAliveInterval=30:未收到服务端数据时,每隔 30 秒发送一次 SSH 保活请求。ServerAliveCountMax=3:连续多次没有保活响应时断开连接。
这些参数不会自动重连,也不能保证目标应用一直正常。隧道监听成功和后端服务可访问是两回事。
6. 如果应用运行在 Kubernetes 中
当应用只有集群内部的 Service 时,可以先在服务器上用 kubectl port-forward 创建一个回环地址入口。
假设命名空间是 demo,Service 名称是 web,Service 端口是 80。
在服务器执行:
bash
kubectl -n demo port-forward --address=127.0.0.1 service/web 8080:80
在自己的电脑执行:
bash
ssh -N -L 127.0.0.1:18080:127.0.0.1:8080 user@203.0.113.10
随后访问 http://127.0.0.1:18080。
text
本机 18080
↓ SSH 隧道
服务器回环地址 8080
↓ kubectl port-forward(通过 Service 选择 Pod)
应用 Pod 的目标端口
这里有两个需要持续运行的进程:本机的 SSH 和服务器上的 kubectl port-forward。任意一个退出,访问都会中断。Pod 重建也可能导致端口转发退出,需要重新建立。
7. 常见问题
本地端口被占用
如果出现 Address already in use,换一个左侧的本地端口,再用新端口访问。
SSH 连接成功,但网页打不开
先在服务器验证应用本身:
bash
curl -I http://127.0.0.1:8080
然后在本机验证完整通路,Windows PowerShell 可执行:
powershell
curl.exe -I http://127.0.0.1:18080
检查目标端口、应用协议和 SSH 窗口中的错误。HTTP 状态码还需结合应用判断,例如 401 表示需要认证,并不等于网络不通。
提示 Connection refused
如果是转发通道报告 connect failed: Connection refused,通常表示服务器连接目标地址失败。检查应用是否启动、是否监听指定地址和端口。
提示 administratively prohibited
通常是 SSH 服务端限制了转发,需要管理员检查 AllowTcpForwarding、PermitOpen 等策略。
关闭窗口或电脑休眠后断开
SSH 隧道依赖当前连接。进程退出、网络变化或休眠都可能使它中断,重新执行命令即可。主动停止时,在对应终端按 Ctrl+C。
8. 记住一句话
本地端口是入口,SSH 是加密通道,右侧目标地址由服务器去连接。
text
ssh -N -L 127.0.0.1:本地端口:目标地址:目标端口 用户名@SSH服务器