You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Bash脚本SSH远程机器后创建并维持SSH隧道

解决SSH隧道创建失败并维持存活的问题

我来帮你分析问题出在哪,然后给出可行的修复方案:

问题根源

你原来的脚本写法有个关键错误:ssh ${2}@${3} 后面的 ssh -L ... 并没有被发送到远程服务器执行。因为当你直接运行 ssh user@host 不带任何命令时,SSH会启动交互式登录会话,此时后续的命令会被挂起,直到你退出远程会话才会在本地执行——这就是为什么你只看到了远程服务器的系统信息,隧道根本没创建。

修正后的脚本写法

要让隧道命令在远程服务器上执行,你需要把它作为第一个SSH命令的远程执行参数,同时加上合适的参数让隧道后台运行、避免交互问题:

#!/bin/bash
# 脚本:ssh_to_box.sh
sshpass -p "${1}" ssh -t "${2}@${3}" "ssh -fN -L <port1>:<host>:80 -i /home/<user>/private_key <user_ID>@<host2>"

参数解释:

  • -t:强制为远程会话分配伪终端,避免某些服务器因缺少TTY而拒绝执行后续SSH命令
  • -f:让创建隧道的SSH进程fork到后台运行,不会占用当前终端
  • -N:告诉SSH只做端口转发,不执行任何远程命令,节省资源且更适合隧道场景
  • 用双引号包裹远程命令:确保所有参数(比如带特殊字符的路径)能正确传递到远程服务器

维持隧道存活的优化方案

默认情况下,SSH隧道如果长时间没有流量,可能会被防火墙或路由器断开。你可以通过以下两种方式确保隧道持续存活:

1. 用SSH内置参数保活

在创建隧道的SSH命令中添加存活检测参数:

#!/bin/bash
sshpass -p "${1}" ssh -t "${2}@${3}" "ssh -fN -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -L <port1>:<host>:80 -i /home/<user>/private_key <user_ID>@<host2>"
  • ServerAliveInterval=60:每60秒向目标服务器发送一次存活信号
  • ServerAliveCountMax=3:如果连续3次没收到回应,才断开连接(避免临时网络波动导致隧道中断)

2. 用autossh自动重连(更可靠)

如果你的远程服务器上安装了autossh(可以通过sudo apt install autossh安装),可以用它来自动检测隧道状态并重连:

#!/bin/bash
sshpass -p "${1}" ssh -t "${2}@${3}" "autossh -M 0 -fN -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -L <port1>:<host>:80 -i /home/<user>/private_key <user_ID>@<host2>"
  • -M 0:禁用autossh的监听端口,仅依赖SSH的ServerAlive机制检测连接状态,减少资源占用

重要注意事项

  • 替换脚本中的<port1>、<host>、<user>、<user_ID>、<host2>为你的实际信息
  • 确保远程服务器上的密钥文件/home/<user>/private_key权限设置为600(chmod 600 /home/<user>/private_key),否则SSH会拒绝使用该密钥
  • 如果密码包含空格或特殊字符,脚本中的"${1}"双引号必须保留,避免参数被拆分

内容的提问来源于stack exchange,提问作者vectyvec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:59:21