Ubuntu 22.04上使用gpg处理apt-key和add-apt-repository的弃用问题来添加外部存储库
简介
apt-key
是一个用于管理APT用来验证软件包的密钥的工具。它与 工具密切相关,后者将使用钥匙服务器的外部存储库添加到 APT 安装的可信来源列表中。然而,使用 和 添加的密钥是由 全局信任的。这些钥匙并不局限于授权它们所要使用的单一存储库。任何以这种方式添加的密钥都可以被用来授权添加任何其他的外部版本库,这就带来了一个重要的安全问题。add-apt-repository
apt-key
add-apt-repository
apt
从Ubuntu 20.10开始,使用apt-key
,会产生一个警告,即该工具将在不久的将来被废弃;同样,add-apt-repository
也将很快被废弃。虽然这些废弃警告并不严格阻止在Ubuntu 22.04中使用apt-key
和add-apt-repository
,但不建议忽略它们。
目前的最佳做法是使用gpg
来代替apt-key
和add-apt-repository
,在未来的Ubuntu版本中,这将是唯一的选择。apt-key
和add-apt-repository
本身一直充当包装器,在后台调用gpg
。直接使用gpg
,可以省去中间环节。由于这个原因,gpg
方法可以向后兼容旧版本的Ubuntu,并且可以作为apt-key
的替代品。
本教程将概述两个程序,分别使用apt-key
和add-apt-repository
的替代品。首先是用gpg
,而不是用apt-key
,使用公钥添加一个外部仓库。其次,作为补充,本教程将介绍使用gpg
的钥匙服务器添加外部资源库,以替代使用add-apt-repository
。
前提条件
要完成本教程,你需要一台Ubuntu 22.04服务器。使用具有sudo
权限的非root用户并启用防火墙。
第1步 - 识别组件和密钥格式
PGP,即Pretty Good Privacy,是一个专有的加密程序,用于对文件和目录进行签名、加密和解密。PGP文件是公钥文件,在这个过程中用来认证存储库是apt
内的有效来源。 GPG,即GNU Privacy Guard,是PGP的一个开源替代品。GPG文件通常是钥匙圈,也就是持有多个钥匙的文件。这两种文件类型通常用于签署和加密文件。
gpg
是GPG的命令行工具,可用于授权外部存储库与 。然而, 只接受GPG文件。为了用PGP文件使用这个命令行工具,你必须转换它们。apt
gpg
Elasticsearch提供了一个常见的密钥转换场景,并将被用作本节的例子。你将下载一个PGP格式的密钥,并将其转换为apt
,文件扩展名为.gpg
。你将通过运行带有--dearmor
标志的gpg
命令来完成这一工作。接下来,你将把版本库链接添加到软件包来源列表中,同时附加一个对你转换后的密钥的直接引用。最后,你将通过安装Elasticsearch包来验证这个过程。
需要添加存储库与密钥验证的项目总是会给你提供一个公钥和一个代表其确切位置的存储库URI。
下面是为Elasticsearch给出的组件。
- 钥匙:
https://artifacts.elastic.co/GPG-KEY-elasticsearch
- 存储库:
https://artifacts.elastic.co/packages/7.x/apt stable main
接下来,你必须确定是否给你一个PGP或GPG文件来工作。你可以通过用curl
打开URL来检查钥匙文件。
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
命令中。gpg
被调用,带有--dearmor
标志,将PGP密钥转换成GPG文件格式,-o
用来表示文件输出。
在Ubuntu上,/usr/share/keyrings
目录是转换后的GPG文件的推荐位置,因为它是Ubuntu存储钥匙圈的默认位置。在这个例子中,该文件被命名为elastic-7.x.gpg
,但任何名字都可以。
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
,而不需要使用类似下面的命令进行转换。
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
文件中提取源,.list
文件在sources.list.d
目录中,而.source
文件在sources.list.d
目录中。虽然这三个选项之间没有功能上的区别,但建议考虑这三个选项,并选择最适合你需要的方法。
选项1 - 直接添加到sources.list
第一种方法是在/etc/apt/sources.list
,即包含apt
资源的主文件中直接插入一行代表源。这个文件里有多个源,包括Ubuntu自带的默认源。直接编辑这个文件是完全可以接受的,尽管选项2和选项3将提供一个更模块化的解决方案,可以更容易编辑和维护。
用nano
或你喜欢的文本编辑器打开/etc/apt/sources.list
。
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数据将被下载到的架构。这里是 和 。amd64
arm64
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--创建一个新的.list
文件在sources.list.d
使用这个选项,你将在sources.list.d
目录下创建一个新的文件。apt
同时解析这个目录和sources.list
的版本库添加。这种方法允许你在不同的文件中物理地隔离版本库的添加。如果你以后需要删除这个补充或进行编辑,你可以删除这个文件,而不是编辑中央的sources.list
文件。将你的添加内容分开,使其更容易维护,编辑sources.list
,可能会影响到文件中的其他资源库,更容易出错。
要做到这一点,用管道将echo
命令输入到tee
命令中,以创建这个新文件,并插入适当的行。在下面的例子中,该文件被命名为elastic-7.x.list
,但任何名字都可以,只要它是目录中唯一的文件名。
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
文件在sources.list.d
第三种方法是向.sources
文件而不是.list
文件写入。这种方法相对较新,使用的是deb822
的多行格式,与deb . . .
的声明相比不那么含糊,不过功能上是相同的。创建一个新的文件。
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
将导致安装失败,或者安装来自apt
的过期的默认包。
更新你的存储库。
sudo apt update
然后安装你的软件包。
sudo apt install elasticsearch
与apt-key
的方法相比,这一步没有什么变化。一旦这个命令完成,你就完成了安装。
附录 - 使用钥匙服务器添加外部版本库
本节将简要介绍使用gpg
和钥匙服务器而不是公钥来添加一个外部仓库。这个过程与公钥方法几乎相同,区别在于如何调用gpg
。
add-apt-repository
是与 相对应的基于钥匙服务器的方法,并且两者都将被废弃。这个方案使用不同的组件。你得到的不是一个钥匙和存储库,而是一个钥匙服务器的URL和钥匙ID。在这种情况下,你可以直接从钥匙服务器下载到适当的 格式,而不需要转换任何东西。因为 很快就会被废弃,你将改用 来下载到一个文件,同时覆盖默认的 行为,即导入到一个现有的钥匙圈。apt-key
.gpg
add-apt-repository
gpg
gpg
以开源编程语言R为例,以下是给出的组件,这些组件也可以在官方项目网站的安装说明中找到。
- Keyserver。
keyserver.ubuntu.com
- 钥匙ID。
E298A3A825C0D65DFD57CBB651716619E084DAB9
- 储存库。
https://cloud.r-project.org/bin/linux/ubuntu jammy-cran40/
首先,使用gpg
直接从钥匙服务器下载。请注意,根据下载流量,这个下载命令可能需要一段时间才能完成。
sudo gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/R.gpg --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
这个命令包括以下标志,这些标志与使用gpg
的公钥不同。
--no-default-keyring
combined with 允许输出到一个新的文件,而不是导入到一个现有的钥匙圈中,这是在这种情况下 的默认行为。--keyring
gpg
--keyserver
与 结合,提供你要下载的特定密钥和位置。--recv-keys
--homedir
用于覆盖 默认的创建临时文件的位置。 需要创建这些文件来完成命令,否则 将试图写入 ,这将导致一个权限错误。相反,这个命令将临时文件放在适当的 目录中。gpg
gpg
gpg
/root
/tmp
接下来,将资源库添加到.list
文件中。这与使用公钥添加外部版本库的方式完全相同,将echo
命令插入tee
命令。
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
接下来,更新你的软件库列表。
sudo apt update
然后你就可以安装这个软件包了。
sudo apt install r-base
使用gpg
来添加外部软件库,在公钥和钥匙服务器之间是相似的,区别在于你如何调用gpg
。
结论
使用公钥或钥匙服务器添加外部资源库可以通过gpg
,而不需要使用apt-key
或add-apt-repository
作为中介。使用这种方法可以确保你的程序在未来的Ubuntu版本中不会被淘汰,因为apt-key
和add-apt-repository
已经被废弃,并将在未来的版本中被移除。使用gpg
添加外部软件库,可以确保一个密钥只用于授权一个你想要的软件库。