我们与外部方建立了与其中一台服务器的连接。该方使用 sftp 登录并上传了一些文件。该方未关闭会话,他们也不知道如何关闭(这是一台 Windows 服务器,他们使用的脚本似乎不支持该功能)。
现在,服务器上周因为内存不足而崩溃了。经过一番搜索,我发现有 2500 个 SSH 连接(有些是几个月前的)。每个连接只占用一点内存,但合在一起就导致服务器崩溃。我把它们全部杀了,现在服务器运行正常。
我该如何防止这种情况再次发生?我希望在几个小时后终止所有会话。这可以从服务器端实现吗?还是我应该自己为此创建一个脚本?
关于 SSH 超时的文章已经有很多,但所有解决方案都是客户端的。
编辑:现在我已经创建了这个每晚运行的脚本:count=$(ps aux | grep [USERNAME] | wc -l) echo "Found $count processes";
for i in $(seq $count)
do
echo "kill $i"
kill -9 $(ps aux | grep [USERNAME] | grep -v grep | head -n 1 | tr -s ' ' | cut -f 2 -d ' ')
done
service ssh restart
您需要将 [USERNAME] 替换为登录的用户。它将终止此用户的所有进程,但在我的例子中,只有此用户正在运行 SSH 连接。
答案1
编辑 SSH 服务器的配置文件以包含
ClientAliveInterval 600
ClientAliveCountMax 0
这将在 10 分钟(600 秒)后断开所有空闲客户端的连接。
引用手册:
客户端存活数最大值
设置 sshd(8) 可以发送的客户端活动消息数量(见下文),而无需从客户端接收任何消息。如果在发送客户端活动消息时达到此阈值,sshd 将断开客户端连接,终止会话。[...]
默认值为 3。如果 ClientAliveInterval(见下文)设置为 15,并且 ClientAliveCountMax 保留为默认值,则无响应的 SSH 客户端将在大约 45 秒后断开连接。此选项仅适用于协议版本 2。
客户端存活间隔
设置超时间隔(以秒为单位),如果在此间隔后未从客户端收到任何数据,sshd(8) 将通过加密通道发送一条消息以请求客户端的响应。默认值为 0,表示这些消息不会发送到客户端。此选项仅适用于协议版本 2。