跳转至内容

Google Authenticator

来自 ArchWiki

Google Authenticator 提供了一种使用一次性密码 (OTP) 的两步验证程序,该程序最初由 开放身份验证倡议 (OATH) 标准化。该验证机制集成在 Linux PAM 系统中。本指南介绍了该机制的安装和配置。

有关反向操作(在 Linux 下生成与 Google Authenticator 兼容的代码),请参阅下面的 #代码生成

安装

安装 libpam-google-authenticator 软件包,它提供了客户端程序 google-authenticator(1) 和 PAM 模块 pam_google_authenticator.so。开发版本可通过 google-authenticator-libpam-gitAUR 获取。

配置

本节涵盖了如何配置系统的 PAM,以要求 SSH 验证以及(可选的)桌面登录 使用 Google Authenticator OTP 验证。

注意 完成配置需要生成一个 密钥文件。请考虑在编辑(并因此应用)PAM 配置之前生成该文件。

SSH

警告 如果您全部通过 SSH 进行配置,在测试一切运行正常之前请勿关闭会话,否则您可能会被锁定在系统之外。

通常人们仅对远程登录要求两步验证。相应的 PAM 配置文件是 /etc/pam.d/sshd。如果您想在全局范围内使用 Google Authenticator,则需要修改 /etc/pam.d/system-auth,但在这种情况下请极其谨慎,以免将自己锁定在系统之外。在本指南中,我们通过编辑 /etc/pam.d/sshd 来进行,这在本地会话中操作是最安全的(但并非必须)。

若要同时输入 Unix 密码和 OTP,请将 pam_google_authenticator.so 添加到 /etc/pam.d/sshd 中 system-remote-login 行之上。

auth            required        pam_google_authenticator.so
auth            include         system-remote-login
account         include         system-remote-login
password        include         system-remote-login
session         include         system-remote-login

这将在提示输入 Unix 密码之前先要求输入 OTP。更改这两个模块的顺序将反转此顺序。

警告 只有生成了密钥文件(见下文)的用户才被允许使用 SSH 登录。

若要允许使用 OTP 或 Unix 密码其中之一登录,请使用:

auth            sufficient      pam_google_authenticator.so

/etc/ssh/sshd_config.d/99-archlinux.conf 中启用键盘交互认证 (keyboard interactive authentication)。

KbdInteractiveAuthentication yes

最后,重新加载 sshd.service

警告 如果您使用 SSH 密钥对进行身份验证并 禁用了密码登录,OpenSSH 将忽略所有上述设置。不过,从 OpenSSH 6.2 版本开始,您可以添加 AuthenticationMethods 以同时允许:双因子验证和基于密钥的验证。请参阅 OpenSSH#Two-factor authentication and public keys

仅在从本地网络外部连接时请求 OTP

有时,我们只想在从本地网络外部连接时启用 2FA 功能。为了实现这一点,请创建一个文件(例如 /etc/security/access-local.conf)并添加允许绕过 2FA 的网络地址

# only allow from local IP range
+ : ALL : 192.168.20.0/24
# Additional network: VPN tunnel ip range (in case you have one)
+ : ALL : 10.8.0.0/24
+ : ALL : LOCAL
- : ALL : ALL

然后编辑您的 /etc/pam.d/sshd 并添加以下行:

#%PAM-1.0
auth [success=1 default=ignore] pam_access.so accessfile=/etc/security/access-local.conf
auth      required  pam_google_authenticator.so
auth      include   system-remote-login
account   include   system-remote-login
password  include   system-remote-login
session   include   system-remote-login
警告 success=1 仅在 pam_google_authenticator 行之后至少存在另一行认证行时才有效。如果不是这种情况,success 必须设置为 done

桌面登录

警告 在另一个控制台上测试结果之前,请勿退出当前会话。

Google Authenticator PAM 插件也可用于控制台登录和 GDM。只需将以下内容添加到 /etc/pam.d/login/etc/pam.d/gdm-password 文件中:

auth required pam_google_authenticator.so

用法

每个想要使用两步验证的用户都需要:

  • 在其主文件夹中生成一个密钥文件,并且
  • 相应地设置其 OTP 生成器

生成密钥文件

提示 安装 qrencode 以生成可扫描的 QR 码。使用验证器应用扫描 QR 码即可自动配置密钥。

google-authenticator 按照以下方式生成 TOTP 密钥文件:

$ google-authenticator
Do you want authentication tokens to be time-based (y/n) y
generated_QR_code_here
Your new secret key is: ZVZG5UZU4D7MY4DH
Your verification code is 269371
Your emergency scratch codes are:
  70058954
  97277505
  99684896
  56514332
  82717798

Do you want me to update your "/home/username/.google_authenticator" file (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, tokens are good for 30 seconds and in order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with poor
time synchronization, you can increase the window from its default
size of 1:30min to about 4min. Do you want to do so (y/n) n

If the computer that you are logging into is not hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting (y/n) y

建议安全地保存紧急备份代码 (emergency scratch codes)(将其打印并保存在安全位置),因为当您丢失手机(即 OTP 生成器)时,这是您登录(通过 SSH)的唯一方式。它们也存储在 ~/.google_authenticator 中,因此只要您处于登录状态,随时都可以查看它们。

存储位置

如果您想更改密钥文件的存储路径,可以使用 --secret 标志

$ google-authenticator --secret="/path_folder/username"

然后,不要忘记在 /etc/pam.d/sshd 中更改 PAM 的位置路径

/etc/pam.d/sshd
auth required pam_google_authenticator.so user=root secret=/path_folder/${USER}

user=root 用于强制 PAM 使用 root 用户搜索文件。

此外,请注意密钥文件的权限。该文件必须仅对所有者可读 (chmod: 400)。在这里,所有者是 root。

$ chown root:root /path_file/secret_key_files
$ chmod 400 /path_file/secret_key_files

代码生成

在最后的设置步骤中,每个用户必须将其主目录中生成的密钥文件与所选的 OTP 生成器关联,以提供验证码。用户可以在不同设备上设置生成器以实现冗余,例如在手机上的 OTP 应用程序和一个独立的密码管理器中,或者决定依赖于之前生成的紧急备份代码作为备份。

手机生成器

在您的手机上安装一个生成器应用程序(例如):

在移动应用程序中,创建一个新账户,然后扫描生成密钥文件时告知您的 URL 中的 QR 码,或者手动输入密钥(在上述示例中为 'ZVZG5UZU4D7MY4DH')。

现在,您应该看到手机上每 30 秒生成一个新的验证码令牌。

如果您将 Google Authenticator 配置在其他系统中,那么丢失设备可能会导致您无法登录这些系统。拥有额外的代码生成方式会非常有帮助。

代码管理器

gashellAUR 提供了一个支持显示、生成、存储和管理 Google Authenticator 代码的脚本。另一个可选方案是 auther-gitAUR

KeePassXC

GUI 密码管理器 keepassxc 允许将其条目与 Google Authenticator 代码关联,然后它可以生成 OTP 代码并通过 QR 码导出其密钥。

命令行

生成代码最简单的方法是使用 oathtool(1)。它包含在 oath-toolkit 软件包中,可以使用如下方式:

$ oathtool --totp --base32 secret_key

在大多数具有足够用户权限的 Android 系统上,由于 Google Authenticator 数据库是一个 sqlite3 数据库,因此可以将其从设备中复制出来并直接访问。然而,在 2022 年 7 月的某个时间点,账户表中的密钥列开始使用加密。如果您的数据库备份没有使用这种加密,此 shell 脚本将读取 Google Authenticator 数据库并为找到的每个密钥生成实时代码

google-authenticator.sh
#!/bin/sh

# This is the path to the Google Authenticator app file.  It is typically
# located in /data under Android.  Copy it to your PC in a safe location and
# specify the path to it here.
DB="/path/to/com.google.android.apps.authenticator/databases/databases"

sqlite3 "$DB" 'SELECT email,secret FROM accounts;' | while read A
do
        NAME=`echo "$A" | cut -d '|' -f 1`
        KEY=`echo "$A" | cut -d '|' -f 2`
        CODE=`oathtool --totp -b "$KEY"`
        echo -e "\e[1;32m$CODE\e[0m - \e[1;33m$NAME\e[0m"
done

测试

从另一台机器和/或另一个终端窗口 SSH 连接到您的主机

$ ssh hostname
login as: username
Verification code: generated/backup_code
Password: password
$

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.