通用第二因素(U2F)是一個開放標準,它基於類似智慧卡中的安全技術,使用專門的 USB 或 NFC 設備來加強和簡化雙因素身份驗證(2FA)。
該標準最早由谷歌和 Yubico 開發,並包含了來自 NXP 的貢獻,現在由 FIDO 聯盟進行維護。
所有與 U2F 和 U2F 設備相關的文章請參考分類:通用第二因素。
當前最新的標準是 WebAuthn。
用於網頁認證
谷歌、Facebook、Twitter 和 GitHub 等主流網站都支持使用 U2F,更多網站的清單和設置文檔請參考 2fa.directory 或 dongleauth.com。對於所有支持該功能的瀏覽器,很可能只需要安裝 libfido2包。Yubico 提供了一個測試頁用於進行測試。
Firefox
Chromium/Chrome
用於用戶會話認證
YubiKey 的製造商 Yubico 開發了一個 U2F PAM 模塊,可用於在登陸時進行二次驗證,也可以完全替代密碼。
安裝 PAM 模塊
該模塊是 pam-u2f包 的一部分。
添加密鑰
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 密鑰上的按鈕進行確認。
hostname
替換為正確的主機名。如果你有多個密鑰,參考下方進行添加:
$ pamu2fcfg -o pam://hostname -i pam://hostname -n >> ~/.config/Yubico/u2f_keys
-n
選項。對於同一用戶的後續條目,它將按照規範要求省略生成條目中的用戶名部分。多個相同用戶名的條目會導致 PAM 出現不可預測的行為。另外,不要手動進行分行,u2f_keys
文件中只能存在一行內容。[1]
無密碼 sudo
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
。
GDM 登錄
在現有的 auth
行後添加以下內容:
/etc/pam.d/gdm-password
auth required pam_u2f.so nouserok origin=pam://hostname appid=pam://hostname
注意 nouserok
選項,該選項允許在用戶未配置密鑰時規則失效,適用於多用戶環境下其中只有部分用戶使用 U2F 密鑰的情況。
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
/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 進行靜態數據加密
從 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