内网穿透单个服务快捷实现记录

1
2
3
4
5
6
7
8
9
10
11
[你的Docker容器(内网)]               [跳板机(云服务器)]                      [外网用户]
| | |
| 容器内业务服务(如8080端口) | SSH服务端 |
| 容器内安装autossh | (配置GatewayPorts=yes) |
| ↓ | ↓ |
| autossh建立反向隧道 | 监听0.0.0.0:8080 |
| -R 8080:localhost:8080 --------------->| (公网可直接访问) |
| | ↓ |
| | 外网用户访问: |
| | curl http://云服务器IP:8080 |
| | ✅ 直接成功 |

内网机器

安装autossh

1
apt-get update && apt-get install -y autossh openssh-client

配置 SSH 免密登录到跳板机

1
2
3
4
5
6
7
8
9
10
# 1. 生成SSH密钥对
ssh-keygen -t rsa -b 4096
# 一路回车使用默认路径

# 2. 将公钥复制到跳板机
ssh-copy-id root@<你的云服务器IP>

# 3. 测试免密登录(第一次连接需要确认指纹)
ssh root@<你的云服务器IP>
# 应该直接登录成功,不需要输入密码

在容器内运行autossh

1
2
# 用autossh(-M 0 表示禁用内置监控端口,使用SSH的保活机制)
autossh -M 0 -fNTR 8080:localhost:8080 root@<你的云服务器IP>

命令参数说明

  • -M 0:禁用 autossh 的监控端口,改用 SSH 的 ServerAliveIntervalServerAliveCountMax 机制保活
  • -f:后台运行
  • -N:不执行远程命令,只建隧道
  • -T:禁用伪终端分配
  • -R 8080:localhost:8080:反向隧道,将跳板机的8080端口转发到容器内的8080端口

跳板机

确保跳板机有公网ip

1
2
3
4
5
6
# 查看端口监听情况
netstat -tulnp | grep 8080
# 应该看到 0.0.0.0:8080 在监听,而不是 127.0.0.1:8080

# 如果只看到127.0.0.1,需要检查跳板机的sshd_config
# 确保设置了 GatewayPorts yes

应该看到这样的输出

1
2
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      409690/sshd: root
tcp6 0 0 :::8080 :::* LISTEN 409690/sshd: root

如果没有,杀死原有的autossh进程,重新建立隧道