如果存在 ssh 隧道,则销毁它并创建新的

如果存在 ssh 隧道,则销毁它并创建新的

我在操作系统重启后打开了一个反向 ssh 隧道(在办公室电脑上到专用服务器)。我通过 将其放入 cron@reboot /myssh.sh中。ssh 在服务器上打开一个端口。
我的问题是:
如果操作系统(办公室电脑)突然死机并再次启动,则 cron 将再次运行脚本,而服务器上的端口仍被上一个会话使用,当然 ssh 将失败(因为它试图打开服务器上的开放端口)。这就是为什么如果办公室电脑重新启动,我无法从服务器访问办公室电脑的原因。
问题:

  1. 如何在办公室电脑上重新打开反向 ssh 之前检查服务器上的 ssh 或端口(并结束上一个会话)?
  2. 我是否必须通过访问器端(服务器)或主机端(办公室电脑)来完成此操作?


目标
我希望无论发生什么情况,ssh 隧道都能保持活动状态。如果互联网连接丢失,只要互联网可用,我仍然可以访问办公室电脑。

答案1

使用控制插座

我刚刚发现了似乎最正确的方法自动SSH

然而多路复用是一个非常大的课题,可以用于其他事物。来源

这个想法Bash 脚本设置...是使用和集成方法称为控制插座。通过此方法,您可以命令关闭旧连接。但是您必须测试此方法在重启后是否有效。

您的要求是:

终止远程服务器上的进程

隧道是在远程机器上运行的一个进程。您可以生成一个脚本来验证隧道的先前实例是否正在运行。

假设这ssh -f -R XXXXX:localhost:YYYYY user@server -N是您的原始命令。XXXXX代表远程服务器上使用的端口,YYYYY 代表本地计算机上的端口。

XXXXX然后,您可以使用以下命令检查远程服务器上没有进程正在监听端口lsof。但是你需要能够使用sudo为了获取进程 ID(进程号) 是监听该端口的程序。

一旦你找到进程号使用端口,您只需在服务器上运行命令即可kill thePID

用于获取 PID 的 Bash 脚本

下面的脚本应该显示进程号正在监听XXXXX并保存在/tmp/remTunPID。如果您的用户没有须藤访问它将不起作用,出于安全原因,PID 将不可见。

脚本:

#!/bin/bash
rPort=XXXXX
theUser=[replace with remote user name]
server=[replace with your server]
if [ -a /tmp/sshPID1 ]
   then
      rm /tmp/sshPID1
fi
if [ -a /tmp/sshPID2 ]
   then
      rm /tmp/sshPID2
fi
if [ -a /tmp/remTunPID ]
   then
      rm /tmp/remTunPID
fi
echo "Enter [sudo] password for ${theUser}:"
ssh -t $theUser@$server "sudo lsof -i tcp:${rPort} | grep  IPv4" > /tmp/sshPID1
while read -a A; do echo ${A[6]}; done < /tmp/sshPID1 > /tmp/sshPID2
cat /tmp/sshPID2 | grep -v pass | tee /tmp/remTunPID
if [ -s /tmp/remTunPID ]
   then
      thePID=$(cat /tmp/remTunPID)
      echo The process $thePID is running at $server listening to $rPort
   else
      echo No process is listening on $rPort at $server
fi

将 和rPort的值分别更改为您的远程端口、远程用户和服务器(域或 IP)的值。theUserserver

此命令将提示您输入须藤密码才能继续,但如果你懂一点,不用担心狂欢你可以看到它被直接请求远程控制带有-t选项。

实际终止进程

您可以在此脚本的语句中添加一个命令if then else fi来终止该进程:

if [ -s /tmp/remTunPID ]
   then
      thePID=$(cat /tmp/remTunPID)
      echo The process $thePID is running on $server and listening on $rPort
      echo Will attempt to kill $thePID
      ssh $theUser@$server "kill ${thePID}"
   else
      echo No process is listening on $rPort
fi

仅当端口正在使用时,此操作才会终止进程。但即使您的机器最初没有启动隧道,它也会终止进程。

自动SSH

自动SSH似乎是处理您想要实现的目标的好工具。也许你应该看看。 来源

相关内容