SSH双因子认证配置:Google Authenticator 动态口令登录实战

如果你的服务器只靠密码登录 SSH,那么它每天都在承受暴力破解的试探:公网上一台普通 VPS(虚拟专用服务器)每天被尝试登录的次数可以轻松超过数千次,只要密码强度稍弱或者曾经泄露,攻击者拿到凭据就能直接进入系统。本文要解决的就是这个问题——如何为 SSH 登录再加一道动态口令验证,让”密码+一次性验证码”组合成为默认登录方式。

本文以最常见的 Google Authenticator(谷歌验证器)为例,在 Linux 服务器上完成 SSH 双因子认证(Two-Factor Authentication,简称 2FA)配置。核心思路是:服务器端安装基于时间的一次性口令(TOTP,Time-based One-Time Password)模块,手机扫码绑定后,每次登录除了密码,还要输入一个 30 秒刷新一次的 6 位动态码。密码即使泄露,没有你的手机,攻击者依然进不来。

下文按真实操作顺序展开:双因子认证解决什么问题、服务器端安装配置、手机端绑定、登录测试与回退保护,最后是密钥登录共存等进阶场景。命令覆盖 Ubuntu/Debian 与 CentOS 两大发行版,配置完成后服务器登录安全性会有质的提升。

服务器机柜配绿色安全盾牌与手机动态口令的 SSH 双因子认证封面图

双因子认证到底解决了什么问题

某台独立服务器只设了密码登录,运维用的是”公司名+2024″这类弱密码。管理员发现异常流量后排查,确认攻击者已通过 SSH 暴力破解登录并植入挖矿程序。若当时开启双因子认证,攻击者拿到密码也过不了动态口令这一关。

从攻击成本算一笔账:12 位随机密码被暴力破解需百年以上,但很多服务器用的是可被字典覆盖的弱密码,攻击者每小时可尝试数万次。启用 2FA 后,攻击者必须同时突破”你知道的(密码)”和”你拥有的(验证器)”两道关卡,动态口令每 30 秒失效,重放无效。

双因子认证不替代密钥登录,而是互补:已用 SSH 密钥的,把动态口令当第二层保险;还在用密码的,2FA 见效最快——习惯不变,只是密码后多输一个 6 位数字。

仅密码登录与密码加动态口令登录的安全性对比图

服务器端安装与 PAM 模块配置

整个配置分三步:安装 TOTP 模块、修改 PAM(Pluggable Authentication Modules,可插拔认证模块)配置、调整 sshd 参数。

第一步:安装 Google Authenticator PAM 模块。

Ubuntu/Debian:

sudo apt update
sudo apt install libpam-google-authenticator -y

CentOS/RHEL 先启用 EPEL 源:

sudo dnf install epel-release -y
sudo dnf install google-authenticator -y

第二步:为当前用户生成密钥。

切换到要开启双因子认证的用户(不要给所有用户批量开),执行:

google-authenticator

初始化会依次询问几个问题,推荐回答:

  • 是否使用基于时间的令牌?回答 y(动态码每 30 秒刷新,服务器需提前开启 NTP 时间同步,否则验证会失败)
  • 是否更新配置文件?回答 y
  • 是否禁止同一令牌多次使用?回答 y(防止 30 秒窗口内的重放攻击)
  • 是否扩展令牌有效期到 4 个时间窗口?回答 y(容忍 1-2 分钟时钟偏差)
  • 是否开启限速保护?回答 y(攻击者每 30 秒最多试 3 次)

执行完成后,终端会输出二维码、密钥和 5 个应急刮刮码(scratch codes)。二维码用手机 App 扫码绑定;刮刮码必须离线抄写保存——手机丢失时就靠它们紧急登录。

第三步:修改 PAM 与 sshd 配置。

编辑 /etc/pam.d/sshd,开头加入一行:

auth required pam_google_authenticator.so

编辑 /etc/ssh/sshd_config,确认三项配置:

ChallengeResponseAuthentication yes
UsePAM yes
PasswordAuthentication yes

新版系统可用 KbdInteractiveAuthentication yes 替代第一项,二选一即可。然后重启 SSH 服务:

sudo systemctl restart sshd

注意:pam_google_authenticator.so 这一行要加在 @include common-auth 之前,否则会出现”验证码错了仍然放行”的逻辑漏洞,配置顺序决定认证链的严密程度。

手机端绑定与登录测试

服务器端配置完成后,还要在手机上绑定并完成测试,才能正式启用强制验证。

绑定验证器 App。

在手机上安装 Google Authenticator(iOS 和 Android 应用商店均可免费下载),也兼容 Microsoft Authenticator、FreeOTP 等支持 TOTP 标准的验证器。打开 App 选择”扫描二维码”,对准终端上的二维码扫码即可。绑定成功后 App 立即显示 6 位动态码,每 30 秒自动刷新。

如果终端无法显示二维码(比如串口或受限环境),把命令输出中的密钥手动输入 App:选择”输入设置密钥”,账户名建议填服务器 IP 或别名方便区分,密钥栏粘贴那串字母数字组合即可。

保持当前会话不退出,开新窗口测试。

这是整篇教程最重要的一条守则:重启 sshd 后,当前已登录会话不会断开,这是天然的”后悔药”。此时不要退出当前窗口,先新开一个终端验证双因子认证是否正常:

ssh youruser@your-server-ip
# 依次提示输入:
# Verification code: (输入手机上的 6 位动态码)
# Password: (输入用户密码)

两个凭据都正确并能进入系统,说明配置成功;新窗口被挡住时,可立即在旧会话里回滚配置,不会把自己锁在门外。

常见失败现象排查。

两类常见报错:一是动态码正确仍被拒,多是服务器与手机时钟偏差过大,执行 sudo timedatectl set-ntp true 开启时间同步后重试;二是登录时根本不提示验证码,通常是 PAM 行位置不对或 UsePAM yes 未生效,检查 /etc/pam.d/sshd 是否保存、sshd 是否真的重启。

回退保护与密钥登录共存

双因子认证最大的风险不是配置失败,而是失败后把自己锁在门外。除了”保留旧会话再测试”,还有两道保险值得提前布好。

第一道保险:应急刮刮码。 初始化时输出的 5 个一次性应急码,每个只能用一次,打印或抄写到离线处(不要存手机里)。手机没电、验证器误删时,输入任意一个应急码即可替代动态码登录。

第二道保险:控制台救援通道。 带智能平台管理接口(IPMI,Intelligent Platform Management Interface)的机器确认带外口可用;云主机确认 VNC(虚拟网络控制台)救援入口可用。SSH 配置出错时,这些是最后的救命稻草。

已经在用 SSH 密钥登录的团队,可以采用”密钥免密 + 动态码二次验证”组合,把密码从认证链中去掉:/etc/pam.d/sshd 保持不变,sshd_config 中设置:

PubkeyAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

登录流程变成:密钥通过后再输入动态码,密码彻底退出认证链。攻击面从”密码+验证码”缩小到”私钥+验证码”,安全性显著更高。

SSH 登录依次通过密钥槽位与动态口令槽位后到达服务器的架构示意图

多台服务器统一管理:每台单独执行 google-authenticator 生成密钥,App 里按主机名建条目即可。不要把同一台服务器的密钥二维码分享给多人——正确方式是每位管理员用各自手机分别绑定,.google_authenticator 支持多密钥共存。

配合 2FA 的其他加固措施

动态口令挡住暴力破解的最后一击,但完整的登录加固还包括外围措施,比如VPS 防火墙三套工具的配置方法,每项只需几分钟:

  • 把 SSH 默认端口 22 改为 20000 以上高位端口,过滤绝大多数无差别扫描,改 sshd_config 的 Port 字段即可
  • 用 AllowUsers youruser 白名单限定可登录账户,封死 root 远程登录(PermitRootLogin no)
  • 安装 fail2ban 之类的防爆破工具,自动封禁连续失败的来源 IP,配合nftables 防火墙规则实战收窄端口暴露面,与 2FA 形成纵深防御
  • 定期检查 /var/log/auth.log(Debian 系)或 /var/log/secure(RHEL 系),确认是否仍有异常尝试

这些措施与 2FA 并不冲突:端口和白名单减少无效流量,fail2ban 自动封禁攻击者,2FA 在凭据泄露时兜底,三层叠加后 SSH 暴露面基本收敛。

托管在 Hostease 独立服务器上的读者,可直接用机房救援控制台作带外通道。更多实战内容见服务器分类教程。

总结

回顾整个流程:安装 libpam-google-authenticator、运行 google-authenticator 生成密钥与应急码、修改 PAM 与 sshd 配置、手机扫码绑定、新窗口验证登录——五步完成后,SSH 登录就从”单凭密码”升级为”密码+动态口令”双重保护。

最后再强调三个守则:改配置前保留旧会话、应急码离线保存、服务器与手机时钟保持同步——这三点覆盖了绝大多数把自己锁在门外的翻车场景。

如果你需要一台可自由配置防火墙与 SSH 策略的服务器,可以考虑 Hostease VPS 主机,完整 root 权限配合本文教程,几分钟即可部署。也欢迎在评论区分享你配置 2FA 时踩过的坑。

发表评论