不能仅靠 apt-key list 防范私有源劫持,因其只显示已导入公钥,不关联源、不验证来源;应建立“源–密钥–签名”绑定,用 sources.list.d 中 signed-by 指定专属 keyring,并核对官网指纹。

直接比对线上主机的 apt-key list 输出,不能有效防范私有源劫持——因为该命令只显示“已导入的公钥”,不体现“哪个密钥对应哪个源”,更不校验密钥来源是否真实可信。真正关键的是建立“源–密钥–签名”三者绑定关系,并切断非官方密钥注入路径。
看清 apt-key list 的本质局限
apt-key list 仅列出当前 APT 信任数据库中所有 GPG 公钥的指纹、创建时间与 UID 信息。它无法告诉你:
- 这个密钥是否被某个
sources.list或sources.list.d/中的源实际引用 - 该密钥是否通过 HTTPS 官网下载,还是从 keyserver 随机拉取(易被污染)
- 密钥是否已过期、是否被撤销、是否属于已下线的旧仓库
- 同一密钥是否被多个不同域名的第三方源共用(增加单点失效风险)
用 sources.list.d + keyring 路径做精准映射
现代 Debian/Ubuntu 推荐弃用 apt-key 全局管理,改用“按源隔离密钥”方式。每个第三方源应有专属 .gpg 密钥环文件,并在 sources.list 条目中显式指定路径:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 检查所有源定义:运行
grep -r "deb.*https" /etc/apt/sources.list /etc/apt/sources.list.d/,确认协议为 HTTPS - 定位密钥绑定:对每个第三方源(如
docker-ce.list),查看其是否含[arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] - 验证密钥文件存在性:
ls -l /usr/share/keyrings/*.gpg,缺失即说明该源未正确配置信任链 - 比对密钥指纹:
gpg --no-default-keyring --keyring /usr/share/keyrings/docker-archive-keyring.gpg --list-keys --with-fingerprint,再与 Docker 官网公布的指纹逐字核对
清理不可信密钥并阻断自动注入
很多自动化脚本(尤其 Docker、NodeSource、MongoDB 安装文档)仍使用过时的 apt-key add 方式,把密钥无差别塞进全局信任库,埋下劫持隐患:
- 列出所有非官方密钥:
apt-key list | grep -A1 "pub.*2048R\|4096R" | grep -B1 -E "(untrusted|third-party|unknown)" - 删除高风险密钥:
sudo apt-key del "C80E383C3DE9F082E01391A0366C67DE91CA5D5F"(示例 ID,需替换为实际可疑指纹) - 禁用 apt-key recv-keys:
sudo rm -f /usr/bin/apt-key或重命名为apt-key.bak(仅限高级运维,需确保团队无遗留脚本依赖) - 审计 cron 和 systemd timer:运行
systemctl list-timers --all | grep apt和crontab -l; sudo crontab -l,防止定时任务偷偷重装密钥
上线前必须执行的三项交叉验证
每次新增源或升级系统后,执行以下三步可快速识别异常:
-
源协议一致性检查:所有
deb行必须以https://开头;出现http://或ftp://立即注释并上报 -
密钥路径存在性检查:对每个含
signed-by=的源,运行test -f /path/to/key.gpg && echo OK || echo "MISSING KEY" -
签名验证实测:临时启用该源后执行
apt update 2>&1 | grep "NO_PUBKEY\|BADSIG",出现报错即说明密钥未生效或已被篡改










