用心打造
VPS知识分享网站

APT更新提示NO_PUBKEY怎么办?软件源签名修复教程

在Debian或Ubuntu服务器执行 apt update 时,如果看到 NO_PUBKEYThe following signatures couldn't be verified,说明APT无法用本机信任的公钥验证该仓库的Release元数据。软件包不一定已经损坏,但这条信任链当前无法成立。

正确做法不是跳过签名检查,而是确认报错仓库、从官方渠道取得对应密钥,并用Signed-By限制它只信任该仓库。 这样既能恢复更新,也不会把第三方密钥变成全局信任。

NO_PUBKEY

先锁定报错的软件源和密钥指纹

重新刷新索引并完整保留输出:

sudo apt update 2>&1 | tee /tmp/apt-update.log

重点记录仓库域名、发行版代号、组件名称,以及 NO_PUBKEY 后面的长十六进制指纹。不要只凭最后8位短ID下载密钥;短ID更容易发生碰撞,也不足以证明密钥身份。

随后列出所有已配置源:

grep -RhsE '^[[:space:]]*(deb|Types:)' \
  /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null

如果同一仓库同时存在传统 .list 和新式 .sources 文件,应先消除重复项。密钥必须与具体仓库地址对应,不能看到NO_PUBKEY就随便导入搜索结果中的公钥。

判断是密钥缺失、过期还是仓库配置错误

NO_PUBKEY最常见于首次添加第三方源、系统升级后遗留旧源、仓库轮换签名密钥,以及keyring文件被删除或权限不正确。若同时出现 EXPKEYSIG,更接近密钥过期;出现 BADSIG 则要怀疑下载损坏、代理缓存或仓库端签名异常。

先核对系统代号与源中suite是否匹配:

. /etc/os-release
printf 'ID=%s VERSION_CODENAME=%s\n' "$ID" "$VERSION_CODENAME"

把第三方源暂时注释后再次执行 apt update,可以确认问题是否来自该源。不要通过修改系统时间、反复清缓存或更换镜像来掩盖指纹不匹配;这些动作不能建立可信身份。

从软件源官方渠道获取签名密钥

优先使用仓库官方安装文档给出的HTTPS地址。以通用写法为例,先创建专用目录,再下载并转换为二进制keyring:

sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://packages.example.com/repository-key.gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/example.gpg
sudo chmod 0644 /etc/apt/keyrings/example.gpg

如果官方直接提供去装甲后的 .gpg 文件,可用 curl -fsSL 下载到该目录,不要重复执行 gpg --dearmor。在继续配置前检查完整指纹:

gpg --show-keys --with-fingerprint /etc/apt/keyrings/example.gpg

将输出与官方文档在另一个可信通道公布的指纹逐字符比较。下载成功只说明拿到了一个文件,指纹一致才说明拿对了密钥。

用Signed-By把密钥绑定到单一仓库

传统单行源可以这样写:

deb [signed-by=/etc/apt/keyrings/example.gpg] https://packages.example.com/debian stable main

新式deb822源可写成:

Types: deb
URIs: https://packages.example.com/debian
Suites: stable
Components: main
Signed-By: /etc/apt/keyrings/example.gpg

Signed-By 会限制该源只能使用指定keyring中的密钥,而不是让它信任系统中所有第三方密钥。keyring还必须能被 _apt 用户读取,因此常用权限是目录0755、文件0644。

不要把新密钥继续塞进全局trusted.gpg。 现代APT推荐每个仓库使用独立文件,删除某个源时也能一并移除其信任边界。

为什么不建议继续使用apt-key

apt-key add 管理的是全局受信密钥集合,任何被加入其中的密钥理论上都可能为其他未严格绑定的仓库签名。官方手册已将大多数 apt-key 用法标记为弃用,仅保留少数兼容用途。

迁移时先找出旧文件:

ls -l /etc/apt/trusted.gpg /etc/apt/trusted.gpg.d/ 2>/dev/null

不要一次性删除所有旧keyring。应逐个确认它们服务的仓库,为仍在使用的源建立独立文件和 Signed-By,刷新成功后再清理对应旧条目。迁移目标是缩小信任范围,不是简单换一个存放目录。

修复后刷新索引并做完整验证

完成配置后清理旧索引并重新拉取:

sudo rm -rf /var/lib/apt/lists/partial/*
sudo apt update

不必常规删除整个 /var/lib/apt/lists;先清理未完成下载即可。检查输出应没有NO_PUBKEY、BADSIG、EXPKEYSIG或未签名仓库警告,再查看包候选来源:

apt-cache policy package-name

确认版本确实来自预期域名和suite后,先用测试包或 apt-get -s upgrade 模拟升级。验收标准不仅是命令退出码为0,还包括来源、指纹和候选版本都符合预期。

避免不安全的临时绕过

不要设置 Acquire::AllowInsecureRepositories=true,不要给源添加 trusted=yes,也不要使用允许未认证软件包的参数。这些选项会把身份验证失败变成静默风险,攻击者或错误镜像提供的包可能进入系统。

如果业务急需恢复而官方密钥无法取得,应先禁用有问题的第三方源,让Debian或Ubuntu官方源继续更新安全补丁;需要其中软件时,可回退到已验证的内部镜像或固定的已知版本。

需要在隔离环境演练软件源迁移时,可以用 萤光云 建立同版本测试机,也可以通过 LightNode 准备临时节点。测试机仍要使用真实的签名校验,不要复制生产凭据。

建立可维护的软件源密钥流程

把每个仓库的源文件、keyring路径、完整指纹、官方获取地址和预计轮换日期记录在配置管理中。部署时固定HTTPS地址,并在导入后自动校验指纹;密钥轮换则先并行加入新密钥,验证新签名可用后再移除旧密钥。

定期检查已经下线的仓库和孤立keyring,避免服务器长期保留无用信任。真正稳定的修复应当可重复部署、可审计,并能在密钥再次轮换时快速定位。

常见问题

只有一台服务器报NO_PUBKEY,其他机器正常,是什么原因?

通常是该机缺少keyring、文件权限不对、源配置未写 Signed-By,或仍引用旧路径。对比源文件和完整指纹比复制整台机器的trusted.gpg更安全。

可以从公钥服务器按短ID获取密钥吗?

不建议。应从仓库官方文档提供的地址获取,并核对完整指纹。公钥服务器只负责分发,不能替你证明密钥属于目标仓库。

更换镜像地址后还需要重新导入密钥吗?

如果新镜像属于同一仓库并由同一密钥签名,可以复用;若运营方或Release签名发生变化,必须按新仓库文档重新验证。

温馨提示

软件源签名是服务器供应链安全的第一道门。任何以关闭认证换取apt update成功的做法,都只能算绕过故障,不能算修复。 修改前备份源文件,修改后保存完整指纹和验证记录。

赞(0)
未经允许不得转载;国外VPS测评网 » APT更新提示NO_PUBKEY怎么办?软件源签名修复教程
分享到