CentOS 9 手动编译 OpenSSH 9.3.2p2 后,sshd 服务无限重启?别慌,这个 systemd 依赖问题我帮你解决了
CentOS 9 手动编译 OpenSSH 9.3.2p2 后解决 sshd 无限重启问题全指南最近在 CentOS 9 上手动编译安装 OpenSSH 9.3.2p2 后不少工程师遇到了 sshd 服务无限重启的棘手问题。系统日志中反复出现Active: activating (auto-restart)状态服务始终无法正常启动。这实际上是一个典型的 systemd 集成问题本文将深入剖析其根源并提供完整的解决方案。1. 问题现象与诊断当你在 CentOS 9 上手动编译安装 OpenSSH 9.3.2p2 后执行systemctl status sshd可能会看到如下状态● sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled) Active: activating (auto-restart) (Result: exit-code) since Mon 2023-11-20 14:30:22 CST; 5s ago Docs: man:sshd(8) man:sshd_config(5) Process: 12345 ExecStart/usr/sbin/sshd -D $OPTIONS (codeexited, status255/EXCEPTION) Main PID: 12345 (codeexited, status255/EXCEPTION)关键诊断步骤检查日志journalctl -u sshd -b可能会显示类似Failed to notify systemd的错误验证依赖ldd /usr/sbin/sshd | grep systemd可能显示缺少 systemd 相关库源码检查查看 sshd.c 文件确认是否包含 sd_notify 相关调用提示这个问题通常发生在从源码编译安装 OpenSSH 时如果使用系统包管理器安装则不会出现因为发行版维护者已经处理了这些集成问题。2. 问题根源分析这个问题的核心在于systemd 集成缺失。现代 Linux 发行版使用 systemd 作为初始化系统而 OpenSSH 需要与 systemd 正确通信以报告服务状态。具体来说sd_notify 机制systemd 要求服务通过 sd_notify() 函数通知其状态变化编译时依赖默认编译可能缺少 systemd 开发库导致相关功能无法编译进去链接库缺失即使代码包含相关调用如果链接时缺少 -lsystemd 也会导致功能失效关键缺失组件组件作用影响systemd-devel提供 sd_notify 等函数定义编译时必需-lsystemd链接 systemd 库运行时必需sd-daemon.h包含相关头文件代码编译必需3. 完整解决方案3.1 安装必要依赖首先安装 systemd 开发包sudo dnf install systemd-devel同时确保其他编译依赖已安装sudo dnf install openssl-devel zlib-devel pam-devel3.2 修改 OpenSSH 源代码编辑 sshd.c 文件在源代码目录中找到sshd.c大约在 2099 行左右可能因版本略有不同在server_accept_loop调用前添加sd_notify(0, READY1); /* Accept a connection and return in a forked child */ server_accept_loop(sock_in, sock_out, newsock, config_s);添加头文件在文件头部 include 部分添加#include systemd/sd-daemon.h3.3 修改 Makefile找到 Makefile 并编辑通常在源代码根目录定位到LIBS定义大约第 51 行修改为包含 systemd 链接LIBS-lcrypto -ldl -lutil -lz -lcrypt -lresolv -lsystemd3.4 重新编译安装执行以下命令重新编译./configure --prefix/usr --sysconfdir/etc/ssh --with-pam --with-systemd \ --with-ssl-dir/usr --with-zlib/usr make sudo make install关键配置选项说明--with-systemd明确启用 systemd 支持--prefix/usr确保安装到系统路径--sysconfdir/etc/ssh保持配置文件位置一致3.5 重启服务并验证完成安装后sudo systemctl daemon-reload sudo systemctl restart sshd sudo systemctl status sshd现在应该能看到正常运行的状态● sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2023-11-20 15:00:00 CST; 10s ago Docs: man:sshd(8) man:sshd_config(5) Main PID: 54321 (sshd) Tasks: 1 (limit: 4915) Memory: 5.2M CGroup: /system.slice/sshd.service └─54321 /usr/sbin/sshd -D4. 常见编译问题与解决在手动编译 OpenSSH 过程中可能会遇到其他问题4.1 依赖库缺失错误常见错误及解决方案错误信息解决方案zlib.h: No such filesudo dnf install zlib-developenssl/ssl.h: No such filesudo dnf install openssl-develpam/pam_appl.h: No such filesudo dnf install pam-develkrb5.h: No such filesudo dnf install krb5-devel4.2 配置选项建议推荐的基本配置选项./configure --prefix/usr \ --sysconfdir/etc/ssh \ --with-pam \ --with-systemd \ --with-ssl-dir/usr \ --with-zlib/usr \ --with-md5-passwords \ --with-privsep-path/var/empty/sshd \ --with-selinux4.3 安装后验证安装完成后建议进行以下验证版本检查ssh -V应显示OpenSSH_9.3.2p2功能测试ssh localhost确认可以正常连接日志检查journalctl -u sshd -f观察是否有异常日志5. 系统集成注意事项5.1 SELinux 配置如果系统启用了 SELinux可能需要更新上下文sudo restorecon -Rv /usr/sbin/sshd /etc/ssh5.2 Firewall 配置确保防火墙允许 SSH 连接sudo firewall-cmd --permanent --add-servicessh sudo firewall-cmd --reload5.3 备份与回滚重要系统服务升级前应做好备份备份原 sshdsudo cp /usr/sbin/sshd /usr/sbin/sshd.bak备份配置文件sudo cp -r /etc/ssh /etc/ssh.bak回滚方法sudo mv /usr/sbin/sshd.bak /usr/sbin/sshd sudo systemctl restart sshd6. 性能优化建议成功解决问题后可以考虑以下优化启用硬件加速sudo sed -i s/#HostKeyAlgorithms/HostKeyAlgorithms/ /etc/ssh/sshd_config优化加密算法 在/etc/ssh/sshd_config中添加KexAlgorithms curve25519-sha256,ecdh-sha2-nistp521 Ciphers chacha20-poly1305openssh.com,aes256-gcmopenssh.com MACs hmac-sha2-512-etmopenssh.com启用压缩适用于高延迟网络Compression yes连接保持ClientAliveInterval 60 ClientAliveCountMax 37. 安全加固措施新版本 OpenSSH 提供了更多安全功能禁用旧协议Protocol 2限制用户登录AllowUsers admin deploy DenyUsers root启用证书认证PubkeyAuthentication yes PasswordAuthentication no限制监听接口ListenAddress 192.168.1.100日志增强LogLevel VERBOSE8. 监控与维护升级后建议设置监控服务状态监控sudo systemctl enable --now sshd连接数监控watch -n 60 netstat -ant | grep :22 | wc -l失败登录报警sudo grep Failed password /var/log/secure | mail -s SSH Failed Logins adminexample.com定期更新检查ssh -V | awk {print $1} | cut -d_ -f2