内核维护者 PGP 指南

作者:

Konstantin Ryabitsev <konstantin@linuxfoundation.org>

本文档面向 Linux 内核开发人员,尤其是子系统维护人员。它包含 Linux 基金会发布的更通用 “保护代码完整性” 指南中讨论的信息子集。请阅读该文档,以更深入地讨论本指南中提到的一些主题。

PGP 在 Linux 内核开发中的作用

PGP 有助于确保 Linux 内核开发社区生成的代码的完整性,并在较小程度上通过 PGP 签名的电子邮件交换在开发人员之间建立可信的通信渠道。

Linux 内核源代码以两种主要格式提供

  • 分布式源代码存储库(git)

  • 定期发布快照(tarball)

git 存储库和 tarball 都带有创建官方内核版本的内核开发人员的 PGP 签名。这些签名提供了一种加密保证,即通过 kernel.org 或任何其他镜像提供的可下载版本与这些开发人员在其工作站上的版本相同。为此

  • git 存储库在所有标签上都提供 PGP 签名

  • tarball 为所有下载提供分离的 PGP 签名

信任开发人员,而不是基础设施

自从 2011 年核心 kernel.org 系统遭到破坏以来,内核归档项目的主要运作原则一直是假设基础设施的任何部分都可能随时遭到破坏。因此,管理员已采取深思熟虑的步骤来强调信任必须始终放在开发人员身上,而不是代码托管基础设施上,无论后者的安全实践有多好。

上述指导原则是需要本指南的原因。我们希望确保通过信任开发人员,我们不会只是将未来潜在安全事件的责任推卸给其他人。我们的目标是提供一套开发人员可以用来创建安全工作环境并保护用于建立 Linux 内核本身完整性的 PGP 密钥的指南。

PGP 工具

使用 GnuPG 2.2 或更高版本

你的发行版应该已经默认安装了 GnuPG,你只需要验证你是否正在使用合理的新版本。要检查,请运行

$ gpg --version | head -n1

如果你的版本是 2.2 或更高版本,那么一切正常。如果你的版本早于 2.2,那么本指南中的某些命令可能无法工作。

配置 gpg-agent 选项

GnuPG 代理是一个辅助工具,每当你使用 gpg 命令时,它会自动启动,并在后台运行,目的是缓存私钥密码。为了调整密码从缓存中过期的时机,你需要了解以下两个选项

  • default-cache-ttl (秒):如果你在生存时间到期之前再次使用同一个密钥,则倒计时将重置为另一个周期。默认值为 600(10 分钟)。

  • max-cache-ttl (秒):无论你自初始密码输入以来多久使用过该密钥,如果最大生存时间倒计时到期,你都必须再次输入密码。默认值为 30 分钟。

如果你发现这些默认值太短(或太长),你可以编辑你的 ~/.gnupg/gpg-agent.conf 文件来设置你自己的值

# set to 30 minutes for regular ttl, and 2 hours for max ttl
default-cache-ttl 1800
max-cache-ttl 7200

注意

不再需要在你的 shell 会话开始时手动启动 gpg-agent。你可能需要检查你的 rc 文件以删除你在旧版本 GnuPG 中使用的任何内容,因为它可能不再执行正确的操作。

保护你的 PGP 密钥

本指南假设你已经有一个用于 Linux 内核开发目的的 PGP 密钥。如果你还没有,请参阅前面提到的 “保护代码完整性” 文档,以获取有关如何创建新密钥的指导。

如果你的当前密钥弱于 2048 位 (RSA),你也应该创建一个新密钥。

了解 PGP 子密钥

PGP 密钥很少由单个密钥对组成 -- 通常它是独立子密钥的集合,可以根据其在创建时分配的功能用于不同的目的。 PGP 定义了密钥可以拥有的四种功能

  • [S] 密钥可用于签名

  • [E] 密钥可用于加密

  • [A] 密钥可用于身份验证

  • [C] 密钥可用于认证其他密钥

具有 [C] 功能的密钥通常称为“主”密钥,但这种术语具有误导性,因为它暗示认证密钥可以代替同一链上的任何其他子密钥使用(就像物理“主密钥”可以用来打开为其他密钥制造的锁一样)。由于情况并非如此,本指南将其称为“认证密钥”,以避免任何歧义。

充分理解以下内容至关重要

  1. 所有子密钥都是彼此完全独立的。如果你丢失了私有子密钥,则无法从你链上的任何其他私钥恢复或重新创建它。

  2. 除了认证密钥外,还可以有多个具有相同功能的子密钥(例如,你可以有 2 个有效的加密子密钥,3 个有效的签名子密钥,但只有一个有效的认证子密钥)。所有子密钥都是完全独立的 -- 加密到 [E] 子密钥的消息无法使用你可能拥有的任何其他 [E] 子密钥解密。

  3. 单个子密钥可能具有多种功能(例如,你的 [C] 密钥也可以是你的 [S] 密钥)。

具有 [C](认证)功能的密钥是唯一可以用来指示与其他密钥的关系的密钥。只有 [C] 密钥可以用于

  • 添加或撤销具有 S/E/A 功能的其他密钥(子密钥)

  • 添加、更改或撤销与密钥关联的身份(uid)

  • 添加或更改自身或任何子密钥的到期日期

  • 为信任网络目的签署其他人的密钥

默认情况下,GnuPG 在生成新密钥时创建以下内容

  • 一个具有认证和签名功能的子密钥([SC]

  • 一个单独的具有加密功能的子密钥([E]

如果你在生成密钥时使用了默认参数,那么你将拥有这些。你可以通过运行 gpg --list-secret-keys 进行验证,例如

sec   ed25519 2022-12-20 [SC] [expires: 2024-12-19]
      000000000000000000000000AAAABBBBCCCCDDDD
uid           [ultimate] Alice Dev <[email protected]>
ssb   cv25519 2022-12-20 [E] [expires: 2024-12-19]

sec 条目下的长行是你的密钥指纹 -- 每当你看到下面的示例中出现 [fpr] 时,它指的是这个 40 个字符的字符串。

确保你的密码足够强

GnuPG 使用密码来加密你的私钥,然后再将它们存储在磁盘上。这样,即使你的 .gnupg 目录被泄露或整个被盗,攻击者也无法使用你的私钥,除非他们先获得密码来解密它们。

你的私钥必须受到强密码保护,这一点至关重要。要设置或更改它,请使用

$ gpg --change-passphrase [fpr]

创建单独的签名子密钥

我们的目标是通过将你的认证密钥移动到离线介质来保护它,因此,如果你只有一个组合的 [SC] 密钥,那么你应该创建一个单独的签名子密钥

$ gpg --quick-addkey [fpr] ed25519 sign

注意

GnuPG 中的 ECC 支持

请注意,如果你打算使用不支持 ED25519 ECC 密钥的硬件令牌,则应选择“nistp256”而不是“ed25519”。请参阅下面有关推荐硬件设备的章节。

备份你的认证密钥以进行灾难恢复

你的 PGP 密钥上来自其他开发人员的签名越多,你就有更多理由创建一个备份版本,该版本存在于数字介质以外的其他介质上,以便进行灾难恢复。

创建私钥可打印硬拷贝的最佳方法是使用专门为此目的编写的 paperkey 软件。有关输出格式及其优于其他解决方案的优势的更多详细信息,请参阅 man paperkey。Paperkey 应该已经为大多数发行版打包。

运行以下命令以创建私钥的硬拷贝备份

$ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt

打印出该文件(或将输出直接管道传输到 lpr),然后拿起笔在纸的边缘写下您的密码。强烈建议这样做,因为密钥打印输出仍然使用该密码加密,并且如果您更改密码,当您创建备份时,您将不会记得它以前是什么 - 保证

将生成的打印输出和手写的密码放入信封中,并将其存储在安全且受保护的地方,最好是远离您家的地方,例如您的银行金库。

注意

您的打印机可能不再是连接到并行端口的简单哑设备,但是由于输出仍然使用您的密码加密,因此即使打印到“云集成”的现代打印机,也应该仍然是相对安全的操作。

备份您的整个 GnuPG 目录

警告

!!!不要跳过此步骤!!!

如果您需要恢复 PGP 密钥,拥有随时可用的 PGP 密钥备份非常重要。这与我们使用 paperkey 所做的灾难级别准备不同。每当您需要使用您的 Certify 密钥时,您也需要依赖这些外部副本,例如当您更改自己的密钥或在会议和峰会后签署其他人的密钥时。

首先,获取一个小 USB “拇指” 驱动器(最好是两个!),您将使用它进行备份。您需要使用 LUKS 对它们进行加密 - 请参阅您的发行版的文档,了解如何完成此操作。

对于加密密码,您可以使用与 PGP 密钥相同的密码。

加密过程结束后,重新插入 USB 驱动器并确保它已正确挂载。将您的整个 .gnupg 目录复制到加密存储中

$ cp -a ~/.gnupg /media/disk/foo/gnupg-backup

现在您应该测试以确保一切正常

$ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]

如果您没有收到任何错误,那么您应该可以开始了。卸载 USB 驱动器,对其进行清晰标记,这样下次您需要使用随机 USB 驱动器时就不会将其清除,并将其放在安全的地方 - 但不要太远,因为您时不时需要使用它来执行诸如编辑身份、添加或撤销子密钥或签署其他人的密钥之类的操作。

从您的主目录中删除 Certify 密钥

我们主目录中的文件不像我们想象的那样受到良好的保护。它们可以通过许多不同的方式泄露或被盗

  • 在快速复制主目录以设置新工作站时不小心

  • 由于系统管理员的疏忽或恶意行为

  • 通过安全性较差的备份

  • 通过桌面应用程序(浏览器、PDF 查看器等)中的恶意软件

  • 在跨越国际边界时通过胁迫

使用良好的密码保护您的密钥可以大大降低上述任何风险,但是可以通过键盘记录器、肩窥或其他任何方式发现密码。因此,建议的设置是从您的主目录中删除 Certify 密钥并将其存储在离线存储中。

警告

请参阅上一节,并确保您已完整备份 GnuPG 目录。如果我们接下来要做的事情没有可用的备份,将会使您的密钥变得无用!

首先,识别您的 Certify 密钥的密钥指纹

$ gpg --with-keygrip --list-key [fpr]

输出将类似于这样

pub   ed25519 2022-12-20 [SC] [expires: 2022-12-19]
      000000000000000000000000AAAABBBBCCCCDDDD
      Keygrip = 1111000000000000000000000000000000000000
uid           [ultimate] Alice Dev <[email protected]>
sub   cv25519 2022-12-20 [E] [expires: 2022-12-19]
      Keygrip = 2222000000000000000000000000000000000000
sub   ed25519 2022-12-20 [S]
      Keygrip = 3333000000000000000000000000000000000000

找到 pub 行下方(Certify 密钥指纹正下方)的密钥指纹条目。这将直接对应于 ~/.gnupg 目录中的文件

$ cd ~/.gnupg/private-keys-v1.d
$ ls
1111000000000000000000000000000000000000.key
2222000000000000000000000000000000000000.key
3333000000000000000000000000000000000000.key

您要做的就是简单地删除与 Certify 密钥指纹对应的 .key 文件

$ cd ~/.gnupg/private-keys-v1.d
$ rm 1111000000000000000000000000000000000000.key

现在,如果您发出 --list-secret-keys 命令,它将显示 Certify 密钥丢失(# 表示它不可用)

$ gpg --list-secret-keys
sec#  ed25519 2022-12-20 [SC] [expires: 2024-12-19]
      000000000000000000000000AAAABBBBCCCCDDDD
uid           [ultimate] Alice Dev <[email protected]>
ssb   cv25519 2022-12-20 [E] [expires: 2024-12-19]
ssb   ed25519 2022-12-20 [S]

您还应该删除 ~/.gnupg 目录中的任何 secring.gpg 文件,这些文件可能是以前版本的 GnuPG 遗留下来的。

如果您没有“private-keys-v1.d”目录

如果您没有 ~/.gnupg/private-keys-v1.d 目录,那么您的私钥仍存储在 GnuPG v1 使用的旧版 secring.gpg 文件中。对您的密钥进行任何更改,例如更改密码或添加子密钥,都应该自动将旧的 secring.gpg 格式转换为使用 private-keys-v1.d

完成此操作后,请务必删除仍然包含您的私钥的过时的 secring.gpg 文件。

将子密钥移动到专用加密设备

即使 Certify 密钥现在可以安全地防止泄露或被盗,子密钥仍然在您的主目录中。任何设法获得这些密钥的人都能够解密您的通信或伪造您的签名(如果他们知道密码)。此外,每次执行 GnuPG 操作时,密钥都会被加载到系统内存中,并且可以被足够高级的恶意软件(例如 Meltdown 和 Spectre)从那里窃取。

完全保护您的密钥的最佳方法是将它们移动到能够进行智能卡操作的专用硬件设备。

智能卡的优势

智能卡包含一个加密芯片,该芯片能够存储私钥并直接在卡本身上执行加密操作。由于密钥内容永远不会离开智能卡,因此您插入硬件设备的计算机的操作系统无法检索私钥本身。这与我们之前用于备份目的的加密 USB 存储设备非常不同 - 当 USB 设备插入并挂载时,操作系统能够访问私钥内容。

使用外部加密 USB 介质不能替代拥有支持智能卡的设备。

可用的智能卡设备

除非您的所有笔记本电脑和工作站都具有智能卡读卡器,否则最简单的方法是获取实现智能卡功能的专用 USB 设备。有几种选择

  • Nitrokey Start:基于 FSI Japan 的 Gnuk 的开放硬件和自由软件。它是为数不多的支持 ED25519 ECC 密钥的商用设备之一,但提供的安全功能最少(例如抗篡改或某些侧信道攻击)。

  • Nitrokey Pro 2:与 Nitrokey Start 类似,但更具抗篡改性并提供更多安全功能。Pro 2 支持 ECC 加密 (NISTP)。

  • Yubikey 5:专有硬件和软件,但比 Nitrokey Pro 便宜,并且提供 USB-C 形式,这对于较新的笔记本电脑更有用。提供其他安全功能,例如 FIDO U2F 等,现在终于支持 NISTP 和 ED25519 ECC 密钥。

您的选择将取决于成本、您所在地区的运输可用性以及开放/专有硬件注意事项。

注意

如果您在 MAINTAINERS 中列出或在 kernel.org 上拥有帐户,您 有资格获得 Linux 基金会提供的免费 Nitrokey Start

配置您的智能卡设备

您的智能卡设备应该在您将其插入任何现代 Linux 工作站后立即工作 (TM)。您可以通过运行以下命令来验证它

$ gpg --card-status

如果您看到完整的智能卡详细信息,那么您就可以开始了。不幸的是,排除所有可能导致您出现问题的原因超出了本指南的范围。如果您在使该卡与 GnuPG 一起使用时遇到问题,请通过常用的支持渠道寻求帮助。

要配置您的智能卡,您需要使用 GnuPG 菜单系统,因为没有方便的命令行开关

$ gpg --card-edit
[...omitted...]
gpg/card> admin
Admin commands are allowed
gpg/card> passwd

您应该设置用户 PIN (1)、管理员 PIN (3) 和重置代码 (4)。请务必记录并将其存储在安全的地方 - 尤其是管理员 PIN 和重置代码(它允许您完全擦除智能卡)。您很少需要使用管理员 PIN,如果您不记录它,您将不可避免地忘记它是什么。

回到主卡菜单,您还可以设置其他值(例如姓名、性别、登录数据等),但这不是必需的,并且如果您丢失智能卡,还会泄漏有关您的智能卡的信息。

注意

尽管名称为“PIN”,但卡上的用户 PIN 和管理员 PIN 都不需要是数字。

警告

某些设备可能要求您在更改密码之前将子密钥移动到设备上。请查看设备制造商提供的文档。

将子密钥移动到智能卡

退出卡片菜单(使用“q”),并保存所有更改。接下来,让我们将子密钥移动到智能卡上。对于大多数操作,您需要您的 PGP 密钥密码和卡片的管理员 PIN 码。

$ gpg --edit-key [fpr]

Secret subkeys are available.

pub  ed25519/AAAABBBBCCCCDDDD
     created: 2022-12-20  expires: 2024-12-19  usage: SC
     trust: ultimate      validity: ultimate
ssb  cv25519/1111222233334444
     created: 2022-12-20  expires: never       usage: E
ssb  ed25519/5555666677778888
     created: 2017-12-07  expires: never       usage: S
[ultimate] (1). Alice Dev <[email protected]>

gpg>

使用 --edit-key 会再次将我们带入菜单模式,您会注意到密钥列表略有不同。从这里开始,所有命令都将在此菜单模式下完成,如 gpg> 所示。

首先,让我们选择要放入卡上的密钥——您可以通过键入 key 1 来完成(它是列表中的第一个,即 [E] 子密钥)

gpg> key 1

在输出中,您现在应该在 [E] 密钥上看到 ssb** 指示当前“选定”的密钥。它作为一个切换工作,意味着如果您再次键入 key 1* 将消失,并且该密钥将不再被选择。

现在,让我们将该密钥移动到智能卡上

gpg> keytocard
Please select where to store the key:
   (2) Encryption key
Your selection? 2

由于它是我们的 [E] 密钥,将其放入加密槽是有意义的。当您提交选择时,系统将首先提示您输入 PGP 密钥密码,然后提示您输入管理员 PIN 码。如果命令返回时没有错误,则表示您的密钥已移动。

重要提示:现在再次键入 key 1 以取消选择第一个密钥,并键入 key 2 以选择 [S] 密钥

gpg> key 1
gpg> key 2
gpg> keytocard
Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1

您可以将 [S] 密钥用于签名和身份验证,但我们要确保它在签名槽中,因此选择 (1)。同样,如果您的命令返回时没有错误,则表示操作成功。

gpg> q
Save changes? (y/N) y

保存更改将从您的主目录中删除您移动到卡上的密钥(但没关系,因为如果我们需要再次为更换智能卡执行此操作,我们会在备份中保存它们)。

验证密钥是否已移动

如果您现在执行 --list-secret-keys,您将在输出中看到细微的差异

$ gpg --list-secret-keys
sec#  ed25519 2022-12-20 [SC] [expires: 2024-12-19]
      000000000000000000000000AAAABBBBCCCCDDDD
uid           [ultimate] Alice Dev <[email protected]>
ssb>  cv25519 2022-12-20 [E] [expires: 2024-12-19]
ssb>  ed25519 2022-12-20 [S]

ssb> 输出中的 > 表示子密钥仅在智能卡上可用。如果您回到您的密钥目录并查看那里的内容,您会注意到那里的 .key 文件已被存根替换

$ cd ~/.gnupg/private-keys-v1.d
$ strings *.key | grep 'private-key'

输出应包含 shadowed-private-key,以指示这些文件只是存根,而实际内容在智能卡上。

验证智能卡是否正常工作

要验证智能卡是否按预期工作,您可以创建一个签名

$ echo "Hello world" | gpg --clearsign > /tmp/test.asc
$ gpg --verify /tmp/test.asc

这应该在您的第一个命令中要求您输入智能卡 PIN 码,然后在您运行 gpg --verify 后显示“Good signature”。

恭喜,您已成功地使窃取您的数字开发者身份变得极其困难!

其他常见的 GnuPG 操作

以下是您使用 PGP 密钥需要执行的一些常见操作的快速参考。

挂载安全的离线存储

您需要您的 Certify 密钥才能执行以下任何操作,因此您首先需要挂载您的备份离线存储并告诉 GnuPG 使用它

$ export GNUPGHOME=/media/disk/foo/gnupg-backup
$ gpg --list-secret-keys

您需要确保在输出中看到 sec 而不是 sec## 表示该密钥不可用,您仍然在使用常规的主目录位置)。

延长密钥过期日期

Certify 密钥的默认过期日期为自创建之日起 2 年。这样做既是出于安全考虑,也是为了使过时的密钥最终从密钥服务器中消失。

要将密钥的过期时间从当前日期延长一年,只需运行

$ gpg --quick-set-expire [fpr] 1y

您也可以使用特定的日期,如果更容易记住(例如,您的生日、1 月 1 日或加拿大国庆日)

$ gpg --quick-set-expire [fpr] 2025-07-01

记住将更新后的密钥发送回密钥服务器

$ gpg --send-key [fpr]

在任何更改后更新您的工作目录

在使用离线存储对密钥进行任何更改后,您需要将这些更改导回您的常规工作目录

$ gpg --export | gpg --homedir ~/.gnupg --import
$ unset GNUPGHOME

通过 ssh 使用 gpg-agent

如果您需要在远程系统上对标签或提交进行签名,您可以通过 ssh 转发您的 gpg-agent。请参阅 GnuPG wiki 上提供的说明

如果您可以修改远程端的 sshd 服务器设置,它会更流畅地工作。

将 PGP 与 Git 结合使用

Git 的核心功能之一是其分散性——一旦将存储库克隆到您的系统,您就可以拥有项目的完整历史记录,包括其所有标签、提交和分支。但是,在数百个克隆存储库到处漂浮的情况下,如何验证他们拥有的 linux.git 副本没有被恶意的第三方篡改?

或者,如果在代码中发现后门,并且提交中的“作者”行说是您完成的,而您非常确定与它没有任何关系,会发生什么?

为了解决这两个问题,Git 引入了 PGP 集成。签名标签通过确保其内容与创建该标签的开发人员工作站上的内容完全相同,来证明存储库的完整性,而签名提交使某人几乎不可能在没有访问您的 PGP 密钥的情况下冒充您。

配置 git 以使用您的 PGP 密钥

如果您的密钥环中只有一个密钥,那么您实际上不需要执行任何额外的操作,因为它会成为您的默认密钥。但是,如果您碰巧有多个密钥,则可以告诉 git 应使用哪个密钥([fpr] 是您的密钥的指纹)

$ git config --global user.signingKey [fpr]

如何使用签名标签

要创建签名标签,只需将 -s 开关传递给 tag 命令

$ git tag -s [tagname]

我们的建议是始终对 git 标签进行签名,因为这允许其他开发人员确保他们从中拉取的 git 存储库没有被恶意更改。

如何验证签名标签

要验证签名标签,只需使用 verify-tag 命令

$ git verify-tag [tagname]

如果您从项目存储库的另一个分支拉取标签,则 git 应该在您拉取的尖端自动验证签名,并在合并操作期间向您显示结果

$ git pull [url] tags/sometag

合并消息将包含如下内容

Merge tag 'sometag' of [url]

[Tag message]

# gpg: Signature made [...]
# gpg: Good signature from [...]

如果您正在验证其他人的 git 标签,则需要导入他们的 PGP 密钥。请参阅下面的“如何使用签名补丁”部分。

配置 git 以始终对带注释的标签进行签名

如果您正在创建带注释的标签,您很可能希望对其进行签名。要强制 git 始终对带注释的标签进行签名,您可以设置全局配置选项

$ git config --global tag.forceSignAnnotated true

如何使用签名提交

创建签名提交很容易,但在 Linux 内核开发中使用它们要困难得多,因为它依赖于发送到邮件列表的补丁,而此工作流程不会保留 PGP 提交签名。此外,当您重新建立存储库以匹配上游时,即使您自己的 PGP 提交签名最终也会被丢弃。出于这个原因,大多数内核开发人员不费心签署他们的提交,并且会忽略他们工作中依赖的任何外部存储库中的签名提交。

但是,如果您的工作 git 树在某个 git 托管服务(kernel.org、infradead.org、ozlabs.org 或其他)上公开可用,那么建议您对所有 git 提交进行签名,即使上游开发人员没有直接从中受益。

我们建议这样做是出于以下原因

  1. 如果需要执行代码取证或跟踪代码来源,即使是带有 PGP 提交签名的外部维护树对于此类目的也很有价值。

  2. 如果您需要重新克隆本地存储库(例如,在磁盘故障后),这将使您可以在恢复工作之前轻松验证存储库的完整性。

  3. 如果有人需要挑选您的提交,这将使他们可以在应用之前快速验证其完整性。

创建签名提交

要创建签名提交,您只需将 -S 标志传递给 git commit 命令(由于与另一个标志冲突,它是大写的 -S

$ git commit -S

配置 git 以始终对提交进行签名

您可以告诉 git 始终对提交进行签名

git config --global commit.gpgSign true

注意

在打开此选项之前,请确保配置 gpg-agent

如何使用签名补丁

可以使用您的 PGP 密钥对发送到内核开发人员邮件列表的补丁进行签名。由于现有的电子邮件签名机制(PGP-Mime 或 PGP-inline)往往会导致常规代码审查任务出现问题,因此您应该使用 kernel.org 为此目的创建的工具,该工具将加密证明签名放入消息头中(类似于 DKIM)

安装和配置 patatt

Patatt 已经为许多发行版打包,因此请先在那里检查。您也可以使用“pip install patatt”从 pypi 安装它。

如果您已经使用 git 配置了 PGP 密钥(通过 user.signingKey 配置参数),那么 patatt 不需要进一步配置。您可以通过在您想要使用的存储库中安装 git-send-email 钩子来开始签署您的补丁。

patatt install-hook

现在,您使用 git send-email 发送的任何补丁都将自动使用您的加密签名进行签名。

检查 patatt 签名

如果您使用 b4 来检索和应用补丁,那么它将自动尝试验证它遇到的所有 DKIM 和 patatt 签名,例如

$ b4 am [email protected]
[...]
Checking attestation on all messages, may take a moment...
---
  ✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers
  ✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall
  ✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls
  ---
  ✓ Signed: openpgp/[email protected]
  ✓ Signed: DKIM/kernel.org

注意

Patatt 和 b4 仍在积极开发中,您应该查看这些项目的最新文档以获取任何新的或更新的功能。

如何验证内核开发人员身份

签署标签和提交很容易,但是如何验证用于签署内容的密钥是否属于实际的内核开发人员而不是恶意的冒名顶替者呢?

使用 WKD 和 DANE 配置自动密钥检索

如果您还没有其他开发人员公钥的广泛集合,那么您可以依靠密钥自动发现和自动检索来启动您的密钥环。如果从头开始创建自己的信任网的前景太令人生畏,GnuPG 可以借助其他委托信任技术,即 DNSSEC 和 TLS,来帮助您入门。

将以下内容添加到您的 ~/.gnupg/gpg.conf

auto-key-locate wkd,dane,local
auto-key-retrieve

基于 DNS 的命名实体身份验证(“DANE”)是一种在 DNS 中发布公钥并使用 DNSSEC 签名区域保护公钥的方法。Web 密钥目录(“WKD”)是另一种使用 https 查找来达到相同目的的方法。当使用 DANE 或 WKD 查找公钥时,GnuPG 将在将自动检索的公钥添加到您的本地密钥环之前分别验证 DNSSEC 或 TLS 证书。

Kernel.org 为所有拥有 kernel.org 账户的开发人员发布 WKD。一旦您在 gpg.conf 中进行了上述更改,您就可以自动检索 Linus Torvalds 和 Greg Kroah-Hartman 的密钥(如果您还没有它们)

如果您拥有 kernel.org 账户,那么您应该将 kernel.org UID 添加到您的密钥,以使 WKD 对其他内核开发人员更有用。

信任网络 (WOT) 与首次使用信任 (TOFU)

PGP 包含一种称为“信任网络”的信任委托机制。其核心是试图取代 HTTPS/TLS 世界中对集中式证书颁发机构的需求。PGP 不是由各种软件制造商来决定谁应该是您信任的认证实体,而是将此责任留给每个用户。

不幸的是,很少有人了解信任网络的工作原理。虽然它仍然是 OpenPGP 规范的重要组成部分,但最近版本的 GnuPG(2.2 及更高版本)实现了一种称为“首次使用信任” (TOFU) 的替代机制。您可以将 TOFU 视为“类似于 SSH 的信任方法”。使用 SSH,您第一次连接到远程系统时,它的密钥指纹会被记录和记住。如果将来密钥发生更改,SSH 客户端会提醒您并拒绝连接,迫使您决定是否选择信任更改后的密钥。类似地,当您第一次导入某人的 PGP 密钥时,它会被认为是有效的。如果在将来的任何时候 GnuPG 遇到另一个具有相同身份的密钥,则先前导入的密钥和新密钥都将被标记为无效,您需要手动确定保留哪个密钥。

我们建议您使用组合的 TOFU+PGP 信任模型(这是 GnuPG v2 中的新默认值)。要设置它,请在 ~/.gnupg/gpg.conf 中添加(或修改) trust-model 设置

trust-model tofu+pgp

使用 kernel.org 信任网络存储库

Kernel.org 维护着一个包含开发人员公钥的 git 存储库,以替代在过去几年中几乎已经失效的密钥服务器网络。有关如何将该存储库设置为公钥来源的完整文档可以在这里找到

如果您是内核开发人员,请考虑提交您的密钥以包含到该密钥环中。