如果你在Ubuntu系统上管理软件源时遇到"apt-key is deprecated"警告,或者发现添加的GPG密钥无法正常验证软件包,那么你正面临一个关键的过渡期:传统的apt-key管理方式已被淘汰,新的密钥环管理方法正在全面推行。这不仅是命令的简单替换,更涉及系统安全架构的升级。核心解决路径是,停止使用apt-key add命令,转而将GPG密钥直接导入到/etc/apt/trusted.gpg.d/目录下的独立密钥环文件,或者使用更现代的signed-by方法直接关联到具体的软件源列表文件。理解并掌握这套新机制,是确保你的Ubuntu系统持续安全、稳定更新软件的基础。

为什么apt-key被弃用?安全模型的根本转变

要理解新方法,必须先清楚旧命令被淘汰的原因。过去,运行sudo apt-key add keyfile.asc会将GPG公钥添加到系统全局的受信任密钥环(通常是/etc/apt/trusted.gpg/etc/apt/trusted.gpg.d/中的一个集合)。这意味着,任何被添加至此的密钥,都对所有软件源(包括官方源和任何第三方源)签署的软件包拥有信任权限。这带来了一个显著的安全风险:如果一个第三方源的密钥被泄露或恶意植入,攻击者可以利用该密钥为任何软件源(包括核心系统源)签署恶意软件包,系统也会毫无戒备地信任它。这是一种“全有或全无”的信任模型,粒度太粗,不符合最小权限安全原则。

新的管理哲学:源-密钥精确绑定

新的管理方式旨在建立“源到密钥”的一对一精确信任关系。其核心思想是:一个GPG密钥只对它关联的特定软件源列表(.list文件)负责。这样,即使某个第三方源的密钥出现问题,其影响范围也被严格限制在该源提供的软件包内,不会污染系统对其他软件源(尤其是Ubuntu官方源)的信任判断。这极大地提升了系统的整体安全性,是现代Linux发行版软件包管理安全演进的重要一步。

方法一:将密钥导入/etc/apt/trusted.gpg.d/目录(推荐过渡方法)

这是最接近旧习惯的新方法,适用于多数情况。你不再需要apt-key add,而是使用gpg命令本身来处理密钥,并将其输出到指定位置。

首先,获取软件源提供的GPG密钥文件。通常,它会以.asc(ASCII格式)或.gpg(二进制格式)扩展名提供。假设你下载或收到了一个repo-key.asc文件。

步骤1:将密钥转换为适合apt的格式并放入信任目录。 使用以下命令:

sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/repo-key.gpg repo-key.asc

命令解析:--dearmor选项将ASCII格式的密钥(armored)转换为二进制格式(gpg格式),这是apt所必需的。-o指定输出文件。请注意,输出文件最好使用.gpg扩展名,并放置于/etc/apt/trusted.gpg.d/目录下。系统会自动读取该目录下所有.gpg文件。

步骤2:创建或修改对应的软件源列表文件。/etc/apt/sources.list.d/目录下创建你的源文件,例如my-repo.list。其内容格式如下:

deb [arch=amd64] https://repo.example.com/ubuntu focal main

完成以上两步后,运行sudo apt update,apt就会自动使用trusted.gpg.d/目录下相应的密钥来验证该源提供的软件包索引。虽然密钥仍放在一个“受信任”的目录,但由于管理上每个源通常对应独立的密钥文件,在实践层面已经实现了分离。但更彻底的方法是下面的第二种。

方法二:使用signed-by实现绝对精准绑定(最安全、最现代)

这是Ubuntu官方文档目前推荐的最佳实践。它完全摒弃了全局信任目录,将密钥文件放在任意路径(通常是/usr/share/keyrings/),并在源列表行中显式声明使用哪个密钥文件来验证该源。这实现了最强的一对一绑定。

步骤1:将密钥文件放入/usr/share/keyrings/目录。 同样使用gpg --dearmor命令:

sudo gpg --dearmor -o /usr/share/keyrings/repo-key.gpg repo-key.asc

步骤2:在软件源列表行中通过[signed-by=...]选项指定密钥。 这是最关键的一步。你的my-repo.list文件内容应如下所示:

deb [signed-by=/usr/share/keyrings/repo-key.gpg arch=amd64] https://repo.example.com/ubuntu focal main

注意signed-by选项的完整路径。这样一来,当apt访问https://repo.example.com/ubuntu这个源时,只会且必须使用/usr/share/keyrings/repo-key.gpg这个密钥来验证,系统全局的其他密钥对它无效。这种方式的声明性和安全性是最高的。

如何迁移和清理旧的apt-key密钥?

对于已经使用apt-key add添加的旧密钥,你需要进行迁移并清理,以彻底拥抱新安全模型。

1. 查看当前已添加的密钥列表:

sudo apt-key list

输出会显示密钥ID(通常是以”/“结尾的8位或16位十六进制字符串,如"ABCD1234"或"ABCDEF0123456789")和关联的UID。

2. 导出特定密钥到文件,并采用新方法导入。 假设你要迁移密钥ID为"ABCD1234"的密钥:

sudo apt-key export ABCD1234 | sudo gpg --dearmor -o /usr/share/keyrings/migrated-key.gpg

或者,如果你知道该密钥对应哪个源,最好直接从软件源官方重新下载最新的密钥文件,这能确保密钥的时效性和真实性。

3. 修改对应的源列表文件,添加signed-by选项。 如上文方法二所述。

4. 测试新配置。 运行sudo apt update,确保该源的索引能正常更新且没有警告。

5. 从旧密钥环中删除已迁移的密钥。 确认新配置工作无误后,可以安全地删除旧密钥:

sudo apt-key del ABCD1234

重要警告: 切勿盲目删除所有旧密钥,特别是那些你无法识别或可能被系统关键组件(如某些驱动PPA)使用的密钥。务必确认每个密钥都有新的替代管理方式后再删除。

处理特殊格式的密钥添加脚本

许多软件提供商(如Docker、NodeSource等)过去会提供一键安装脚本,其中包含类似curl ... | sudo apt-key add -的管道命令。在新的安全规范下,你应该分解这些步骤。

旧脚本模式:

curl -fsSL https://example.com/key.asc | sudo apt-key add -

新安全操作模式:

curl -fsSL https://example.com/key.asc | sudo gpg --dearmor -o /usr/share/keyrings/example-key.gpg
echo "deb [signed-by=/usr/share/keyrings/example-key.gpg] https://repo.example.com/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/example.list

这样,你既执行了相同的功能,又遵循了更安全的密钥绑定实践。

常见问题与故障排除

1. 执行apt update时出现”NO_PUBKEY“错误。 这明确表示apt找不到合适的密钥来验证对应源的签名。请检查:

(1)密钥文件路径在signed-by选项中是否正确;

(2)密钥文件是否已使用gpg --dearmor正确转换;

(3)密钥是否已过期或被撤销,需要从源头获取新密钥。

2. 一个源需要多个密钥怎么办? 目前signed-by选项不支持指定多个文件。解决方案是,使用gpg工具将多个密钥合并到一个文件中再引用。例如:cat key1.asc key2.asc | sudo gpg --dearmor -o /usr/share/keyrings/combined-key.gpg,然后在源列表行中指向这个合并后的文件。

3. 如何验证密钥文件的格式和内容? 使用gpg --list-packets /usr/share/keyrings/your-key.gpg命令可以查看二进制密钥包的信息。使用file /usr/share/keyrings/your-key.gpg命令可以查看文件类型,正确应为”PGP public key ring“。

总结与最佳实践建议

apt-key到现代密钥环管理的转变,是Ubuntu系统安全加固的必要环节。为了系统长治久安,建议你立即采纳以下工作流:

1. 停止使用apt-key add命令。 将其从你的知识库中标记为“已废弃”。

2. 优先采用“方法二”(signed-by)。 将密钥文件放在/usr/share/keyrings/,并在源地址行中显式声明。这是最清晰、最安全的方式。

3. 逐步审计和迁移现有系统。 检查/etc/apt/sources.list.d/下的所有第三方源,为它们建立独立的密钥绑定,并清理旧的全局密钥环。

4. 文档化你的操作。 特别是对于服务器环境,记录每个第三方源的密钥来源、存放路径和关联的列表文件,便于后续维护和故障排查。

5. 保持密钥更新。 像关注软件更新一样关注重要软件源GPG密钥的轮换通知,及时更换过期的密钥。

拥抱这项改变,虽然初期需要一些适应和迁移工作,但它为你管理的Ubuntu系统构建了一道更精细、更坚固的安全防线。这不仅是跟上技术发展的步伐,更是对系统安全负责的体现。