方案说明
该方案参考你看到的 CSDN 文章思路,属于 **「独立目录编译 + 手动拷贝系统文件 + 重建系统服务」** 的半自动升级方式:
- 先将
OpenSSL、OpenSSH编译安装到独立隔离目录,不直接覆盖系统原有文件,降低编译炸系统风险; - 再手动把新版二进制程序、工具拷贝到系统标准路径,让系统默认调用新版;
- 重建
systemd服务文件,适配新版启动逻辑; - 全程保留旧文件备份,支持一键回滚,适合生产环境谨慎升级、不想直接
--prefix=/usr全覆盖的场景。
环境基线
- 操作系统:银河麒麟 V10(RPM 系)
- 升级版本:OpenSSH 10.3p1 + OpenSSL 3.6.2
- 独立安装目录:
- OpenSSL:
/usr/local/openssl3 - OpenSSH:
/usr/local/openssh
- OpenSSL:
- 系统标准路径:
/usr/bin、/usr/sbin、/usr/libexec、/etc/ssh
方案优缺点
✅ 优点:
- 编译阶段完全隔离系统,失误不会直接破坏系统自带 SSH/OpenSSL;
- 可灵活切换新旧版本,回滚简单;
- 兼容原有运维习惯,
systemctl、端口、路径和原生一致。
❌ 缺点:
- 步骤多、人工操作多,属于「半自动」;
- 需手动处理动态库、服务文件、文件拷贝,坑点比纯全覆盖多;
- 后续版本迭代仍需重复拷贝操作。
一、前置准备(必做)
1. 全局备份(生产环境重中之重)
备份系统原有 SSH 二进制、配置、服务文件,用于故障回滚
# 备份系统原有 ssh/sshd 二进制
mkdir -p /opt/ssh_backup
cp /usr/bin/ssh /opt/ssh_backup/ssh.bak
cp /usr/sbin/sshd /opt/ssh_backup/sshd.bak
cp /usr/bin/scp /opt/ssh_backup/scp.bak
# 备份 SSH 配置文件
cp -r /etc/ssh /opt/ssh_backup/etc_ssh.bak
# 备份 systemd 服务文件
cp /usr/lib/systemd/system/sshd.service /opt/ssh_backup/sshd.service.bak
2. 关闭 SELinux(麒麟 V10 必做,否则启动拦截)
# 临时关闭(当前生效)
setenforce 0
# 永久关闭(重启生效)
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
3. 安装编译依赖包
# 麒麟V10/ CentOS/RHEL 通用
yum install -y gcc make zlib-devel pam-devel perl perl-IPC-Cmd libselinux-devel libtool
4. 上传 / 解压源码包
假设源码放在 /opt 目录,按需修改路径:
cd /opt
# 解压 OpenSSL
tar -zxvf openssl-3.6.2.tar.gz
# 解压 OpenSSH
tar -zxvf openssh-10.3p1.tar.gz
二、第一步:独立编译安装 OpenSSL 3.6.2
安装到独立目录 /usr/local/openssl3,不覆盖系统自带 OpenSSL。
cd /opt/openssl-3.6.2
# 编译配置:指定独立安装目录
./config --prefix=/usr/local/openssl3 shared zlib-dynamic
# 编译(多线程加速,nproc 为CPU核心数)
make -j$(nproc)
# 安装到独立目录
make install
配置动态链接器(关键!否则找不到 SSL 库)
独立目录的动态库不会被系统默认识别,必须配置链接器:
# 新增 openssl 库路径
echo "/usr/local/openssl3/lib64" > /etc/ld.so.conf.d/openssl3.conf
# 刷新动态链接缓存
ldconfig
# 验证 OpenSSL 版本(独立目录调用)
/usr/local/openssl3/bin/openssl version
补充:如需全局调用新版 openssl,可临时配置环境变量(可选)
echo 'export PATH=/usr/local/openssl3/bin:$PATH' >> /etc/profile source /etc/profile openssl version
三、第二步:独立编译安装 OpenSSH 10.3p1
安装到独立目录 /usr/local/openssh,仅编译不改动系统文件。
cd /opt/openssh-10.3p1
# 编译配置:指定独立目录 + 关联新版OpenSSL + 启用PAM + 禁用废弃GSSAPI
./configure \
--prefix=/usr/local/openssh \
--sysconfdir=/etc/ssh \
--with-ssl-dir=/usr/local/openssl3 \
--with-zlib \
--with-pam \
--without-gssapi
# 编译
make -j$(nproc)
# 安装到独立目录
make install
补充基础目录与主机密钥
OpenSSH 运行依赖专属空目录与密钥文件:
# 创建专属运行目录并授权
mkdir -p /var/empty
chmod 700 /var/empty
# 生成主机密钥(避免密钥缺失启动失败)
ssh-keygen -A
# 修正密钥权限(SSH 强校验)
chmod 600 /etc/ssh/ssh_host_*
chown root:root /etc/ssh/ssh_host_*
四、第三步:手动迁移新版程序到系统路径(半自动核心)
将 /usr/local/openssh 下的新版二进制、工具手动拷贝到系统标准路径,实现全局调用新版。
1. 拷贝主程序(ssh、sshd、scp 等)
# 客户端工具 /usr/bin
cp /usr/local/openssh/bin/* /usr/bin/
# 服务端主程序 /usr/sbin
cp /usr/local/openssh/sbin/sshd /usr/sbin/
# SFTP 等辅助工具 /usr/libexec
cp /usr/local/openssh/libexec/* /usr/libexec/
2. 验证当前版本
此时系统默认调用已变为新版 OpenSSH:
ssh -V
sshd -V
五、第四步:修正 sshd_config 配置文件(适配 10.3p1)
沿用系统原有配置文件,只修复废弃参数 + SFTP 路径(历史踩坑点):
# 1. 注释废弃的 GSSAPI 参数
sed -i 's/^GSSAPIAuthentication/#GSSAPIAuthentication/' /etc/ssh/sshd_config
sed -i 's/^GSSAPICleanupCredentials/#GSSAPICleanupCredentials/' /etc/ssh/sshd_config
# 2. 注释/删除废弃 NotifyHostKeys
sed -i 's/^NotifyHostKeys/#NotifyHostKeys/' /etc/ssh/sshd_config
# 3. 修正 SFTP 路径(匹配系统 /usr/libexec)
sed -i 's#Subsystem sftp .*#Subsystem sftp /usr/libexec/sftp-server#' /etc/ssh/sshd_config
# 4. 校验配置(无输出=配置正常)
sshd -t
如果你想用极简配置,直接覆盖写入:
cat > /etc/ssh/sshd_config << EOF Port 22 PermitRootLogin yes PasswordAuthentication yes PubkeyAuthentication yes UsePAM yes UseDNS no X11Forwarding no Subsystem sftp /usr/libexec/sftp-server EOF
六、第五步:重建 systemd sshd 服务(重点)
独立编译 + 手动拷贝后,原有服务文件部分逻辑不匹配,必须重建服务文件。
1. 停止旧服务、清理旧服务链接
# 停止当前 SSH 服务
systemctl stop sshd
# 禁用旧开机自启
systemctl disable sshd
# 删除旧服务软链接
rm -f /etc/systemd/system/multi-user.target.wants/sshd.service
# 备份原有服务文件(前面已全局备份,此处可跳过)
mv /usr/lib/systemd/system/sshd.service /usr/lib/systemd/system/sshd.service.old
2. 创建全新 systemd 服务文件
两种方式任选其一,方式一(源码自带)最推荐。
方式一:使用 OpenSSH 源码自带服务文件(官方标准)
cd /opt/openssh-10.3p1
# 拷贝红帽系适配的 service 文件
cp contrib/redhat/sshd.service /usr/lib/systemd/system/sshd.service
方式二:手动编写服务文件(通用兼容)
vi /usr/lib/systemd/system/sshd.service
写入以下内容(适配系统路径,无需修改):
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/sshd
# 启动前校验配置
ExecStartPre=/usr/sbin/sshd -t
# 前台启动sshd,适配systemd
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
保存退出 :wq。
3. 重载 systemd 配置 + 启用服务
# 重载服务列表(修改service文件后必执行)
systemctl daemon-reload
# 设置开机自启
systemctl enable sshd
# 启动 SSH 服务
systemctl start sshd
# 查看服务状态
systemctl status sshd
七、第六步:防火墙放行(麒麟 V10 必做)
firewall-cmd --permanent --add-service=ssh
firewall-cmd --reload
八、全功能验证(确认升级成功)
# 1. 版本校验
ssh -V && sshd -V
# 2. 配置语法校验
sshd -t
# 3. 端口监听校验
ss -lntp | grep sshd
# 4. 本地登录测试(密码登录正常)
ssh root@127.0.0.1
# 5. SFTP 功能测试(文件传输正常)
sftp root@127.0.0.1
九、完整回滚方案(生产故障应急)
新版异常时,一键切回系统原有 SSH,全程基于第一步的备份文件:
# 1. 停止新版服务
systemctl stop sshd
# 2. 恢复原有二进制程序
cp /opt/ssh_backup/ssh.bak /usr/bin/ssh
cp /opt/ssh_backup/sshd.bak /usr/sbin/sshd
cp /opt/ssh_backup/scp.bak /usr/bin/scp
# 3. 恢复原有配置文件
rm -rf /etc/ssh
cp -r /opt/ssh_backup/etc_ssh.bak /etc/ssh
# 4. 恢复原有 systemd 服务文件
mv /usr/lib/systemd/system/sshd.service /usr/lib/systemd/system/sshd.service.new
cp /opt/ssh_backup/sshd.service.bak /usr/lib/systemd/system/sshd.service
# 5. 重载服务、重启
systemctl daemon-reload
systemctl enable sshd
systemctl start sshd
# 6. 验证回滚结果
ssh -V
systemctl status sshd
十、常见坑点汇总(排错指南)
-
报错:error while loading shared libraries 原因:OpenSSL 动态库未配置链接器 解决:重新执行
ldconfig,检查/etc/ld.so.conf.d/openssl3.conf路径是否正确。 -
sshd 启动失败,提示无效配置项 原因:残留
GSSAPIAuthentication/NotifyHostKeys解决:按第四步注释废弃参数,重新sshd -t校验。 -
SFTP 连接失败 原因:
Subsystem sftp路径不匹配 解决:确保路径为/usr/libexec/sftp-server。 -
外网无法连接 22 端口 原因:防火墙 / SELinux 未关闭 解决:重新执行 SELinux 关闭、防火墙放行命令。
-
systemctl 识别不到服务 原因:修改 service 文件后未执行
daemon-reload解决:systemctl daemon-reload后再启动。
十一、两种升级方案对比(选型参考)
| 对比项 | 全覆盖安装(你之前使用) | 半自动独立编译 + 手动迁移(本文方案) |
|---|---|---|
编译 --prefix |
/usr(直接覆盖系统) |
/usr/local/xxx(独立隔离) |
| 操作难度 | 低,make install 一步到位 |
高,需手动拷贝、重建服务、配动态库 |
| systemd 服务 | 沿用原生服务,无需改动 | 必须重建服务文件 |
| 风险等级 | 中等(直接覆盖系统文件) | 低(编译阶段隔离,有完整备份回滚) |
| 维护成本 | 低,后续无需额外操作 | 高,版本迭代需重复拷贝文件 |
| 适用场景 | 常规运维、追求简单稳定 | 生产严格管控、怕系统崩溃、多版本测试 |
总结
- 这套半自动方案 核心逻辑:隔离编译 → 手动迁移 → 重建服务,适合对系统稳定性要求极高、不敢直接全覆盖的场景;
- 你之前用的全覆盖方案更简洁、运维效率更高,日常环境优先推荐;
- 两套方案核心坑点一致:废弃参数注释、SFTP 路径、SELinux / 防火墙、密钥权限,掌握后两种方式都能熟练使用。