Chipmunk & Panda

-- 鼠熊部落格

All work and no play makes Jack a dull boy.

Ubuntu 使用 SSH 反向通道实现外网访问内网设备

1 背景

设置三台设备,分别为校园网服务器、家庭网主机、外网云服务器。三台设备均可访问外网,但由于校园网与家庭网互不连通且无公网 IP,相互无法直接访问。现需要借助外网云服务器,实现由家庭网主机访问校园网服务器。

2 解决方案

2.1 SSH 原生命令

SSH 本身支持反向通道,故可以从校园网服务器向外网服务器发起请求,建立一个反向通道,使得家庭网主机可以以外网服务器为跳板,访问校园网服务器。

假设外网服务器 IP 为 123.123.123.123 且 SSH 端口默认为 22,正常情况下,使用 SSH 以 root 用户访问外网服务器的命令可能为:

1
ssh root@123.123.123.123

为了建立反向通道,需要在连接时增加选项 -R,该选项用于远程端口转发,允许将远程主机上的端口转发到本地(必须要以 root 用户登录到远程主机):

1
ssh -fCNR 12345:localhost:22 root@123.123.123.123

上述代码的含义为:使用 root 用户连接到设备 123.123.123.123,并监听该设备的 12345 端口,将到达该端口的消息转发至 IP 为 localhost 的设备(即本地)的 22 端口。

还额外增加了几个选项:

  • -f:后台运行 SSH 客户端。
  • -C:压缩数据传输。
  • -N:不执行远程命令。

在校园网服务器上运行该代码后,便完成了反向通道的建立,此时,便可以在家庭网主机上通过访问外网服务器的 12346 端口,实现对校园网服务器的访问:

1
ssh -p 12345 me@123.123.123.123

最后,建议实现校园网服务器到外网服务器的 SSH 免密登录,以便于在校园网服务器上运行反向通道的命令(否则每次都需要输入密码)。

在校园网服务器上,执行 ssh-keygen 生成密钥对,并将公钥添加至外网服务器的 ~/.ssh/authorized_keys 文件中:

1
2
ssh-keygen
ssh-copy-id root@123.123.123.123

即可无密码连接外网服务器。

2.2 AutoSSH

可以借助 AutoSSH,自动在反向通道完蛋时重新建立。
Ubuntu 下,可以直接安装:

1
sudo apt install autossh

使用方法与 SSH 基本相同,只是多了一个 -M 选项,用于指定监控端口:

1
autossh -M 12346 -fCNR 12345:localhost:22 root@123.123.123.123

上述代码的含义为,使用本地端口 12346 监控反向通道的状态,当反向通道断开时,自动执行后面的语句 (ssh) -R 12345:localhost:22 root@ 重新建立。

2.3 服务化

为了使得反向通道能够在系统启动时自动建立,可以将 AutoSSH 服务化,实现开机自启。

以下内容针对 Ubuntu 22.04,不同版本或其他发行版下操作可能不同。

创建一个新的服务文件:

1
sudo vim /etc/systemd/system/autossh-tunnel.service

文件内容形如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=Auto SSH Tunnel
After=network-online.target
Requires=network-online.target

[Service]
User=root
Type=simple
ExecStart=/bin/autossh -M 12346 -fCNR 12345:localhost:22 root@123.123.123.123
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process

[Install]
WantedBy=multi-user.target
WantedBy=graphical.target

大概注意点包括:

  • After:依赖网络服务。
  • Requires:依赖网络服务。
  • User:服务运行用户。
  • ExecStart:服务启动命令。
  • ExecReload:服务重载命令。

可根据需要自行对服务文件进行修改。

保存文件后,启动服务,并设置开机自启:

1
2
sudo systemctl start autossh-tunnel
sudo systemctl enable autossh-tunnel

现在可重启校园网服务器,检查反向通道是否自动建立。