Ubuntu使用Google Authenticator(MFA)

基本知识点:

info.support.huawei.com/info-finder...

zhuanlan.zhihu.com/p/137732928...

Authenticator安装:

应用地址:uuou.lanzouo.com/b011lkrqve

密码:ayo

7.0版本可能出现无法扫码的情况,那就安装6.0版本
重要提示:执行下述操作时,务必确保你已开了多个活动会话(如控制台或已连接的 SSH 会话)登录服务器。

一定得是多个!!!一定得是多个!!!一定得是多个!!!

不然一个不小心都导致服务器再也无法正常登录,别问为什么,说多了都是泪

使用 Google Authenticator

系统版本:Ubuntu 25.04.2

Google Authenticator 是一个开源的基于 TOTP(Time-based One-Time Password) 的 MFA 方案。

📦安装 Google Authenticator

在 Linux 服务器(如 CentOS、Ubuntu)上安装

bash 复制代码
 # Ubuntu/Debian
 sudo apt update && sudo apt install libpam-google-authenticator  
 ​
 # CentOS
 sudo yum install epel-release && sudo yum install google-authenticator  

⚙️配置 Google Authenticator

安装完成后,你需要为特定的用户生成一个密钥。请切换到需要启用双因素认证的用户账户下操作,不要直接使用 root 用户(除非你就是想为 root 用户配置)。

bash 复制代码
 # 切换到目标用户,例如用户名为 'ayo'
 su - ayo
 ​
 # 运行配置程序
 google-authenticator

命令选项

bash 复制代码
google-authenticator -t -f -d -w 3 -e 5 -r 3 -R 15

选项说明:

  • -t : 使用 TOTP 验证
  • -f : 将配置保存到 ~/.google_authenticator
  • -d : 不允许重复使用以前使用的令牌
  • -w 3 : 允许的令牌的窗口大小。 默认情况下,令牌每 30 秒过期一次。 窗口大小 3 允许在当前令牌之前和之后使用令牌进行身份验证以进行时钟偏移。
  • -e 5 : 生成 5 个紧急备用代码
  • -r 3 -R 15 : 限速,每 15 秒允许 3 次登录

更多帮助信息可以使用 --help 选项查看。

接下来会弹出好几个配置信息,建议全选y

程序运行后,将会更新配置文件,并且显示下面信息:

  • 二维码,您可以使用大多数身份验证器应用程序扫描此代码。
  • 一个秘密的钥匙,如果您无法扫描二维码,请在您的应用中输入此密钥。
  • 初始验证码,该验证码将在30秒后失效。
  • 5 个一次性使用紧急代码的列表。

紧急代码 主要作用是在你无法获取常规动态验证码时,作为紧急后备登录方式,帮你重新获得账户的访问权限

将应急恢复码妥善保存到安全的地方,以防手机丢失无法获取动态码

常见的使用场景。比如手机丢失、损坏、没电,或者验证器App(如Google Authenticator)被意外删除或无法使用.

信息说明

运行命令后,会进入一个交互式配置界面,以下是建议的选项:

  • 基于时间的令牌 : 输入 y
  • 更新配置文件 : 输入 y
  • 禁止重复使用令牌 : 输入 y(以增强安全性)
  • 允许时间容差 : 根据情况选择 yn。如果服务器或手机时间可能不同步,可以输入 y以避免验证码失效问题。
  • 启用速率限制 : 输入 y(以防止暴力破解)
sh 复制代码
 google-authenticator
     ​
 ########### 基于时间的令牌
 Do you want authentication tokens to be time-based (y/n) y
 ​
 ----------------------
 此处二维码使用手机扫描
 已验证ID->扫描QR码
 ----------------------
 ​
 Your new secret key is:XXXXXXXXX
 Enter code from app (-1 to skip):【输入手机上的六位数字】
 Code confirmed
 Your emergency scratch codes are:
   XXXXXXXX
   XXXXXXXX
   XXXXXXXX
   XXXXXXXX
   XXXXXXXX
 ​
 【剩下的步骤全都输入y即可】
 ########### 更新配置文件
 # 翻译:您希望我更新您的"/root/.google_authenticator"文件吗?(是/否)
 Do you want me to update your "/home/XXXXXX/.google_authenticator" file? (y/n) y
 ​
 ########### 禁止重复使用令牌
 # 翻译:您是否要禁止同一身份验证令牌的多次使用?这会限制您大约每 30 秒登录一次,但会增加您发现甚至阻止中间人攻击的机会(是/否)
 Do you want to disallow multiple uses of the same authentication
 token? This restricts you to one login about every 30s, but it increases
 your chances to notice or even prevent man-in-the-middle attacks (y/n) y
 ​
 ########### 允许时间容差
 # 翻译:默认情况下,移动应用程序每 30 秒生成一个新的令牌。
 # 为了补偿客户端和服务器之间可能存在的时间偏差,
 # 我们在当前时间之前和之后各允许一个额外的令牌。这允许认证服务器和客户端之间的时间偏差最多为 30 秒。如果您
 # 遇到时间同步不佳的问题,可以将窗口从默认的 3 个允许的代码(一个之前的代码、当前代码、下一个代码)增加到 17 个允许的代码(8 个之前的代码、当前代码和 8 个下一个代码)。这将允许客户端和服务器之间的时间偏差最多为 4 分钟。
 # 您要这样做吗?(是/否)
 By default, a new token is generated every 30 seconds by the mobile app.
 In order to compensate for possible time-skew between the client and the server,
 we allow an extra token before and after the current time. This allows for a
 time skew of up to 30 seconds between authentication server and client. If you
 experience problems with poor time synchronization, you can increase the window
 from its default size of 3 permitted codes (one previous code, the current
 code, the next code) to 17 permitted codes (the 8 previous codes, the current
 code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
 between client and server.
 Do you want to do so? (y/n) y
 ​
 ​
 ########### 启用速率限制
 # 翻译:如果您登录的计算机未针对暴力破解登录尝试进行加固,您可以为身份验证模块启用速率限制。默认情况下,这将限制攻击者每 30 秒最多尝试登录 3 次。您要启用速率限制吗?(是/否)
 If the computer that you are logging into isn't hardened against brute-force
 login attempts, you can enable rate-limiting for the authentication module.
 By default, this limits attackers to no more than 3 login attempts every 30s.
 Do you want to enable rate-limiting? (y/n) y

📱手机端设置

你需要在手机上安装验证器App【安卓应用安装】并添加账户:

  1. 安装应用: 在 Google Play (Android) 或 App Store (iOS) 搜索并安装 "Google Authenticator"。
  2. 添加账户: 打开应用,点击 "+" 号,选择"扫描二维码",扫描终端中显示的二维码。如果无法扫描,也可以选择"手动输入",填写终端中显示的密钥。

🔧系统配置(SSH 与 PAM)

要让 SSH 登录时要求验证码,需要进行一些系统配置。

注意:请勿关闭当前ssh连接,否则可能会因为配置错误无法通过ssh连接服务器

**强烈建议**:在重启 SSH 服务前,请确保你已通过另一种会话方式(如控制台或另一个已连接的SSH会话) 保持在服务器上的登录状态,以便在新配置出现问题时能够回退。

修改 PAM 配置

编辑 PAM 的 SSH 配置文件:

sh 复制代码
sudo vim /etc/pam.d/sshd

在文件底部添加下方内容:

sh 复制代码
 # Google Authenticator MFA
 # 仅进行Google Authenticator验证。required控制标志意味着该模块必须成功,认证才能通过(但 nullok选项为未配置用户提供了灵活性)
 auth required pam_google-authenticator.so nullok
 ​
 # 标准密码认证
 # auth required pam_unix.so try_first_pass nullok

nullok 最后一行末尾的单词告诉 PAM 这种身份验证方法是可选的。这允许没有 OATH-TOTP 令牌的用户仍然使用他们的 SSH 密钥登录。一旦所有用户都拥有 OATH-TOTP 令牌,您就可以 nullok 从此行中删除以强制使用MFA。

注意 :有可能因为历史原因有些用户哪怕你没有执行google-authenticator为其绑定MFA,但是其用户文件夹只要存在~/.google_authenticator文件就会触发Google Authenticator MFA的认证

SSH 认证流程最终由 PAM 模块处理。确保 /etc/pam.d/sshd文件中包含了 Google Authenticator 的 PAM 模块,并且其顺序在密码认证模块之后。

修改 SSH 配置

配置sshd_config支持MFA认证:

bash 复制代码
 sudo vim /etc/ssh/sshd_config

可选配置项有:

sh 复制代码
 # 启用挑战应答
 # 此选项启用挑战-应答认证机制。这是一种比静态密码更安全的认证方式,服务器会生成一个随机"挑战",客户端需要根据这个挑战和用户密码(或其他凭证)通过特定算法计算出一个"应答"并返回给服务器进行验证。像Google Authenticator这类双因素认证(2FA)工具通常依赖于此机制。
 ChallengeResponseAuthentication yes 
 ​
 ​
 # 使用PAM进行认证管理,以便支持双因素认证等高级功能
 # 此选项表示SSH服务将使用Linux的可插拔认证模块(PAM)框架来处理认证请求。PAM提供了高度的灵活性,允许系统管理员通过配置来组合多种认证方法。
 UsePAM yes 
 ​
 ​
 # 启用键盘交互,确保客户端兼容性(这一行对于某些SSH客户端(如Xshell、Termius)的正常提示至关重要)
 # 此选项启用键盘交互式认证。这对于许多SSH客户端(如Xshell, Termius)正常显示双因素认证(2FA)的输入提示至关重要。即使禁用了密码认证(PasswordAuthentication no),只要启用了PAM且PAM配置要求2FA,此项就必须为 yes,否则用户可能无法输入验证码。
 KbdInteractiveAuthentication yes 

注意:基本上所有教程都没有说关于KbdInteractiveAuthentication的配置,如果你的文件中默认这个配置是no的话,一定要把它改成yes,否则mfa将不生效!

重启 SSH 服务

**⚠️ 重要提醒**:重启 SSH 服务前,务必确保你已通过另一个活动会话(如控制台或已连接的 SSH 会话)登录服务器。这样,若新配置有误导致无法登录,你仍有途径进行修复。说多了都是泪!!!

sh 复制代码
sudo systemctl restart ssh

🔐 登录验证

配置完成后,当你再次通过 SSH 登录该用户账户时,会看到如下提示:

sh 复制代码
ssh ubuntu@your_server_ip
Password: <输入用户密码>
Verification code: <输入手机Google Authenticator App上显示的6位动态码>

登录成功后,你的 SSH 安全性就得到了显著提升

🗑️ 移除当前登录用户的Google Authenticator

移除当前登录用户的 Google Authenticator 执行如下命令即可

sh 复制代码
rm -f ~/.google_authenticator

🗑️ 卸载 Google Authenticator

如果你不再需要双因子认证,可以卸载它。

**⚠️ 重要提醒**:在执行这步操作的时候,务必确保你已通过另一个或多个活动会话(如控制台或已连接的 SSH 会话)登录服务器。这样,若新配置有误导致无法登录,你仍有途径进行修复。说多了都是泪!!!

卸载软件包

对于 Debian/Ubuntu 系统:

sh 复制代码
# 卸载软件包
 sudo apt purge libpam-google-authenticator -y
 ​
 # 清除残留的配置文件和依赖
 sudo apt autoremove -y
 sudo apt autoclean

对于 CentOS/RHEL 系统

需先确认安装包名称,通常是 google-authenticatorpam-google-authenticator

sh 复制代码
# 查看已安装的包名
 rpm -qa | grep -i google-authenticator
 ​
 # 卸载(替换为实际包名)
 sudo yum remove -y google-authenticator
 ​
 # 清除缓存
 sudo yum clean all

恢复 PAM 和 sshd 配置(关键)

  • PAM 配置 :记得编辑 /etc/pam.d/sshd文件,移除 之前添加的 auth required pam_google_authenticator.so,还有其他所有与 Google Authenticator 相关的行。
  • SSH 配置 :根据你的安全需求,决定是否将 /etc/ssh/sshd_config中的 ChallengeResponseAuthenticationKbdInteractiveAuthentication改回 no或者注释掉,并移除任何添加的 AuthenticationMethods行。

  • 用户密钥文件 :卸载软件不会自动删除各用户家目录中的 ~/.google_authenticator文件,如需清理,请手动删除。

sh 复制代码
 # 以 root 权限执行,递归查找并删除所有用户的 MFA 配置
 find /home /root -name ".google_authenticator" -delete
 ​
 # 该命令会删除 `/home` 目录下所有普通用户,以及 `/root` 目录下 root 用户的 MFA 配置文件。

重启 SSH 服务

最后,重启 SSH 服务以使配置更改生效:

sh 复制代码
sudo systemctl restart ssh

注意事项或骚操作

登录顺序

有些博客对于/etc/pam.d/sshd配置文件

sh 复制代码
auth required pam_google_authenticator.so

会将上述配置项会放在配置文件的第一行,那在登录服务器的时候就会出现先进行PAM认证 再走密码认证 ,你如果想控制验证的先后顺序,那就得注意common-auth的位置

sh 复制代码
@include common-auth

如果@include common-authauth命令前,则表示先就行密码认证,如果在后,则表示先执行你配置的PAM认证

参考如下:

sh 复制代码
# 执行密码验证(放在最前面,能确保先输密码)
@include common-auth
# #################################################################
​
# 你可以在这里放你的认证配置
​
# #################################################################
​
# 后续规则(与认证无关)
account    required     pam_nologin.so
......
​
# #################################################################
​
# 也可以在页面的最后一开开始写你的配置

配置项注意

你如果确定要用PAM认证,在/etc/ssh/sshd_config文件中,有些博客可能会给出

你还可以通过 AuthenticationMethods指令来精确控制认证方式。例如,如果希望用户必须先通过公钥认证,再完成双因子认证,可以添加:

sh 复制代码
 AuthenticationMethods publickey,keyboard-interactive

注意:/etc/pam.d/sshd文件配置auth后,/etc/ssh/sshd_config文件尽可能不要配置AuthenticationMethods,将这个认证选项注释掉,如果不然会导致整个认证流程的混乱,影响你正常登录服务器,除非你真的懂整个流程,那当我没说

认证流程的控制

这里只是我个人学到的一个骚操作,这里记录一下,先看两条命令

命令一:

仅让 ayo 用户执行 MFA 验证,root 和其他用户跳过 MFA

sh 复制代码
# PAM configuration for the Secure Shell service
# 1. 先执行密码验证(必须放在最前面,确保先输密码)
# Standard Un*x authentication.
@include common-auth
​
​
# #################################################################
# 2. 对 root 用户:密码验证成功后,跳过后续2个模块(ayo判断+MFA验证),直接登录
# success=2 → 跳过第3、4行,避免MFA拦截
auth [success=2 default=ignore] pam_succeed_if.so user = root
​
# 3. 对 非ayo用户(除root外):密码验证成功后,跳过后面1个MFA模块,直接登录
# success=1 → 仅ayo用户会执行第4行的MFA验证
auth [success=1 default=ignore] pam_succeed_if.so user != ayo
​
# 4. 仅 ayo 用户会执行这行:强制MFA验证(必须成功,否则登录失败)
auth required pam_google_authenticator.so
​
# #################################################################
​
# Disallow non-root logins when /etc/nologin exists.
account    required     pam_nologin.so
​
......

命令二:

仅root用户触发PAM认证,其他用户不受影响

sh 复制代码
# PAM configuration for the Secure Shell service
​
# 1. 先执行密码验证(必须放在最前面,确保先输密码)
# Standard Un*x authentication.
@include common-auth
​
# #################################################################
# 2. 对 非root用户:密码验证成功后,跳过后续1个MFA模块,直接登录
# success=1 → 跳过第3行的MFA验证,仅root用户会执行第3行
auth [success=1 default=ignore] pam_succeed_if.so user != root
​
# 3. 仅 root 用户会执行这行:强制MFA验证(必须成功,否则登录失败)
auth required pam_google_authenticator.so
​
# #################################################################
# 后续规则(与认证无关)
# ####################
​
# Disallow non-root logins when /etc/nologin exists.
account    required     pam_nologin.so
​
......

解释如下:

  • auth :表示这条规则属于 PAM 的认证阶段(Authentication),用于控制用户登录时的验证流程。
  • []:在 PAM 配置中,[](中括号)的作用是包裹控制标志(control flags) ,用于定义 "当模块执行结果为成功 / 失败 / 其他状态时,后续的认证流程应该如何处理"。它是 PAM 规则中流程控制的核心语法 ,所有关于 "条件跳转""结果处理" 的逻辑都通过中括号内的参数定义。中括号内的参数通常由 "状态 = 动作" 组成,格式为 [状态1=动作1 状态2=动作2 ...],用于指定模块在不同执行结果下的行为。
  • success=N :当模块执行 "成功" 时,跳过后续的 N 条规则(N 是数字,如 success=2 表示跳过 2 条)
  • default=动作:当模块执行结果不匹配任何其他状态时(默认情况),执行指定动作

    • 当模块执行结果不匹配任何其他状态时(默认情况),执行指定动作:

      • default=ignore:忽略该结果,继续执行下一条规则;
      • default=bad:判定为失败,终止当前认证流程;
      • default=die:立即终止所有认证流程。
    • 其他少见状态(如 ignore=ignoremodule_unknown=ignore 等)

      • 用于处理模块不存在、参数错误等特殊情况,通常保持默认即可。
  • pam_succeed_if.so:这是 PAM 的条件判断模块,用于检查用户的属性(如用户名、组、UID 等)是否满足指定条件

  • user = root:模块的参数,指定判断条件:"当前登录的用户是否为 root"

  • required :控制标志,表示该模块必须验证成功,整个认证流程才能通过(如果该模块验证失败,无论其他模块结果如何,登录都会被拒绝)。

  • pam_google_authenticator.so:这是 Google Authenticator 的 PAM 模块,用于验证用户的 MFA(多因素认证)验证码(如谷歌验证码)。

相关推荐
小猪乔治爱打球6 小时前
[Golang 修仙之路] 场景题:红包系统设计
后端·面试
程序猿二饭6 小时前
SpringBoot 实现支持多个微信小程序的登录
后端
AlpsMonaco6 小时前
kubernetes(k8s)集群迁移更新
后端
华仔啊6 小时前
刚学 Java 就被内存溢出劝退?这 10 个集合内存管理技巧救了我!
java·后端
武子康6 小时前
大数据-90 Spark RDD容错机制:Checkpoint原理、场景与最佳实践 容错机制详解
大数据·后端·spark
花花无缺6 小时前
python自动化-pytest-标记
后端·python
Villiam_AY6 小时前
使用 chromedp 高效爬取 Bing 搜索结果
后端·爬虫·golang
CryptoPP6 小时前
跨境金融数据对接实践:印度NSE/BSE股票行情API集成指南
开发语言·后端·金融
程序员爱钓鱼6 小时前
Go语言实战案例-实现简易定时提醒程序
后端·google·go