OpenSSH 半自动升级方案(独立编译 + 手动迁移 + 重建 systemd 服务)

方案说明

该方案参考你看到的 CSDN 文章思路,属于 **「独立目录编译 + 手动拷贝系统文件 + 重建系统服务」** 的半自动升级方式:

  1. 先将 OpenSSLOpenSSH 编译安装到独立隔离目录,不直接覆盖系统原有文件,降低编译炸系统风险;
  2. 再手动把新版二进制程序、工具拷贝到系统标准路径,让系统默认调用新版;
  3. 重建 systemd 服务文件,适配新版启动逻辑;
  4. 全程保留旧文件备份,支持一键回滚,适合生产环境谨慎升级、不想直接 --prefix=/usr 全覆盖的场景

环境基线

  • 操作系统:银河麒麟 V10(RPM 系)
  • 升级版本:OpenSSH 10.3p1 + OpenSSL 3.6.2
  • 独立安装目录:
    • OpenSSL:/usr/local/openssl3
    • OpenSSH:/usr/local/openssh
  • 系统标准路径:/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

十、常见坑点汇总(排错指南)

  1. 报错:error while loading shared libraries 原因:OpenSSL 动态库未配置链接器 解决:重新执行 ldconfig,检查 /etc/ld.so.conf.d/openssl3.conf 路径是否正确。

  2. sshd 启动失败,提示无效配置项 原因:残留 GSSAPIAuthentication / NotifyHostKeys 解决:按第四步注释废弃参数,重新 sshd -t 校验。

  3. SFTP 连接失败 原因:Subsystem sftp 路径不匹配 解决:确保路径为 /usr/libexec/sftp-server

  4. 外网无法连接 22 端口 原因:防火墙 / SELinux 未关闭 解决:重新执行 SELinux 关闭、防火墙放行命令。

  5. systemctl 识别不到服务 原因:修改 service 文件后未执行 daemon-reload 解决:systemctl daemon-reload 后再启动。


十一、两种升级方案对比(选型参考)

对比项 全覆盖安装(你之前使用) 半自动独立编译 + 手动迁移(本文方案)
编译 --prefix /usr(直接覆盖系统) /usr/local/xxx(独立隔离)
操作难度 低,make install 一步到位 高,需手动拷贝、重建服务、配动态库
systemd 服务 沿用原生服务,无需改动 必须重建服务文件
风险等级 中等(直接覆盖系统文件) 低(编译阶段隔离,有完整备份回滚)
维护成本 低,后续无需额外操作 高,版本迭代需重复拷贝文件
适用场景 常规运维、追求简单稳定 生产严格管控、怕系统崩溃、多版本测试

总结

  1. 这套半自动方案 核心逻辑:隔离编译 → 手动迁移 → 重建服务,适合对系统稳定性要求极高、不敢直接全覆盖的场景;
  2. 你之前用的全覆盖方案更简洁、运维效率更高,日常环境优先推荐;
  3. 两套方案核心坑点一致:废弃参数注释、SFTP 路径、SELinux / 防火墙、密钥权限,掌握后两种方式都能熟练使用。
相关推荐
半旧夜夏1 小时前
【保姆级】微服务组件环境搭建(Docker Compose版)
java·linux·spring cloud·微服务·云原生·容器
Wpa.wk1 小时前
win环境本地文件上传远程服务器(scp/远程连接工具)
运维·服务器
Soari2 小时前
SSH 主机密钥冲突
运维·网络·ssh
爱莉希雅&&&2 小时前
zabbix快速搭建和使用
android·linux·数据库·zabbix·监控
z200509302 小时前
【linux学习】深入理解linux文件I/O,从C标准库到内核态
linux·学习·操作系统
清溪5492 小时前
Erlang-SSH未授权(CVE-2025-32433)复现
安全·ssh
黑泽明Coding2 小时前
使用密钥登录ssh
运维·ssh
J2虾虾2 小时前
Spring AI Alibaba - Tools
服务器·人工智能·spring
weixin_307779133 小时前
面向高性能保密计算的定制 Linux 系统构建与自动部署方案
linux·安全·网络安全·性能优化·系统安全