启用 SSH 双因素认证(2FA)最稳妥的方案是结合 Google Authenticator 与 PAM 模块,适合暴露在公网且需要高等级安全合规的服务器。
先说结论:通过安装 libpam-google-authenticator 模块并配置 PAM 与 SSHD,可实现密码加动态验证码的双重验证,但配置不当可能导致无法登录。
- 先判断:确认业务是否允许增加登录步骤,以及是否具备手机验证码生成条件。
- 优先做:在保持当前 SSH 会话不断开的情况下进行修改,并预留备用登录方式(如控制台)。
- 再验证:使用新终端测试登录,确认验证码生效且原会话未受影响后再重启服务。
前置检查与版本兼容性
在开始配置前,务必确认 OpenSSH 版本,不同版本对认证方法的语法支持存在差异。
ssh -V
若版本低于 OpenSSH 7.3,AuthenticationMethods 参数可能不支持逗号分隔的多重认证逻辑,需查阅对应版本文档。建议生产环境保持 OpenSSH 较新版本以获得更好支持。
安装与初始化
以下命令适用于主流 Linux 发行版,请根据系统类型选择安装方式:
# Ubuntu/Debian 系列
sudo apt update
sudo apt install libpam-google-authenticator -y
# CentOS/RHEL 系列(需先启用 EPEL)
sudo yum install epel-release -y
sudo yum install google-authenticator -y
初始化用户密钥:切换到需要启用 2FA 的具体用户(包括 root),运行初始化命令。注意每个用户都需要单独执行,不能复制配置文件。
su - username
google-authenticator
按提示输入 y 完成配置,系统会显示二维码和紧急备用码。务必将备用码离线保存,这是手机丢失后的唯一恢复途径。
配置 PAM 与 SSHD
1. 配置 PAM 模块
编辑 SSH 的 PAM 配置文件,确保在认证阶段加载验证器。
sudo vim /etc/pam.d/sshd
在文件开头添加以下内容:
auth required pam_google_authenticator.so
2. 修改 SSH 服务配置
编辑 SSH 主配置文件,启用 PAM 和挑战响应认证。
sudo vim /etc/ssh/sshd_config
确认或修改以下参数:
UsePAM yes
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
注意:AuthenticationMethods 中的逗号表示“与”逻辑(即需要密钥 + 验证码),此语法通常要求 OpenSSH 7.3 及以上版本。生产环境建议强制所有用户启用 2FA,不要使用降低安全性的例外参数。
语法检查与服务重启
关键步骤:在重启服务前,必须检查 SSH 配置文件语法,防止因配置错误导致服务无法启动。
sudo sshd -t
若无输出则表示语法正确。若有报错,请立即根据提示修正配置,切勿直接重启。
确认无误后重启 SSH 服务:
sudo systemctl restart sshd
验证方法
不要关闭当前已登录的 SSH 窗口,新开一个终端尝试登录:
ssh -v user@host
观察输出日志,若看到 debug1: Next authentication method: keyboard-interactive 且登录过程中提示输入验证码(Verification code),则说明配置生效。同时检查系统日志(/var/log/auth.log 或/var/log/secure),确认是否有 pam_google_authenticator 相关的验证记录。
紧急救援与常见坑
1. 把自己锁在门外(紧急救援):若配置错误导致无法 SSH 登录,切勿惊慌。通过云服务商提供的 VNC 控制台或物理机房控制台登录服务器,回滚 /etc/ssh/sshd_config 或 /etc/pam.d/sshd 配置,并重启服务。因此,配置前确保拥有控制台访问权限至关重要。
2. 文件权限错误:用户目录下的.google_authenticator 文件权限必须是 600 且属主正确,否则 PAM 会因权限不足跳过验证。
chmod 600 ~/.google_authenticator
chown username:username ~/.google_authenticator
3. 时间不同步:动态验证码基于时间生成,服务器与手机时间偏差超过 30 秒会导致验证失败,建议开启 NTP 时间同步。
4. SELinux 拦截:在开启了 SELinux 的系统上,若模块路径不对或上下文错误,可能导致模块无法加载,临时可设为 permissive 模式排查。
参考来源
- Google Authenticator PAM Module: https://github.com/google/google-authenticator