跳转到内容

通用第二因素

来自 Arch Linux 中文维基

通用第二因素(U2F)是一个开放标准,它基于类似智能卡中的安全技术,使用专门的 USB 或 NFC 设备来加强和简化双因素身份验证(2FA)。

该标准最早由谷歌和 Yubico 开发,并包含了来自 NXP 的贡献,现在由 FIDO 联盟进行维护。

所有与 U2F 和 U2F 设备相关的文章请参考分类:通用第二因素

当前最新的标准是 WebAuthn

用于网页认证[编辑 | 编辑源代码]

谷歌、Facebook、Twitter 和 GitHub 等主流网站都支持使用 U2F,更多网站的清单和设置文档请参考 2fa.directorydongleauth.com。对于所有支持该功能的浏览器,很可能只需要安装 libfido2。Yubico 提供了一个测试页用于进行测试。

Firefox[编辑 | 编辑源代码]

Firefox/微调#Fido U2F 身份验证

Chromium/Chrome[编辑 | 编辑源代码]

Chromium#U2F 身份验证

用于用户会话认证[编辑 | 编辑源代码]

YubiKey 的制造商 Yubico 开发了一个 U2F PAM 模块,可用于在登陆时进行二次验证,也可以完全替代密码。

注意:虽然本文提到了 Yubico/YubiKey,基本上所有 U2F 和/或 FIDO2 合规密钥都受 pam-u2f 支持。

安装 PAM 模块[编辑 | 编辑源代码]

该模块是 pam-u2f 的一部分。

添加密钥[编辑 | 编辑源代码]

注意:下面使用的目录是默认路径。对于单用户实现,可以将文件移动到你选择的目录下,然后在 pam_u2f.so 一行末添加 authfile=/path/to/u2f_keys,该操作可用于将 u2f_keys 移动到文件系统上的受保护位置。对于多用户实现,可参考 pam-u2f 官方文档使用中心化映射文件。

首先使用 pamu2fcfg 添加密钥:

$ mkdir ~/.config/Yubico
$ pamu2fcfg -o pam://hostname -i pam://hostname > ~/.config/Yubico/u2f_keys

输入 PIN 码后,通过按下 U2F 密钥上的按钮进行确认。

注意:如果由于不同网络下的 DHCP 等原因导致系统主机名被更改,你将无法进行登录。为避免该情况发生,建议指定上述选项,并将 hostname 替换为正确的主机名。

如果你有多个密钥,参考下方进行添加:

$ pamu2fcfg -o pam://hostname -i pam://hostname -n >> ~/.config/Yubico/u2f_keys
注意:以上命令必须使用 -n 选项。对于同一用户的后续条目,它将按照规范要求省略生成条目中的用户名部分。多个相同用户名的条目会导致 PAM 出现不可预测的行为。另外,不要手动进行分行,u2f_keys 文件中只能存在一行内容。[1]

无密码 sudo[编辑 | 编辑源代码]

警告:在保存配置更改前,先单独打开一个具有 root 权限的 shell 环境(如 sudo -s),这样可以保证出问题后能够撤回更改。

在文件中加入第一行:

/etc/pam.d/sudo
auth            sufficient      pam_u2f.so cue origin=pam://hostname appid=pam://hostname

别忘了替换掉 hostname 一项。接下来打开一个新的命令行窗口,执行 sudo ls。密钥上的 LED 应该会开始闪烁,按下后命令就会开始执行。cue 选项用于提示用户所需进行的操作(Please touch the device)。

要让密钥作为使用 sudo 的唯一方法(即不回退使用密码),需要将其它认证方式注释掉(默认一般只有 system-auth 一项)。

/etc/pam.d/sudo
#auth           include         system-auth

你还需要将 pam_u2f.so 一行的 sufficient 替换为 required

警告:这会导致用户在没有配置 U2F 密钥的情况下无法使用 sudo。

GDM 登录[编辑 | 编辑源代码]

在现有的 auth 行后添加以下内容:

/etc/pam.d/gdm-password
auth            required      pam_u2f.so nouserok origin=pam://hostname appid=pam://hostname

注意 nouserok 选项,该选项允许在用户未配置密钥时规则失效,适用于多用户环境下其中只有部分用户使用 U2F 密钥的情况。

注意:该方法不适用于用户主目录(home)加密的情况,该目录在登录流程完成前尚未完全解密,导致无法使用 u2f_keys 文件。在这种情况下,可以参考 pam-u2f 官方文档使用中心化映射文件。

有些多功能密钥(例如 Trezor Model T)带有 U2F/PAM 功能,但根据 CTAP 2.0 标准[2],在系统启动时其可能不会启用该功能。在有多个 U2F 密钥的情况下,pam-u2f 会依次查找并等待设备(Trezor)超时,之后才提示提供或触碰其它 U2F 密钥,导致 GDM 出现长达 2 分钟的延时 [3]。You could try adding the nodetect option alongside debug and finish any device specific login (ex. screen PIN) before GDM loads.

SDDM/KDE[编辑 | 编辑源代码]

SDDM 似乎在用户初始登录时不支持 pam_u2f。可以使用自动登录,然后编辑 /etc/pam.d/kde 来控制屏幕锁定。

如果你使用的是带有生物识别验证功能的 U2F 密钥(如 Yubikey Bio),并希望使用 1FA 功能,请使用 /etc/pam.d/kde-fingerprint,注释掉 pam_fprintd.so 行,并在其位置上进行修改。这样可以避免在身份验证后显示解锁按钮,而不是立即解锁 [4]

以下为参考示例:

/etc/pam.d/kde-fingerprint
#%PAM-1.0

auth       required                    pam_shells.so
auth       requisite                   pam_nologin.so
auth       requisite                   pam_faillock.so      preauth

# take over fprintd for u2f since yubikey bio is a fingerprint reader and bypasses kscreenlocker's "unlock" button
#-auth      required                    pam_fprintd.so
auth required pam_u2f.so cue pinverification=0 userverification=1

auth       optional                    pam_permit.so
auth       required                    pam_env.so

account    include                     system-local-login

password   required                    pam_deny.so

session    include                     system-local-login
警告:不要像其它 PAM 配置文件一样在 /etc/pam.d/kde-fingerprint 中使用 auth sufficient,这会导致即使认证失败也能绕过锁屏界面。

其它认证方式[编辑 | 编辑源代码]

可以参考上文为其它服务启用 PAM 模块。以 Cinnamon 屏保为例,可以修改 /etc/pam.d/cinnamon-screensaver

对于 Polkit,需要先将 /usr/lib/pam.d/polkit-1 复制到 /etc/pam.d/polkit-1,然后再进行修改。

排障[编辑 | 编辑源代码]

如果你把自己锁在系统外了,需要先启动到恢复模式或 U 盘,然后撤回 PAM 的配置并重启。

如果 pam-u2f 模块静默失败了,可以在 /etc/pam.d/ 下文件对应的行中添加 debug 关键字。

OpenSSH[编辑 | 编辑源代码]

8.2 以及上版本的 OpenSSH 原生支持 FIDO/U2F 密钥,详情请参考 SSH 密钥#FIDO/U2F

使用 LUKS 进行静态数据加密[编辑 | 编辑源代码]

此页面或章节适合移动到 systemd-cryptenroll

附注: systemd-cryptenroll 不止支持 FIDO。(在 Talk:Trusted Platform Module#move systemd-cryptenroll to separate article 讨论)


从 248版本开始,可以通过 systemd 使用 FIDO2 密钥解锁 LUKS 分区

首先需要配置 /etc/crypttab 文件(具体参考下方),如果需要解锁根分区,也可以配置 initramfs。配置步骤与使用 TPM 芯片解锁类似,具体请参考 systemd-cryptenroll#Trusted Platform Module

注册密钥需要使用 systemd-cryptenroll。首先使用以下命令列出检测到的密钥:

$ systemd-cryptenroll --fido2-device=list

然后在 LUKS 槽中注册密钥,指定 auto 值(如果有多个设备,也可以 FIDO2 设备的路径,例如 /dev/hidrawX):

$ systemd-cryptenroll --fido2-device=auto /dev/sdX

非根分区[编辑 | 编辑源代码]

对于非根分区,crypttab 如下:

/etc/crypttab
data /dev/sdX none fido2-device=auto

对于加密分区是由 LVM 管理的逻辑卷的情况同样可用:

/etc/crypttab
data /dev/vg1/data none fido2-device=auto