我有一台运行 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 需要停止它以便重启/关闭。