如何使用gpg在Ubuntu 22.04上添加外部仓库以处理apt-key和add-apt-repository的弃用

介绍

apt-key是用于管理APT用于验证软件包的密钥的实用工具。它与add-apt-repository实用工具密切相关,后者使用密钥服务器将外部存储库添加到APT安装的受信任源列表中。然而,使用apt-keyadd-apt-repository添加的密钥在全局上被apt信任。这些密钥不仅限于授权它们原本针对的单个存储库。以这种方式添加的任何密钥都可以用于授权添加任何其他外部存储库,这是一个重要的安全问题。

从Ubuntu 20.10开始,使用apt-key会产生一个警告,该工具将在不久的将来被弃用;同样,add-apt-repository也将很快被弃用。虽然这些弃用警告不严格阻止在Ubuntu 22.04中使用apt-keyadd-apt-repository,但不建议忽略这些警告。

当前的最佳实践是使用gpg代替apt-keyadd-apt-repository,在未来的Ubuntu版本中,这将是唯一的选项。apt-keyadd-apt-repository本身一直充当包装器,后台调用gpg。直接使用gpg可以省略中间步骤。因此,gpg方法与旧版本的Ubuntu向后兼容,并可以作为apt-key的替代品。

本教程将概述两个使用apt-keyadd-apt-repository的替代方法。首先是使用gpg而不是apt-key添加一个带有公钥的外部仓库。其次,作为补充,本教程将介绍使用gpg和密钥服务器添加外部仓库,作为使用add-apt-repository的替代方法。

前提条件

完成本教程,您需要一个Ubuntu 22.04服务器。请根据我们的Ubuntu 22.04的初始服务器设置指南设置服务器,并创建一个具有sudo权限和启用了防火墙的非root用户。

步骤1 —— 识别组件和关键格式

PGP(Pretty Good Privacy)是一款专有的加密程序,用于对文件和目录进行签名、加密和解密。PGP文件是公钥文件,在此过程中用于验证仓库为有效源的身份。GPG(GNU Privacy Guard)是PGP的开源替代方案。GPG文件通常是包含多个密钥的密钥环文件(keyrings)。这两种文件类型通常用于对文件进行签名和加密。

gpg是GPG的命令行工具,可用于授权外部仓库与apt一起使用。然而,gpg只接受GPG文件。为了使用此命令行工具与PGP文件一起使用,您必须将其转换。

Elasticsearch提供了一个常见的密钥转换场景,并将用作本节的示例。您将下载一个针对PGP格式化的密钥,并使用.gpg文件扩展名将其转换为与apt兼容的格式。您将通过使用--dearmor标志运行gpg命令来执行此操作。接下来,您将将存储库链接添加到软件包源列表中,并附加对已转换密钥的直接引用。最后,您将通过安装Elasticsearch软件包来验证此过程。

需要添加具有密钥验证的存储库的项目将始终为您提供公钥和表示其确切位置的存储库URI。对于我们的Elasticsearch示例,文档在其安装页面上提供了这些组件

以下是Elasticsearch的组件:

  • 密钥:https://artifacts.elastic.co/GPG-KEY-elasticsearch
  • 存储库:https://artifacts.elastic.co/packages/7.x/apt stable main

接下来,您需要确定是否提供了PGP或GPG文件供您使用。您可以通过使用curl打开URL来检查密钥文件:

  1. curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch

这将输出密钥文件的内容,其以以下内容开头:

Output
-----BEGIN PGP PUBLIC KEY BLOCK----- . . .

尽管URL中有GPG,但第一行表明这实际上是一个PGP密钥文件。请注意,因为apt只接受GPG格式,所以请注意这一点。最初,apt-key检测到PGP文件,并通过在后台调用gpg自动将其转换为GPG。第2步将涵盖从PGP手动转换为GPG,以及在不需要转换时应该怎么做。

第2步 – 下载密钥并转换为与apt兼容的文件类型

使用gpg方法时,您必须在将密钥添加到软件包源列表之前始终先下载密钥。以前使用apt-key时,不一定需要按照这个顺序操作。现在,您必须在源列表中引用已下载密钥文件的路径。如果您尚未下载密钥,显然无法引用现有的路径。

使用Elasticsearch时,您将使用PGP文件,并在下载后将其转换为GPG文件格式。以下示例使用curl下载密钥,并将下载内容传输到gpg命令中。使用--dearmor标志调用gpg以将PGP密钥转换为GPG文件格式,使用-o指定输出文件。

在Ubuntu上,/usr/share/keyrings目录是推荐存放转换后GPG文件的位置,因为这是Ubuntu存储其密钥环的默认位置。在此示例中,文件名为elastic-7.x.gpg,但任何名称都可以使用:

  1. curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elastic-7.x.gpg

这将把PGP文件转换为正确的GPG格式,使其准备好添加到apt的源列表中。

注意:如果下载的文件已经是GPG格式,您可以直接将文件下载到/usr/share/keyrings而无需进行转换,如以下示例所示:

  1. curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo tee /usr/share/keyrings/elastic-7.x.gpg

在这种情况下,curl命令的输出将被传输到tee以将文件保存到正确的位置。

步骤3 — 将存储库添加到软件包来源列表中

使用下载并转换为正确的GPG文件格式的密钥,您可以将存储库添加到apt软件包源,并明确将其与所获得的密钥链接。有三种方法可以实现这一点,所有方法都与apt如何查找来源有关。 apt从中央的sources.list文件、sources.list.d目录中的.list文件以及sources.list.d目录中的.source文件中提取源。尽管这三个选项之间没有功能上的区别,但建议考虑这三个选项,并选择最适合您需求的方法。

选项1 — 直接添加到sources.list

第一种方法涉及将表示源的行直接插入到 /etc/apt/sources.list 文件中,该文件是包含 apt 源的主要文件。该文件中包含多个源,包括随 Ubuntu 一起提供的默认源。直接编辑该文件是完全可以接受的,但是选项2和选项3将提供更模块化的解决方案,可以更容易地进行编辑和维护。

使用 nano 或您喜欢的文本编辑器打开 /etc/apt/sources.list

  1. sudo nano /etc/apt/sources.list

然后在文件的末尾添加外部仓库:

/etc/apt/sources.list
. . .
deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/elastic-7.x.gpg] https://artifacts.elastic.co/packages/7.x/apt stable main

此行包含关于源的以下信息:

  • deb:表示该源使用常规的 Debian 架构。
  • arch=amd64,arm64 指定将下载 APT 数据的架构。这里是 amd64arm64
  • signed-by=/usr/share/keyrings/elastic-7.x.gpg:指定用于授权该源的密钥,这里指向存储在 /usr/share/keyrings 中的 .gpg 文件。该行的此部分必须包含在内,而在之前的 apt-key 方法中不需要。这个添加是迁移到 apt-key 的关键更改,因为它将密钥绑定到一个单独的仓库,该仓库有权进行授权,并修复了 apt-key 中的原始安全漏洞。
  • https://artifacts.elastic.co/packages/7.x/apt stable main:这是表示仓库中数据确切位置的 URI。
  • /etc/apt/sources.list.d/elastic-7.x.list:这是要创建的新文件的位置和名称。
  • /dev/null:当命令的输出不需要时使用。将tee指向此位置会省略输出。

按下CTRL+O然后CTRL+X保存并退出。

选项2 – 在sources.list.d中创建一个新的.list文件

选择此选项时,您将在sources.list.d目录中创建一个新文件。apt会解析该目录和sources.list以添加存储库。此方法允许您在单独的文件中物理隔离存储库添加。如果您以后需要删除此添加或进行编辑,可以删除此文件而不是编辑中央的sources.list文件。将添加项保持分离使得更容易进行维护,而编辑sources.list可能会对文件中的其他存储库产生影响,从而更容易出错。

要实现此目标,将一个echo命令通过管道传递到tee命令中,以创建此新文件并插入适当的行。在下面的示例中,文件名为elastic-7.x.list,但只要是目录中的唯一文件名即可。

  1. echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/elastic-7.x.gpg] https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list > /dev/null

这个命令与手动创建文件并插入相应的文本行是相同的。

选项3 — 在 sources.list.d 中创建一个 .sources 文件

第三种方法是写入一个 .sources 文件而不是一个 .list 文件。这种方法相对较新,使用的是 deb822 的多行格式,与 deb . . . 声明相比不那么模糊,但功能上是相同的。创建一个新文件:

  1. sudo nano /etc/apt/sources.list.d/elastic-7.x.sources

然后使用 deb822 格式添加外部仓库:

/etc/apt/sources.list.d/elastic-7.x.sources
Types: deb
Architectures: amd64 arm64
Signed-By: /usr/share/keyrings/elastic-7.x.gpg
URIs: https://artifacts.elastic.co/packages/7.x/apt
Suites: stable
Components: main

在插入文本后保存并退出。

这类似于单行格式,并且逐行比较可以看出两者的信息是相同的,只是组织方式不同。需要注意的是,该格式在有多个参数时(例如 amd64,arm64)不使用逗号,而是使用空格。

接下来,您将通过进行测试安装来验证此过程。

步骤4 — 从外部仓库安装软件包

您必须调用apt update命令来提示apt查看主sources.list文件以及sources.list.d目录下的所有.list.sources文件。在调用apt install之前未更新会导致安装失败,或者安装过时的默认软件包。

更新您的软件源:

  1. sudo apt update

然后安装您的软件包:

  1. sudo apt install elasticsearch

apt-key方法相比,此步骤没有任何变化。完成此命令后,您将完成安装。

附加说明-使用密钥服务器添加外部软件源

本节将简要介绍如何使用密钥服务器而不是公钥来添加外部软件源的过程。该过程与使用公钥方法几乎相同,唯一的区别是调用gpg的方式。

add-apt-repository是基于密钥服务器的apt-key的对应物,两者都将被弃用。这种情况使用不同的组件。与密钥和存储库不同,您将获得密钥服务器URL和密钥ID。在这种情况下,您可以直接从密钥服务器下载到相应的.gpg格式,无需进行任何转换。由于add-apt-repository即将被弃用,您将使用gpg来下载到文件,同时覆盖默认的gpg行为,即导入到现有密钥环中。

以开源编程语言R为例,以下是给定的组件,也可以在官方项目网站的安装说明中找到

  • 密钥服务器: keyserver.ubuntu.com
  • 密钥ID: E298A3A825C0D65DFD57CBB651716619E084DAB9
  • 存储库: https://cloud.r-project.org/bin/linux/ubuntu jammy-cran40/

首先,使用gpg直接从密钥服务器下载。请注意,根据下载流量的不同,此下载命令可能需要一些时间才能完成:

  1. sudo gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/R.gpg --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9

此命令包含以下标志,与使用公钥的gpg不同:

  • --no-default-keyring结合--keyring,允许将输出到新文件而不是导入到现有密钥环中,默认情况下,在此情况下gpg的行为。
  • --keyserver--recv-keys结合使用,提供了你正在下载的特定密钥和位置。
  • --homedir用于覆盖gpg默认位置以创建临时文件。 gpg需要创建这些文件来完成命令,否则gpg将尝试写入/root,从而导致权限错误。相反,此命令将临时文件放置在适当的/tmp目录中。

接下来,将存储库添加到.list文件中。这与使用公钥添加外部存储库的方式完全相同,通过将echo命令通过管道传递给tee命令来实现:

  1. echo "deb [arch=amd64 signed-by=/usr/share/keyrings/R.gpg] https://cloud.r-project.org/bin/linux/ubuntu jammy-cran40/" | sudo tee /etc/apt/sources.list.d/R.list > /dev/null

然后,更新存储库列表:

  1. sudo apt update

然后你可以安装软件包:

  1. sudo apt install r-base

使用gpg添加外部存储库,公钥和密钥服务器之间的操作方式相似,不同之处在于如何调用gpg

结论

{
“error”: “Upstream error…”
}

Source:
https://www.digitalocean.com/community/tutorials/how-to-handle-apt-key-and-add-apt-repository-deprecation-using-gpg-to-add-external-repositories-on-ubuntu-22-04