当我在通过 SSH 登录时关闭或重新启动服务器时,SSH 连接会挂起或冻结。终端变得完全无响应,并且 SSH 会话最多需要一分钟才能识别出连接已丢失。
此问题发生在新的 Debian 12 (openssh-server 1:9.2p1-2) 上,但不会发生在旧的 Debian 10 上。
在 Debian 10 上,当我重新启动服务器时,SSH 连接会立即干净地注销,并显示以下消息:
Connection to debian10 closed by remote host.
Connection to debian10 closed.
当我使用详细选项连接到两台服务器,然后重新启动它们时,我发现了一些差异:
ssh 会话干净地结束:
$ ssh -vvv -E /tmp/a debian10
debug3: send packet: type 1
debug1: channel 0: free: client-session, nchannels 1
debug3: channel 0: status: The following connections are open:
#0 client-session (t4 r0 i0/0 o0/0 e[write]/0 fd 6/7/8 sock -1 cc -1)
debug3: fd 1 is not O_NONBLOCK
Transferred: sent 4668, received 7428 bytes, in 34.8 seconds
Bytes per second: sent 134.3, received 213.7
debug1: Exit status -1
ssh 会话冻结:
$ ssh -vvv -E /tmp/b debian12
debug3: send packet: type 80
debug3: receive packet: type 82
debug3: send packet: type 80
debug3: send packet: type 80
debug3: send packet: type 80
Timeout, server debian12 not responding.
我发现了类似的问题,但所有答案都表明与 systemd 有关。我没有使用 systemd,我在两台服务器上都使用 sysvinit。
所以,总结一下:两台服务器使用相同的 ssh 客户端时表现不同,因此我怀疑服务器端有一些不同(大概是 openssh-server 的行为)
更新:
这是我的重启顺序(运行级别 6):
/etc/rc6.d/K01cron
/etc/rc6.d/K01ssh
/etc/rc6.d/K01urandom
/etc/rc6.d/K02sendsigs
/etc/rc6.d/K03rsyslog
/etc/rc6.d/K05networking
/etc/rc6.d/K06umountfs
/etc/rc6.d/K07umountroot
/etc/rc6.d/K08reboot
请注意,ssh
守护进程在 之前终止networking
。但这应该不会产生任何影响,因为正常关闭sshd
不会影响现有的 ssh 连接。
更新2:
这是我在控制台上看到的关闭顺序:
[ ok Sending processes configured via /etc/ini[....] Stopping: cron
[ ok ] Stopping: sshd
[ ok ] Asking all remaining processes to terminate...done.
[ ok ] All processes ended within 1 seconds...done.
[ ok ] Stopping: rsyslogd
[ ok ] Deconfiguring network interfaces...done.
[ ok ] Will now unmount temporary filesystems: /tmp
[ ok ] Will now unmount local filesystems: /var
[ ok ] Mounting root filesystem read-only...done.
[info] Will now halt.
[79896.954129] reboot: Power down
答案1
根本原因
对于标准的 systemd 和 sysvinit,有序关闭将按一定顺序杀死守护进程并取消配置硬件。特别是,我们预计,当 IP 仍然处于活动状态时sshd
,侦听 22 的 sshd 以及bash
其生成的子级的各种 sshd 应该收到告诉它们终止的终止信号。发送这些信号后,IP 堆栈应保持至少一秒钟的状态。您遇到的超时与客户端在开放连接上发送 TCP 流量到不再响应这些 TCP 数据包的服务器一致。
在您的 debian12 服务器上查看 /etc/init.d/rc。当从多用户运行级别 2 更改时,它会通过按顺序运行带有K75
, 等前缀的关闭脚本来终止守护进程。确保在关闭网络接口sshd
之前将其终止。ifconfig
重命名脚本以使用不同的两位数序列号将更改执行顺序。
请注意,如果脚本相互竞争,您可以通过插入临时sleep
语句来减慢脚本的速度。
使固定
即使您在筛选那些曲折的小初始化脚本迷宫中的系统日志时遇到困难,仍然有一些简单的解决方法。
简单的shutdown -r +1
root 权限让您有 60 秒的时间按下 CTRL-D,在烟花开始之前优雅地断开 ssh。
像这样的命令(sleep 5 && reboot) &
可以在更短的时间内完成这一任务。你可能必须
诺哈普
它,或者以其他方式disown
将后台进程从 pty 的作业控制中分离出来。因此,为该命令创建一个简短的脚本可能会很方便。
让我们知道 需要更改哪些细节你的系统。
答案2
检查您的/etc/ssh/sshd_config
配置并UsePAM yes
确保安装了软件包libpam-systemd
dbus
systemd-logind 保留本地和远程(ssh)活动用户会话的记录,并将生成的进程分配给用户“切片”。如果在 systemd 停止时配置正确,它将在禁用网络连接之前对用户切片内的所有内容发出 SIGTERM,其中应包括您的 ssh 连接。