Centos7环境升级openssh7.4p1至openssh9.8p1版本
- 引
- 测试步骤
-
- centos7容器
- 安装yum-utils
- 安装openssh
- openssh配置和启动
-
- [生成 SSH 主机密钥](#生成 SSH 主机密钥)
- [修改 SSH 配置文件](#修改 SSH 配置文件)
- [设置 Root 密码](#设置 Root 密码)
- [启动 SSH 服务](#启动 SSH 服务)
- 远程连接容器内centos
- 安装打包依赖
- [下载打包脚本、指定 openssh 版本](#下载打包脚本、指定 openssh 版本)
- [一键下载源码 + 编译打包](#一键下载源码 + 编译打包)
引
生产环境系统使用的是Centos7版本,默认安装的是openssh7.4p1,最近扫描出来这个组件存在很多中高风险的安全漏洞,打补丁的方式感觉很繁琐,工作量比较大,选择尝试直接升级openssh版本,最终比对了一下,选择了9.8p1版本。
由于是生产环境,之前的安装部署工作都没有参与,个人还是比较谨慎。
想到的办法是在本地docker环境模拟一下7.4升级9.8的操作,看是否会出现ssh会话断连以及升级后无法连接等问题。

测试步骤
centos7容器
配置好镜像源后,直接拉取centos:7镜像
bash
docker pull centos:7
启动容器
bash
# 注意将容器内部的22端口映射出来
docker run -d --name centos7 -p 2222:22 centos:7 sleep infinity
启动没问题后,可以使用docker exec命令进入容器内部,使用ssh -V命令查看,应该是没有预装的,镜像版本的centos比较纯净,很多工具都没有安装的。
bash
# 进入容器内部,注意替换为自己的container id
docker exec -it 容器Id /bin/bash
# 查看ssh和ssl版本
ssh -V
openssl version
安装yum-utils
我这里的容器内部可以访问外网,并且我的宿主机是arm架构的,对应的,容器也是arm的,可能和主流的x86 amd架构有区别,大体思路我认为是一致的。
修改ARM64 专用阿里云 centos7 vault 源
bash
cat > /etc/yum.repos.d/CentOS-Base.repo <<'EOF'
[base]
name=CentOS-7.9 Base-Aliyun-aarch64
baseurl=https://mirrors.aliyun.com/centos-vault/altarch/7.9.2009/os/aarch64/
enabled=1
gpgcheck=0
[updates]
name=CentOS-7.9 Updates-Aliyun-aarch64
baseurl=https://mirrors.aliyun.com/centos-vault/altarch/7.9.2009/updates/aarch64/
enabled=1
gpgcheck=0
[extras]
name=CentOS-7.9 Extras-Aliyun-aarch64
baseurl=https://mirrors.aliyun.com/centos-vault/altarch/7.9.2009/extras/aarch64/
enabled=1
gpgcheck=0
EOF
刷新 yum 缓存
bash
yum clean all && yum makecache
安装yum-utils
bash
yum install -y yum-utils
安装openssh
在/opt/ssh目录下,下载openssh-server及其依赖包,并升级安装安装
bash
mkdir -p /opt/ssh
# 进入目录
cd /opt/ssh
# 下载rpm包
yumdownloader --resolve openssl openssh openssh-server openssh-clients
# 升级覆盖安装
rpm -Uvh --replacepkgs *.rpm
查看ssh和ssl版本
bash
ssh -V
openssl version
openssh配置和启动
生成 SSH 主机密钥
由于容器是纯净环境,通常缺少主机密钥,直接启动 sshd 会报错(提示无法加载 host key)。
bash
bash
ssh-keygen -A
(注:该命令会自动在 /etc/ssh/ 目录下生成 RSA、ECDSA 和 ED25519 等类型的密钥)
修改 SSH 配置文件
编辑 /etc/ssh/sshd_config 文件,确保允许 root 用户通过密码登录:
bash
vi /etc/ssh/sshd_config
找到并修改或取消以下两行的注释:
bash
PermitRootLogin yes
PasswordAuthentication yes
设置 Root 密码
Docker 默认拉取的 CentOS 镜像中,root 账户是没有密码的,必须手动设置一个密码才能进行 SSH 认证:
bash
passwd root
按提示输入两次新密码
启动 SSH 服务
bash
# 后台运行
/usr/sbin/sshd -D &
远程连接容器内centos
使用ssh工具连接,localhost的2222端口,输入用户名root和秘钥,测试连接,正常情况到这里就可以登录了。如果使用localhost不行,换成127.0.0.1试试。
到此,准备工作就算完成了。
其实,如果我的环境是x86 amd的,应该更好办,网上9.8的资源支持amd架构的比较多,但是arm的不好找。能找到完整有效rpm包的话,直接下载下来升级覆盖就行了。
安装打包依赖
bash
# 安装开发套件+rpmbuild打包工具
yum groupinstall -y "Development Tools"
yum install -y rpm-build pam-devel krb5-devel zlib-devel libXt-devel libX11-devel gtk2-devel perl-IPC-Cmd perl-Time-Piece systemd-devel imake wget unzip
下载打包脚本、指定 openssh 版本
bash
cd /opt
wget https://github.com/boypt/openssh-rpms/archive/refs/heads/main.zip
unzip main.zip && cd openssh-rpms-main
这里如果容器里面下载不下来,可以在宿主机直接通过地址下载后,复制到容器内部的/opt目录下
编辑ssl和ssh的版本信息
bash
# 修改版本配置version.env
vim version.env
# 修改:
OPENSSHSRC=openssh-9.8p1.tar.gz # 要9.9就改成openssh-9.9p1.tar.gz
# OpenSSL选型:9.x openssh最低需要openssl1.1.1,脚本自动下载内置openssl源码编译进rpm,不改动系统原生openssl1.0.2k,完美兼容centos7自带openssl
OPENSSLSRC=openssl-1.1.1w.tar.gz
一键下载源码 + 编译打包
这里会根据version.env配置的版本去拉取对应的源码,再编译
bash
# 下载openssh、openssl、askpass源码
bash pullsrc.sh
这里如果拉取有问题,可以直接替换镜像源,或者切换到downloads目录下,直接wget下载,目的其实你就是根据version信息去下载对应版本的源码包。

编译
bash
# 编译生成rpm,输出目录:./RPMS/aarch64/
bash compile.sh el7
我这里编译时遇到了以下报错
bash
error: File not found: /opt/openssh-rpms-main/el7/BUILDROOT/openssh-9.8p1-1.el7.aarch64/usr/libexec/openssh/sshd-auth
RPM build errors:
File not found: /opt/openssh-rpms-main/el7/BUILDROOT/openssh-9.8p1-1.el7.aarch64/usr/libexec/openssh/sshd-auth
/opt/openssh-rpms-main
删除 spec 里的 sshd-auth 行,再重新编译
bash
sed -i '/sshd-auth/d' el7/SPECS/openssh.spec
bash compile.sh el7
升级
编译完成后,在目录/opt/openssh-rpms-main/el7/RPMS/aarch64下生成了以下三个rpm包

进入该目录,直接安装rpm包
bash
# 进入目录
cd /opt/openssh-rpms-main/el7/RPMS/aarch64
# 检查以下依赖项
yumdownloader --resolve openssh-9.8p1-1.el7.aarch64.rpm openssh-clients-9.8p1-1.el7.aarch64.rpm openssh-server-9.8p1-1.el7.aarch64.rpm
# 安装
rpm -Uvh --force --nodeps openssh-*.rpm

到了这里,升级安装就完成了,但新的会话可能还是连接不进来,需要做一些配置
特别注意,不要关闭当前窗口
配置更新并重载
bash
# 检查配置,如果有报错的话就用ai查一下缺啥
sshd -t
bash
# 新的 sshd 配置里带了容器不支持的 GSSAPI 认证参数
sed -i 's/^GSSAPIAuthentication/#&/' /etc/ssh/sshd_config
sed -i 's/^GSSAPICleanupCredentials/#&/' /etc/ssh/sshd_config
# 删除错误的配置行
sed -i '/^HostKeyAlgorithms/d' /etc/ssh/sshd_config
sed -i '/^PubkeyAcceptedAlgorithms/d' /etc/ssh/sshd_config
sed -i '/^KexAlgorithms/d' /etc/ssh/sshd_config
# 写入 OpenSSH 9.8 支持的正确兼容配置
echo "PubkeyAcceptedAlgorithms +ssh-rsa" >> /etc/ssh/sshd_config
echo "HostKeyAlgorithms +ssh-rsa" >> /etc/ssh/sshd_config
# 开启密码登录 + root 登录
sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
sed -i 's/^PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
# 测试配置
sshd -t
检查没问题后,重启或者重新加载配置,我这里为了避免重启之后出现断联(模拟生产环境),选择重新加载配置
bash
sshd_pid=$(ps aux | grep "/usr/sbin/sshd -D" | grep -v grep | awk '{print $2}')
kill -HUP $sshd_pid
至此,升级工作测试完成,新的会话可以正常连接。