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 / 防火墙、密钥权限,掌握后两种方式都能熟练使用。
相关推荐
实心儿儿4 小时前
Linux —— 应用层协议HTTP
linux·网络·http
有续技术5 小时前
哈斯 (Haas) 机床 IP、端口号配置内容总结
运维·服务器
小张同学a.5 小时前
LAMP架构2
linux·运维·网络·架构·负载均衡
千河殇 多想和她5 小时前
如何在Reaonix中使用CodeGraph以及CodeGraph效果实测经验分享
linux·运维·ubuntu
心念枕惊5 小时前
新写了个直播录制工具,可录制抖音快手斗鱼直播
运维·服务器·数据库
躺不平的理查德6 小时前
CMAKE备忘录
linux·运维·服务器
9624566 小时前
跨域与私有网络访问限制排查实录
运维·服务器·网络
面对疾风叭!哈撒给6 小时前
Linux ARM架构的docker和docker-compose离线安装
linux·docker·架构
阿虎儿6 小时前
Linux 下为局域网 IP(如 192.168.1.100)打造不受浏览器警告的自签名 SSL/TLS 证书
linux·安全·https
不在逃避q7 小时前
一步一步学习使用LiveBindings()TListView进阶使用(),打造天气预报程序
服务器·数据库·学习