为 SSH 密钥登录配置 TOTP 2FA 验证

背景

TOTP(Time-based One Time Password)是一种基于时间的、不依赖于网络的验证码。可以提供根据固定时间间隔生成固定位数的验证码。相较于其它验证码(短信、邮箱等),TOTP 根据时间和密钥来计算验证码,而不需要网络传输验证码,因而很难受到中间人攻击的影响。此外,TOTP 生成的验证码极难反推出初始密钥,几乎无法进行基于统计的攻击。

目前已有的大多是允许 SSH 通过公钥登录,或者是通过密码 + TOTP 的方式登录。前者很难被暴力破解,但是除非为私钥设置强密码或通过 YubiKey 等方式加密保存密钥,否则很容易被窃取密钥。后者本质上是 2FA 认证,尽管已经足够强大,但是一旦 TOTP 失窃,则更容易被暴力破解。相比之下,密钥 + TOTP 的方法既不需要过强的密码,也可以提供最高的安全性。

⚠️ 安全自负
本文所述内容仅供参考,错误操作可能导致系统无法登录。阁下应自行确保所有系统安全设置符合所在地区法律法规要求,并在做出改变前采取一切必要的备份和安全措施(包括但不限于系统快照、文件备份、保留空余 SSH session 等)。在阁下的系统上产生的一切后果由阁下自行承担。

教程

安装依赖

首先安装命令行版本的 Google Authenticator。

sudo apt install ssh libpam-google-authenticator
Bash

在您的手机或其他设备上安装好 Microsoft Authenticator、Google Authenticator、Authy 或者 1Password 等支持 TOTP 的密码管理工具。

设置 SSH 密钥

生成一个 SSH 密钥,建议使用 ed25519 或 ed448 等 ECC 算法,如果有兼容性考虑(使用 2014 年左右以前的老 SSH),则建议使用 4096bit 及以上的 RSA 密钥。

ssh-keygen -t ed25519
Bash

将本机的 ~/.ssh/id_ed25519.pub 文件中的公钥中的内容添加的服务器的 ~/.ssh/authorized_keys 文件当中。本机的 ~/.ssh/id_ed25519 中的私钥请务必妥善保存,最好设置密码,不应该让任何人接触。

设置 TOTP

在命令行中输入:

google-authenticator
Bash

根据提示设置 TOTP,通过 Microsoft Authenticator、Google Authenticator、Authy 或者 1Password 等支持 TOTP 的密码管理工具扫描生成的二维码,可以根据需要妥善私密地保管恢复密钥。

设置 SSH PAM 认证

修改 /etc/ssh/sshd_config 文件

# 取消密码登录,防止暴力破解
PermitRootLogin without-password

# 如果有则取消注释改为 yes,若无则添加
ChallengeResponseAuthentication yes
UsePAM yes

# 若有则取消注释改为 no,若无则添加
PasswordAuthentication no

# 若有则取消注释改为如下,若无则添加
AuthenticationMethods publickey,keyboard-interactive
Bash

修改 /etc/pam.d/sshd 文件

注释掉如下内容:

#@include common-auth
# account  required     pam_access.so
#@include common-password
Bash

在文件结尾添加如下内容,触发 Google Authenticator 进行 PAM:

# TOTP via Google Authenticator
auth required pam_google_authenticator.so
Bash

重启 SSH 服务

通过下列命令重启 SSH 服务:

sudo systemctl restart sshd
Bash

现在可以测试是否配置成功。请注意,配置的时候务必保证有一个闲置的 SSH session 可用,以防止修改后无法登录系统。

发表评论