Google Authenticator
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 身份验证,以及(可选)桌面登录。
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。 更改两个模块的顺序将颠倒此顺序。
要允许使用 OTP 或您的 Unix 密码登录,请使用
auth sufficient pam_google_authenticator.so
在 /etc/ssh/sshd_config.d/99-archlinux.conf
中启用键盘交互式身份验证
KbdInteractiveAuthentication yes
最后,重新加载 sshd.service
。
AuthenticationMethods
以同时允许两种身份验证方式:双因素身份验证和基于密钥的身份验证。 请参阅 OpenSSH#双因素身份验证和公钥。仅当从本地网络外部连接时请求 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
桌面登录
Google Authenticator PAM 插件也可用于控制台登录和 GDM。 只需将以下内容添加到 /etc/pam.d/login
或 /etc/pam.d/gdm-password
文件中
auth required pam_google_authenticator.so
使用
每个想要使用两步验证的用户都需要
- 在其主文件夹中生成一个密钥文件,以及
- 相应地设置他们的 OTP 生成器
生成密钥文件
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
建议安全地存储紧急备用代码(将它们打印出来并保存在安全的位置),因为当您丢失手机(即您的 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 应用程序和单独的密码管理器中,或者决定依赖先前生成的紧急备用代码作为备份。
手机生成器
在您的手机上安装生成器应用程序(例如)
- FreeOTP for Android (F-Droid, Google Play) 或 iOS (App Store)。
- FreeOTP+ for Android (F-Droid, Google Play)。
- Aegis for Android (F-Droid, Google Play)。
- Bitwarden for Android (F-Droid, Google Play) 或 iOS (App Store)。
- Google Authenticator for Android (Google Play) 或 iOS (App Store)。
在移动应用程序中,创建一个新账户,然后扫描在生成密钥文件时告诉您的 URL 中的二维码,或者手动输入密钥(在上面的示例中为“ZVZG5UZU4D7MY4DH”)。
现在您应该看到手机上每 30 秒生成一个新的密码令牌。
如果您已将 Google Authenticator 配置为与其他系统一起使用,那么丢失您的设备可能会使您无法登录这些系统。 拥有其他生成代码的方式可能会有所帮助。
代码管理器
脚本 gashellAUR 提供了显示、生成、存储和管理 Google Authenticator 代码的功能。 另一种选择是 auther-gitAUR。
KeePassXC
GUI 密码管理器 keepassxc 允许将 Google Authenticator 代码与其条目关联,然后它可以生成 OTP 代码并通过二维码导出其密钥。
命令行
生成代码的最简单方法是使用 oathtool(1)。 它在 oath-toolkit 软件包中提供,可以按如下方式使用
$ oathtool --totp --base32 secret_key
在大多数具有足够用户访问权限的 Android 系统上,可以复制设备上的 Google Authenticator 数据库并直接访问,因为它是一个 sqlite3 数据库。 但是,在 2022 年 7 月的某个时候,accounts 表上的 secret 列开始使用加密。 如果您的数据库备份未使用此加密,则此 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 $