如何在Linux中终止或者断开挂起的ssh会话

时间:2020-01-09 10:41:08  来源:igfitidea点击:

如何在Linux中断开悬挂的ssh会话。
断开Unix中卡住的ssh会话,终止卡住的ssh会话。
在Unix中终止无响应的ssh会话。
杀死卡住的ssh会话。
在Linux中终止卡住的ssh会话。
在Linux中杀死ssh会话。
关闭ssh连接。
终止LInux中无响应的ssh会话。
使用ServerAliveInterval自动终止或者断开挂起的ssh会话。
在Linux中使用超时自动终止PSSH会话。
在特定时间段后,断开linux中挂起的pssh会话的连接。
在Linux中自动杀死卡住的ssh会话。
在Unix中自动断开悬挂的ssh会话。

在本文中,我们将围绕该主题涵盖各种示例,以消除卡住的ssh会话,即在Linux中断开挂起的ssh会话。

什么是无响应的SSH会话?

SSH会话无响应意味着主机和客户端之间的SSH连接无响应或者已无响应。
由于各种原因(最有可能是由于服务器和客户端之间的网络波动)可能会导致出现这种情况。
我们可以"列出所有活动的SSH连接",然后检查空闲时间以获取其当前状态。

我们还可以从远程主机获取其PID,以手动终止无响应的ssh会话。

终止卡住的ssh会话

有一个"秘密"键盘快捷键可以强制无响应的ssh会话退出。
从冻结的会话终端中,按以下顺序按以下键:Enter~.

提示:

必须按照冻结会话的顺序执行该命令,以杀死无响应的ssh会话。

从SSH的手册页

ESCAPE CHARACTERS
     When a pseudo-terminal has been requested, ssh supports a number of functions through the use of an escape character.
     A single tilde character can be sent as ~ or by following the tilde by a character other than those described below.  The escape character must always follow a newline to be interpreted as special.  The escape character can be changed in configuration files using the EscapeChar configuration directive or on the command line by the -e option.
     The supported escapes (assuming the default ‘~’) are:
     ~.      Disconnect.	 
     ~^Z     Background ssh.
     ~#      List forwarded connections.
	..... output trimmed

例如:

其中我已经使用用户'hynman'创建了一个从node1node2的活动会话。
现在,该会话处于挂起状态。

node1:~ # ssh -q  hynman@node2
Password:
Last login: Fri Jan 31 10:47:39 2019 from 10.43.22.85
[hynman@node2 ~]$

其中我按下Enter键,然后按一下~和.

说明:

其中按~和.(点)将被隐藏,并且在屏幕上将不可见。
但是在完成此序列后,会话将立即终止。

[hynman@node2 ~]$   <-- Here I pressed Enter
[hynman@node2 ~]$node1:~ #
			 ^
			 |
Here I pressed ~ (tilde) followed by . (dot)

如我们所见,我的挂起的会话已终止,并且我返回了我的本地主机。

重要的提示:

在处理嵌套的SSH会话时,我们可以添加多个波浪号字符,以仅中断链中的一个SSH会话,而保留其他SSH会话。
例如,如果我们嵌套在3个级别中(例如,从本地ssh从Machine→Machine1→Machine2→Machine3进行ssh),则输入Enter→~→.
将使我们返回本地会话,请输入Enter→~→~→.
将会把我们留在Machine1中,而'Enter'→~→~→~→.将把我们留在Machine2中。
这也适用于其他转义序列,例如将ssh会话临时移至后台。
上面的方法适用于任何级别的嵌套,只需添加更多的代字号即可。

例如:其中我已经从node1到node2以及从node2到node3进行了活动SSH会话,即node1→node2→node3

node1:~ # ssh -q  hynman@node2
Password:
Last login: Fri Jan 31 11:04:17 2019 from node1
[hynman@node2 ~]$ssh -q [email protected]
Password:
Last login: Sun Jan 26 13:55:55 2019 from node2

现在,其中我将断开的SSH会话从node3断开到node2而不是node1断开。
因此,我将按" Enter"→"~"→"~"。

[hynman@node3 ~]$   <-- Here I pressed Enter
[hynman@node3 ~]$[hynman@node2 ~]$<-- And I have been disconnected from node3 and my session is at node1 -> node2
				^
				|
Here I pressed ~ ~ (tilde) two times followed by . (dot)

自动断开挂起的SSH会话

现在,在上面的示例中,我们正在手动终止卡住的ssh会话,但是要自动断开挂起的SSH会话,或者在自动执行任务并且SSH进程卡住时,在这种情况下,最好是SSH本身断开挂起的SSH会话本身而不是有人手动干预并终止该过程。

在这种情况下,我们可以使用ServerAliveInterval自动断开挂起的SSH会话。

从手册页:

ServerAliveCountMax
             Sets the number of server alive messages (see below) which Jan be sent without ssh(1) receiving any messages back from the server.  If this threshold
             is reached while server alive messages are being sent, ssh will disconnect from the server, terminating the session.  It is important to note that
             the use of server alive messages is very different from TCPKeepAlive (below).  The server alive messages are sent through the encrypted channel and
             therefore will not be spoofable.  The TCP keepalive option enabled by TCPKeepAlive is spoofable.  The server alive mechanism is valuable when the
             client or server depend on knowing when a connection has become inactive.
             The default value is 3.  If, for example, ServerAliveInterval (see below) is set to 15 and ServerAliveCountMax is left at the default, if the server
             becomes unresponsive, ssh will disconnect after approximately 45 seconds.
     ServerAliveInterval
             Sets a timeout interval in seconds after which if no data has been received from the server, ssh(1) will send a message through the encrypted channel
             to request a response from the server.  The default is 0, indicating that these messages will not be sent to the server.

因此,使用ServerAliveInterval可以设置超时值,如果提供的SSH会话无响应,将使用该超时值。
我们可以通过命令行或者在相应用户的主目录内创建一个ssh_config文件来使用它。

方法1:

启动SSH连接时,请使用-o ServerAliveInterval = XX以及SSH命令。
其中用我们合适的超时值替换XX。

例如:我正在运行从node1到node2的SSH会话,并且将断开NIC接口的连接。
现在,这不是挂起会话的最佳方案,但这将有助于解释我们的步骤和示例。
现在,我提供了5秒的间隔,在断开会话连接之前,TCP数据包将被发送两次。

node1:~ # ssh -vvv -i /export/home/sufuser/.ssh/id_rsa -o ServerAliveInterval=5 -o ServerAliveCountMax=2 root@node2 "/sbin/ifdown bond0"

在屏幕上打印的调试日志中,在断开会话连接之前发送了两个调试数据包

debug3: send packet: type 80
debug3: send packet: type 80
debug3: send packet: type 1
packet_write_wait: Connection to node2 port 22: Broken pipe

现在按预期其中进行会话,每隔5秒发送2个TCP数据包后,会话将自动断开连接。

方法2:

我们可以通过在用户主目录内创建一个新文件ssh_config来为每个用户配置这些值。
例如,如果我的用户的主目录是"/home/hynman /",则创建以下文件

# touch /home/hynman/.ssh/ssh_config

添加以下内容

Host *
 ServerAliveCountMax 3
 ServerAliveInterval 10

这里的" *"用于指代任何匹配的主机。
如果我们希望将其限制为某个主机,请提供IP /主机名。

方法3:

最后,我们可以更新/etc/ssh/ssh_config并添加相同的值。
这是配置将不在用户级别,而是在系统级别

添加以下内容

# vim /etc/ssh/ssh_config
Host *
 ServerAliveCountMax 3
 ServerAliveInterval 10

使用超时终止SSH会话

我们还可以使用timeout命令来断开挂起的SSH会话。
为活动会话定义超时值。

说明:

即使会话未处于挂起状态,超时也会终止该会话/命令。

这样做的好处是,如果对于自动化我们正在使用ssh命令,并且我们不希望自动化脚本在执行过程中卡住,则可以使用timeout命令在特定时间段后终止会话。

从超时的手册页中:

-k, --kill-after=DURATION
              also send a KILL signal if COMMAND is still running
              this long after the initial signal was sent

例如:我创建了一个脚本来捕获SIGTERM并捕获超时进度

node1:~ # cat /tmp/script.sh
#!/bin/bash
trap 'echo "`date`: SIGTERM received!"' 15
echo "`date`: Starting"
sleep 20
echo "`date`: Stage Two"
sleep 20
echo "`date`: Finished"

添加-k 12开关告诉超时,在初始SIGTERM之后12秒钟将SIGKILL发送到进程。
同样,由于SIGTERM信号,在3秒钟后显示SIGTERM收到的消息。
此后十二秒,整个脚本被杀死。
它不会完成第二次" 20秒"睡眠,并且在此之后也不会显示"完成"消息。
这是处理超时的一种更有力的方法。

node1:~ # timeout -k 12 3 /tmp/script.sh ; date
Fri Jan 31 13:26:45 IST 2019: Starting
Terminated
Fri Jan 31 13:26:48 IST 2019: SIGTERM received!
Fri Jan 31 13:26:48 IST 2019: Stage Two
Killed
Fri Jan 31 13:27:00 IST 2019

同样,我们可以通过SSH命令使用超时。
假设我们知道SSH命令执行将花费10秒,那么我们可以将20秒的超时定义为终止会话的困难时间

例如:

node1:~ # time timeout -k 25 20  ssh -q -i /export/home/sufuser/.ssh/id_rsa root@node2 "sleep 1m"
real    0m20.008s
user    0m0.012s
sys     0m0.008s

断开PSSH会话

PSSH是执行SSH(并行)而不是顺序执行的另一工具。

现在,在PSSH中,有一个内部参数可用于在特定时间段后终止活动会话。
我们无需依赖任何其他工具来断开SSH会话。

在pssh的手册页中:

-t timeout
       --timeout timeout
              Make connections time out after the given number of seconds.  With a value of 0, pssh will not timeout any connections.

例如:使用以下语法执行pssh,以在30秒后自动执行超时

node1:~ # pssh  --timeout 30 -l root -H node2 sleep 40
[1] 14:21:48 [FAILURE] node2 Timed out, Killed by signal 9

因此,正如所预期的那样,在提供的超时值之后,PSSH会话会被超时信号自动终止。