pacman/软件包签名

出自 ArchWiki
(重定向自 Pacman-key)

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

信任网络示例

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

设置

配置 pacman

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

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

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

/etc/pacman.conf
SigLevel = Required DatabaseOptional

TrustedOnlypacman 默认编译的参数。默认配置与使用以下全局选项相同:

SigLevel = Required DatabaseOptional TrustedOnly

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

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

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

警告: SigLevel TrustAll 选项的存在是为了调试目的,并且使得信任未经验证的密钥变得非常容易。对于所有官方仓库,您应该使用 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 密钥环,或启用签名的 非官方用户仓库

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

  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 并且失败,则重启可能可以解决问题。

另请参阅