为什么当 SSH 连接中断时控制台有时会永远挂起?

为什么当 SSH 连接中断时控制台有时会永远挂起?

我在许多控制台(Linux、Mac 等)以及许多不同网络中的许多不同机器上都看到过这种情况。我永远无法确定发生这种情况的确切原因:您所要做的就是通过 SSH 登录到机器。如果连接由于某种原因中断(为简单起见,假设网线被拔掉),那么有时控制台会永远挂起 - 有时,它会正常退出到父 shell。

发生这种情况时真的很烦人(例如,您会丢失命令历史记录。)是否有一个秘密的键盘快捷键可以强制退出(Ctrl-C 或 Ctrl-D 不起作用)?而且,在所有实现中出现这种随机“错误”的原因到底是什么?

答案1

有一个“秘密”的键盘快捷键可以强制退出:~) 从冻结的会话中,按顺序按下这些键:Enter~.波浪号(仅在换行符后)被 ssh 客户端识别为转义序列,句点告诉客户端立即终止其业务。

通信问题上的长时间挂起行为不是错误,SSH 会话挂起,希望另一方能够恢复。如果网络中断,有时甚至几天后您都可以恢复 SSH 会话。当然,您可以使用上述序列明确地告诉它放弃并终止。您还可以做各种事情,例如在客户端中设置保持活动超时,这样如果它在一定时间内没有活动链接,它就会自行关闭,但默认行为是尽可能保持连接!

编辑:此中断键的另一个有用的应用是引起本地 ssh 客户端的注意,并将其置于后台,以便返回到您的本地 shell 一分钟 - 比如从历史记录中获取一些内容 - 然后将其置于后台以继续远程工作。Enter~ Ctrl+Z将 ssh 客户端发送到本地 shell 的后台作业队列,然后fg像往常一样将其取回。

编辑:处理嵌套的 SSH 会话时,您可以添加多个波浪号,以便只退出链中的一个 SSH 会话,但保留其他会话。例如,如果您嵌套在 3 个级别中(即,您从本地->Machine1->Machine2->Machine3 进行 ssh),Enter~.将使您返回到本地会话,Enter~~.将使您留在 Machine1 中,并将Enter~~~.使您留在 Machine2 中。这也适用于其他转义序列,例如将 ssh 会话暂时移至后台。上述方法适用于任何级别的嵌套,只需添加更多波浪号即可。

最后,您可以使用Enter~?打印可用退出命令的帮助菜单。

TL;DR - 支持的转义命令是支持的转义序列:

 ~.   - terminate connection (and any multiplexed sessions)
 ~B   - send a BREAK to the remote system
 ~C   - open a command line
 ~R   - request rekey
 ~V/v - decrease/increase verbosity (LogLevel)
 ~^Z  - suspend ssh
 ~#   - list forwarded connections
 ~&   - background ssh (when waiting for connections to terminate)
 ~?   - this message
 ~~   - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

答案2

SSH 提供了保持活动的功能。将以下内容添加到本地~/.ssh/config(如果不存在则创建):

ServerAliveInterval 15
ServerAliveCount 3

此设置将建立通过安全隧道每 15 秒发送一次的保持活动信号。连续三次失败后,SSH 客户端将退出。

请注意,在某些系统(包括 macOS 10.14)上,它需要是:

ServerAliveInterval 15
ServerAliveCountMax 3

摘自 ask.ubuntu 上的这个答案:https://askubuntu.com/a/29967/30266

答案3

它挂起是 TCP 的功能,而不是 SSH 的功能。除非 TCP 通知使用该连接的应用程序该连接不再存在,否则应用程序无法知道 TCP 会话/连接已断开。从每个主机的角度来看,TCP 会话仍处于已建立状态,除了 RST 或对 TCP 保持活动数据包缺乏响应(这并未普遍实现)之外,没有什么可以说长时间空闲(没有数据流)会话无效。在我看来,这似乎不是 SSH 中的错误,我期望这种行为。

答案4

就我而言,问题出在 MTU 过大。如果您使用 NAT,您可以在路由器上更改 MTU,但我在服务器上更改 MTU:

sudo /sbin/ifconfig eth0 mtu 1036
sudo /etc/init.d/networking restart

在 Windows 上,您还可以增加此项:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"TcpMaxDataRetransmissions"=dword:00000010

相关内容