SSH 会话在关机/重启时挂起

SSH 会话在关机/重启时挂起

我有一台运行 Debian 和 sshd 的服务器,如果我需要重新启动服务器,我的 SSH 会话会在客户端挂起,直到 TCP 超时。我认为这是因为在sshd终止时它没有明确关闭与主机的开放 SSH 会话。我应该怎么做才能先断开所有人的连接,然后正常终止自身?到目前为止,我还没有看到与关闭行为相关的sshd参数。man sshd_config

答案1

当您关闭或重新启动系统时,systemd会尝试尽快停止所有服务。这涉及关闭网络并终止所有仍处于活动状态的进程 - 通常按此顺序。因此,当 systemd 终止处理 SSH 会话的分叉 SSH 进程时,网络连接已被禁用,并且它们无法正常关闭客户端连接。

您的第一个想法可能是在关机期间第一步就终止所有 SSH 进程,并且有相当多的 systemd 服务文件可以执行此操作。

但当然有一个更简洁的解决方案(它“应该”如何完成):systemd-logind.
systemd-logind跟踪活动用户会话(本地和 SSH 会话),并将其中生成的所有进程分配给所谓的“切片”。这样,当系统关闭时,systemd 只需向用户切片内的所有内容(包括处理特定会话的分叉 SSH 进程)发送 SIGTERM 即可,然后继续关闭服务和网络。

systemd-logind需要 PAM 模块来接收新用户会话的通知,并且您需要dbus使用loginctl它来检查其状态,因此请安装以下两个模块:

apt-get install libpam-systemd dbus

确保您/etc/ssh/sshd_config确实要使用该模块UsePAM yes

答案2

您需要在客户端而不是服务器端进行设置。编辑您的文件~/.ssh/config以包含

ServerAliveInterval 15
ServerAliveCountMax 5

这意味着在 15 秒不活动后,您的客户端将向服务器发送一条消息。如果没有收到任何响应,它将重试最多 5 次,如果仍然没有收到答复,它将关闭会话。

答案3

此行为已报告Debian 错误,您只需要正确设置软件包附带的关机脚本,因为默认情况下它们不会被自动复制:

cp /usr/share/doc/openssh-client/examples/ssh-session-cleanup.service /etc/systemd/system/
systemctl  enable ssh-session-cleanup.service

答案4

遗憾的是,serverfault 不允许我在帖子中回答,因为多年来积分太少了。但我不需要在其他博客上发垃圾邮件来获得解锁 ^^... 因此作为专用答案:

正如 Rfraile 提到的

cp /usr/share/doc/openssh-client/examples/ssh-session-cleanup.service /etc/systemd/system/
systemctl  enable ssh-session-cleanup.service

可以。要使用它而不重新启动实例/服务器,您应该执行其他任务:

systemctl daemon-reload
systemctl start ssh-session-cleanup.service

因此该服务已注册并启动,并且 systemd 需要停止它以便重启/关闭。

相关内容