双因素认证 2FA 实战:TOTP 动态口令与 SSH 登录防护配置

适用场景

双因素认证 2FA 适用于以下场景:服务器 SSH 密码被暴力破解或撞库导致入侵;员工账号口令泄露后攻击者直接登录内部系统;合规审计要求关键系统启用动态口令(如等保 2.0 三级要求采用双因素认证)。本文从 TOTP 动态口令原理出发,给出 Linux SSH 登录启用 Google Authenticator、PAM 联动与恢复预案的完整配置方案。

前置条件

  • 一台 Linux 服务器(本文以 Ubuntu 22.04 / CentOS 7+ 为例),已配置密钥登录更佳
  • 手机安装支持 TOTP 的认证应用(Google Authenticator、Microsoft Authenticator 或 1Password)
  • SSH 服务(openssh-server)运行正常,具备 root 权限

原理说明

TOTP(Time-based One-Time Password,基于时间的一次性口令)是双因素认证的主流实现。其核心是共享密钥 + 时间窗口:服务端与客户端持有同一份 Base32 编码的密钥,双方以 30 秒为一个周期,用 HMAC-SHA1 对时间戳计算一次性验证码。由于每次登录都需要”知道的(密码)+ 拥有的(手机)”两类凭证,即使密码泄露,攻击者没有动态口令也无法登录。Linux 侧通过 PAM(Pluggable Authentication Modules)把 TOTP 校验插入 SSH 认证链,实现”密码 + 动态口令”两步验证。

操作步骤

1. 安装并初始化 google-authenticator

# Ubuntu
sudo apt update && sudo apt install -y libpam-google-authenticator

# CentOS
sudo yum install -y epel-release
sudo yum install -y google-authenticator

# 为当前用户生成密钥(交互式问答全部选 y)
google-authenticator

关键参数:初始化时生成的二维码与 16 位 Base32 密钥务必备份保存;~/.google_authenticator 文件权限应为 600,内含密钥与一次性应急码。

2. 配置 PAM 接入 SSH

# 编辑 /etc/pam.d/sshd,在文件顶部加入
# Ubuntu
auth required pam_google_authenticator.so

# CentOS:同时把 sshd 文件开头的 auth substack password-auth 行注释掉
# 并新增:
auth required pam_google_authenticator.so

3. 修改 sshd_config 启用验证

# 编辑 /etc/ssh/sshd_config
UsePAM yes
ChallengeResponseAuthentication yes      # 老版本(CentOS7)
KbdInteractiveAuthentication yes        # 新版本(Ubuntu22+)
AuthenticationMethods "password,keyboard-interactive"   # 密码+动态口令 两步

关键参数AuthenticationMethods "password,keyboard-interactive" 强制要求两类凭证都通过;若只配置公钥登录,可改为 "publickey,keyboard-interactive",实现”密钥 + 动态口令”。

4. 重启并验证

# 重启前务必保持当前 SSH 会话不退出,避免配置错误把自己锁在外面
sudo systemctl restart sshd

# 新开终端测试登录,会依次提示密码与验证码
ssh user@server
# Password:
# Verification code:

5. 恢复预案与批量部署

# 应急码:初始化时生成的 5 个一次性应急码保存在 ~/.google_authenticator 中,锁死时可用
# 查看应急码(每行开头不含密钥的行)
cat ~/.google_authenticator | tail -5

# 批量部署:将应急码与密钥文件拷贝到新用户家目录并 chmod 600
sudo cp /home/tpl/.google_authenticator /home/newuser/
sudo chown newuser:newuser /home/newuser/.google_authenticator
sudo chmod 600 /home/newuser/.google_authenticator

配置验证

# 1. 检查 PAM 模块是否加载成功
ldd /usr/lib/x86_64-linux-gnu/security/pam_google_authenticator.so | head -1
# 或
sudo grep google /etc/pam.d/sshd

# 2. 验证时间同步(TOTP 依赖系统时钟,偏差超 30 秒会验不过)
timedatectl status
# 应显示 System clock synchronized: yes

# 3. 用手机验证码实测登录,错误验证码应被拒绝三次(默认最大尝试次数为 3)

常见问题

Q1:配置后 SSH 完全无法登录怎么办?

若新开连接连密码都输不了,说明 PAM 或 sshd_config 配置有误。应急方案:通过云控制台 VNC 登录(绕过 SSH),撤销 AuthenticationMethods 行或注释 PAM 条目后重启 sshd。若服务器无 VNC,务必保持一个已建立的管理会话不断开,再逐步调整配置。

Q2:动态口令总是验证失败?

先检查服务器时间是否同步(timedatectl),TOTP 对时钟偏差敏感;再确认手机 App 与服务器密钥一致,可通过 google-authenticator 重新初始化生成新密钥。另外检查是否有多个 .google_authenticator 副本,SSH 登录用户的家目录必须与初始化用户一致。

总结

双因素认证 2FA 是抵御密码暴力破解与撞库的有效手段,通过 PAM + google-authenticator 即可在半小时内为 SSH 登录加上 TOTP 动态口令。关键在于配置前保持管理会话、配置后保留应急码、并确保服务器时间同步。建议将 2FA 逐步推广到 Web 后台、VPN 等所有关键入口,形成统一的多因素认证体系。