我最近购买了 U2F 安全密钥,并且已成功将我的 Ubuntu 18.04 计算机配置为需要通过密钥进行身份验证以及我常用的密码才能登录。我希望更改我的身份验证配置,以便:
- 当我第一次登录我的机器时,我需要输入密码并插入 U2F 密钥
- 当我锁定已登录的机器时,我只需插入 U2F 密钥即可解锁。
这对于普通的 GNOME 锁屏来说是可能的吗?如果是这样,我必须编辑哪个 pam 配置?
目前我唯一改变的是添加
auth required pam_u2f.so
到 /etc/pam.d/gdm-password,下
@include common-auth
答案1
GNOME 用作gdm-password
登录和解锁的 PAM 服务名称,因此无法在 PAM 中区分它们。为此,您必须创建 GNOME Shell 的自定义构建,特别是编辑js/gdm/util.js根据上下文使用不同的服务名称。如果你这样做的话,这对于向他们进行公关来说将是一个非常有用的功能。
答案2
作为一个更好的(比我上面建议的 pam_alreadyloggedin )解决方法,您还可以使用自定义脚本来检查当前会话是否被锁定并根据情况更改行为。为此,您可以使用pam_脚本模块。例如,在你的 pam 配置中,输入如下内容:
# Skip regular password checks when there is a current session and it is
# locked. This skips a number of modules from common-auth when
# succesful, so this breaks when extra primary modules are added there,
# but this seems to be the only way (using success=done prevents
# optional post-auth modules from running).
auth [success=2 default=ok] pam_script.so dir=/etc/pam.d/is-current-session-locked
@include common-auth
auth required pam_u2f.so
然后,创建一个名为/etc/pam.d/is-current-session-locked/pam_script_auth
以下内容的脚本并使其可执行:
#!/bin/sh
if [ -z "$XDG_SESSION_ID" ]; then
return 1
fi
if ! loginctl show-session "$XDG_SESSION_ID" | grep '^LockedHint=yes$' > /dev/null; then
return 1
fi
# Current session is locked, return success
return 0
该脚本检查是否有登录会话 ID,然后询问 loginctl 会话是否被锁定。这确实需要桌面环境在锁定桌面时告诉登录,但似乎 Gnome 会这样做(至少在 Ubuntu Disco 上)。
答案3
一个可能的解决方法是使用pam_已经登录模块。当您已经在不同的 tty 上登录时,这通常用于无需密码登录,但是通过一些创造性的 pam 配置,它也可以用于区分第一次登录(尚未登录)和解锁或第二次登录(已经登录)。它所做的选择并不完美,但可能足以满足您的需求。
一个重要的警告是,该模块无法识别 X 会话,只能识别终端会话(因为它检查 tty 设备的所有权,而 X 会话没有该设备,因此它最终会查找/dev/:0
不存在的设备)。实际上,这意味着如果您在 X 会话中打开了任何终端(而且还有在后台运行的屏幕或 tmux),它会识别您已登录。
我认为类似以下内容可能适合您的用例:
# Skip regular password checks when already logged in (i.e. also when
# unlocking). This skips a number of modules from common-auth when
# succesful, so this breaks when extra primary modules are added there,
# but this seems to be the only way (using success=done prevents
# optional post-auth modules from running).
auth [success=2 default=ok] pam_alreadyloggedin.so debug
@include common-auth
auth required pam_u2f.so
您可能需要根据common-auth
文件包含的内容进行调整。
答案4
这对我有用,我必须改编 Matthijs Kooijman 的答案,因为 Ubuntu 22.04 LTS 上未设置 XDG_SESSION_ID 变量。
我创建了/etc/pam.d/is-logged-in
脚本
#!/bin/sh
TTY=$(basename "$PAM_TTY")
SESSION_ID=$(loginctl list-sessions --no-legend | grep -Ei "$TTY$" | head -n1 | cut -d' ' -f1)
if loginctl show-session "$SESSION_ID" | grep '^LockedHint=yes$' >/dev/null; then
echo "Session $SESSION_ID is locked."
return 0
else
echo "Session $SESSION_ID is unlocked."
return 1
fi
然后我们将其标记为可执行文件sudo chmod +x /etc/pam.d/is-logged-in
现在我们可以添加两行/etc/pam.d/gdm-fingerprint
auth required pam_succeed_if.so user != root quiet_success
+auth [success=1 default=ignore] pam_exec.so quiet seteuid /etc/pam.d/is-logged-in
+auth required pam_exec.so /bin/sleep infinity
auth required pam_fprintd.so
第一行仅在存在活动且锁定的会话时才允许指纹身份验证(因此不适用于登录屏幕),第二行将使 pam 模块在失败时永远等待,因此 gdm 不会进入循环或显示任何内容错误。