如何使反向 SSH 连接保持长期可访问?

如何使反向 SSH 连接保持长期可访问?

我有一台服务器,还有一台位于一个不方便的网络后面的桌面。为了远程访问我的桌面,我让它与我的服务器保持反向 SSH 连接,然后我可以通过它正在使用的任何反向 SSH 端口通过 SSH 连接到我的服务器和桌面。

具体来说,我的桌面正在运行一个小 Bash 脚本,如下:

#!/bin/bash
while true; do
    ssh -X -R 19123:localhost:22 http://www.example.pro/
    sleep 1000
done

然后,在服务器上,可以使用以下命令访问桌面:

ssh localhost -p 19123

这似乎工作正常。连接可以可靠地维持和重新建立,我可以从桌面在服务器上运行命令等,验证连接确实处于活动状态。

然而过了一段时间,比如几天后,桌面就无法从服务器访问了。在桌面上,连接处于活动状态,但在服务器上返回了以下错误消息:

ssh: connect to host localhost port 19123: Connection refused

有人能猜到会发生什么吗?更重要的是,考虑到服务器无法定期重启等,有人能建议如何防止这种情况发生吗?

答案1

让你的 ssh 时不时地发送一个 keepalive 数据包来提供帮助。

在您的~/.ssh/config文件中添加以下内容:

Host *
ServerAliveInterval 15

这应该在服务器和客户端上进行设置。

您可以将上面的数字更改为您想要的任何数字。这是每 15 秒设置的,我的服务器连接似乎保持正常,没有任何问题。

希望这可以帮助!

答案2

正如@Terrance所说,您应该使用keepalive来保持连接打开。但是,为了提高稳定性,我还建议使用来autossh监控ssh连接。由于它不是默认安装的,因此您需要使用来安装它sudo apt install autossh

安装后,您可以像这样执行它:

/usr/bin/autossh -f -o "ServerAliveInterval 900" -TN -R30582:localhost:5724 [email protected]

这将设置一个到 的 ssh 隧道[email protected]。请注意,任何无法理解的选项autossh都会传递给ssh自身。

它也不会分配伪终端,从而节省了资源。

这很好,但我们可以做得更好。为了使其永久和自动化,我们可以设置一个 systemd 服务。在其中创建一个/etc/systemd/system后缀为 的文件.service,并在其中放入如下内容:

[Unit]
Description=SSH tunnel

[Service]
Type=forking
Environment=AUTOSSH_PIDFILE=/var/run/ssh-tunnel/ssh-tunnel.pid
PIDFile=/var/run/ssh-tunnel/ssh-tunnel.pid
ExecStartPre=/bin/mkdir -p /var/run/ssh-tunnel
ExecStartPre=-/bin/chown username:username /var/run/sbrl-ssh-tunnel
ExecStart=/bin/sh -c 'until ping -c1 bobsrockets.io &>/dev/null && sleep 5; do :; done && /usr/bin/autossh -f -o "UserKnownHostsFile /home/username/.ssh/known_hosts" -o "IdentityFile /home/username/.ssh/ssh-tunnel_ed25519" -o "PubkeyAuthentication=yes" -o "PasswordAuthentication=no" -o "ServerAliveInterval 900" -TN -R30582:localhost:5724 -p 7261 [email protected]'

[Install]
WantedBy=network-online.target

这里有几点值得注意:

  • username应替换为autossh将在以下情况下运行的本地用户帐户
  • 我禁用密码验证,并在此处启用公钥验证,以便它可以在没有任何外部干预的情况下启动。确保在服务器上创建一个ssh-tunnel没有 shell 的特殊帐户(在我的示例中),并确保在安装此服务文件之前设置公钥并对其进行测试。
  • -p 7261用于指定要连接的远程服务器上的目标端口。如果需要,请更新它,否则如果不需要,请删除它。
  • known_hosts我使用选项指定文件的位置UserKnownHostsFile,因为当作为 systemd 服务运行时autossh似乎无法找到它。确保将其指向合适的known_hosts文件,以便可以自动打开 ssh 连接。
  • 我使用了一些 shell 脚本 ( until ping -c1 bobsrockets.io &>/dev/null && sleep 5; do :; done) 来确保它等到我们能够到达目标主机后再启动 autossh。否则我会遇到问题。
  • -f在这里用于获取autosshfork。这可以避免无用的sh进程闲置。

来源

  • 我曾在博客中提到过此事这里
  • 我原本读过本文,其中更详细地解释了 autossh 的一些不同选项,如果您需要的话。

相关内容