通过 pam-u2f,可以用触摸 CanoKey 的方式代替 GDM 登录和 sudo 认证时的账户密码,同时保留密码作为备用。
USB 权限
见CanoKey 官方 Linux 系统配置。摘录如下
文件:/etc/udev/rules.d/69-canokeys.rules
# GnuPG/pcsclite
SUBSYSTEM!="usb", GOTO="canokeys_rules_end"
ACTION!="add|change", GOTO="canokeys_rules_end"
ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42d4", ENV{ID_SMARTCARD_READER}="1"
LABEL="canokeys_rules_end"
# FIDO2
# note that if you find this line in 70-fido.rules, you can ignore it
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="42d4", TAG+="uaccess", GROUP="plugdev", MODE="0660"
# make this usb device accessible for users, used in WebUSB
# change the mode so unprivileged users can access it, insecure rule, though
SUBSYSTEMS=="usb", ATTR{idVendor}=="20a0", ATTR{idProduct}=="42d4", MODE:="0666"
# if the above works for WebUSB (web console), you may change into a more secure way
# choose one of the following rules
# note if you use "plugdev", make sure you have this group and the wanted user is in that group
#SUBSYSTEMS=="usb", ATTR{idVendor}=="20a0", ATTR{idProduct}=="42d4", GROUP="plugdev", MODE="0660"
#SUBSYSTEMS=="usb", ATTR{idVendor}=="20a0", ATTR{idProduct}=="42d4", TAG+="uaccess"
sudoedit /etc/udev/rules.d/69-canokeys.rules # 然后在文件中加入上面内容
sudo udevadm control --reload-rules && sudo udevadm trigger
安装 PAM 模块
见 ArchWiki:Installing the PAM module。
sudo pacman -Syu pam-u2f
pam-u2f 也支持 CanoKey 等兼容 U2F/FIDO2 的密钥,不限于 YubiKey。
修改前备份
见 ArchWiki:Passwordless sudo。修改认证配置前,打开一个独立终端并保留 root shell,方便配置出错时恢复:
sudo -i
建议在这个 root shell 中备份配置,直到全部测试完成再关闭。
登记密钥
见 ArchWiki:Adding a key 和 pamu2fcfg 手册。
插入 CanoKey,在需要使用密钥认证的普通用户账户下执行:
mkdir -p ~/.config/Yubico
pamu2fcfg -u "$(id -un)" \
-o pam://canokey-local \
-i pam://canokey-local \
> ~/.config/Yubico/canokey-pam
如果提示输入 PIN,输入密钥的 FIDO2 PIN,按回车后按设备提示触摸。
完成后可以检查输出文件:
cat ~/.config/Yubico/canokey-pam
文件应包含以当前用户名和冒号开头的一行登记信息。
系统登记文件
见 pam_u2f 手册的 authfile 和 Caveats。
本文选择 /etc/u2f_mappings,让登录前即可读取登记信息,不依赖家目录解密。
chmod 600 ~/.config/Yubico/canokey-pam
sudo install -o root -g root -m 600 \
~/.config/Yubico/canokey-pam /etc/u2f_mappings
注意这条命令会覆盖已有的 /etc/u2f_mappings。后续配置 PAM 读取 /etc/u2f_mappings,不再读取用户目录中的中间副本。
sudo:触摸认证,密码备用
见 ArchWiki:Passwordless sudo,参数定义见 pam_u2f 手册。
sudoedit /etc/pam.d/sudo
在原有第一条 auth 规则前加入下面一整行,保留原有其他配置:
auth sufficient pam_u2f.so authfile=/etc/u2f_mappings origin=pam://canokey-local appid=pam://canokey-local cue userpresence=1 pinverification=0 userverification=0
例如:
#%PAM-1.0
auth sufficient pam_u2f.so authfile=/etc/u2f_mappings origin=pam://canokey-local appid=pam://canokey-local cue userpresence=1 pinverification=0 userverification=0
auth include system-auth
account include system-auth
session include system-auth
session optional pam_systemd.so class=none
sufficient 使密钥认证成功时可以提前通过 auth 阶段,前提是此前没有未满足的 required 失败;失败时继续后面的密码认证。保留 auth include system-auth 才能继续使用原有密码路径。
| 参数 | 作用 |
|---|---|
authfile |
指定系统登记文件 |
origin、appid |
与登记时使用的标识一致 |
cue |
显示触摸提示 |
userpresence=1 |
要求触摸确认 |
pinverification=0、userverification=0 |
不主动要求 PIN 或生物识别 |
GDM:触摸登录,密码备用
GDM 是 Gnome 附带的登录管理器。
ArchWiki:GDM login 提供的是使用 required 的双因素示例。下面将其调整为 sufficient,用于触摸替代密码,并保留原有密码路径。
建立本地配置
见 pam.d(5)。
先复制默认配置:
sudo cp -a /usr/lib/pam.d/gdm-password /etc/pam.d/gdm-password
如果已经存在,直接编辑,不要再次复制覆盖:
sudoedit /etc/pam.d/gdm-password
/etc/pam.d/ 中的同名文件会完整覆盖 /usr/lib/pam.d/ 中的软件包默认文件。
使用 /etc 保存本机调整,可以保留软件包提供的默认文件,方便以后比较和恢复。
添加认证规则
将下面三行放在原有第一条 auth 规则前:
auth required pam_shells.so
auth requisite pam_nologin.so
auth sufficient pam_u2f.so authfile=/etc/u2f_mappings origin=pam://canokey-local appid=pam://canokey-local cue userpresence=1 pinverification=0 userverification=0
前两行保留 Arch system-login 认证栈中的 shell 与禁止登录状态检查。
以常见的 GDM 默认配置为例,修改后为:
#%PAM-1.0
auth required pam_shells.so
auth requisite pam_nologin.so
auth sufficient pam_u2f.so authfile=/etc/u2f_mappings origin=pam://canokey-local appid=pam://canokey-local cue userpresence=1 pinverification=0 userverification=0
auth include system-local-login
auth optional pam_gnome_keyring.so
account include system-local-login
password include system-local-login
password optional pam_gnome_keyring.so use_authtok
session include system-local-login
session optional pam_gnome_keyring.so auto_start
注意:不要把 Wiki 双因素示例中的 nouserok 加进这条 sufficient 规则。模块手册指出,nouserok 会使未登记用户或登记文件缺失等情况返回成功,在这里可能导致跳过密码认证。
其它
登记提示 FIDO_ERR_USER_ACTION_TIMEOUT
例如:
Enter PIN for /dev/hidraw14:
error: fido_dev_make_cred (47) FIDO_ERR_USER_ACTION_TIMEOUT
因为输入密钥后要摸一下canokey的按钮,不要傻等着。
更换或增加密钥
先按“修改前备份”保存配置,再将新登记写到新文件,检查成功后合并或替换 /etc/u2f_mappings。如果更换 pam://canokey-local,需要重新登记,并同步修改 sudo、GDM 两处的标识。
多把密钥的格式见 ArchWiki:Adding a key 和 pamu2fcfg 的 -n 参数。同一账户的多把密钥放在同一行,后续密钥用 -n 省略用户名。
密钥丢失时,用密码登录后删除系统登记文件中的旧凭据,或替换为新的有效登记。
升级后比较 GDM 配置
diff -u /usr/lib/pam.d/gdm-password /etc/pam.d/gdm-password
撤销密钥认证
删除相应pam文件中的对应内容即可。
2026-10-19