要让ssh真正支持双因子认证(密钥+手机验证码),关键在sshd_config中配置authenticationmethods publickey,keyboard-interactive,并配套启用challengeresponseauthentication yes、usepam yes、passwordauthentication no,且pam规则须置于/etc/pam.d/sshd首行,用户还需单独运行google-authenticator初始化。

要让 SSH 真正支持双因子认证(密钥 + 手机验证码),关键不在装插件,而在 sshd_config 里写对 AuthenticationMethods,并确保它和 PAM、挑战响应流程严格协同。只改一半,服务端根本不会触发第二步验证。
核心配置必须四件套齐备
以下四行必须同时存在且值正确,缺一不可:
- AuthenticationMethods publickey,keyboard-interactive:明确要求先过公钥,再走交互式验证(即输入 TOTP 验证码)
- ChallengeResponseAuthentication yes:启用 keyboard-interactive 流程,否则第二步直接跳过
- UsePAM yes:让 SSH 加载 /etc/pam.d/sshd,才能调用 pam_google_authenticator.so
- PasswordAuthentication no:禁用密码登录,防止绕过 OTP 直接输密码
PAM 规则要加在 sshd 文件开头
编辑 /etc/pam.d/sshd,在第一行插入:
auth [success=done new_authtok_reqd=done default=ignore] pam_google_authenticator.so nullok
说明:
- nullok 允许尚未配置 OTP 的用户暂时仍能登录(上线前测试用),正式启用后可删掉
- 必须放在其他 auth 行之前,否则可能被后续规则覆盖或跳过
- 若用的是非标准路径的 so 文件(如 /usr/local/lib/security/),需确认路径准确
用户侧:每个要双因子的账号都得单独初始化
以目标用户身份运行:
google-authenticator -t -f -d -r 3 -R 30 -w 17
参数含义:
- -t:启用基于时间的 TOTP(推荐)
- -f:强制生成新密钥,覆盖旧配置
- -d:允许同一令牌多次使用(不推荐,仅调试用;生产环境应去掉)
- -r 3:最多容忍 3 次连续错误尝试
- -R 30:每 30 秒刷新一次验证码
- -w 17:窗口宽度为 17(即支持 ±8 个时间片,容错约 ±4 分钟)
执行后会在 ~/.google_authenticator 生成密钥和应急码,务必备份应急码。
验证是否真生效
别只看配置文件保存了没——实测才靠谱:
- 语法检查:sudo sshd -t,无输出即配置格式正确
- 连接时加 -v 参数:ssh -v user@host,日志中必须出现 Next authentication method: keyboard-interactive
- 若卡在公钥后就登录成功,说明第二步没触发 → 检查 ChallengeResponseAuthentication 或 PAM 加载顺序
- 若提示“Permission denied (publickey)”,说明公钥失败 → 先确保 PubkeyAuthentication yes 且密钥已部署











