「OpenSSH」- 保持SSH在线(不掉线、不断开)

  CREATED BY JENKINSBOT

问题描述

在使用SSH远程服务器时,如果在一段时间内未进行任何操作,则连接会断开(或者挂起,无响应)。

本文将介绍如何配置SSH客户端,以解决该问题。

问题原因

该问题的原因由很多:

	可能是当前使用的NAT防火墙自动关闭会话;
	可能是远程服务器操作系统自动关闭空闲会话(当前TCP连接长时间没有数据流动)

这些都会导致连接被释放(断开)。

解决办法

可以定期向服务器发送报文,以暗示服务器该连接是使用中,请不要释放。

在SSH中,有两个ServerAliveCountMaxServerAliveInterval选项,可以实现该功能。

修改/etc/ssh/ssh_config(系统级别)或~/.ssh/config(用户级别):

Host *
    ServerAliveInterval 300
    ServerAliveCountMax 5

上述配置表示,如果超过300秒(ServerAliveInterval)没有收到服务端发送的报文,则客户端发送一个消息,并要求服务器返回。如果服务器没有返回,则再次重试,最多5次(ServerAliveCountMax),如果一直没有收到服务端的响应,则断开连接。

超时自动断开的使用

虽然自动断开连接不好的,但是它也有其他的用途。比如在远程使用ssh执行命令时,我们希望超时自动断开:

#!/bin/sh

ssh -o ServerAliveInterval=2 -o ServerAliveCountMax=2  root@ip-address "doing some stuff"

在执行以上命令后,如果服务器断开连接(比如修改网络配置),在四秒钟后,客户端将断开连接。

附加说明

# 在服务端配置

上述解决方案,只是针对客户端的配置。实际上,还可以就是SSH服务端/etc/ssh/sshd_config配置:

ClientAliveInterval 300
ClientAliveCountMax 2

参数含义是类似的,但是该配置会作用于每一个连接。

当大量用户反馈SSH掉线频繁时,可以考虑修改SSH服务端的配置文件。在日常中,可能修改SSH客户端配置才是更常见的做法。

# 存活报文

有客户端发送的存活报文类型为80,而服务端相应的报文类型为82,这一点可以通过ssh -vvv进行查看。并且报文是通过加密信道发送的,不同于TCPKeepAlive,因为TCPKeepAlive是可以欺骗的。

# 其他客户端

本文针对SSH客户端,即ssh(1)命令。对于PuTTY、SecureCRT、XShell等等客户端都是类似的,这些软件的设置中,一般都包含”*keep*alive*”之类的设置。

参考文献

How to Keep Alive SSH Sessions
How to prevent SSH from disconnecting if it’s been idle for a while