pacman/软件包签名

出自 ArchWiki

为了确定软件包是否是真实的,pacman 使用 OpenPGP 密钥在一个 信任网络 模型中。当前的主签名密钥可以在这里找到。至少三个主签名密钥被用来签名开发者和软件包维护者自己的密钥。然后他们被用来签名他们的软件包。每个用户也有一个唯一的 OpenPGP 密钥,在你配置 pacman-key(8) 时生成。正是这个信任网络将用户的密钥链接到主密钥。

信任网络示例

  • 自定义软件包:使用本地密钥制作和签名的软件包。
  • 非官方软件包:由开发者制作和签名的软件包。然后,使用本地密钥来签名开发者的密钥。
  • 官方软件包:由开发者制作和签名的软件包。开发者的密钥由 Arch Linux 主密钥签名。你使用你的密钥来签名主密钥,并且你信任他们为开发者担保。
注意: HKP 协议使用 11371/tcp 端口进行通信。为了从服务器获取签名密钥(使用 pacman-key),需要此端口进行通信。

设置

配置 pacman

/etc/pacman.conf 中的 SigLevel 选项决定了使用 pacman -S 安装软件包所需的信任级别。有关 SigLevel 的详细说明,请参阅 pacman.conf(5) § 软件包和数据库签名检查,以及文件注释。可以全局设置签名检查,也可以按仓库设置。如果 SigLevel[options] 部分全局设置,则所有使用 pacman -S 安装的软件包都需要签名。使用默认 pacman.conf 中的 LocalFileSigLevel 设置,你构建并使用 pacman -U 安装的任何软件包都不需要使用 makepkg 进行签名。

注意: 尽管所有官方软件包现在都已签名,但截至 2018 年 11 月,数据库签名仍在 进行中。如果设置了 Required,则也应设置 DatabaseOptional

对于远程软件包,默认配置将仅支持安装由受信任密钥签名的软件包

/etc/pacman.conf
SigLevel = Required DatabaseOptional

TrustedOnly 是一个默认编译到 pacman 中的参数。默认配置与使用以下全局选项相同

SigLevel = Required DatabaseOptional TrustedOnly

以上也可以在配置中更下方的仓库级别实现,例如

[core]
SigLevel = PackageRequired
Include = /etc/pacman.d/mirrorlist

显式地为仓库的软件包添加签名检查,但不要求数据库被签名。此处的 Optional 将关闭此仓库的全局 Required 设置。

警告: TrustAll SigLevel 选项的存在是为了调试目的,并且非常容易信任尚未验证的密钥。对于所有官方仓库,您应该使用 TrustedOnly

初始化密钥环

要初始化 pacman 密钥环,请运行

# pacman-key --init

管理密钥环

验证主密钥

密钥的初始设置是使用以下命令实现的

# pacman-key --populate

当提示时,花时间验证 主签名密钥,因为这些密钥用于共同签名(并因此信任)所有其他打包者的密钥。

OpenPGP 密钥对于人类来说太大(2048 位或更多),无法直接使用,因此它们通常被哈希以创建 40 位十六进制数字的指纹,该指纹可用于手动检查两个密钥是否相同。指纹的最后八位数字作为密钥的名称,称为“(短)密钥 ID”(指纹的最后十六位数字将是“长密钥 ID”)。

添加开发者密钥

官方开发者和 软件包维护者 的密钥由主密钥签名,因此您无需使用 pacman-key 自己签名它们。每当 pacman 遇到它不识别的密钥时,它都会提示您从 /etc/pacman.d/gnupg/gpg.conf 中配置的 keyserver 下载它(或者通过在命令行中使用 --keyserver 选项)。维基百科维护着一个 密钥服务器列表

一旦您下载了开发者密钥,您就不必再次下载它,并且它可以用于验证由该开发者签名的任何其他软件包。

注意: archlinux-keyring 软件包是 base 的依赖项,包含最新的密钥。但是,也可以使用 pacman-key --refresh-keys (以 root 身份)手动更新密钥。在执行 --refresh-keys 时,您的本地密钥也将在远程密钥服务器上查找,您将收到关于未找到它的消息。这无需担心。

添加非官方密钥

此条目或章节需要扩充。

原因: 解释如何按照 archlinux-keyring 推出自定义密钥环软件包。(在 Talk:Pacman/Package_signing#Addition_of_guide_to_create_unofficial_keyrings 中讨论)

此方法可用于将密钥添加到 pacman 密钥环,或启用签名的 非官方用户仓库

首先,从其所有者处获取 密钥 IDkeyid)。然后使用以下两种方法之一将其添加到密钥环

  1. 如果在密钥服务器上找到密钥,请使用以下命令导入它
    # pacman-key --recv-keys keyid
  2. 如果提供了密钥文件的链接,请下载它,然后运行
    # pacman-key --add /path/to/downloaded/keyfile

建议验证指纹,就像验证任何主密钥或您要签名的任何其他密钥一样

$ pacman-key --finger keyid

最后,您必须在本地签名导入的密钥

# pacman-key --lsign-key keyid

您现在信任此密钥来签名软件包。

使用 gpg 调试

为了调试目的,您可以直接使用 gpg 访问 pacman 的密钥环,例如

# gpg --homedir /etc/pacman.d/gnupg --list-keys

技巧与诀窍

定期升级系统

通过 pacman#升级软件包 定期升级系统可以防止大多数签名错误。如果延迟不可避免并且系统升级延迟了很长时间,请在系统升级之前手动同步软件包数据库并升级 archlinux-keyring 软件包

# pacman -Sy --needed archlinux-keyring && pacman -Su

此命令不被认为是部分升级,因为它首先同步软件包数据库并升级密钥环软件包。两者都必须在启动系统升级之前处理,以确保可以正确验证所有升级软件包的签名。

注意:2022-07-29 起,archlinux-keyring-wkd-sync.service 和相关的 systemd 计时器 已被创建并默认启用,解决了 signature from "Some Developer <developer_email@archlinux.org>" is marginal trust 问题(例如 BBS#278332),无需任何用户干预,每周获取一次已信任密钥的新签名。

定期更新系统时间

系统时间 错误时,签名密钥可能被认为是过期的(或无效的),并且软件包的签名检查将失败。通过使用 网络时间协议守护程序 定期同步系统时钟。

故障排除

无效签名错误

pacman-key 依赖于 系统时间。如果您的系统时钟未同步,系统安装/升级可能会失败,并显示

error: PackageName: signature from "User <email@archlinux.org>" is invalid
error: failed to commit transaction (invalid or corrupted package (PGP signature))
Errors occurred, no packages were upgraded.

如果使用 ntpd,请使用 ntpd -qg,然后使用 hwclock -w (以 root 身份)更正系统时间。

可以使用其他 NTP 客户端。请参阅 时间同步

如果更正系统时钟无法解决故障,请尝试以下方法之一

从缓存中移除软件包

某些软件包可能已损坏或可能未签名,从而导致失败。从系统缓存中删除每个有问题的软件包 rm /var/cache/pacman/pkg/pkgname,以便重新下载它,或者清除整个缓存

重置所有密钥

通过删除 /etc/pacman.d/gnupg 目录(以 root 身份)并重新运行 pacman-key --init,然后运行 pacman-key --populate 以重新添加默认密钥,从而删除或重置系统中安装的所有密钥。

禁用签名检查

警告: 请谨慎使用。禁用软件包签名将允许 pacman 安装不受信任的软件包。

如果您不关心软件包签名,则可以完全禁用 OpenPGP 签名检查。编辑 /etc/pacman.conf 以在 [options] 下添加以下行

SigLevel = Never
#LocalFileSigLevel = Optional
#RemoteFileSigLevel = Required

您需要注释掉任何仓库特定的 SigLevel 设置,因为它们会覆盖全局设置。这将导致不进行签名检查,这在 pacman 4 之前的行为。如果您这样做,则无需使用 pacman-key 设置密钥环。如果您决定启用软件包验证,则可以稍后更改这些选项。

无法导入密钥

此条目或章节需要语言、wiki 语法或样式改进。请参阅 Help:Style 以获取参考。

原因: 说明可以更清晰。不清楚本节与前一节有何不同。冗余信息。(在 Talk:Pacman/Package signing 中讨论)

此问题有多种可能的来源

  • 过时的 archlinux-keyring 软件包。
  • 时钟设置为不正确的日期。
  • 您的 ISP 阻止了用于导入 OpenPGP 密钥的端口。
  • 您的 pacman 缓存包含来自先前尝试的未签名软件包副本。
  • dirmngr 未正确配置。

在执行升级同步时,您可能会因为过时的 archlinux-keyring 软件包而卡住。

以下是一些可能在您的情况下起作用的解决方案。

升级系统

首先查看升级系统是否可以修复它。

更换密钥服务器

如果您怀疑密钥服务器存在问题,您可以尝试切换到 Ubuntu 密钥服务器。为此,请编辑 /etc/pacman.d/gnupg/gpg.conf 并将 keyserver 行更改为

keyserver hkp://keyserver.ubuntu.com

清理缓存的软件包

如果您怀疑您的 pacman 缓存 /var/cache/pacman/pkg/ 可能包含未签名的软件包,请尝试手动清理缓存或运行

# pacman -Sc

这将删除所有未安装的缓存软件包。

签名是未知信任

有时在运行 pacman -Syu 时,您可能会遇到此错误

error: package-name: signature from "packager" is unknown trust

发生这种情况是因为软件包 package-name 中使用的 packager 的密钥在本地 pacman-key gpg 数据库中不存在和/或不受信任。Pacman 似乎并不总是能够在继续之前检查密钥是否已接收并标记为受信任。这也可能是因为密钥自添加到您的密钥链以来已过期。

通过以下方式缓解

以上最后两个选项破坏了信任链,应谨慎使用。

通过代理更新密钥

为了在使用代理时更新密钥,必须在 /etc/gnupg/dirmngr.conf/etc/pacman.d/gnupg/dirmngr.conf 中都设置 honor-http-proxy 选项。有关更多信息,请参阅 GnuPG#使用密钥服务器

注意: 如果在未使用 honor-http-proxy 选项的情况下使用 pacman-key 并且失败,则重新启动可能会解决该问题。

参见