如何让SSH隧道自动重启?
如何让SSH隧道自动重启?
我太懂你这种场景的烦恼了——靠iPhone USB共享5G在咖啡店干活,结果手机一拿开隧道就断,AutoSSH还报错,确实闹心。给你几个靠谱的解决方案,亲测能解决这种网络波动下的隧道自动重启问题:
1. 正确配置AutoSSH(大概率你之前参数没设对)
AutoSSH本身就是用来保持SSH连接的,但默认配置可能不适合你的网络环境。试试用下面的命令启动隧道:
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -L 本地端口:目标数据库地址:数据库端口 你的用户名@服务器地址
解释下关键参数:
-M 0:关闭AutoSSH自带的监控端口,改用SSH原生的心跳机制,更稳定ServerAliveInterval 30:每30秒给服务器发一次心跳包,检测连接状态ServerAliveCountMax 3:连续3次心跳没回应就判定连接断开,自动重启隧道
这样配置后,当手机拿回、网络恢复时,AutoSSH会自动重新建立隧道,而且不会像之前那样报错。
2. 用systemd服务托管隧道(彻底解放终端)
如果希望隧道在后台持续运行,哪怕你关掉终端也能自动重启,推荐用systemd创建一个服务:
- 创建服务配置文件:
touch ~/.config/systemd/user/ssh-db-tunnel.service
- 编辑文件,填入以下内容(记得替换成你的实际参数):
[Unit] Description=自动维持数据库SSH隧道 After=network.target [Service] ExecStart=/usr/bin/autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -L 5432:localhost:5432 your-name@your-server-ip Restart=always RestartSec=5 # 断开后5秒自动重试 User=你的Mac用户名 [Install] WantedBy=default.target
- 启用并启动服务:
systemctl --user enable --now ssh-db-tunnel.service
之后可以用这个命令查看状态:
systemctl --user status ssh-db-tunnel.service
不管是网络断开还是系统重启,这个服务都会自动帮你维持隧道。
3. 自己写个简单的监控脚本(灵活可控)
要是觉得AutoSSH太复杂,自己写个bash脚本也能搞定,逻辑就是循环检查隧道是否存活,挂了就重启:
#!/bin/bash # 替换成你的隧道参数 LOCAL_PORT=5432 REMOTE_DB_PORT=5432 SERVER_USER="your-name" SERVER_IP="your-server-ip" while true; do # 用nc命令检查本地隧道端口是否连通 nc -z localhost $LOCAL_PORT if [ $? -ne 0 ]; then echo "$(date): 隧道已断开,正在重启..." # 杀掉旧的SSH进程(避免残留) pkill -f "ssh -L $LOCAL_PORT:localhost:$REMOTE_DB_PORT $SERVER_USER@$SERVER_IP" # 后台启动新隧道 ssh -N -L $LOCAL_PORT:localhost:$REMOTE_DB_PORT $SERVER_USER@$SERVER_IP & fi # 每10秒检查一次 sleep 10 done
保存为tunnel-monitor.sh,加执行权限:
chmod +x tunnel-monitor.sh
然后后台运行:
./tunnel-monitor.sh &
这个脚本逻辑简单,你可以根据自己的需求调整检查间隔或者重试逻辑。
最后提醒
不管用哪种方法,一定要配置SSH密钥登录,不然自动重启的时候会卡在输入密码的环节,导致隧道无法重建。
备注:内容来源于stack exchange,提问作者Thomas




