作者删除所有磁盘SSH密钥,改用YubiKey等安全隔区存储
来源标题:I deleted all my SSH keys
一位长期使用YubiKey ed25519-sk密钥的用户删除了所有传统磁盘SSH密钥,改为完全依赖硬件安全隔区(YubiKey、TPM、Apple Secure Enclave)保存和加密密钥材料,目标是磁盘上不留任何未受保护的密钥。作者承认传统密码短语加密方式对多数威胁模型已足够,但出于个人偏好仍选择硬件方案。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
我从 ed25519-sk 密钥配合 YubiKey 可用之初就一直在用它们。但由于一些特定使用场景(也坦白说,YubiKey 挺贵的),我手上一直留着几个传统的磁盘密钥,等着我最终决定处理掉它们。
这篇文章记录了我如何使用各种安全隔区(YubiKey、TPM、Apple Secure Enclave)来保存/加密 SSH 密钥材料,从而实现磁盘上不存放任何未受保护的密钥材料这一目标。
大概吧。我并不是想说这篇文章是所有人使用 SSH 密钥的唯一方式。使用口令短语会用 bcrypt 和 AES 加密密钥,即使磁盘上的密钥文件以某种方式泄露,也能保持保护。而有了正常工作的 ssh-agent,每个会话只需要输入一次口令短语,之后解密后的密钥材料就保存在内存中。
所以没错,“传统”方法对大多数威胁模型来说大概够用了。但我还是想转向硬件支持的密钥,主要是为了那份满足感。
当我说“硬件驻留”密钥时,我指的是使用安全隔区或 YubiKey 这类专用硬件来存储或保护密钥材料的密钥。理论上的好处是:使用密钥时必须要有生成该 SSH 密钥的硬件。没有任何机制可以泄露或窃取用这种方法生成的密钥。磁盘上存在的任何材料,没有硬件就是无用的。
我将尝试三种不同的硬件方法来实现这一目标,我认为它们能覆盖我的所有需求:
使用 YubiKey(5 及更新版本),SSH 密钥可以通过 ed25519-sk(其中 -sk 代表“Security Key”)直接注册到设备中。除了 OpenSSH 本身之外,不需要任何额外软件。
要将新的 SSH 密钥存储到 YubiKey 上,插入设备并运行:
ssh-keygen -t ed25519-sk -O resident -O application="ssh:nameyourkey" -f ~/.ssh/id_ed25519-sk
命令中设置的 application 标签是任意的,可以设为你喜欢的任何易记字符串,以便在同一 YubiKey 上创建多个密钥时区分它们。
如果安装了 ykman,你现在可以查看注册到设备中的凭据列表:
$ ykman fido credentials list Enter your PIN: Credential ID RP ID Username Display name 0f41fb61... ssh:yournamehere openssh openssh
如果 ykman 提示你尚未在 YubiKey 上设置 FIDO PIN,可以用 ykman fido access change-pin 来设置。
注意,你实际上不需要 ykman 就能注册或使用 YubiKey 上的 SSH 密钥,但它确实让设备管理更方便。
密钥创建后,你可以从磁盘上获取公钥:
$ cat ~/.ssh/id_ed25519-sk.pub sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIA9B+2GGCkQvBzpa4WobQhfC9YU5Su3pKXBmVLSXEqfRAAAAEHNzaDp5b3VybmFtZWhlcmU= user@hostname
这个密钥可以像任何其他 SSH 公钥一样使用——添加到主机的 authorized_keys 中、用 ssh-copy-id 复制,或粘贴到依赖 SSH 的服务中,比如 Git 托管平台。
你还会在磁盘上找到一个 ~/.ssh/id_ed25519-sk 文件(没有 .pub 扩展名)。注意,虽然这看起来像私钥,但它实际上不包含密钥材料。它只是一个用于在硬件设备上找到相关密钥的句柄。
要配置该密钥进行身份验证,可以像普通密钥一样用 ssh-add 注册,或直接在 ~/.ssh/config 中指定:
Host blog.infected.systems IdentityFile ~/.ssh/id_ed25519-sk
从这里开始,你就可以像使用普通密钥一样 SSH 登录目标主机了。SSH 命令运行时,会要求你轻触 YubiKey 以确认在场。
使用上述默认设置创建的 ed25519-sk 密钥时,每次使用密钥都会要求你通过物理触摸 YubiKey 来确认在场。
保持这个默认设置大概是个好主意,但如果你有需要无人值守使用密钥的特定场景,可以这样生成一个免触摸密钥:
ssh-keygen -t ed25519-sk -O resident -O no-touch-required -O application="ssh:nameyourkey" -f ~/.ssh/id_ed25519-sk
使用免触摸密钥时,虽然恶意行为者即使拥有 YubiKey 所插入主机的 root 权限也无法窃取密钥,但有权访问的恶意行为者可以在不需要任何在场检测或人工交互的情况下使用该密钥。所以在这么做之前,请确保这确实符合你的风险承受能力。
要将免触摸密钥用于对远程服务器的无人值守身份验证,需要在目标主机的 authorized_keys 文件中该条目前面加上 no-touch-required,否则 OpenSSH 的默认安全设置会拒绝该密钥。
$ cat ~/.ssh/authorized_keys no-touch-required sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIA9B+2GGCkQvBzpa4WobQhfC9YU5Su3pKXBmVLSXEqfRAAAAEHNzaDp5b3VybmFtZWhlcmU= user@hostname
方法 2:TPM
YubiKey 很好,但相当贵。如果我们能用主机上已有的 TPM 来保护密钥材料,那就很有用了。嗯,事实证明我们可以!
不幸的是这确实需要额外软件,但它是一个相当精简的 Golang 包——ssh-tpm-agent。可以直接从 GitHub 用 Go 安装,不过 Ubuntu 已有原生打包,我也正在为 Fedora 打包。
要创建一个带 PIN 的 TPM 支持的 SSH 密钥,运行:
ssh-tpm-keygen -N "your-pin"
这个过程会询问你将密钥存储在哪里,以及是否要为其设置口令短语。从这里开始,我们再次得到一个密钥对,带有 .pub 文件,可以用于 authorized_keys 或按我们喜欢的方式复制。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。