哪些命令(确切地说)应该替换已弃用的 apt-key?

use*_*711 26 apt

在新的 ubuntu 20.10 虚拟机上为本地存储库设置密钥时,我收到一条消息,提示 apt-key add 已被弃用,我应该阅读apt-key(8) 手册页。在apt-key(8)手册页单词串成的集合,但如果它包含的信息,我不能挖角出来。谁能告诉我,我应该在终端上输入什么,而不是:

apt-key add name-of-file
Run Code Online (Sandbox Code Playgroud)

该命令在向我鸣喇叭后显然仍然有效,所以我能够继续,但想知道我将来需要做什么。

Ask*_*eli 35

你需要知道为什么 apt-key add被弃用

到目前为止,所有答案都解决了症状(“不要使用apt-key add”),但未能解决导致被弃用的实际问题apt-key add。问题不是将密钥附加到一个大的密钥环文件etc/apt/trusted.gpg与手动将单密钥密钥环文件放入目录的问题/etc/apt/trusted.gpg.d/。这两件事是等价的,做任何一件都会带来巨大的安全风险。

问题是,你添加到任何按键或者以上是完全和无条件地信任的贴切。这意味着任何包含 apt 签名密钥的第三方存储库都可以替换整个系统上的任何包,而不会提出任何问题。即使我们假设没有一个 repo 所有者是恶意的,攻击者也可能会破坏一个 repo,这具有相同的最终结果。

Ugo Delle Donne 的答案中给出的将密钥转换为 apt 将接受的(传统)密钥环 v4 格式的说明是正确且有用的,但这只是解决方案的一半。我将在这里重申它们(稍微清理一下),以便将所有步骤合并到一个地方:

  • 下载密钥:
    • wget https://host.domain.tld/path/to/<keyfile>.<ext>
      (不需要-O>;wget默认将文件保存在当前目录中,文件名与服务器上的文件名相同。)
  • 验证文件类型是否为“PGP 公钥块公钥(旧)”:
    • file <keyfile>.<ext>
  • gpg 支持多种密钥格式,因此如果您的密钥采用不同的格式,请将其导入临时密钥环,然后再次导出:
    • gpg --no-default-keyring --keyring ./temp-keyring.gpg --import <keyfile>.<ext>
    • gpg --no-default-keyring --keyring ./temp-keyring.gpg --export --output <your-keyfile-name>.gpg
    • rm temp-keyring.gpg

既然您已拥有转换后的密钥,请不要apt通过将其复制到 将其添加到的受信任密钥库/etc/apt/trusted.gpg.d/。相反,把它放在像/usr/local/share/keyrings/. (您需要先创建该keyrings目录。)该位置没有什么特别之处,它只是/usr/local针对特定于这台机器的东西的约定,share因为它不是二进制文件或库或特定于任何给定用户,keyrings只是描述性名称。

在这一点上,什么都没有改变,apt也不知道密钥存在。最后一步是修改.list存储库的特定文件,以告诉 apt 在哪里可以找到该特定 repo的密钥。

  • 编辑文件/etc/apt/sources.list.d/<example>.list,在deburl之间,添加[signed-by=/usr/local/share/keyrings/<your-keyfile-name>.gpg]

现在 apt 将接受该存储库中所有包的密钥签名,并且仅接受该存储库。

笔记:

  • 如果您已经有密钥环文件/etc/apt/trusted.gpg.d/,您可以它们复制 移动/usr/local/share/keyrings/原样,然后更新所有相应的.list文件,使每个文件都有一个signed-by指向其自己密钥的字段。
  • 如果您的/etc/apt/trusted.gpg密钥环文件中已经有官方存储库密钥之外的密钥,则此答案详细说明了定位和删除它们的步骤。然后,您可以按照上述所有相同步骤以更安全的方式设置它们。(也可以从该密钥环中导出它们,但确切的步骤留给读者作为练习。)
  • 要将 repo 的密钥从密钥服务器导入到独立文件:
    • gpg --no-default-keyring --keyring <output-file-name>.gpg --keyserver <some.keyserver.uri> --recv-keys <fingerprint>
    • 这应该为您提供一个无需转换即可接受的密钥。
  • Apt 仍然非常受信任,恶意或受感染的 repo 可以轻松绕过此措施,因为包目前可以在其安装脚本中以 root 身份运行任意 shell 代码。不过,关闭一个攻击向量并没有什么坏处,其他方面正在(缓慢地)取得进展。
  • 或者,您可以Deb822使用单个.sources文件而不是.list文件切换到更新、更详细的格式。这是更多的工作,但我个人认为结果更具可读性。

资料来源:

  • 是否有原因导致此过程不能自动使用某些“apt”命令来替换已弃用的行为?从描述来看,它似乎很容易编写脚本。 (6认同)
  • @RobieBasak 看起来 Debian 确实有[这方面的说明](https://wiki.debian.org/DebianRepository/UseThirdParty#Complete_example),但我不得不说这听起来真的很复杂。希望“add-apt-repository”将被更新或其他一些工具将被放在一起来自动化这个过程...... (5认同)
  • 根据 Ubuntu 22.04 上的“man 5sources.list”,如果您是系统管理员,想要添加带有密钥环的 apt 源,则密钥环应该转到 /etc/apt/keyrings/(例如,对于 winehq 存储库)。另一方面,如果您是 pkg 维护者,想要使用包 postinst 脚本安装密钥环(例如 google-chrome、Microsoft 团队、slack),您应该将其放在 /usr/share/keyrings/ 中。 (4认同)
  • “这意味着任何包含 apt 签名密钥的第三方存储库都可以替换整个系统上的任何包,而不会提出任何问题。” -- 即使您使用较新的方法,这也是可能的,不是吗?因为 apt 仍然不知道允许哪个存储库运送哪些包。除非您还实施了一些固定,但我在任何说明中都看不到这一点。 (3认同)
  • @Hrobky 是的,**如果** 密钥是一个旧的二进制格式的“公钥块”,它已经被 ascii-armored,它会起作用。但是,如果密钥文件是 apt 不支持的较新的二进制“keybox 数据库”格式,则需要*实际转换*为旧的公钥块格式(如果适用,则在亲爱的之后)。如果有那个二进制→二进制转换的一步命令,我还没有遇到过。 (2认同)
  • @laur,恐怕我没有例子。当我写这个答案时,我下载、转换并安装了一堆密钥,我很确定我记得至少遇到过一个即使在“--dearmor”之后 apt 也无法识别的密钥,这让我寻找我的答案中的转换方法......但我没有记下是哪些。作为一般规则,我想说默认情况下通过 `--dearmor` 进行管道传输没有什么坏处(如果密钥不是 ascii-armored,gpg 将成功退出而不更改任何内容)。如果 apt 在生成的密钥上阻塞,*然后*尝试二进制→二进制转换解决方法。 (2认同)
  • 任何你**完全没有抓住要点**!问问自己: *你推荐的东西适合 Ubuntu 的存在吗?* …不,绝对不适合。正确的方法是,对于你选择的包管理器工具,询问用户:“*你想要完全吗?并无条件信任 $packageSourcePeople?与你的计算机?*”……在安装 Ubuntu 时,它也必须问这个问题!因为你表现得就像 Ubuntu 维护者在某种程度上神奇地毫无疑问地不可能腐败,并且与其他人有任何不同。**这被证明是危险的错误。** (2认同)
  • 如果 deb 和 URL 之间已经有另一个条目,例如 `[arch=amd64]`,则必须将其添加到括号内,例如 `deb [arch=amd64signed-by=/etc/apt/keyrings/vivaldi-release. gpg] http://repo.vivaldi.com/stable/deb/ stable main`,否则您会从 apt 中收到语法错误:“列表文件中的格式错误的条目 3”。 (2认同)
  • 请在您的答案中添加@IngoSteinke的建议(如果已经有括号条目,如何添加签名者)。此外,此工作流程中最烦人的部分是查找每个源的 gpg 密钥,因为它们没有一致的存储方式。我最终只是从系统中删除了所有密钥,然后迭代运行 apt-key update 并谷歌搜索每个问题源以找到其密钥。我很惊讶这里有这么多古老的钥匙,也许把它们拿掉就好了...... (2认同)

小智 13

不推荐使用的原因是因为 usingapt-key add只是将 gpg 密钥附加到受信任的全局 APT 密钥环。它类似于添加local_repo.list/etc/apt/sources.list.d/而不是使用的首选方法add-apt-repository dep /link/to/repo version,它将消息附加到全局sources.list文件中。

我认为这比使用 .d 文件夹更难以理解,但本质上我们希望将 gpg 密钥放入独立的密钥环文件中,然后在源列表中指向此密钥环文件。默认密钥环文件位置为/usr/share/keyrings,它可以是 .asc 或 .gpg 文件。我不确定其中的区别,但我确实知道全局密钥环文件是二进制文件,而不是纯文本。

例如:

使用通用名称有时可能有点难以理解,所以这里是安装 mongoDB 的示例:

获取 MongoDB gpg 密钥并将其添加到新的密钥环文件中

curl https://www.mongodb.org/static/pgp/server-4.2.asc | sudo tee -a /usr/share/keyrings/buster-mongodb-org-4_2.asc
Run Code Online (Sandbox Code Playgroud)

添加 apt 的源条目,指向这个新的密钥环。

例如,如果您的存储库文件位于/etc/apt/sources.list.d/mongodb-org-4_2.list运行以下命令来添加密钥文件:

echo "deb [signed-by=/usr/share/keyrings/buster-mongodb-org-4_2.asc] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.2 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-4_2.list
Run Code Online (Sandbox Code Playgroud)

从这个新添加的存储库安装 mongodb

sudo apt install -y mongodb-org

参考

这对我来说仍然是新鲜事,但我所知道的大部分内容都来自unix SE 中的这个出色的答案


Art*_*ild 9

我创建了一个 shell 脚本,可以下载并安装要[signed-by=]sources.list.

它可以在github.com/ameinild/add-apt-key上找到。

用于安装 APT 密钥的 POSIX 脚本

一般帮助

此脚本将帮助安装 APT 存储库的 PGP 密钥。

该脚本最多支持 2 个参数:

  • 第一个参数是输入文件。这可以是:
    • URL - 密钥将被下载到当前路径(使用 wget 或 curl)
    • 文件名 - 读取当前路径中的现有密钥
    • 路径和文件名 - 读取给定路径中的现有密钥
  • 第二个参数是关键输出路径和输出名称。这可以是:
    • 仅文件名 - 输出路径在配置中设置,保存为给定文件名
    • 路径和文件名 - 此处给出输出路径,保存为给定的文件名
    • 仅一个路径(以 / 结尾) - 此处给出输出路径,文件名取自现有密钥
    • 空 - 在配置中设置输出路径,文件名取自现有密钥

该脚本有一个配置文件/usr/local/etc/add-apt-key.conf,其中可以设置以下变量:

  • keypath :存储转换后的密钥的路径 - 默认为/etc/apt/keyrings
  • verbosity:如果设置为 Yes - 显示额外输出
  • removetmp:如果设置为“是”- 删除输入(未转换)文件

示例 1: ( PWD=/root)

sudo add-apt-key https://mariadb.org/mariadb_release_signing_key.asc /usr/share/keyrings/
Run Code Online (Sandbox Code Playgroud)

将下载密钥/root,将其转换并存储为 /usr/share/keyrings/mariadb_release_signing_key.gpg

示例 2: ( PWD=/home/user)

sudo add-apt-key /root/mariadb_release_signing_key.asc /usr/share/keyrings/mariadbkey
Run Code Online (Sandbox Code Playgroud)

将使用现有的密钥/root,将其转换并存储为 /usr/share/keyrings/mariadbkey.gpg

例3:( PWD=/home/user)

sudo add-apt-key mariadb_release_signing_key.asc mariadbkey
Run Code Online (Sandbox Code Playgroud)

将使用现有的密钥/home/user,将其转换并存储为 /etc/apt/keyrings/mariadbkey.gpg

安装 PGP 密钥后,还可以将密钥和存储库添加到/etc/apt/sources.list

  • 添加此选项的选择将作为第一个输入选项出现在脚本中
  • 如果选择“是”,则必须将存储库字符串粘贴为第二个输入选项

这样就完成了密钥安装,将相应的存储库行添加到/etc/apt/sources.list

安装

通过运行以下命令进行安装:

sudo curl -L https://raw.githubusercontent.com/ameinild/add-apt-key/master/add-apt-key -o /usr/local/bin/add-apt-key
sudo curl -L https://raw.githubusercontent.com/ameinild/add-apt-key/master/add-apt-key.conf -o /usr/local/etc/add-apt-key.conf
sudo chmod a+rx /usr/local/bin/add-apt-key
Run Code Online (Sandbox Code Playgroud)

  • 因此,上面已经清楚地表明Linux绝对不适合普通最终用户。Ubuntu 和其他人应该警告你,你需要认真的高级技能,并且必须愿意花费大量时间来培训、搜索和处理这些问题......更重要的是,不能保证你无论做什么都会工作或不工作会产生进一步的问题。这是不诚实的行为。 (8认同)
  • 我非常确定 Ubuntu 的未来版本将调整自己的脚本以适应安装 PGP 密钥的“新”方式。与此同时,我编写了一个脚本来帮助其他用户尽可能实现自动化。如果您发现它太高级并且没有用,那也没关系,但它实际上是为了提供帮助。 (3认同)
  • 密钥的新默认位置是“/etc/apt/keyrings”。 (3认同)
  • @YannMonnier 你是100%正确的。如果 Ubuntu 开发人员无法将他们的“安全问题”与社区的实际需求相匹配,那么 Ubuntu 桌面将不再是一个可行的选择。我是 Slackware 的忠实粉丝,它的工具更加精简和简单(尽管缺乏文档)。它们也可能“不太安全”,但我们不是在这里经营银行 - 这是一台电脑! (2认同)

小智 8

我偶然发现了同样的问题,幸运的是其他一些问题照亮了道路。在我的示例中,我试图向最近的 Kali linux 添加一个 teamviewer 存储库,但我被密钥验证阻止了。

我很确定有一种更优雅的方法可以做到这一点,但以下步骤帮助我解决了这个问题:

  1. 下载相关密钥

    wget -O - https://download.teamviewer.com/download/linux/signature/TeamViewer2017.asc > ~/teamviewer.key

  2. 验证文件类型

    file ~/teamviewer.key

    它应该是PGP 公钥块 Public-Key(旧)

  3. 创建一个钥匙圈

    gpg --no-default-keyring --keyring ./teamviewer_keyring.gpg --import teamviewer.key

  4. 该文件仍然不是可以添加到/etc/apt/trusted.gpg.d/的有效密钥,因为它是一个密钥环,但我们可以从密钥环中提取密钥

    gpg --no-default-keyring --keyring ./teamviewer_keyring.gpg --export > ./teamviewer.gpg

  5. 此文件是您要移动到受信任密钥文件夹的密钥

    sudo mv ./teamviewer.gpg /etc/apt/trusted.gpg.d/

快乐sudo apt update!!!

  • 不要使用这个接受的答案,也不要将文件放入“/etc/apt/trusted.gpg.d/”中。查看点赞数最多的问题以获得更好的解决方案。 (18认同)

nye*_*yet 7

作为直接的工作方式,替换apt-key addgpg --dearmor

curl [KEYURL] | sudo gpg --dearmor --yes -o /etc/apt/trusted.gpg.d/[KEYFILE].gpg

但是,不建议这样做(除了与 apt-key 类似),因为受信任目录中的所有密钥都是无条件受信任的;最好将输出放在(非全局)受信任目录中(正如其他人所建议的那样),并让每个源分别指定要信任的密钥。


Loc*_*ith 7

更新:2023 年 11 月 15 日,早在 8 月份,我提交给 apt-manage 项目的 PR 已被接受,它包含一个快速安装脚本,将在 Debian 和 Ubuntu 及其衍生版本上安装 apt-manage。

我再次修改了下面的答案,将安装替换为快速安装脚本。


更新:2023 年 5 月 16 日,我可以确认 apt-manage 是我发现的使用密钥正确管理 apt 源的最安全、最一致的方法。

我重写了答案,删除了我的个人脚本(如果您愿意,您可以在修订历史记录中查看它)以专注于命令而不是我的个人代码。


这里所有的答案都很棒,我从他们身上学到了很多东西。

根据 @mesterlion 的评论,截至目前,有一个工具可以完成所有这些工作,并且可以正确完成,并由 Pop!_OS 团队妥善维护。

该工具是RepoLibapt-manage模块的一部分,该模块在版本 2 中引入了子命令。key

所以在 Pop!_OS 22.04 中,安装将如下所示:

sudo apt install --yes apt-manage
Run Code Online (Sandbox Code Playgroud)

上游项目(Ubuntu 和 Debian)缺少这个软件包,因为:该apt-manage项目有一个快速安装脚本(完全公开,我为其提交了 PR)。
安装将如下所示:

sudo apt install --yes apt-manage
Run Code Online (Sandbox Code Playgroud)

更多详细信息可以在git-repo 的安装部分找到README.md

实施例1

安装后apt-manage,下面是我的系统中的一组调用的示例:

curl https://raw.githubusercontent.com/pop-os/repolib/HEAD/quick-install.sh | bash 
Run Code Online (Sandbox Code Playgroud)

示例 2:在新的 Ubuntu 计算实例上初始化 docker

# Adding PPA
sudo apt-manage add --terse --format=sources ppa:ppa:alessandro-strada/ppa

# Adding APT source and assinging a key
sudo apt-manage add --terse --format=sources --name Microsoft --identifier packages-microsoft-com 'deb [arch=amd64] https://packages.microsoft.com/ubuntu/22.04/prod jammy main'
# Assigning a key via URL
sudo apt-manage key packages-microsoft-com --url=https://packages.microsoft.com/keys/microsoft.asc

# R-Project needed some additional love - because they do something 'different':
sudo apt-manage add --terse --format=sources --name R-Project --identifier cloud-r-project-org 'deb [arch=amd64] https://cloud.r-project.org/bin/linux/ubuntu jammy-cran40/ ""_""'
# Specific to R-Project, as one of the values are empty and the command line can' pass it effectively.
sudo sed -i /etc/apt/sources.list.d/cloud-r-project-org.sources -Ee 's/""_""//g'
# Assigning a key via fingerprint
sudo apt-manage key cloud-r-project-org --fingerprint=E298A3A825C0D65DFD57CBB651716619E084DAB9

# After all were added, run update.
sudo apt update
Run Code Online (Sandbox Code Playgroud)