一、问题背景
在很多实验室环境中:
- GPU 服务器(内网机器)❌ 没有公网 IP
- 无法直接 SSH ❌
- 无法用 VS Code Remote ❌
- Jupyter / TensorBoard 无法访问 ❌
但通常:
👉可以访问外网(主动连接)
💡 二、核心思路(关键!)
我们引入一台有公网 IP 的云服务器作为“跳板机”。
实验室服务器 C ---> 云服务器 B <--- 本地电脑 A (主动连接)核心技术:
👉SSH 反向隧道(Reverse SSH Tunnel)
本质一句话:
让内网服务器主动“把自己暴露”到公网。
⚙️ 三、环境准备
1️⃣ 云服务器 B(阿里云等)
确保 SSH 配置允许端口转发:
sudo vim /etc/ssh/sshd_config修改为:
AllowTcpForwarding yes GatewayPorts yes重启 SSH:
sudo systemctl restart sshd2️⃣ 开放安全组端口
在云服务器控制台开放:
TCP 123453️⃣ 实验室服务器 C
准备 SSH 私钥:
chmod 600 /root/.ssh/aliyun.pem测试连接:
ssh -i /root/.ssh/aliyun.pem root@47.104.XXX.XXX🔌 四、建立反向 SSH 隧道
在实验室服务器执行:
ssh -i /root/.ssh/aliyun.pem \ -o ServerAliveInterval=30 \ -o ServerAliveCountMax=3 \ -o ExitOnForwardFailure=yes \ -NR 0.0.0.0:12345:localhost:22 \ root@47.104.XXX.XXX🔍 参数解释
| 参数 | 含义 |
|---|---|
-R | 远程端口转发 |
12345 | 云服务器开放端口 |
localhost:22 | 映射到本机 SSH |
-N | 不执行命令 |
ServerAliveInterval | 心跳保活 |
ExitOnForwardFailure | 转发失败直接退出 |
🧪 五、验证连接
在云服务器 B:
ss -tln | grep 12345应看到:
0.0.0.0:12345在本地电脑 A:
ssh -p 12345 用户名@47.104.XXX.XXX连接成功 🎉
🔄 六、实现自动重连 + 开机自启(关键)
使用 systemd 创建服务。
1️⃣ 创建服务文件
sudo nano /etc/systemd/system/reverse-ssh.service写入:
[Unit] Description=Persistent reverse SSH tunnel After=network-online.target Wants=network-online.target [Service] Type=simple User=root ExecStart=/usr/bin/ssh \ -i /root/.ssh/aliyun.pem \ -o StrictHostKeyChecking=accept-new \ -o ServerAliveInterval=30 \ -o ServerAliveCountMax=3 \ -o ExitOnForwardFailure=yes \ -o TCPKeepAlive=yes \ -N -R 0.0.0.0:12345:localhost:22 \ root@47.104.XXX.XXX Restart=always RestartSec=10 [Install] WantedBy=multi-user.target2️⃣ 启动服务
sudo systemctl daemon-reload sudo systemctl enable reverse-ssh sudo systemctl start reverse-ssh3️⃣ 查看状态
systemctl status reverse-ssh💻 七、VS Code 远程连接
编辑本地 SSH 配置:
~/.ssh/configHost lab HostName 47.104.XXX.XXX Port 12345 User 实验室用户名VS Code Remote SSH 直接连接:
lab🌐 八、扩展:Jupyter / TensorBoard / Web服务
修改 service:
ExecStart=/usr/bin/ssh \ -i /root/.ssh/aliyun.pem \ -o ServerAliveInterval=30 \ -o ServerAliveCountMax=3 \ -N \ -R 0.0.0.0:12345:localhost:22 \ -R 0.0.0.0:8888:localhost:8888 \ -R 0.0.0.0:6006:localhost:6006 \ root@47.104.XXX.XXX对应服务
| 端口 | 服务 |
|---|---|
| 12345 | SSH |
| 8888 | Jupyter |
| 6006 | TensorBoard |
访问方式:
http://47.104.XXX.XXX:8888🧩 九、常见问题
❓ Q1:必须有公网 IP 吗?
❌ 不需要
✅ 只需要能访问外网
❓ Q2:为什么连接不上?
常见原因:
- 没开
GatewayPorts yes - 安全组没放行端口
- 端口被占用
❓ Q3:为什么端口是 127.0.0.1?
👉 没开启公网绑定
解决:
GatewayPorts yes🔥 十、最终效果
你将获得:
| 能力 | 是否支持 |
|---|---|
| SSH 远程 | ✅ |
| VS Code Remote | ✅ |
| Jupyter | ✅ |
| TensorBoard | ✅ |
| HTTP 服务 | ✅ |
| 自动重连 | ✅ |
| 开机自启 | ✅ |