通用第二因素 - Arch Linux 中文维基

跳转到内容

# 通用第二因素

来自 Arch Linux 中文维基
翻译状态：

- 本文（或部分内容）译自 Universal 2nd Factor，最近一次同步于 2025-01-28，若英文版本有所更改，则您可以帮助同步与翻译更改的内容。
- 您可以在 ArchWiki 的对应页面找到本文翻译的原始修订历史。
- 本文可能与英文原文存在出入。

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

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

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

当前最新的标准是 WebAuthn。

## 用于网页认证

谷歌、Facebook、Twitter 和 GitHub 等主流网站都支持使用 U2F，更多网站的清单和设置文档请参考 2fa.directory 或 dongleauth.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

分类：​

- 通用第二因素
- 使用“模板:Move”标记的页面或章节

通用第二因素
添加话题