三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

CentOS 7运维实战:手把手教你从源码编译OpenSSH 9.3 RPM包(含spec文件修改避坑点)

CentOS 7运维实战:手把手教你从源码编译OpenSSH 9.3 RPM包(含spec文件修改避坑点)

CentOS 7生产环境安全升级指南:OpenSSH 9.3 RPM包深度定制与实战部署

在CentOS 7的长期维护周期中,系统自带的OpenSSH版本往往无法跟上安全更新的节奏。当关键漏洞爆发时,运维团队面临两难选择:要么冒险使用官方滞后的版本,要么承受源码编译带来的管理混乱。本文将揭示第三种解决方案——通过源码构建标准化RPM包,既满足安全需求,又保持系统可维护性。

1. 为什么选择RPM方式升级OpenSSH?

直接make install的源码安装方式在生产环境存在诸多隐患。我曾亲眼见证某企业因紧急修复漏洞而直接编译安装OpenSSH,结果三个月后系统崩溃时,运维团队无法确认当时修改了哪些文件,最终不得不重装整个系统。相比之下,RPM包提供以下核心优势:

  • 版本可控性:每个安装文件都有精确记录,支持rpm -q查询
  • 依赖管理:自动处理库文件关联,避免"工作但不知为何工作"的状态
  • 回滚能力:通过yum history undo快速恢复到前一版本
  • 批量部署:构建一次即可在多台服务器安全部署

关键决策点:当你的服务器需要满足等保2.0三级要求中的SSH加密强度条款时,自制RPM几乎是唯一选择。CentOS 7默认的OpenSSH 7.4即使打上所有补丁,也无法支持最新的ed25519-sk算法。

2. 构建环境准备与依赖处理

2.1 基础环境配置

首先确保构建机与生产环境保持一致性:

# 验证系统版本 cat /etc/redhat-release | grep 'CentOS Linux 7' # 清理可能存在的旧编译环境 rm -rf ~/rpmbuild

安装必备工具链时,特别注意开发库的版本匹配:

yum install -y rpm-build gcc make pam-devel \ zlib-devel openssl-devel perl-devel \ libXt-devel gtk2-devel

注意:生产环境中建议使用本地Yum仓库,避免直接连接外网下载依赖包。可以通过reposync工具同步官方源到内网。

2.2 源码获取与验证

从官方镜像获取源码并验证完整性:

wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.3p1.tar.gz wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.3p1.tar.gz.asc gpg --keyserver hkps://keys.openpgp.org --recv-keys 6D920D30 gpg --verify openssh-9.3p1.tar.gz.asc

常见问题处理:

  • 若遇到"No public key"错误,可尝试添加--keyserver hkps://keyserver.ubuntu.com
  • 国内服务器建议使用阿里云镜像加速下载

3. spec文件深度定制实战

3.1 初始spec文件获取

从源码中提取模板:

tar xzf openssh-9.3p1.tar.gz cp openssh-9.3p1/contrib/redhat/openssh.spec ~/rpmbuild/SPECS/

或者从现有RPM提取(更适合修改已有安装):

rpmrebuild -e -p --notest-install openssh-server-7.4p1-21.el7.x86_64.rpm

3.2 关键修改项详解

使用vim编辑spec文件时,这些是必须处理的痛点:

  1. 解决依赖冲突
# 注释掉可能引发问题的依赖项 #BuildRequires: openssl-devel < 1.1 #PreReq: /etc/ssh/sshd_config
  1. 优化编译选项(在%configure段添加):
--with-ssl-dir=/usr \ --with-pam \ --with-zlib \ --with-md5-passwords \ --with-tcp-wrappers
  1. 控制子包生成(避免不必要的组件):
%global no_x11_askpass 1 %global no_gnome_askpass 1
  1. 安全加固默认配置(在%install段添加):
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' $RPM_BUILD_ROOT/etc/ssh/sshd_config sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' $RPM_BUILD_ROOT/etc/ssh/sshd_config

3.3 版本信息维护

更新Release标签避免与官方包冲突:

Release: 1.el7.custom%{?dist}

添加自定义 changelog:

%changelog * Wed Aug 2023 Your Name <your.email@example.com> - 安全升级至OpenSSH 9.3p1 - 禁用root密码登录 - 移除X11相关依赖

4. 构建与测试全流程

4.1 完整构建命令

rpmbuild -ba --define '_topdir /root/rpmbuild' \ --define 'dist .el7' \ ~/rpmbuild/SPECS/openssh.spec

构建产物位置:

/root/rpmbuild/RPMS/x86_64/ ├── openssh-9.3p1-1.el7.custom.x86_64.rpm ├── openssh-clients-9.3p1-1.el7.custom.x86_64.rpm └── openssh-server-9.3p1-1.el7.custom.x86_64.rpm

4.2 测试安装方案

推荐使用Docker容器进行沙盒测试

docker run -it --rm centos:7 /bin/bash yum install -y yum-utils yum-config-manager --add-repo file:///path/to/your/rpm/repo yum install openssh-server-9.3p1-1.el7.custom

关键验证步骤:

  1. 服务启动:systemctl start sshd
  2. 版本确认:sshd -V
  3. 连接测试:ssh -v localhost
  4. 回滚测试:yum downgrade openssh-server

4.3 生产环境部署策略

  1. 分阶段部署

    • 先在非关键业务节点部署
    • 观察48小时无异常后推广
    • 最后处理数据库管理等关键节点
  2. 应急回滚方案

# 记录当前版本 rpm -qa openssh-server > /root/ssh_version_backup.txt # 准备旧版RPM包 yumdownloader openssh-server-7.4p1-21.el7 # 回滚命令(紧急情况使用) yum -y downgrade openssh-server-*.rpm

5. 高级调优与问题排查

5.1 性能优化参数

/etc/ssh/sshd_config中添加:

UseDNS no GSSAPIAuthentication no LoginGraceTime 30s MaxAuthTries 3 MaxSessions 10

5.2 SELinux策略调整

新建模块允许新版本SSH:

cat > ssh.te <<'EOF' module ssh 1.0; require { type sshd_t; class process setrlimit; } allow sshd_t self:process setrlimit; EOF checkmodule -M -m -o ssh.mod ssh.te semodule_package -o ssh.pp -m ssh.mod semodule -i ssh.pp

5.3 常见故障处理

问题1:服务启动报Permission denied

# 检查上下文 ls -Z /usr/sbin/sshd restorecon -v /usr/sbin/sshd

问题2:客户端连接超时

# 验证防火墙规则 iptables -L -n | grep 22 firewall-cmd --list-all # 检查TCP包装器 grep sshd /etc/hosts.allow

问题3:审计日志异常

ausearch -m AVC -ts recent | grep sshd

在完成所有测试后,建议将自定义的RPM包存入本地Yum仓库,方便后续批量部署。对于需要严格版本控制的金融环境,可以考虑使用rpm --sign添加数字签名。

← 返回列表