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 公钥,验证只有匹配公钥才允许更新。