1.4.5 包签名校验与安全更新策略
包签名校验是保障软件来源可信与防篡改的基础措施,应作为仓库管理与更新策略的默认流程。核心思路是导入发行版或可信仓库的 GPG 公钥,对仓库元数据与包体进行完整性和身份校验,防止中间人攻击与供应链污染。
签名校验原理与范围(含草图)
RPM/YUM/DNF 签名校验实践(含安装/命令解释)
- 目标:导入公钥、强制签名校验、验证安装过程拒绝未签名包。
1) 安装工具(如系统精简未安装 rpm/gpg)
# RHEL/CentOS/Rocky
sudo dnf install -y rpm gpg
2) 导入发行版或内部仓库公钥
# 从官方路径导入(示例:Rocky)
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
# 从内网HTTP导入(示例)
sudo rpm --import http://repo.intra.example.com/keys/RPM-GPG-KEY-INTRA
命令解释:rpm --import 将公钥写入 RPM 的信任库,供后续校验使用。
3) 仓库配置启用校验
# /etc/yum.repos.d/intra.repo
[intra-base]
name=Intra Base
baseurl=http://repo.intra.example.com/rocky/9/BaseOS/x86_64/os/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=http://repo.intra.example.com/keys/RPM-GPG-KEY-INTRA
参数解释:
- gpgcheck=1:校验包体签名
- repo_gpgcheck=1:校验仓库元数据签名
- gpgkey=:公钥位置
4) 验证公钥与安装行为
# 查看已导入公钥
rpm -qi gpg-pubkey* | egrep 'Name|Version|Summary|Build Date'
# 触发更新校验(预期:未签名包将被拒绝)
sudo dnf install -y nginx
APT/DEB 签名校验实践(含安装/命令解释)
- 目标:使用 signed-by 绑定仓库公钥,缩小信任面。
1) 安装工具
# Debian/Ubuntu
sudo apt update
sudo apt install -y gnupg ca-certificates
2) 获取并保存仓库公钥
# 建议专用 keyring 目录
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL http://repo.intra.example.com/keys/intra.gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/intra.gpg
命令解释:gpg --dearmor 将 ASCII 公钥转换为二进制 keyring。
3) 绑定仓库与公钥
# /etc/apt/sources.list.d/intra.list
deb [signed-by=/etc/apt/keyrings/intra.gpg] http://repo.intra.example.com/ubuntu jammy main
4) 更新与校验
sudo apt update
sudo apt install -y nginx
安全更新策略(含配置示例与回滚思路)
- 分层更新:安全更新优先、功能更新按窗口、紧急修复走审批。
1) 版本锁定示例(RPM)
# 安装版本锁定插件
sudo dnf install -y 'dnf-command(versionlock)'
# 锁定关键组件版本
sudo dnf versionlock add nginx-1.24.0-1.el9
# 查看锁定列表
sudo dnf versionlock list
2) 版本锁定示例(APT)
# 锁定包版本
sudo apt-mark hold nginx
# 查询锁定状态
apt-mark showhold
3) 更新窗口与日志记录(示例脚本)
#!/usr/bin/env bash
# /usr/local/sbin/secure-update.sh
set -euo pipefail
log=/var/log/secure-update.log
date >> "$log"
dnf -y update --security | tee -a "$log"
排错清单与定位命令
- 现象:更新时报错 GPG key not installed
# 解决:导入公钥并重试
sudo rpm --import http://repo.intra.example.com/keys/RPM-GPG-KEY-INTRA
sudo dnf clean metadata && sudo dnf makecache
- 现象:
repomd.xml signature could not be verified
# 可能原因:repo_gpgcheck=1 但仓库未签名元数据
# 临时验证:对照仓库管理员提供的签名与公钥
sudo curl -I http://repo.intra.example.com/repodata/repomd.xml
- 现象:APT 报
NO_PUBKEY
# 解决:导入缺失公钥并绑定 signed-by
sudo gpg --dearmor -o /etc/apt/keyrings/intra.gpg /tmp/intra.pub
sudo apt update
练习
1) 在测试机上创建一个未签名的本地 RPM 仓库(仅用于学习),确认 gpgcheck=1 时安装失败。
2) 将 repo_gpgcheck=1 启用后,观察 dnf makecache 的错误提示并定位缺失签名文件。
3) 在 Ubuntu 上为同一仓库配置两个不同的 signed-by 公钥,验证只有匹配公钥才允许更新。