brintos

brintos / linux-shallow public Read only

0
0
Text · 31.6 KiB · eb12694 Raw
790 lines · plain
1.. SPDX-License-Identifier: GPL-2.02.. include:: ../disclaimer-zh_CN.rst3 4:Original: Documentation/process/maintainer-pgp-guide.rst5 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.md24 25PGP 在 Linux 内核开发中的作用26=============================27 28PGP 有助于确保 Linux 内核开发社区产出代码的完整性,并在较小程度上,通过29PGP 签名的电子邮件交换,在开发者之间建立可信的交流渠道。30 31Linux 内核源代码主要有两种(维护)方式:32 33- 分布式源仓库 (git)34- 定期发布快照 (tarballs)35 36git 仓库和 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 54PGP 工具55========56 57使用 GnuPG 2.2 或更高版本58-------------------------59 60默认情况下,你的发行版应该已经安装了 GnuPG,你只需要验证你使用的是相当新的61版本即可。要检查,请运行::62 63    $ gpg --version | head -n164 65如果你有 2.2 或更高版本,那么你就可以开始了。如果你的版本早于 2.2,则本指66南中的某些命令可能不起作用。67 68配置 gpg-agent 选项69~~~~~~~~~~~~~~~~~~~70 71GnuPG 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 180085    max-cache-ttl 720086 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 105PGP 密钥很少由单个密钥对组成 - 通常它是独立子密钥的集合,这些子密钥106可根据其功能用于不同的目的,并在创建时分配。PGP 定义了密钥可以具有的107四种功能:108 109- **[S]** 密钥可用于签名110- **[E]** 密钥可用于加密111- **[A]** 密钥可用于身份验证112- **[C]** 密钥可用于验证其他密钥113 114具有 **[C]** 功能的密钥通常称为“主”密钥,但该术语具有误导性,因为115它意味着可以使用Certify密钥来代替同一链上的任何其他子密钥(如物理116“主密钥”可用于打开为其他钥匙制作的锁)。由于情况并非如此,本指南将117其称为“认证密钥”以避免任何歧义。118 119充分理解以下内容至关重要:120 1211. 所有子项彼此完全独立。如果你丢失了私有子密钥,则无法从链上的任何122   其他私钥恢复或重新创建它。1232. 除 Certify 密钥外,可以有多个具有相同功能的子密钥(例如,你可124   以有 2 个有效的加密子密钥、3 个有效的签名子密钥,但只有 1 个有125   效的认证子密钥)。所有子密钥都是完全独立的——加密到一个 **[E]**126   子密钥的信息(messages)无法使用你可能拥有的任何其他 **[E]**127   子密钥解密。1283. 单个子密钥可能具有多种功能(例如,你的 **[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          000000000000000000000000AAAABBBBCCCCDDDD151    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 160GnuPG 在将私钥存储到磁盘之前使用密码对其进行加密。这样,即使你的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 sign175 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.txt196 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-backup232 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          000000000000000000000000AAAABBBBCCCCDDDD271          Keygrip = 1111000000000000000000000000000000000000272    uid           [ultimate] Alice Dev <adev@kernel.org>273    sub   cv25519 2022-12-20 [E] [expires: 2022-12-19]274          Keygrip = 2222000000000000000000000000000000000000275    sub   ed25519 2022-12-20 [S]276          Keygrip = 3333000000000000000000000000000000000000277 278找到该线 ``pub`` 下方的keygrip项 (位于“认证密钥指纹”的正下方)。279这将直接对应于你``~/.gnupg`` 目录中的一个文件::280 281    $ cd ~/.gnupg/private-keys-v1.d282    $ ls283    1111000000000000000000000000000000000000.key284    2222000000000000000000000000000000000000.key285    3333000000000000000000000000000000000000.key286 287你所要做的只是删除与证书密钥 keygrip 对应的 .key 文件::288 289    $ cd ~/.gnupg/private-keys-v1.d290    $ rm 1111000000000000000000000000000000000000.key291 292现在,如果你发出命令 ``--list-secret-keys`` ,它将显示证书密钥丢293失( 表示 ``#`` 它不可用)::294 295    $ gpg --list-secret-keys296    sec#  ed25519 2022-12-20 [SC] [expires: 2024-12-19]297          000000000000000000000000AAAABBBBCCCCDDDD298    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 存储设备有很大不同——当333USB 设备插入并安装时,操作系统能够访问私钥内容。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-6361.. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nkpr2-nitrokey-pro-2-3362.. _`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.html365 366配置你的智能卡设备367------------------368 369当你将智能卡设备插入任何现代 Linux 工作站时,它就应该可以正常工作370(TM)。你可以通过运行来验证它::371 372    $ gpg --card-status373 374如果你看到完整的智能卡详细信息,那么你就可以开始了。不幸的是,对所有375可能无法正常工作的原因进行故障排除超出了本指南的范围。如果你在使该卡376与 GnuPG 配合使用时遇到问题,请通过常规支持渠道寻求帮助。377 378要配置你的智能卡,你需要使用 GnuPG 菜单系统,因为没有方便的命令行开379关::380 381    $ gpg --card-edit382    [...omitted...]383    gpg/card> admin384    Admin commands are allowed385    gpg/card> passwd386 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/AAAABBBBCCCCDDDD415         created: 2022-12-20  expires: 2024-12-19  usage: SC416         trust: ultimate      validity: ultimate417    ssb  cv25519/1111222233334444418         created: 2022-12-20  expires: never       usage: E419    ssb  ed25519/5555666677778888420         created: 2017-12-07  expires: never       usage: S421    [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 1432 433在输出中,你现在在 **[E]** 子密钥应该看到 ``ssb*`` 。意味着这个子434密钥当前被选中。它用作切换键,这意味着如果你再次输入 ``key 1`` ,435``*`` 将会消失并且该键将不再被选择。436 437现在,让我们将该密钥移至智能卡上::438 439    gpg> keytocard440    Please select where to store the key:441       (2) Encryption key442    Your selection? 2443 444由于它是我们的 **[E]** 密钥,因此将其放入加密槽中是有意义的。当你提445交选择时,系统将首先提示你输入 PGP 密钥密码,然后输入管理员 PIN 码。446如果命令返回且没有错误,则你的密钥已被移动。447 448**重要提示**:现在再次键入 ``key 1`` 以取消选择第一个键,并 ``key 2``449选择 **[S]** 密钥::450 451    gpg> key 1452    gpg> key 2453    gpg> keytocard454    Please select where to store the key:455       (1) Signature key456       (3) Authentication key457    Your selection? 1458 459你可以使用 **[S]** 密钥进行签名和身份验证,但我们希望确保它位于签名槽中,460因此选择 (1)。跟之前一样,如果你的命令返回且没有错误,则操作成功::461 462    gpg> q463    Save changes? (y/N) y464 465保存更改将删除你从主目录移动到卡上的密钥(但这没关系,因为我们还有备份,466让我们需要替换智能卡时再次执行此操作)。467 468验证密钥是否已移动469~~~~~~~~~~~~~~~~~~470 471如果你现在执行 ``--list-secret-keys`` ,你将看到输出中存在细微的差异::472 473    $ gpg --list-secret-keys474    sec#  ed25519 2022-12-20 [SC] [expires: 2024-12-19]475          000000000000000000000000AAAABBBBCCCCDDDD476    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.d484    $ 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.asc495    $ gpg --verify /tmp/test.asc496 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-backup514    $ gpg --list-secret-keys515 516你需要确保你看到 ``sec`` 而不是 ``sec#`` 在输出中( ``#`` 意味着517密钥不可用并且你仍在使用常规主目录位置)。518 519延长密钥有效期520~~~~~~~~~~~~~~521 522证书密钥的默认到期日期为自创建之日起 2 年。这样做既是出于安全原因,也523是为了使过时的密钥最终从密钥服务器中消失。524 525要将密钥的有效期从当前日期延长一年,只需运行::526 527    $ gpg --quick-set-expire [fpr] 1y528 529如果更容易记住,你也可以使用特定日期(例如你的生日、1 月 1 日或加拿大530国庆日)::531 532    $ gpg --quick-set-expire [fpr] 2025-07-01533 534请记住将更新后的密钥发送回密钥服务器::535 536    $ gpg --send-key [fpr]537 538进行任何更改后更新你的工作目录539~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~540 541使用离线存储对密钥进行任何更改后,你需要将这些更改导入回常规工作目录542中::543 544    $ gpg --export | gpg --homedir ~/.gnupg --import545    $ unset GNUPGHOME546 547通过 ssh 使用 gpg-agent548~~~~~~~~~~~~~~~~~~~~~~~549 550如果你需要在远程系统上签署标签或提交,你可以通过 ssh 转发你的551gpg-agent。552 553请参考 GnuPG wiki 上提供的说明:554 555- `Agent通过SSH转发`_556 557如果你可以修改远程端的 sshd 服务器设置,则工作会更顺利。558 559.. _`Agent通过SSH转发`: https://wiki.gnupg.org/AgentForwarding560 561将 PGP 与 Git 结合使用562======================563 564Git 的核心功能之一是它的分散性——一旦将仓库克隆到你的系统,你就拥有该565项目的完整历史记录,包括其所有标签、提交和分支。然而,随着数百个克隆仓566库的出现,人们如何验证他们的 linux.git 副本没有被恶意第三方篡改?567 568或者,如果在代码中发现后门,并且提交中的“Author”行表示它是由你完成的,569而你非常确定 `自己与它无关`_ ,会发生什么?570 571为了解决这两个问题,Git 引入了 PGP 集成。签名的标签通过确保其内容与创572建标签的开发人员的工作站上的内容完全相同来证明仓库的完整性,而签名的提573交使其他人几乎不可能在无法访问你的 PGP 密钥的情况下冒充你。574 575.. _`自己与它无关`: https://github.com/jayphelps/git-blame-someone-else576 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/sometag607 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 tags621~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~622 623如果你要创建带注释的标签,你很可能会想要对其进行签名。要强制 git 始终签624署带注释的标签,你可以设置一个全局配置选项::625 626    $ git config --global tag.forceSignAnnotated true627 628如何使用签名的提交629------------------630 631创建签名提交很容易,但在 Linux 内核开发中使用它们要困难得多,因为它依赖632于发送到邮件列表的补丁,并且此工作流程不保留 PGP 提交签名。此外,当重新633调整仓库以匹配上游时,甚至你自己的 PGP 提交签名最终也会被丢弃。因此,大634多数内核开发人员不会费心签署他们的提交,并且会忽略他们在工作中依赖的任何635外部仓库中的签名提交。636 637但是,如果你的工作 git 树在某些 git 托管服务(kernel.org、638infradead.org、ozlabs.org 或其他)上公开可用,那么建议你签署所有 git639提交,即使上游开发人员不直接受益于这种做法。640 641我们推荐这样做的原因如下:642 6431. 如果需要执行代码取证或跟踪代码来源,即使是外部维护的带有 PGP 提交签名644   的树对于此类问题也很有价值。6452. 如果你需要重新克隆本地仓库(例如,在磁盘故障后),这可以让你在恢复工646   作之前轻松验证仓库的完整性。6473. 如果有人需要挑选你的提交,这可以让他们在应用之前快速验证其完整性。648 649创建签名提交650~~~~~~~~~~~~651 652要创建签名提交,你只需将 ``-S`` 标志传递给 ``git commit`` 命令(由于653与另一个标志冲突,所以它是大写的 ``-S`` )::654 655    $ git commit -S656 657配置 git 始终对提交进行签名658~~~~~~~~~~~~~~~~~~~~~~~~~~~659 660你可以告诉 git 总是签署提交::661 662    git config --global commit.gpgSign true663 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安装和配置 patatt684~~~~~~~~~~~~~~~~~685 686Patatt 已针对许多发行版进行了打包,因此请先检查那里。你还可以使用687“ ``pip install patatt`` ”从 pypi 安装它。688 689如果你已经使用 git 配置了 PGP 密钥(通过``user.signingKey`` 配置参数),690则 patatt 不需要进一步配置。你可以通过在所需的仓库中安装 git-send-email691钩子来开始签署补丁::692 693    patatt install-hook694 695现在,你使用 ``git send-email`` 发送的任何补丁都将自动使用你的加密签696名进行签名697 698检查 patatt 签名699~~~~~~~~~~~~~~~~700 701如果你用于 ``b4`` 检索和应用补丁,那么它将自动尝试验证它遇到的所有702DKIM 和 patatt 签名,例如::703 704    $ b4 am 20220720205013.890942-1-broonie@kernel.org705    [...]706    Checking attestation on all messages, may take a moment...707    ---708      ✓ [PATCH v1 1/3] kselftest/arm64: Correct buffer allocation for SVE Z registers709      ✓ [PATCH v1 2/3] arm64/sve: Document our actual ABI for clearing registers on syscall710      ✓ [PATCH v1 3/3] kselftest/arm64: Enforce actual ABI for SVE syscalls711      ---712      ✓ Signed: openpgp/broonie@kernel.org713      ✓ Signed: DKIM/kernel.org714 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,local737    auto-key-retrieve738 739基于 DNS 的命名实体身份验证(“DANE”)是一种在 DNS 中发布公钥并使用740DNSSEC 签名区域保护它们的方法。Web 密钥目录(“WKD”)是使用 https741查找来达到相同目的的替代方法。当使用 DANE 或 WKD 查找公钥时,GnuPG742将分别验证 DNSSEC 或 TLS 证书,然后将自动检索的公钥添加到本地密钥环。743 744Kernel.org 为所有拥有 kernel.org 帐户的开发人员发布 WKD。一旦你的745``gpg.conf`` 中进行了上述更改,你就可以自动检索 Linus Torvalds 和746Greg Kroah-Hartman 的密钥(如果你还没有它们)::747 748    $ gpg --locate-keys torvalds@kernel.org gregkh@kernel.org749 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_key754 755信任网 (WOT) 与首次使用信任 (TOFU)756-----------------------------------757 758PGP 结合了称为“信任网”的信任委托机制。从本质上讲,这是一次尝试取代759HTTPS/TLS 世界对集中式证书颁发机构的需求。PGP 将这一责任留给每个760用户,而不是由各种软件制造商规定谁应该是你值得信赖的认证实体。761 762不幸的是,很少有人了解信任网是如何运作的。虽然它仍然是 OpenPGP 规763范的一个重要方面,但最新版本的 GnuPG(2.2 及更高版本)已经实现了764一种称为“首次使用信任”(TOFU) 的替代机制。你可以将 TOFU 视为“类似765SSH 的信任方法”。使用 SSH,第一次连接到远程系统时,其密钥指纹会被766记录并记住。如果将来密钥发生变化,SSH 客户端将向你发出警报并拒绝连767接,迫使你决定是否选择信任更改后的密钥。同样,第一次导入某人的 PGP768密钥时,它被认为是有效的。如果将来的任何时候 GnuPG 遇到具有相同标769识的另一个密钥,则先前导入的密钥和新密钥都将被标记为无效,你将需要手770动确定保留哪一个。771 772我们建议你使用 TOFU+PGP 组合信任模型(这是 GnuPG v2 中新默认的)。773若要设置它,在 ``~/.gnupg/gpg.conf`` 中添加(或修改)774``trust-model`` 设置::775 776    trust-model tofu+pgp777 778使用 kernel.org 信任网仓库779--------------------------780 781Kernel.org 维护着一个包含开发人员公钥的 git 仓库,作为复制密钥服782务器网络的替代品,而在过去几年中,该网络几乎已经陷入黑暗。有关如何将783该仓库设置为公钥来源的完整文档可以在此处找到:784 785- `内核开发者密钥环`_786 787如果你是内核开发人员,请考虑提交你的密钥以将其包含到该密钥环中。788 789.. _`内核开发者密钥环`: https://korg.docs.kernel.org/pgpkeys.html790