1. 项目概述
作为一名长期维护Linux服务器的运维工程师,最近OpenSSH爆出的CVE-2024-6387漏洞让我不得不立即着手升级系统上的OpenSSH版本。这个漏洞影响范围广,危害严重,可能导致远程代码执行。本文将详细记录我在CentOS 7.9系统上将OpenSSH从7.4p1升级到9.8p1的完整过程,包括所有关键步骤、遇到的问题及解决方案。
2. 升级前的准备工作
2.1 系统环境确认
在开始升级前,首先需要确认当前系统的详细环境信息:
bash复制# 查看内核版本
uname -a
# 输出示例:Linux CentOS7 3.10.0-1160.el7.x86_64
# 查看CentOS发行版信息
cat /etc/centos-release
# 输出示例:CentOS Linux release 7.9.2009 (Core)
# 查看当前OpenSSH版本
ssh -V
# 输出示例:OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
这些信息对于后续的依赖包选择和问题排查至关重要。特别是OpenSSL的版本,因为新版的OpenSSH 9.8需要OpenSSL 3.x的支持。
2.2 关键配置文件备份
在进行任何系统级升级前,备份是必不可少的步骤。以下是必须备份的关键文件和目录:
bash复制# 备份SSH相关配置
cp -rf /etc/ssh /etc/ssh.bak
# 备份OpenSSL二进制文件
cp -rf /usr/bin/openssl /usr/bin/openssl.bak
# 备份PAM配置
cp -rf /etc/pam.d /etc/pam.d.bak
# 备份systemd服务文件
cp -rf /usr/lib/systemd/system /usr/lib/systemd/system.bak
重要提示:备份时建议使用绝对路径,并确保备份目录与原目录不在同一分区,避免意外覆盖或删除。
2.3 安装编译依赖工具
编译新版本的OpenSSH需要一系列开发工具和库文件。由于CentOS 7的默认yum源可能版本较旧,建议先切换到阿里云的镜像源:
bash复制# 备份原有yum源
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
# 下载阿里云yum源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# 清理并重建yum缓存
yum clean all
yum makecache
安装编译所需的依赖包:
bash复制yum install -y vim gcc gcc-c++ glibc make autoconf openssl openssl-devel \
pcre-devel pam-devel zlib-devel tcp_wrappers-devel tcp_wrappers \
libedit-devel perl-IPC-Cmd wget tar
这些依赖包包含了编译器(gcc)、自动化工具(make/autoconf)、加密库(openssl-devel)、认证模块(pam-devel)等OpenSSH编译所必需的基础组件。
3. 下载并解压源代码包
3.1 获取最新版本源代码
我们将下载三个关键组件的源代码:zlib、OpenSSL和OpenSSH。建议在/usr/local/src目录下进行操作:
bash复制cd /usr/local/src
# 下载zlib压缩库
wget https://www.zlib.net/zlib-1.3.1.tar.gz
# 下载OpenSSL加密库
wget https://www.openssl.org/source/openssl-3.2.1.tar.gz
# 下载OpenSSH
wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gz
3.2 解压源代码包
bash复制# 解压zlib
tar -zxvf zlib-1.3.1.tar.gz
# 解压OpenSSL
tar -zxvf openssl-3.2.1.tar.gz
# 解压OpenSSH
tar -zxvf openssh-9.8p1.tar.gz
解压后会在当前目录生成三个目录:zlib-1.3.1、openssl-3.2.1和openssh-9.8p1,分别对应三个组件的源代码。
4. 编译安装依赖组件
4.1 编译安装zlib
zlib是一个广泛使用的压缩库,OpenSSH需要它来处理数据压缩:
bash复制cd zlib-1.3.1
# 配置安装路径
./configure --prefix=/usr/local/zlib
# 编译安装(使用2个CPU核心并行编译)
make -j 2
make test # 运行测试确保编译正确
make install
# 添加库文件路径到系统配置
echo '/usr/local/zlib/lib' >> /etc/ld.so.conf.d/zlib.conf
ldconfig -v # 更新动态链接库缓存
编译参数说明:
--prefix=/usr/local/zlib:指定安装目录-j 2:使用2个CPU核心并行编译,加快速度
4.2 编译安装OpenSSL
OpenSSL是OpenSSH的加密基础,必须先行升级:
bash复制cd ../openssl-3.2.1
# 配置安装参数
./config --prefix=/usr/local/openssl
# 编译安装
make -j2
make install
# 备份旧版OpenSSL
mv /usr/bin/openssl /usr/bin/openssl.bak
# 创建符号链接
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/openssl/lib64/libssl.so.3 /usr/lib64/libssl.so.3
ln -s /usr/local/openssl/lib64/libcrypto.so.3 /usr/lib64/libcrypto.so.3
# 添加库文件路径
echo '/usr/local/openssl/lib64' >> /etc/ld.so.conf.d/ssl.conf
ldconfig -v
验证OpenSSL版本:
bash复制openssl version -v
# 应显示:OpenSSL 3.2.1 30 Jan 2024
注意:如果遇到符号链接错误,可能是旧版本的库文件残留导致,可以尝试手动删除/usr/lib64/libssl.so和/usr/lib64/libcrypto.so后再创建链接。
5. 编译安装OpenSSH
5.1 卸载旧版本OpenSSH
在安装新版本前,需要先卸载旧版本,但要注意保持当前SSH会话不被中断:
bash复制# 卸载旧版OpenSSH(不要关闭当前SSH会话)
yum remove openssh -y
# 清理残留配置文件
rm -rf /etc/ssh/*
关键提示:这个操作会移除openssh、openssh-clients和openssh-server三个包。务必确保你有其他方式访问服务器(如控制台),或者在一个不会被中断的SSH会话中操作。
5.2 编译安装OpenSSH 9.8
bash复制cd ../openssh-9.8p1
# 配置编译参数
./configure --prefix=/usr/local/openssh \
--sysconfdir=/etc/ssh \
--with-pam \
--with-ssl-dir=/usr/local/openssl/ \
--with-zlib=/usr/local/zlib
# 检查配置输出,确保PAM支持已启用
# 在输出中查找:PAM support: yes
# 编译安装
make -j 2
make install
配置参数详解:
--prefix:指定OpenSSH安装目录--sysconfdir:指定配置文件目录--with-pam:启用PAM认证支持--with-ssl-dir:指定OpenSSL安装路径--with-zlib:指定zlib安装路径
5.3 配置SSH服务
bash复制# 复制启动脚本
cp contrib/redhat/sshd.init /etc/init.d/sshd
# 备份原有PAM配置
cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
# 复制二进制文件到系统路径
cp /usr/local/openssh/sbin/sshd /usr/sbin/
cp /usr/local/openssh/bin/ssh /usr/bin/
cp /usr/local/openssh/bin/ssh-keygen /usr/bin/
# 添加服务到系统启动项
chkconfig --add sshd
5.4 修改SSH配置文件
编辑/etc/ssh/sshd_config,确保包含以下关键配置:
bash复制echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config
echo 'UsePAM yes' >> /etc/ssh/sshd_config
这些配置确保:
- 允许root登录(生产环境建议禁用)
- 启用密码认证
- 启用PAM认证模块
5.5 配置PAM模块
确保/etc/pam.d/sshd文件包含以下内容:
bash复制#%PAM-1.0
auth required pam_sepermit.so
auth substack password-auth
auth include postlogin
account required pam_nologin.so
account include password-auth
password include password-auth
session required pam_selinux.so close
session required pam_loginuid.so
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
6. 启动服务与验证
6.1 启动SSH服务
bash复制# 结束现有SSH进程(确保当前会话不会被中断)
ps -ef | grep sshd | grep -v grep | awk '{print $2}' | xargs kill
# 启动新SSH服务
/etc/init.d/sshd start
# 或者使用
systemctl start sshd
6.2 验证版本
bash复制sshd -V
# 应显示:OpenSSH_9.8p1, OpenSSL 3.2.1 30 Jan 2024
ssh -V
# 应显示相同版本信息
6.3 检查服务状态
bash复制systemctl status sshd
正常输出应显示服务为active (running)状态,并监听22端口。
7. 常见问题与解决方案
7.1 升级后无法登录
如果升级后无法通过SSH登录,通常是由于以下配置问题:
bash复制# 确保sshd_config中有以下配置
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config
echo 'UsePAM yes' >> /etc/ssh/sshd_config
# 然后重启SSH服务
/etc/init.d/sshd restart
7.2 启动时报"no hostkeys available"
这个错误通常是由于密钥文件权限问题导致:
bash复制# 修正密钥文件权限
chown root:root /etc/ssh/*
chmod 600 /etc/ssh/*
7.3 SELinux导致的问题
如果SELinux处于enforcing模式,可能会导致SSH登录失败。临时解决方案:
bash复制# 临时设置为permissive模式
setenforce 0
# 永久禁用(需重启)
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
注意:生产环境不建议完全禁用SELinux,可以针对SSH配置适当的SELinux策略。
7.4 编译过程中的常见错误
-
缺少依赖包:如果编译失败,通常是由于缺少某些开发包。根据错误信息安装对应的*-devel包。
-
版本不兼容:确保OpenSSL和zlib的版本与OpenSSH的要求匹配。本文使用的版本组合经过验证。
-
符号链接问题:如果遇到库文件找不到的错误,检查/usr/lib64/下的符号链接是否正确指向新安装的库文件。
8. 安全加固建议
虽然我们为了便利启用了root登录和密码认证,但在生产环境中建议:
-
禁用root登录:修改sshd_config中的
PermitRootLogin为no。 -
使用密钥认证:禁用密码认证,改用更安全的SSH密钥认证。
-
修改默认端口:将SSH端口从22改为其他高端口,减少自动化攻击。
-
启用防火墙:使用firewalld或iptables限制SSH访问来源IP。
-
定期更新:关注OpenSSH的安全公告,及时应用安全补丁。
完成所有配置后,建议在新的SSH会话中测试连接,确认一切正常后再关闭原来的会话。这样即使新配置有问题,还可以通过原会话进行修复。