树莓派放家里宽带上运行,希望能在外随时随地控制,但宽带又没有公网 IP,怎么从外网访问内网的树莓派呢?如果手边有个公网 VPS 的话,那这个问题就可以使用反向 SSH 隧道解决了。
在树莓派终端运行下面的命令,可以建立一个简单的 SSH 反向隧道。
$ ssh -R *:2222:localhost:22 vps
vps
是我的一条 ssh 连接项目。-R
表示建立反向隧道,*:2222:localhost:22
表示将远程2222
端口上的数据转发到本地22
端口,其中*
表示监听远程机器上的所有 interface(默认只监听远端的 localhost,这里的星号也可写作0.0.0.0
),最后启动本地 sshd 服务端。
像下面这样就能 SSH 连接到内网的树莓派了。x.x.x.x
是 VPS 的 IP,-p
通过端口2222
连接。
$ ssh -p 2222 alarm@x.x.x.x
然后把它完善下,做成一个服务。我希望达成的目标是这样的:开机自动启动 SSH 反向隧道,SSH 连接丢失或超时则自动重连,如果断网的话就关机。
树莓派系统为 Archlinuxarm(systemd 系统都可)的话,在目录/etc/systemd/system/
中新建ssh-reverse.timer
[Unit]
Description=Reverse SSH Tunnel on VPS
Wants=network-online.target
After=network-online.target network.target
[Timer]
OnActiveSec=10
[Install]
WantedBy=multi-user.target
再在这个目录中新建ssh-reverse.service
[Unit]
Description=Reverse SSH Tunnel on VPS
Wants=network-online.target
After=network-online.target network.target
OnFailure=check-internet.timer
[Service]
User=alarm
ExecStart=/usr/bin/ssh -NTC -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -o StrictHostKeyChecking=no -o ConnectTimeout=2 -R *:2222:localhost:22 vps
RestartSec=3
Restart=always
[Install]
WantedBy=multi-user.target
然后设置断网后自动关机的逻辑。还是在此目录中新建check-internet.timer
[Unit]
Description=Check Internet Connectivity
Wants=network-online.target
After=network-online.target network.target
[Timer]
OnActiveSec=20
RemainAfterElapse=false
[Install]
WantedBy=multi-user.target
再新建check-internet.service
[Unit]
Description=Check Internet Connectivity
Wants=network-online.target
After=network-online.target network.target
StartLimitIntervalSec=20
StartLimitBurst=3
StartLimitAction=poweroff
[Service]
ExecStart=/bin/sh -c 'timeout 2 ping -c1 www.baidu.com >/dev/null'
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
最后运行# systemctl enable ssh-reverse.timer
开机启动ssh-reverse.timer
。另外,不要忘了安装timeout
和ping
这两个 shell 程序。
最后的效果:联网时,树莓派自动建立反向隧道,网络短时波动则自动重连;断网时,最长一分钟后自动关机。