如何重新连接到断开连接的 ssh 会话

pal*_*rse 185 linux ssh gnu-screen

有没有办法连接到已断开连接的 ssh 会话?我们的网络连接到我们单独处理的远程站点时遇到问题;然而,与此同时,由于在连接到远程位置的服务器时丢失数据包,我们会遇到大量断开连接的情况。很多时候会话会保持活动一段时间,有时它恰好处于某些操作(文件编辑、运行某些进程等)的中间,如果可能的话,我需要返回而不是重新启动。

zer*_*o_r 168

尝试在服务器端 sshd.conf 上将 ClientAliveInterval(例如 60)和 TCPKeepAlive(是或否)设置为适当的值。

即使连接丢失几分钟,这也应该使您的会话保持活动状态。

  • 到目前为止,您似乎是唯一一个实际回答问题的人,而不是建议使用屏幕作为解决方法。 (30认同)
  • 也许这不是问的正确地方,但发帖人可以切换答案吗?我们应该将“筛选”答案(我的不是最好的,我喜欢 Mike Pountney 的,但我得到了代表)包含这些信息。 (7认同)
  • 好决定。我们发现这种方法在穿越 cisco ASA/PIX 防火墙时特别有用,默认情况下它喜欢超时 tcp 连接。 (3认同)

kby*_*yrd 151

更新:有关实际答案,请参阅下面的 zero_r 答案

这不是答案,而是一种解决方法。使用屏幕

首次登录时,运行 screen。你得到另一个shell,在里面运行命令。如果您断开连接,screen 进程会使终端保持活动状态,这样您的 shell 及其正在运行的进程就不会发生故障。当您重新连接时,运行“screen -r”以恢复。

配置和使用屏幕还有很多,但以上应该可以解决您的问题。

  • 或者使用 tmux - 一个“更酷”的屏幕,我两个都用过,而且更喜欢 tmux,因为你可以很好地拆分这个术语。 (20认同)
  • 我很高兴地发现我的 Ubuntu 12.x 上已经安装了 `screen`,所以如果你不确定试试这个命令,它会重新连接并恢复 *do-release-upgrade* 进程:sudo screen -D -r (3认同)

Mik*_*ney 70

如上所述,GNU Screen是要走的路。它将允许您在远程框上有一个“屏幕会话”,您可以通过多个“屏幕窗口”在其中运行多个命令。如果您的父 SSH 连接挂了,这将简单地分离,保持其中运行的所有子进程保持活动状态。

man screen”像往常一样是您的朋友,screen如果默认情况下未安装操作系统包,则应将其称为“ ”。

基础是:

很多很酷的东西你可以用屏幕做。我已经使用它超过 10 年了,仍然在寻找新功能。这是我最喜欢的 Unix 实用程序。


jwb*_*ley 57

我不敢相信没有人提到过MOSH

Mosh 是一个单独的协议,可以连接到 SSH 登录过程中,它可以让您的会话在断开连接、更改 IP、高延迟等几天后保持活动状态。它在主页上的解释比我能解释的要好,所以我复制了下面的描述。我的经验和建议是,我在我的 Android 手机上使用它,它是旅行和 SSH 时的救星。例如,当我在火车上连接手机时,我的笔记本电脑也是如此。我建议从源代码编译以获得最新版本,我在 Ubuntu 中的 repo 版本有一些烦恼,这些烦恼在最新版本中得到了修复(在撰写本文时)。

Mosh(移动外壳)

允许漫游的远程终端应用程序,支持间歇性连接,并提供用户按键的智能本地回声和线路编辑。

Mosh 是 SSH 的替代品。它更加强大和响应迅速,尤其是通过 Wi-Fi、蜂窝和长途链接。

Mosh 是免费软件,可用于 GNU/Linux、FreeBSD、Solaris、Mac OS X 和 Android。

来自网站的功能:

  • 更改 IP。保持连接:当您在 Internet 连接之间移动时,Mosh 会自动漫游。在火车上使用 Wi-Fi、在酒店使用以太网以及在海滩上使用 LTE:您将保持登录状态。大多数网络程序在漫游后都会失去连接,包括 SSH 和 Gmail 等网络应用程序。莫什不一样。

  • 美梦成真:使用 Mosh,您可以让您的笔记本电脑进入睡眠状态,稍后再将其唤醒,从而保持连接完好无损。如果您的 Internet 连接中断,Mosh 会警告您 - 但当网络服务恢复时连接会恢复。

  • 摆脱网络延迟:SSH 在显示您自己的输入之前等待服务器的回复。这可能会导致糟糕的用户界面。Mosh 不同:它对打字、删除和行编辑提供即时响应。它自适应地执行此操作,甚至可以在 emacs 和 vim 等全屏程序中运行。在连接不良的情况下,突出的预测带有下划线,因此您不会被误导。

  • 没有特权代码。无守护进程:您无需成为超级用户即可安装或运行 Mosh。客户端和服务器是由普通用户运行的可执行文件,并且仅在连接的生命周期内持续。

  • 相同的登录方法:Mosh 不侦听网络端口或验证用户。mosh 客户端通过 SSH 登录到服务器,用户提供与之前相同的凭据(例如,密码、公钥)。然后 Mosh 远程运行 mosh-server 并通过 UDP 连接到它。

  • 在您的终端内运行,但更好:Mosh 是一个命令行程序,就像 ssh。您可以在 xterm、gnome-terminal、urxvt、Terminal.app、iTerm、emacs、screen 或 tmux 中使用它。但是 mosh 是从头开始设计的,只支持一种字符集:UTF-8。它修复了其他终端和 SSH 中的 Unicode 错误。

  • Control-C 效果很好:与 SSH 不同,mosh 基于 UDP 的协议可以优雅地处理数据包丢失,并根据网络条件设置帧速率。Mosh 不会填满网络缓冲区,因此 Control-C
    总是可以阻止失控的进程。

  • Mosh 不是 ssh 包装器——它是一种不同的协议,几乎与 ssh 完全无关(它只使用 ssh 进行登录)。 (8认同)
  • 安全怎么样,中间的人?加密?密钥交换? (5认同)
  • @NasirIqbal 提出了一个很好的观点。MOSH 似乎使用基于 UDP 构建的定制设计协议,并将其自己的密码套件组合在一起,而不是使用 DTLS。从粗略的谷歌搜索来看,除了 MOSH 之外似乎没有人使用这个协议。考虑到 SSH 会话保护的潜在重要性以及 SSH 是地球上经过最久经考验的协议之一,我不得不说,这让我更喜欢简单的 SSH+Tmux/Screen,尽管 MOSH 确实有很多不错的功能。我会饶有兴趣地观看这个项目,因为它看起来确实很酷。 (4认同)

hay*_*lci 22

autossh 监视您的连接,如果连接断开,它会重新连接。它比保活更可靠。如果您连接到 screen 会话,您将从断开连接的地方继续(请参阅rscreenautossh 附带的内容)

  • 在可配置的保持活动之外,它本质上不允许您重新连接到会话(OP 正在寻找什么)。但是 autossh 对于需要 ssh 隧道、端口映射等的应用程序真的很有帮助。 (2认同)

Jac*_*nkr 19

多路复用器

这是一部经典之作。每当您冒着与终端失去连接的风险时,就使用它。

$ tmux
$ sh do_something_that_takes_forever

!! Connection fails so you reconnect once you notice

$ tmux ls
0: 1 windows (created Tue Aug 23 12:39:52 2011) [103x30]

$ tmux attach -t 0
Run Code Online (Sandbox Code Playgroud)

就这样,你又回来了。


wzz*_*zrd 10

我会安装并启动屏幕来解决您的问题。Screen 将让您重新连接到上一个屏幕会话。

除此之外,screen 还可以让你做一些很酷的事情,比如分屏、查看控制台等。你可以在这里这里找到更多信息。

首先,如果您断开连接,您可以使用

screen -ls
Run Code Online (Sandbox Code Playgroud)

查看您的会话和

screen -r ${session} 
Run Code Online (Sandbox Code Playgroud)

重新连接到一个断开连接的。


小智 10

用于reptyr将正在运行的程序重新设置为新终端的父级。

如何:

假设我们已经ssh从某个先前的 IP 地址连接到aaa.bbb.ccc.old
然后运行aptitude进程,并且在工作过程中连接断开了。

我们再次登录ssh(可以选择从不同的 IP 地址aaa.bbb.ccc.new)。
当前连接使用pty/1伪终端:

$ tty 
/dev/ pts/1

但是有 2 个打开的连接,当前的pts/1连接和旧的断开连接,使用pts/0

$
用户     pts/0         2022-02-22 22:00 ( aaa.bbb.ccc.old )
用户     pts/1         2022-02-22 22:11 ( aaa.bbb.ccc.new )

让我们列出所有 shell 及其子进程:

$ ps auf
用户 PID %CPU %MEM VSZ RSS TTY STAT 启动时间命令
用户        2000   1.3 0.5 10168 5236点/1     Ss 22:11 0:00 -bash
用户        
2001 0.0 0.3 10620 3304 点/1 R+ 22:11 0:00 \_ ps auf用户1000   0.0 0.5 10168 5132点/0     SS 22: 00 0:00 -bash
用户 1001 5.8 16.0 46639 15839 点/0 Sl+ 22:00 0:03 \_ aptitude
根 820 0.0 0.1 5836 1840 tty1 Ss+ 22:00 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
根 810 0.0 0.2 7360 2260 ttyS0 Ss+ 22:00 0:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyS0 vt220

有 2 个bashshell:
当前的pts/1PID2000运行的 shellps auf
和旧的损坏的pts/0PID1000运行的shellaptitude

让我们重新连接到旧的reptyr

$ 须藤reptyr -T 1000

这样我们就可以访问旧的 shell 及其子进程。
由于 aptitude 使用ncurses,您可能需要按Ctrl+L或调整终端仿真器窗口的大小以强制其重新绘制自身。
现在我们可以退出aptitude,然后退出旧 shell ( 1000),
从而返回到新 shell ( 2000),只剩下 1 个连接,即当前连接:

$
用户     pts/1         2022-02-22 22:11 ( aaa.bbb.ccc.new )


mar*_*ppy 6

有时我也忘记运行 screen 并且丢失了我未完成的工作。在这种情况下,尽管我们无法重新连接到损坏的 SSH 会话,但由于reptyr.

从 SSH 会话意外断开连接后,第一件事是运行,screen以免连接再次中断。然后在新会话中,运行ps aux | grep {The process to be resumed}以获取 PID。使用 PID,您可以尝试reptyr {PID}reptyr -T {PID}(如果有子进程)继续工作。

  • 非常好的解决方案!提示:如果服务器上还没有安装reptyr,并且需要恢复的中断会话已经是`apt update`之类的包管理操作,那么现在就无法`apt install reptyr`:可以只scp将 reptyr 可执行文件发送到服务器,然后按照此处所述运行它。 (4认同)