1 .. SPDX-License-Identifier: GPL-2.0 2 .. include:: ../disclaimer-zh_CN.rst 3 4 :Original: Documentation/process/maintainer-pgp-guide.rst 5 6 :翻译: 7 8 司延腾 Yanteng Si <siyanteng@loongson.cn> 9 10 :校译: 11 12 13 =================== 14 内核维护者 PGP 指南 15 =================== 16 17 :作者: Konstantin Ryabitsev <konstantin@linuxfoundation.org> 18 19 本文档面向 Linux 内核开发者,特别是子系统维护人员。文档中含有Linux 基金 20 会发布的更通用的 `保护代码完整性`_ 指南中讨论的内容子集。阅读该文档,以更 21 深入地讨论本指南中提到的一些主题。 22 23 .. _`保护代码完整性`: https://github.com/lfit/itpol/blob/master/protecting-code-integrity.md 24 25 PGP 在 Linux 内核开发中的作用 26 ============================= 27 28 PGP 有助于确保 Linux 内核开发社区产出代码的完整性,并在较小程度上,通过 29 PGP 签名的电子邮件交换,在开发者之间建立可信的交流渠道。 30 31 Linux 内核源代码主要有两种(维护)方式: 32 33 - 分布式源仓库 (git) 34 - 定期发布快照 (tarballs) 35 36 git 仓库和 tarball 都带有创建官方内核版本的内核开发者的 PGP 签名。这 37 些签名提供了加密保证,即保证 kernel.org 或任何其他镜像提供的可下载版本 38 与这些开发者在其工作站上的版本相同。为此: 39 40 - git 仓库在所有标签上提供 PGP 签名 41 - tarball 为所有下载提供独立的 PGP 签名 42 43 信任开发者,不要信基础设施 44 -------------------------- 45 46 自从 2011 年 kernel.org 核心系统遭到入侵以来,内核存档项目的主要运行原 47 则就是假定基础设施的任何部分都可能随时受到入侵。因此,管理员特意采取措施, 48 强调必须始终信任开发者,不能信任代码托管基础设施,无论后者的安全实践有多好。 49 50 上述指导原则正是需要本指南的原因。希望确保通过对开发者的信任,我们不会简 51 单地将未来潜在安全事件的责任归咎于其他人。目的是提供一套指导开发者可以用 52 来创建安全的工作环境并保护用于建立 Linux 内核本身完整性的 PGP 密钥。 53 54 PGP 工具 55 ======== 56 57 使用 GnuPG 2.2 或更高版本 58 ------------------------- 59 60 默认情况下,你的发行版应该已经安装了 GnuPG,你只需要验证你使用的是相当新的 61 版本即可。要检查,请运行:: 62 63 $ gpg --version | head -n1 64 65 如果你有 2.2 或更高版本,那么你就可以开始了。如果你的版本早于 2.2,则本指 66 南中的某些命令可能不起作用。 67 68 配置 gpg-agent 选项 69 ~~~~~~~~~~~~~~~~~~~ 70 71 GnuPG agent是一个辅助工具,每当你使用该命令时,它都会自动启动gpg,并在 72 后台运行,目的是缓存私钥密码。你应该知道两个选项,以便调整密码何时从缓存 73 过期: 74 75 - ``default-cache-ttl`` (秒): 如果在生命周期结束之前再次使用相同的 76 密钥,倒计时将重置为另一段时间。默认值为 600(10 分钟)。 77 - ``max-cache-ttl`` (秒): 无论你自输入初始密码以来多久使用过密钥, 78 如果最大生存时间倒计时结束,你都必须再次输入密码。默认值为 30 分钟。 79 80 如果你发现这些默认值太短(或太长),你可以编辑 ``~/.gnupg/gpg-agent.conf`` 81 文件以设置你自己的值:: 82 83 # 常规ttl设置为30分钟,最大ttl设置为2小时 84 default-cache-ttl 1800 85 max-cache-ttl 7200 86 87 .. note:: 88 89 不需要在 shell 会话开始时手动启动 gpg-agent。你可能需要检查 90 rc 文件来删除旧版本 GnuPG 中的所有内容,因为它可能不再做正确 91 的事情。 92 93 保护你的 PGP 密钥 94 ================= 95 96 本指南假定你已经拥有用于 Linux 内核开发目的的 PGP 密钥。如果你还没 97 有,请参阅前面提到的 "`保护代码完整性`_" 文档,以获取有关如何创建新 98 密钥的指导。 99 100 如果你当前的密钥低于 2048 位 (RSA),你还应该创建一个新密钥。 101 102 了解 PGP 子密钥 103 --------------- 104 105 PGP 密钥很少由单个密钥对组成 - 通常它是独立子密钥的集合,这些子密钥 106 可根据其功能用于不同的目的,并在创建时分配。PGP 定义了密钥可以具有的 107 四种功能: 108 109 - **[S]** 密钥可用于签名 110 - **[E]** 密钥可用于加密 111 - **[A]** 密钥可用于身份验证 112 - **[C]** 密钥可用于验证其他密钥 113 114 具有 **[C]** 功能的密钥通常称为“主”密钥,但该术语具有误导性,因为 115 它意味着可以使用Certify密钥来代替同一链上的任何其他子密钥(如物理 116 “主密钥”可用于打开为其他钥匙制作的锁)。由于情况并非如此,本指南将 117 其称为“认证密钥”以避免任何歧义。 118 119 充分理解以下内容至关重要: 120 121 1. 所有子项彼此完全独立。如果你丢失了私有子密钥,则无法从链上的任何 122 其他私钥恢复或重新创建它。 123 2. 除 Certify 密钥外,可以有多个具有相同功能的子密钥(例如,你可 124 以有 2 个有效的加密子密钥、3 个有效的签名子密钥,但只有 1 个有 125 效的认证子密钥)。所有子密钥都是完全独立的——加密到一个 **[E]** 126 子密钥的信息(messages)无法使用你可能拥有的任何其他 **[E]** 127 子密钥解密。 128 3. 单个子密钥可能具有多种功能(例如,你的 **[C]** 密钥也可以是你 129 的 **[S]** 密钥)。 130 131 携带 **[C]** (证明)能力的密钥是唯一可以用来指示与其他密钥的关系 132 的密钥。仅 **[C]** 密钥可用于: 133 134 - 添加或撤销具有 S/E/A 功能的其他密钥(子密钥) 135 - 添加、更改或撤销与密钥关联的身份 (uid) 136 - 添加或更改其本身或任何子密钥的到期日期 137 - 出于信任网络的目的签署其他人的密钥 138 139 默认情况下,GnuPG 在生成新密钥时创建以下内容: 140 141 - 一个子密钥同时具有认证和签名功能 (**[SC]**) 142 - 具有加密功能的单独子密钥 (**[E]**) 143 144 如果你在生成密钥时使用了默认参数,那么这就是你将得到的。你可以通过 145 运行命令来验证,例如: ``gpg --list-secret-keys`` 146 147 :: 148 149 sec ed25519 2022-12-20 [SC] [expires: 2024-12-19] 150 000000000000000000000000AAAABBBBCCCCDDDD 151 uid [ultimate] Alice Dev <adev@kernel.org> 152 ssb cv25519 2022-12-20 [E] [expires: 2024-12-19] 153 154 在 ``sec`` 这行下面长长的一行就是你的密钥指纹-无论在下文任何地方 155 看到 ``[fpr]`` 都指的是这40个字符。 156 157 确保你的密码强度高 158 ------------------ 159 160 GnuPG 在将私钥存储到磁盘之前使用密码对其进行加密。这样,即使你的 161 ``.gnupg`` 目录全部泄露或被盗,攻击者在没有事先获取密码来解密的 162 情况下也无法使用你的私钥。 163 164 你的私钥受到强密码保护是绝对必要的。要设置或更改它,请使用:: 165 166 $ gpg --change-passphrase [fpr] 167 168 创建一个单独的签名子密钥 169 ------------------------ 170 171 我们的目的是通过将你的证书密钥移动到离线媒介来保护它,因此如果你只 172 有组合的 **[SC]** 密钥,那么你应该创建一个单独的签名子密钥:: 173 174 $ gpg --quick-addkey [fpr] ed25519 sign 175 176 .. note:: GnuPG 中的 ECC 支持 177 178 请注意,如果你打算使用不支持 ED25519 ECC 密钥的硬件密钥,则 179 应选择“nistp256”或“ed25519”。请参阅下面有关推荐硬件设备的 180 部分。 181 182 183 备份你的证书密钥以进行灾难恢复 184 ------------------------------ 185 186 你的 PGP 密钥上来自其他开发者的签名越多,出于灾难恢复的原因,你就越 187 有理由创建一个位于数字媒体之外的备份版本。 188 189 创建私钥的可打印硬拷贝的最佳方法是使用 ``paperkey`` 为此目的编写 190 的软件。有关输出格式及其相对于其他解决方案的优势的更多详细信息,请参 191 阅 ``paperkey`` 参考资料。大多数发行版都应该已经打包了 Paperkey。 192 193 运行以下命令来创建私钥的硬拷贝备份:: 194 195 $ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt 196 197 打印出该文件(或将输出直接传输到 lpr),然后用笔在纸的边缘写下你的密 198 码。 **强烈建议这样做**,因为密钥打印输出仍然使用该密码进行加密,并且 199 如果你更改了它,你将不记得创建备份时它曾经是什么 - *保证*。 200 201 将生成的打印输出和手写密码放入信封中,并存放在安全且受到良好保护的地 202 方,最好远离你的家,例如银行保险柜。 203 204 .. note:: 205 206 你的打印机可能不再是连接到并行端口的简单哑设备,但由于输出仍然使 207 用你的密码进行加密,因此即使“云端打印”的现代打印机也应该保持相 208 对安全的操作 209 210 备份整个 GnuPG 目录 211 ------------------- 212 213 .. warning:: 214 215 **!!!不要跳过这个步骤!!!** 216 217 如果你需要恢复 PGP 密钥,拥有一个随时可用的备份非常重要。这与我们 218 所做的灾难级准备不同 ``paperkey`` 。每当你需要使用你的证书密钥时, 219 例如在会议和峰会后更改你自己的密钥或签署其他人的密钥时,你还将依赖 220 这些外部副本。 221 222 首先获取一个小型 USB “拇指” 驱动器(最好是两个!),用于备份目的。 223 你需要使用 LUKS 对其进行加密——请参阅你的发行版文档以了解如何完成 224 此操作。 225 226 对于加密密码,你可以使用与 PGP 密钥相同的密码。 227 228 加密过程完成后,重新插入 USB 驱动器并确保其正确安装。将整个 ``.gnupg`` 229 目录复制到加密存储:: 230 231 $ cp -a ~/.gnupg /media/disk/foo/gnupg-backup 232 233 你现在应该测试一下,确保一切依然能正常工作:: 234 235 $ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr] 236 237 如果没有出现任何错误,那么就可以开始了。卸下 USB 驱动器,给它贴上 238 明显的标签,这样下次需要使用随机 USB 驱动器时就不会把它吹走,然后 239 放在安全的地方 - 但不要太远,因为你每次都需要使用它时不时地用于诸 240 如编辑身份、添加或撤销子密钥或签署其他人的密钥之类的事情。 241 242 从你的 homedir 中删除 Certify 密钥 243 ---------------------------------- 244 245 我们的主目录中的文件并没有我们想象的那么受到保护。它们可以通过多种 246 不同的方式泄露或被盗: 247 248 - 在制作快速主目录备份以设置新工作站时意外发生 249 - 系统管理员的疏忽或恶意 250 - 通过不安全的备份 251 - 通过桌面应用程序(浏览器、pdf 查看器等)中的恶意软件 252 - 跨越国界时通过胁迫 253 254 使用良好的密码短语保护你的密钥极大地有助于降低上述任何风险,但密码 255 短语可以通过键盘记录器、肩窥或任何其他方式发现。因此,建议的设置是 256 从主目录中删除你的证书密钥并将其存储在离线存储中。 257 258 .. warning:: 259 260 请参阅上一节并确保你已完整备份 GnuPG 目录。如果你没有可用的 261 备份,我们要做的事情将使你的密钥毫无用处! 262 263 首先,确定你的证书密钥的keygrip:: 264 265 $ gpg --with-keygrip --list-key [fpr] 266 267 输出将是这样的:: 268 269 pub ed25519 2022-12-20 [SC] [expires: 2022-12-19] 270 000000000000000000000000AAAABBBBCCCCDDDD 271 Keygrip = 1111000000000000000000000000000000000000 272 uid [ultimate] Alice Dev <adev@kernel.org> 273 sub cv25519 2022-12-20 [E] [expires: 2022-12-19] 274 Keygrip = 2222000000000000000000000000000000000000 275 sub ed25519 2022-12-20 [S] 276 Keygrip = 3333000000000000000000000000000000000000 277 278 找到该线 ``pub`` 下方的keygrip项 (位于“认证密钥指纹”的正下方)。 279 这将直接对应于你``~/.gnupg`` 目录中的一个文件:: 280 281 $ cd ~/.gnupg/private-keys-v1.d 282 $ ls 283 1111000000000000000000000000000000000000.key 284 2222000000000000000000000000000000000000.key 285 3333000000000000000000000000000000000000.key 286 287 你所要做的只是删除与证书密钥 keygrip 对应的 .key 文件:: 288 289 $ cd ~/.gnupg/private-keys-v1.d 290 $ rm 1111000000000000000000000000000000000000.key 291 292 现在,如果你发出命令 ``--list-secret-keys`` ,它将显示证书密钥丢 293 失( 表示 ``#`` 它不可用):: 294 295 $ gpg --list-secret-keys 296 sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19] 297 000000000000000000000000AAAABBBBCCCCDDDD 298 uid [ultimate] Alice Dev <adev@kernel.org> 299 ssb cv25519 2022-12-20 [E] [expires: 2024-12-19] 300 ssb ed25519 2022-12-20 [S] 301 302 你还应该删除 ``~/.gnupg``目录中的所有 ``secring.gpg`` 文件 ,这些 303 文件可能是以前版本的 GnuPG 留下的。 304 305 如果你没有“private-keys-v1.d”目录 306 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 307 308 如果你没有 ``~/.gnupg/private-keys-v1.d`` 目录,那么你的密钥仍存 309 储在 GnuPG v1 使用的旧文件 ``secring.gpg`` 中。对密钥进行任何更改 310 (例如更改密码或添加子密钥)应该会自动转换旧 ``secring.gpg`` 格式以 311 供使用 ``private-keys-v1.d`` 。 312 313 完成此操作后,请确保删除过时的 ``secring.gpg`` 文件,其中仍然包含你 314 的私钥。 315 316 317 将子密钥移至专用加密设备 318 ======================== 319 320 尽管 Certify 密钥现在不会被泄露或被盗,但子密钥仍然位于你的主目录中。 321 任何设法获得这些内容的人都将能够解密你的通信或伪造你的签名(如果他们知 322 道密码)。此外,每次执行 GnuPG 操作时,密钥都会加载到系统内存中,并 323 可能被足够高级的恶意软件(例如 Meltdown 和 Spectre)从那里窃取。 324 325 完全保护密钥的最佳方法是将它们转移到能够进行智能卡操作的专用硬件设备上。 326 327 智能卡的好处 328 ------------ 329 330 智能卡包含一个加密芯片,能够存储私钥并直接在卡本身上执行加密操作。由于 331 密钥内容永远不会离开智能卡,因此插入硬件设备的计算机的操作系统无法自行 332 检索私钥。这与我们之前用于备份目的的加密 USB 存储设备有很大不同——当 333 USB 设备插入并安装时,操作系统能够访问私钥内容。 334 335 使用外部加密 USB 介质并不能替代具有智能卡功能的设备。 336 337 可用的智能卡设备 338 ---------------- 339 340 除非你的所有笔记本电脑和工作站都有智能卡读卡器,否则最简单的方法是获 341 取实现智能卡功能的专用 USB 设备。有多种选择:: 342 343 - `Nitrokey Start`_: 开放硬件和免费软件,日本基于FSI的 `Gnuk` 。 344 少数支持 ED25519 ECC 密钥的商用设备之一,但提供的安全功能最少 345 (例如防篡改或某些旁路攻击)。 346 - `Nitrokey Pro 2`_: 与 Nitrokey Start 类似,但更防篡改并提供 347 更多安全功能。Pro 2 支持 ECC 加密 (NISTP)。 348 - `Yubikey 5`_: 专有硬件和软件,但比 Nitrokey Pro 便宜,并且以 349 USB-C 形式提供,对于较新的笔记本电脑更有用。提供额外的安全功能, 350 例如 FIDO U2F 等,现在终于支持 NISTP 和 ED25519 ECC 密钥。 351 352 你的选择将取决于成本、你所在地理区域的货运便利性以及开放/专有硬件考虑 353 因素。 354 355 .. note:: 356 357 如果你位列于 MAINTAINERS 中或在 kernel.org 上拥有帐户,则你有 358 资格获得Linux 基金会提供的_`qualify for a free Nitrokey Start` 。 359 360 .. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6 361 .. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nkpr2-nitrokey-pro-2-3 362 .. _`Yubikey 5`: https://www.yubico.com/products/yubikey-5-overview/ 363 .. _Gnuk: https://www.fsij.org/doc-gnuk/ 364 .. _`qualify for a free Nitrokey Start`: https://www.kernel.org/nitrokey-digital-tokens-for-kernel-developers.html 365 366 配置你的智能卡设备 367 ------------------ 368 369 当你将智能卡设备插入任何现代 Linux 工作站时,它就应该可以正常工作 370 (TM)。你可以通过运行来验证它:: 371 372 $ gpg --card-status 373 374 如果你看到完整的智能卡详细信息,那么你就可以开始了。不幸的是,对所有 375 可能无法正常工作的原因进行故障排除超出了本指南的范围。如果你在使该卡 376 与 GnuPG 配合使用时遇到问题,请通过常规支持渠道寻求帮助。 377 378 要配置你的智能卡,你需要使用 GnuPG 菜单系统,因为没有方便的命令行开 379 关:: 380 381 $ gpg --card-edit 382 [...omitted...] 383 gpg/card> admin 384 Admin commands are allowed 385 gpg/card> passwd 386 387 你应该设置用户 PIN (1)、管理员 PIN (3) 和重置代码 (4)。请确保将 388 这些信息记录并存储在安全的地方,尤其是管理员 PIN 码和重置代码(它允 389 许你完全擦除智能卡)。你很少需要使用管理员 PIN 码,如果你不记录它, 390 你将不可避免地忘记它是什么。 391 392 回到主卡菜单,你还可以设置其他值(例如姓名、性别、登录数据等),但这 393 不是必需的,并且如果你丢失智能卡,还会泄露有关智能卡的信息。 394 395 .. note:: 396 397 尽管名称为“PIN”,但卡上的用户 PIN 和管理员 PIN 都不需要是数字。 398 399 .. warning:: 400 401 某些设备可能要求你将子密钥移至设备上,然后才能更改密码。请检查设 402 备制造商提供的文档。 403 404 将子密钥移至你的智能卡 405 ---------------------- 406 407 退出卡菜单(使用“q”)并保存所有更改。接下来,让我们将子密钥移至智能卡 408 上。对于大多数操作,你将需要 PGP 密钥密码和卡的管理员 PIN:: 409 410 $ gpg --edit-key [fpr] 411 412 Secret subkeys are available. 413 414 pub ed25519/AAAABBBBCCCCDDDD 415 created: 2022-12-20 expires: 2024-12-19 usage: SC 416 trust: ultimate validity: ultimate 417 ssb cv25519/1111222233334444 418 created: 2022-12-20 expires: never usage: E 419 ssb ed25519/5555666677778888 420 created: 2017-12-07 expires: never usage: S 421 [ultimate] (1). Alice Dev <adev@kernel.org> 422 423 gpg> 424 425 使用 ``--edit-key`` 使我们再次进入菜单模式,你会注意到按键列表有点 426 不同。从现在开始,所有命令都在此菜单模式内完成,如 所示 ``gpg>``。 427 428 首先,让我们选择要放入卡上的密钥 - 你可以通过键入 ``key 1`` (它是 429 列表中的第一个, **[E]** 子密钥)来完成此操作: 430 431 gpg> key 1 432 433 在输出中,你现在在 **[E]** 子密钥应该看到 ``ssb*`` 。意味着这个子 434 密钥当前被选中。它用作切换键,这意味着如果你再次输入 ``key 1`` , 435 ``*`` 将会消失并且该键将不再被选择。 436 437 现在,让我们将该密钥移至智能卡上:: 438 439 gpg> keytocard 440 Please select where to store the key: 441 (2) Encryption key 442 Your selection? 2 443 444 由于它是我们的 **[E]** 密钥,因此将其放入加密槽中是有意义的。当你提 445 交选择时,系统将首先提示你输入 PGP 密钥密码,然后输入管理员 PIN 码。 446 如果命令返回且没有错误,则你的密钥已被移动。 447 448 **重要提示**:现在再次键入 ``key 1`` 以取消选择第一个键,并 ``key 2`` 449 选择 **[S]** 密钥:: 450 451 gpg> key 1 452 gpg> key 2 453 gpg> keytocard 454 Please select where to store the key: 455 (1) Signature key 456 (3) Authentication key 457 Your selection? 1 458 459 你可以使用 **[S]** 密钥进行签名和身份验证,但我们希望确保它位于签名槽中, 460 因此选择 (1)。跟之前一样,如果你的命令返回且没有错误,则操作成功:: 461 462 gpg> q 463 Save changes? (y/N) y 464 465 保存更改将删除你从主目录移动到卡上的密钥(但这没关系,因为我们还有备份, 466 让我们需要替换智能卡时再次执行此操作)。 467 468 验证密钥是否已移动 469 ~~~~~~~~~~~~~~~~~~ 470 471 如果你现在执行 ``--list-secret-keys`` ,你将看到输出中存在细微的差异:: 472 473 $ gpg --list-secret-keys 474 sec# ed25519 2022-12-20 [SC] [expires: 2024-12-19] 475 000000000000000000000000AAAABBBBCCCCDDDD 476 uid [ultimate] Alice Dev <adev@kernel.org> 477 ssb> cv25519 2022-12-20 [E] [expires: 2024-12-19] 478 ssb> ed25519 2022-12-20 [S] 479 480 在 ``ssb>``中的 ``>`` 输出意味着子密钥只能在智能卡上可用,如果你返回 481 密钥目录并查看那里的内容,你会注意到 ``.key`` 那里的文件已被存根替换:: 482 483 $ cd ~/.gnupg/private-keys-v1.d 484 $ strings *.key | grep 'private-key' 485 486 输出应包含 ``shadowed-private-key`` 指示这些文件只是存根,实际内容 487 位于智能卡上。 488 489 验证智能卡是否正常工作 490 ~~~~~~~~~~~~~~~~~~~~~~ 491 492 要验证智能卡是否按预期工作,你可以创建签名:: 493 494 $ echo "Hello world" | gpg --clearsign > /tmp/test.asc 495 $ gpg --verify /tmp/test.asc 496 497 在你的第一条命令执行时,应该会询问你智能卡的PIN,然后在你运行 498 ``gpg --verify`` 后显示"Good signature"。 499 500 恭喜,你已成功使窃取你的数字开发者身份变得极其困难! 501 502 其他常见的 GnuPG 操作 503 --------------------- 504 505 以下是你需要使用 PGP 密钥执行的一些常见操作的快速参考。 506 507 安装你的安全离线存储 508 ~~~~~~~~~~~~~~~~~~~~ 509 510 你将需要你的证书密钥来执行以下任何操作,因此你首先需要安装备份离线存储 511 并告诉 GnuPG 使用它:: 512 513 $ export GNUPGHOME=/media/disk/foo/gnupg-backup 514 $ gpg --list-secret-keys 515 516 你需要确保你看到 ``sec`` 而不是 ``sec#`` 在输出中( ``#`` 意味着 517 密钥不可用并且你仍在使用常规主目录位置)。 518 519 延长密钥有效期 520 ~~~~~~~~~~~~~~ 521 522 证书密钥的默认到期日期为自创建之日起 2 年。这样做既是出于安全原因,也 523 是为了使过时的密钥最终从密钥服务器中消失。 524 525 要将密钥的有效期从当前日期延长一年,只需运行:: 526 527 $ gpg --quick-set-expire [fpr] 1y 528 529 如果更容易记住,你也可以使用特定日期(例如你的生日、1 月 1 日或加拿大 530 国庆日):: 531 532 $ gpg --quick-set-expire [fpr] 2025-07-01 533 534 请记住将更新后的密钥发送回密钥服务器:: 535 536 $ gpg --send-key [fpr] 537 538 进行任何更改后更新你的工作目录 539 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 540 541 使用离线存储对密钥进行任何更改后,你需要将这些更改导入回常规工作目录 542 中:: 543 544 $ gpg --export | gpg --homedir ~/.gnupg --import 545 $ unset GNUPGHOME 546 547 通过 ssh 使用 gpg-agent 548 ~~~~~~~~~~~~~~~~~~~~~~~ 549 550 如果你需要在远程系统上签署标签或提交,你可以通过 ssh 转发你的 551 gpg-agent。 552 553 请参考 GnuPG wiki 上提供的说明: 554 555 - `Agent通过SSH转发`_ 556 557 如果你可以修改远程端的 sshd 服务器设置,则工作会更顺利。 558 559 .. _`Agent通过SSH转发`: https://wiki.gnupg.org/AgentForwarding 560 561 将 PGP 与 Git 结合使用 562 ====================== 563 564 Git 的核心功能之一是它的分散性——一旦将仓库克隆到你的系统,你就拥有该 565 项目的完整历史记录,包括其所有标签、提交和分支。然而,随着数百个克隆仓 566 库的出现,人们如何验证他们的 linux.git 副本没有被恶意第三方篡改? 567 568 或者,如果在代码中发现后门,并且提交中的“Author”行表示它是由你完成的, 569 而你非常确定 `自己与它无关`_ ,会发生什么? 570 571 为了解决这两个问题,Git 引入了 PGP 集成。签名的标签通过确保其内容与创 572 建标签的开发人员的工作站上的内容完全相同来证明仓库的完整性,而签名的提 573 交使其他人几乎不可能在无法访问你的 PGP 密钥的情况下冒充你。 574 575 .. _`自己与它无关`: https://github.com/jayphelps/git-blame-someone-else 576 577 配置 git 使用你的 PGP 密钥 578 -------------------------- 579 580 如果你的密钥环中只有一个密钥,那么你实际上不需要执行任何额外操作,因为 581 它会成为你的默认密钥。但是,如果你碰巧有多个密钥,你可以告诉 git 应该 582 使用哪个密钥(``[fpr]`` 是你密钥的指纹):: 583 584 $ git config --global user.signingKey [fpr] 585 586 如何使用签名标签 587 ---------------- 588 589 要创建签名标签,只需将 ``-s`` 开关传递给 tag 命令:: 590 591 $ git tag -s [tagname] 592 593 我们的建议是始终签署 git 标签,因为这可以让其他开发人员确保他们从中提 594 取的 git 仓库没有被恶意更改。 595 596 如何验证签名标签 597 ~~~~~~~~~~~~~~~~ 598 599 要验证签名标签,只需使用以下 ``verify-tag`` 命令:: 600 601 $ git verify-tag [tagname] 602 603 如果你从项目仓库的另一个分支中拉取标签,git 应该自动验证你拉取的顶 604 部的签名,并在合并操作期间向你显示结果:: 605 606 $ git pull [url] tags/sometag 607 608 合并消息将包含如下内容:: 609 610 Merge tag 'sometag' of [url] 611 612 [Tag message] 613 614 # gpg: Signature made [...] 615 # gpg: Good signature from [...] 616 617 如果你正在验证其他人的 git 标签,那么你将需要导入他们的 PGP 密钥。 618 请参阅下面的":ref:`身份验证`"部分。 619 620 配置 git 始终对带注释的标签(annotated tags)进行签名annotated tags 621 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 622 623 如果你要创建带注释的标签,你很可能会想要对其进行签名。要强制 git 始终签 624 署带注释的标签,你可以设置一个全局配置选项:: 625 626 $ git config --global tag.forceSignAnnotated true 627 628 如何使用签名的提交 629 ------------------ 630 631 创建签名提交很容易,但在 Linux 内核开发中使用它们要困难得多,因为它依赖 632 于发送到邮件列表的补丁,并且此工作流程不保留 PGP 提交签名。此外,当重新 633 调整仓库以匹配上游时,甚至你自己的 PGP 提交签名最终也会被丢弃。因此,大 634 多数内核开发人员不会费心签署他们的提交,并且会忽略他们在工作中依赖的任何 635 外部仓库中的签名提交。 636 637 但是,如果你的工作 git 树在某些 git 托管服务(kernel.org、 638 infradead.org、ozlabs.org 或其他)上公开可用,那么建议你签署所有 git 639 提交,即使上游开发人员不直接受益于这种做法。 640 641 我们推荐这样做的原因如下: 642 643 1. 如果需要执行代码取证或跟踪代码来源,即使是外部维护的带有 PGP 提交签名 644 的树对于此类问题也很有价值。 645 2. 如果你需要重新克隆本地仓库(例如,在磁盘故障后),这可以让你在恢复工 646 作之前轻松验证仓库的完整性。 647 3. 如果有人需要挑选你的提交,这可以让他们在应用之前快速验证其完整性。 648 649 创建签名提交 650 ~~~~~~~~~~~~ 651 652 要创建签名提交,你只需将 ``-S`` 标志传递给 ``git commit`` 命令(由于 653 与另一个标志冲突,所以它是大写的 ``-S`` ):: 654 655 $ git commit -S 656 657 配置 git 始终对提交进行签名 658 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 659 660 你可以告诉 git 总是签署提交:: 661 662 git config --global commit.gpgSign true 663 664 .. note:: 665 666 确保 ``gpg-agent`` 在打开此功能之前进行配置。 667 668 .. _身份验证: 669 670 671 如何使用签名补丁 672 ---------------- 673 674 可以使用你的 PGP 密钥来签署发送到内核开发人员邮件列表的补丁。由于现有的 675 电子邮件签名机制(PGP-Mime 或 PGP-inline)往往会导致常规代码审查任务 676 出现问题,因此你应该使用为此创建的 kernel.org 工具,该工具将加密证明签 677 名放入消息标头中(a-la DKIM): 678 679 - `Patatt Patch Attestation`_ 680 681 .. _`Patatt Patch Attestation`: https://pypi.org/project/patatt/ 682 683 安装和配置 patatt 684 ~~~~~~~~~~~~~~~~~ 685 686 Patatt 已针对许多发行版进行了打包,因此请先检查那里。你还可以使用 687 “ ``pip install patatt`` ”从 pypi 安装它。 688 689 如果你已经使用 git 配置了 PGP 密钥(通过``user.signingKey`` 配置参数), 690 则 patatt 不需要进一步配置。你可以通过在所需的仓库中安装 git-send-email 691 钩子来开始签署补丁:: 692 693 patatt install-hook 694 695 现在,你使用 ``git send-email`` 发送的任何补丁都将自动使用你的加密签 696 名进行签名 697 698 检查 patatt 签名 699 ~~~~~~~~~~~~~~~~ 700 701 如果你用于 ``b4`` 检索和应用补丁,那么它将自动尝试验证它遇到的所有 702 DKIM 和 patatt 签名,例如:: 703 704 $ b4 am 20220720205013.890942-1-broonie@kernel.org 705 [...] 706 Checking attestation on all messages, may take a moment... 707 --- 708 ✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers 709 ✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall 710 ✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls 711 --- 712 ✓ Signed: openpgp/broonie@kernel.org 713 ✓ Signed: DKIM/kernel.org 714 715 .. note:: 716 717 Patatt 和 b4 仍在积极开发中,你应该检查这些项目的最新文档以了解任 718 何新功能或更新功能。 719 720 如何验证内核开发者身份 721 ====================== 722 723 签署标签和提交很容易,但是如何验证用于签署某项内容的密钥是否属于实际的内 724 核开发人员而不是恶意冒名顶替者? 725 726 使用 WKD 和 DANE 配置auto-key-locate(自动密钥检索) 727 ---------------------------------------------------- 728 729 如果你还没有广泛收集其他开发人员的公钥,那么你可以依靠密钥自动发现和自动 730 检索来快速启动你的密钥环。如果从头开始创建自己的信任 Web 的预期太令人畏 731 惧, GnuPG 可以借助其他委托信任技术(即 DNSSEC 和 TLS)来帮助你继续前 732 进。 733 734 将以下内容添加到你的 ``~/.gnupg/gpg.conf``:: 735 736 auto-key-locate wkd,dane,local 737 auto-key-retrieve 738 739 基于 DNS 的命名实体身份验证(“DANE”)是一种在 DNS 中发布公钥并使用 740 DNSSEC 签名区域保护它们的方法。Web 密钥目录(“WKD”)是使用 https 741 查找来达到相同目的的替代方法。当使用 DANE 或 WKD 查找公钥时,GnuPG 742 将分别验证 DNSSEC 或 TLS 证书,然后将自动检索的公钥添加到本地密钥环。 743 744 Kernel.org 为所有拥有 kernel.org 帐户的开发人员发布 WKD。一旦你的 745 ``gpg.conf`` 中进行了上述更改,你就可以自动检索 Linus Torvalds 和 746 Greg Kroah-Hartman 的密钥(如果你还没有它们):: 747 748 $ gpg --locate-keys torvalds@kernel.org gregkh@kernel.org 749 750 如果你有 kernel.org 帐户,那么你应该 `添加 kernel.org UID 到你的密钥中`_ 751 添加到你的密钥中,以使 WKD 对其他内核开发人员更有用。 752 753 .. _`添加 kernel.org UID 到你的密钥中`: https://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_key 754 755 信任网 (WOT) 与首次使用信任 (TOFU) 756 ----------------------------------- 757 758 PGP 结合了称为“信任网”的信任委托机制。从本质上讲,这是一次尝试取代 759 HTTPS/TLS 世界对集中式证书颁发机构的需求。PGP 将这一责任留给每个 760 用户,而不是由各种软件制造商规定谁应该是你值得信赖的认证实体。 761 762 不幸的是,很少有人了解信任网是如何运作的。虽然它仍然是 OpenPGP 规 763 范的一个重要方面,但最新版本的 GnuPG(2.2 及更高版本)已经实现了 764 一种称为“首次使用信任”(TOFU) 的替代机制。你可以将 TOFU 视为“类似 765 SSH 的信任方法”。使用 SSH,第一次连接到远程系统时,其密钥指纹会被 766 记录并记住。如果将来密钥发生变化,SSH 客户端将向你发出警报并拒绝连 767 接,迫使你决定是否选择信任更改后的密钥。同样,第一次导入某人的 PGP 768 密钥时,它被认为是有效的。如果将来的任何时候 GnuPG 遇到具有相同标 769 识的另一个密钥,则先前导入的密钥和新密钥都将被标记为无效,你将需要手 770 动确定保留哪一个。 771 772 我们建议你使用 TOFU+PGP 组合信任模型(这是 GnuPG v2 中新默认的)。 773 若要设置它,在 ``~/.gnupg/gpg.conf`` 中添加(或修改) 774 ``trust-model`` 设置:: 775 776 trust-model tofu+pgp 777 778 使用 kernel.org 信任网仓库 779 -------------------------- 780 781 Kernel.org 维护着一个包含开发人员公钥的 git 仓库,作为复制密钥服 782 务器网络的替代品,而在过去几年中,该网络几乎已经陷入黑暗。有关如何将 783 该仓库设置为公钥来源的完整文档可以在此处找到: 784 785 - `内核开发者密钥环`_ 786 787 如果你是内核开发人员,请考虑提交你的密钥以将其包含到该密钥环中。 788 789 .. _`内核开发者密钥环`: https://korg.docs.kernel.org/pgpkeys.html
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.