我想要实现的只是终止不活动的 SSH 会话。仅仅因为用户已登录并不意味着用户正在做某事。我需要 SSH 守护程序在 X 秒不活动后注销用户。
Debian Bullseye 和 CentOS 不会自动注销不活动的 SSH 会话。至少在合理的时间段内不会。所谓合理的时间,是指少于 10 分钟的时间。
在发布这个问题之前,我已经搜索并阅读了 serverfault.com 上的类似问题,但找不到任何有正确答案的帖子。
在阅读了大量文章(包括 Debian 的手册页)之后https://manpages.debian.org/stretch/openssh-server/sshd_config.5.en.html我在 /etc/ssh/sshd_config 文件中实现了与 ssh 不活动相关的两个选项,如下所示:
ClientAliveInterval 300
ClientAliveCountMax 1
超时值是通过将 ClientAliveInterval 与 ClientAliveCountMax 相乘来计算的。
timeout interval = ClientAliveInterval * ClientAliveCountMax
此设置在 CentOS 上运行良好,因为我得到了“远程主机关闭与 xxxx 的连接。”但它在 Debian 上不起作用。
我是否误解了文档?有人能解释一下我做错了什么吗?
谢谢。
答案1
OpenSSH 选项ClientAliveInterval
并且ClientAliveCountMax
不用于断开连接不活跃会话。事实上,只要客户端和网络链接处于活动状态,它们就会阻止关闭连接,即使是在非活动会话中。
这是 ssh 的内部机制,在建立的隧道内发送一个空数据包,并等待客户端的答复。
就您而言,您每秒发送一个数据包300
,并在1
错过答案后断开连接。
虽然这些选项有助于检测和清理断开连接客户端会话,它们不会终止仍处于连接状态的客户端会话,即使这些客户端处于非活动状态。除非这些客户端不应答空数据包。
正如 @noah 所建议的,要断开不活动的客户端,如果您使用bash
shell,您可以TMOUT
在系统范围的默认值或每个用户的配置文件中设置该值:
TMOUT If set to a value greater than zero, TMOUT is treated as the default timeout for the read builtin. The select command terminates if input does not arrive
after TMOUT seconds when input is coming from a terminal. In an interactive shell, the value is interpreted as the number of seconds to wait for a line of
input after issuing the primary prompt. Bash terminates after waiting for that number of seconds if a complete line of input does not arrive.
例如,添加以下行将/etc/bashrc
在 5 分钟后关闭非活动用户的 bash 会话,但在启用此功能之前请阅读以下警告:
export TMOUT=300
警告:作为 shell 的日常用户,我经常在多任务处理时让某个终端打开。我个人认为如果将 TMOUT 机制设置为较低的值,它会非常烦人(即使您提到的 10 分钟也会让我很烦)。除非将其设置为非常高的值(至少 1 小时),否则我不会推荐它。
我的观点是,OpenSSH 选项ClientAliveInterval
和ClientAliveCountMax
(或服务器端设置的ServerAliveInterval
和ServerAliveCountMax
)足以摆脱僵尸/断开连接的客户端。使用它们时,您已经可以保证服务器上的活动会话与连接客户端上的打开终端相匹配。保持终端打开是用户的选择,虽然我理解您想关闭断开连接的客户端,但我认为关闭合法用户的会话毫无意义。
答案2
不确定 Debian 超时不起作用的原因,但还有其他方法可以强制注销。
因此,首先想到的是在profiles.d
(或sudoers
)配置中添加自动注销用户(将超时扩展到控制台和sudo su
命令)。
启用步骤: https://ostechnix.com/auto-logout-inactive-users-period-time-linux/
答案3
根据我对 Ubuntu Server 22.04 的其他答案的测试,在此添加一些澄清性评论。使用 sshd ClientAliveInterval 和 ClientAliveCountMax 机制,至少在我使用其他 Ubuntu 系统的试验中,ssh 客户端会默默响应空的 Client Alive 消息。因此,如果您保持该客户端处于活动状态,它将永远不会被杀死。但是,如果您暂停客户端:~^Z
,即波浪号后跟 Control-Z,并等待乘以 ClientAliveInterval * ClientAliveCountMax 秒数,则连接将关闭,您可以在从暂停状态恢复客户端时观察到这一点(例如fg
)。如果您不了解 ssh 中的波浪号命令,请键入 ~? 以获取帮助。
所以,我觉得ClientAlive机制比较适合用来捕捉ssh客户端挂起,停止或者暂停以及机器无响应,网络断线等重大悲剧。
我已经测试了 TMOUT ( export readonly TMOUT=7200
),发现它在 bash 中按预期工作。但是,我不确定如果用户选择了不同的 shell,它是否会生效。也许每个 shell 都有自己的机制,或者它们都使用相同的机制(但事情很少能如此顺利地解决!)。请注意,ShellCheck 抱怨“export readonly”并需要“declare -rx”,但我认为 /etc/profile.d 中的脚本不是在 bash 中运行的,而是在 /bin/sh 中运行的,其中“declare”不可用。