背景
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 可用,以防止修改后无法登录系统。