如何才能再次建立已“断开”但仍处于连接的反向 SSH 隧道?

如何才能再次建立已“断开”但仍处于连接的反向 SSH 隧道?

我有一台远程 Raspberry Pi 计算机,它通过反向 SSH 隧道从其限制性防火墙后面连接到我的服务器。想象一下,这台 Raspberry Pi 位于另一个国家/地区难以进入的建筑物屋顶上(可能正在下暴风雨),所以我希望它的连接可靠。

为了连接到服务器,Raspberry Pi 运行如下过程:

while true; do
    ssh -R 19999:localhost:22 www.sern.pro
    sleep 30
done

这部分19999:localhost:22基本上意味着服务器上端口 19999 上的所有流量都应转发到 Raspberry Pi 的端口 22。因此,我可以通过 SSH 连接到服务器,然后运行以下命令来连接到 Raspberry Pi:

ssh localhost -p 19999

这通常可以正常工作,并且在服务器上,netstat --all --timers --program --numeric | egrep '127.0.0.1:*(LISTEN|.*)' | sort类似这样的命令会列出反向 SSH 连接,如下所示:

tcp        0      0 127.0.0.1:19999         0.0.0.0:*               LISTEN      2972/5           off (0.00/0/0)

然而,偶尔我发现服务器上的这个列表消失了Raspberry Pi 仍保持与服务器的 SSH 连接也就是说,该命令ssh localhost -p 19999会导致如下错误信息:

ssh: connect to host localhost port 19999: Connection refused

然而,Raspberry Pi SSH 连接仍然完好无损,能够在服务器上运行命令。当发生这种情况时,我不知道该用什么词来描述出了什么问题。

那么……除了预订航班和爬上楼顶,我怎样才能再次将此活动的 SSH 连接作为正确的反向 SSH 隧道?我如何才能再次访问本地端口?

答案1

十多年前,autossh人们就为这样的目的编写了实用程序。

您可以使用以下连接脚本

#!/bin/sh
export AUTOSSH_GATETIME=0 

autossh -M 0
-o "PubkeyAuthentication=yes" \
-o "StrictHostKeyChecking=false" \
-o "PasswordAuthentication=no" \
-o "ExitOnForwardFailure=yes" \
-o "ServerAliveInterval 60" \
-o "ServerAliveCountMax 3" \
-fNR 19999:localhost:22 www.sern.pro

当然,您需要在启动此脚本之前建立基于密钥的身份验证。

答案2

您看到的问题意味着连接不可用,如果您在列出所有连接的命令末尾检查,您可能会看到该端口的连接不再处于 LISTEN 状态,而是处于 TIME-WAIT 或 CLOSE-WAIT 状态,这意味着连接仍然“活跃”,但仅作为 raspberry 中的运行进程。

为了使其正常工作,您可以创建一个脚本,如果尚未设置,则检查是否存在 reversessh 连接。

为了解决这个问题,您可以向脚本中添加代码来检查设备上是否有 ssh 进程 id,如果您有一个标记文件,那么您可以终止该进程以重新启动隧道。

例如,您有一个名为 RESTARTSSH 的空文件,您可以在脚本中检查该文件是否存在,如果存在,则搜索 ssh 的进程 id 并将其终止,然后重新启动隧道。

要检查进程 ID,您可以使用:

ps -ef | grep ServerAliveInterval | grep -v grep | awk '{print $2}'

相关内容