“扫码+密码”式多重身份核验的核心是用户先扫码绑定totp密钥,登录时必须同时输入系统密码和动态验证码,二者均通过才允许登录;流程依托linux pam框架,通过精确配置pam_google_authenticator.so模块与ssh认证策略实现强制双因素验证。

要实现“扫码+密码”式的多重身份核验,核心是让用户先用手机扫描二维码绑定 TOTP 密钥(即完成扫码),再登录时**同时输入系统密码和动态验证码**。这不是简单的“二选一”,而是密码与动态码**双重通过才允许登录**。整个流程依托 Linux 的 PAM 框架,不改动 SSH 主逻辑,只通过模块串联与控制标志精准调度。
一、前提检查:确保 SSH 已启用 PAM 并支持交互式认证
若底层不支持,后续所有配置都无效:
- 确认 /etc/ssh/sshd_config 中存在且未被注释:
UsePAM yes
ChallengeResponseAuthentication yes
(后者必须开启,否则无法触发 TOTP 输入环节) - 保留 PasswordAuthentication yes —— 即使你主用密钥登录,也需此项来激活 PAM 的密码验证阶段;若彻底禁用密码,TOTP 校验将无处挂载
- 修改后执行 sudo systemctl restart sshd,并用 sshd -T | grep -E "(usepam|challenge)" 验证生效
二、部署 Google Authenticator 并完成扫码绑定
这是“扫码”环节的实质:生成密钥、输出二维码、由手机 App 扫描识别。
- 安装模块(以 Ubuntu/Debian 为例):
sudo apt install libpam-google-authenticator - 切换到目标用户(如 alice),运行:
google-authenticator -t -f -d -w 3 -e 10
→ 会显示二维码 URL、密钥、当前验证码及 10 个应急码(务必离线保存) - 用手机打开 Google Authenticator 或 Microsoft Authenticator,点击“+”→“扫描二维码”,对准终端显示的 QR 码完成绑定
- 绑定成功后,App 每 30 秒生成一个 6 位数字,即后续登录所需的“动态码”
三、精确配置 PAM 规则:强制“密码且动态码”双通过
关键在 /etc/pam.d/sshd 文件中模块的顺序与 control flags。错误写法会导致跳过或短路。
- 在文件顶部附近(必须在
@include common-auth之前)添加一行:
auth [verifier=0 success=ok new_authtok_reqd=ok default=bad] pam_google_authenticator.so secret=/home/${USER}/.google_authenticator - 确保原系统认证行仍存在(通常为
@include common-auth),它负责校验密码 - 不要使用
sufficient或带nullok的宽松配置——那会允许未配 MFA 的用户绕过,也不满足“强制双因素”要求 - 权限加固:
chmod 600 /home/*/\.google_authenticator
chown user:user /home/user/.google_authenticator
四、可选增强:组合公钥 + 密码 + 动态码(三重保险)
若你已使用 SSH 密钥登录,仍想叠加 MFA,需调整认证策略:
- 在 /etc/ssh/sshd_config 中设置:
AuthenticationMethods publickey,keyboard-interactive
这表示必须先通过公钥,再进入键盘交互阶段(触发密码+TOTP) - 此时 PAM 仍按前述方式工作:common-auth 校验密码(即使你没输,PAM 也会调用该流程),接着 google_authenticator.so 校验动态码
- 时间同步很重要:
sudo timedatectl set-ntp true 或 sudo ntpdate pool.ntp.org,避免因时间偏移导致 TOTP 失效










