pacman-key (简体中文)


翻译状态: 本文是英文页面 pacman-key翻译,最后翻译时间:2014-08-14,点击这里可以查看翻译后英文页面的改动。

pacman-key 是 pacman 4 新加的工具。有了它,用户可以管理 pacman 新签名系统的授信密钥。


原理

Pacman 中的软件包签名使用在信任网络中的 GnuPG 密钥 以保证软件包来自开发者而不是伪装者。

提示: 软件包开发者和 TU 都有各自的 PGP 密钥并用它们签名软件包。这些签名能够保证软件包确实来自他们。而每个用户使用 pacman-key 时也会获得一个唯一 PGP 密钥。

目前Archlinux拥有5个主要签名密钥。 其中至少三个主密匙被涌来签署官方开发者和授信用户自己的密钥,而他们将用这些密钥签署自己的包。用户在设置pacman-key时也会生成一个自己的密钥。所以信任网络也会把用户的密钥连接到五大主密钥上面。

密钥也可以用来签名其它的密钥,也就是说签名密钥的所有者能够保证被签名密钥的安全性。要信任一个软件包,需要在用户自己的 PGP 密钥和软件包签名间建立一个密钥链。在 Arch 的密钥结构中,有三种方式:

  • 自定义软件包: 用户自己构建软件包并用自己的密钥签名认证。
  • 非官方软件包: 开发者构建软件包并签名它。用户需要用自己的密钥签名开发者的密钥,将其变为可信。
  • 官方软件包: 开发者构建软件包,而开发者的密钥已经被 Arch 主密钥签名。最终用户用自己的密钥签名主密钥,这样就能信任所有官方开发者。
提示: HKP协议使用11371/tcp端口用来通信。为了从服务器得到签署的密钥(使用pacman-key),这个端口必须打开。
提示:

关于此问题的背景,请访问博客 [1][2][3][4]软件包签名提议 wiki 页面。

配置

配置 pacman

首先通过 /etc/pacman.conf 中的 SigLevel 确定要使用的检查级别。文件的注释中列出了几个可选设置, pacman.conf手册页面 有详细介绍。

签名检查可以设成全局的或针对每个仓库的。如果 SigLevel 在 [options] 节中进行了全局设置,那么所有的包都必须签名。包括你自己编译构建的包,也需要使用 makepkg 进行签名。

注意: 尽管所有的官方软件包现在都进行了签名,但是在2012年6月的时候签名数据库还在开发。如果设置了 Required ,那么 DatabaseOptional 也应该被设置。
默认的设置
/etc/pacman.conf
SigLevel = Required DatabaseOptional
会使得系统只安装被授信的密钥签署的软件包。因为 TrustOnly 是一个已经被编译进pacman的默认设置。 所以上面这些的效果和
SigLevel = Required DatabaseOptional TrustedOnly
是一样的。

上面这些也可以在仓库内部进行设置,比如:

[core]
SigLevel = PackageRequired # ’Optional’ here would turn off a global ’Required’ for this repository
Include = /etc/pacman.d/mirrorlist

哇软件仓库中的软件启用了签名验证,但是并不要求仓库数据库也被签名了。

警告: SigLevel TrustAll 设置仅仅为了测试而存在,使用它会信任未被验证的密钥。对于所有的官方软件源你应该使用 TrustedOnly

初始化密钥环

关于初始化,收集熵 是必须的。 随意移动鼠标,随即按键盘或者运行一些磁盘级别的操作(比如在其他终端运行ls -R /或者find / -name foo 或者 dd if=/dev/sda8 of=/dev/tty7之类的)应该会收集足够的熵。如果你的系统没有足够的熵,这项工作需要好几个小时,但是如果你有,那么就会快多了。


要初始化 pacman 密钥:

# pacman-key --init

这会在 /etc/pacman.d/gnupg 建立新密钥并生成系统主密钥。

注意: 如果你需要通过SSH运行 pacman-key --init ,请在目标机器上安装 haveged ,通过SSH连接后运行:
# haveged -w 1024
# pacman-key --init

pacman-key顺利运行之后,只要停止haveged并且删除它就好了。

# pkill haveged
# pacman -Rs haveged

使用haveged的方案仅适用于通过 SSH连接时——这是一种非常快速获得足够熵的方法。如果你在使用 pacman-key --init 时需要太长的时间,那你就需要这个解决方法。

管理密钥

验证五大主密钥

The initial setup of keys is achieved using:

# pacman-key --populate archlinux

Take time to verify the Master Signing Keys when prompted as these are used to co-sign (and therefore trust) all other packager's keys.

PGP 通常很长(2048 位或更长),不太容易使用,所以通常创建一个40位十六进制指纹,最后八位被称为密钥 ID,是密钥的名字。长签名可以用来检测两个密钥是否相同。

官方开发者密钥

官方开发者和 TU 的密钥已经被主密钥签名认证,所以不需要用 pacman-key 认证它们。pacman 遇到不认识的签名时,它将会询问是否从密钥服务器(设置在{ic|/etc/pacman.d/gnupg/gpg.conf}文件中,或在命令行中使用--keyserver选项)下载。

提示: Wikipedia maintains a list of keyservers.

下载开发者密钥后,以后都不需要下载。以后会用它验证所有这个开发者构建的软件包。

注意:

如果开发者和 TU 的密钥是较早之前导入,它们的签名可能还不存在于本地数据库,用下面命令更新:

# pacman-key --refresh-keys
当使用--refresh-keys 时,本地签名也会被远程查找,并收到未找到的消息,这是正常的。

导入非官方密钥

有两种方法可以实现:

First get the key ID (keyid) from the owner of the key. Then you need to add the key to the keyring:

  • If the key is found on a keyserver, import it with:
    # pacman-key -r keyid
  • If otherwise a link to a keyfile is provided, download it and then run:
    # pacman-key --add /path/to/downloaded/keyfile

Always be sure to verify the fingerprint, as you would with a master key, or any other key which you are going to sign.

$ pacman-key -f keyid

Finally, you need to locally sign the imported key:

# pacman-key --lsign-key keyid

You now trust this key to sign packages.

Using gpg

If pacman-key is not enough, you can manage pacman's keyring by gpg like this:

# gpg --homedir /etc/pacman.d/gnupg $OPTIONS

or

# env GNUPGHOME=/etc/pacman.d/gnupg gpg $OPTIONS

问题解决

Warning: Pacman-key depends on time. If your system clock is wrong, you'll get:
error: PackageName: signature from "User <email@archlinux.org>" is invalid
error: failed to commit transaction (invalid or corrupted package (PGP signature))
Errors occured, no packages were upgraded.

如何收集熵

移动鼠标、不停的随机按键盘按键或者执行磁盘操作例如 updatedb 可以生成足够的熵,可能需要一段时间,请保持耐心。Alt+F2-6 到第二个终端不起作用。


如果需要通过 ssh 运行 pacman-key --init,请在目标机器编译安装 AUR 中的 rng-tools 软件包,通过 ssh 连接并运行:

# sed -i 's/0/10/' /etc/conf.d/rngd
# rngd -f -r /dev/urandom &
# pacman-key --init

pacman-key 成功运行后停止 rngd 并删除软件包。

# killall rngd
# pacman -Rns rng-tools

密钥导入失败处理

可能某些服务商屏蔽了导入 GPG 的端口。

编辑 /etc/pacman.d/gnupg/gpg.confkeyserver hkp://keys.gnupg.net 替换为

keyserver hkp://pgp.mit.edu:11371

If this does not help either, change the keyserver to the kjsl keyserver, which provides this service through port 80 (the HTML port), which should always remain unblocked.

keyserver hkp://keyserver.kjsl.com:80

If you happen to forget to run pacman-key --populate archlinux you might get some errors while importing keys.

禁用签名检查

警告: 小心使用,禁用签名检查,pacman 会自动安装不信任的软件包。

如果不在意软件包签名,可以完全禁用 PGP 签名检查,编辑 /etc/pacman.conf 并注释掉 [options] 下的如下行:

SigLevel = Never

需要同时注释掉软件源的 SigLevel 设置。

这样就不会进行任何签名检查,和 pacman 4 之前一样。如果这样,就不需要用 pacman-key 建立密钥环。

重置所有密钥

如果要删除或重置系统,删除 /etc/pacman.d/gnupg 目录并重新运行 pacman-key --init,然后添加需要的密钥。

Removing stale packages

If the same packages keep failing and you are sure you did all the pacman-key stuff right, try removing them like so rm /var/cache/pacman/pkg/badpackage* so that they are freshly downloaded.

This might actually be the solution if you get a message like error: linux: signature from "Some Person <Some.Person@example.com>" is invalid or similar when upgrading (i.e. you might not be the victim of a MITM attack after all, your downloaded file was simply corrupt).

See also