我的 Ubuntu Linux 服务器文件配置/etc/ssh/sshd_config
如下:
ClientAliveInterval 60
ClientAliveCountMax 60
我假设服务器会以 60 秒的间隔发送 60 个空数据包,以保持连接处于活动状态。连接确实保持活动状态,但持续时间无限长,并且在 1 小时左右后不会断开连接。
我在 1 小时 20 分钟不活动时尝试了它(我只是让 SSH 终端打开,没有输入任何内容),它仍然存在。
可能是什么问题?
答案1
如果“1 小时 20 分钟不活动”是指
- 用户已经 1 小时 20 分钟没有在 shell 中输入内容
- 或者用户
ssh -N …
1小时20分钟前使用过 - 一般情况:1小时20分钟没有数据传输
那么对于该机制来说,不活动并不重要ClientAlive*
。
为了理解这一点ClientAlive*
,让我们从健壮的角度来分析一个已经存在的连接可能会发生什么sshd
。
- 客户端可以正常断开连接。在这种情况下
ssh
通知sshd
,服务器确定连接已终止。 - 可执行文件
ssh
可能因任何原因意外终止(例如,它被强制终止),因此它无法传达其断开连接的意图。仍然客户端操作系统能够正常关闭TCP连接,因此sshd
认识到连接不再存在。 - 整个客户端计算机因某种原因被杀死或消失(例如,由于拔掉网络电缆)。现在
sshd
无法判断客户端是否保持沉默是因为没有数据要发送,还是因为它不再存在。
该ClientAlive*
机制检测最后一种情况。服务器发送客户端活动消息,并且客户端响应(如果客户端存在)。有时候是这样的自动地在 SSH 协议中。使用 SSH 作为传输的应用程序既不受影响也不干扰。
ClientAliveInterval
您使用的设置ClientAliveCountMax
配置服务器询问的频率以及在放弃并认为连接终止之前需要进行多少次未响应的尝试。
ServerAliveInterval
借助和,客户端能够以类似的方式检测死连接ServerAliveCountMax
。
TCP 连接还有一个更通用的机制(并非特定于 SSH):TCP keepalive。比较我的这个答案。
任何类型的保活数据包不仅允许连接端点检测连接是否已失效。他们还“更新”之间的联系。我的意思是,例如,如果长时间没有看到属于某个连接的数据包,带有 NAT 的家庭路由器可能会将其识别为已失效。如果发生这种情况,NAT 条目将被忘记,当连接最终变为活动状态时,路由器将无法正确处理它。比较这个答案。
打开 SSH 终端而不输入任何内容并不会阻止ssh
响应服务器生成的客户端活动消息。如果客户在那里,客户就会做出回应。
要注销在一段时间内未与 shell 交互的用户,您需要 shell:TMOUT
或类似变量(取决于 shell)的帮助。但随后用户可以重新配置他们的壳。
互联网上有一些指南将该ClientAlive*
机制视为 的替代方案TMOUT
。现在你知道这些是不同的事情了。
可能有一些方法可以让操作系统检测用户的“不活动”(例如,没有生成新进程,仅sshd
运行bash
,没有数据流通过其点)。即使我知道它们,我也不会使用它们来终止 SSH 连接看不活跃。
如果用户通过 SSH 请求端口转发怎么办?到转发端口的连接可能随时进入。愿意使用端口的应用程序可以是任何东西,而不知道涉及转发。用户可能希望依靠 SSH 静默等待连接发生。 IMO 仅因为没有流量而终止 SSH 连接并不是一个好的做法。只要客户端响应客户端活动消息,连接就应该保持。
在你的例子中,客户一直在回应。
更新
2023 年引入 OpenSSHChannelTimeout
以及UnusedConnectionTimeout
您可以使用的选项sshd_config
.这些选项正是您所需要的。看我的另一个答案了解详情。