如何用 Google Authenticator 替换 SSH 登录验证
后知后觉 暂无评论

为机器的 SSH 添加二次(2FA)认证,提高安全性。

简介

首先熟悉一下本文的主角:Google Authenticator

项目地址:https://github.com/google/google-authenticator-libpam

那么如何在 Ubuntu 或者其他 Linux 系统上使用此 PAM 模块呢?

一般的可以直接通过官方仓库进行安装,比如:

sudo apt install libpam-google-authenticator

但是一般发行版上的版本都比较低,所以推荐使用编译的方式进行安装最新版。

安装

先克隆仓库

git clone https://github.com/google/google-authenticator-libpam.git

然后按其官方说明进行操作

./bootstrap.sh
./configure
make
sudo make install

第一报错

如果执行第一步 bootstrap 时遇到以下报错:

./bootstrap.sh
./bootstrap.sh: 15: exec: autoreconf: not found

那是缺少依赖,本文以 Debian 为例进行解决,其他发行版大同小异。

sudo apt install dh-make

第二报错

如果执行第二步 configure 时遇到以下报错:

configure: error: Unable to find the PAM library or the PAM header files

也是缺少依赖。

sudo apt install libpam0g-dev

第三报错

如果此步骤报错,一般是编译环境不满足的缘故。

sudo apt install build-essential

第四报错

如果执行第四步 install 时遇到以下报错:

  CC       src/pam_google_authenticator_la-pam_google_authenticator.lo
src/pam_google_authenticator.c:48:10: fatal error: security/pam_appl.h: No such file or directory
   48 | #include <security/pam_appl.h>
      |          ^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:1029: src/pam_google_authenticator_la-pam_google_authenticator.lo] Error 1

还是缺少依赖。

sudo apt install libpam0g-dev

其他

安装过程中可以看到文件的实际安装路径为 /usr/local/lib/security

$ sudo make install
  CC       src/pam_google_authenticator_la-pam_google_authenticator.lo
  CCLD     pam_google_authenticator.la
make[1]: Entering directory '/home/kane/google-authenticator-libpam'
 /bin/mkdir -p '/usr/local/bin'
  /bin/bash ./libtool   --mode=install /usr/bin/install -c google-authenticator '/usr/local/bin'
libtool: install: /usr/bin/install -c google-authenticator /usr/local/bin/google-authenticator
 /bin/mkdir -p '/usr/local/share/doc/google-authenticator'
 /usr/bin/install -c -m 644 FILEFORMAT README.md '/usr/local/share/doc/google-authenticator'
 /bin/mkdir -p '/usr/local/share/doc/google-authenticator'
 /usr/bin/install -c -m 644 totp.html '/usr/local/share/doc/google-authenticator'
 /bin/mkdir -p '/usr/local/share/man/man1'
 /usr/bin/install -c -m 644 man/google-authenticator.1 '/usr/local/share/man/man1'
 /bin/mkdir -p '/usr/local/share/man/man8'
 /usr/bin/install -c -m 644 man/pam_google_authenticator.8 '/usr/local/share/man/man8'
 /bin/mkdir -p '/usr/local/lib/security'
 /bin/bash ./libtool   --mode=install /usr/bin/install -c   pam_google_authenticator.la '/usr/local/lib/security'
libtool: install: /usr/bin/install -c .libs/pam_google_authenticator.so /usr/local/lib/security/pam_google_authenticator.so
libtool: install: /usr/bin/install -c .libs/pam_google_authenticator.lai /usr/local/lib/security/pam_google_authenticator.la
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/sbin" ldconfig -n /usr/local/lib/security
----------------------------------------------------------------------
Libraries have been installed in:
   /usr/local/lib/security

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the 'LD_RUN_PATH' environment variable
     during linking
   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to '/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
make[1]: Leaving directory '/home/kane/google-authenticator-libpam'

使用

使用需要手动调整下系统的调用

安装客户端

在 Android 或 iOS 上安装 Google Authenticator 客户端。

实际上所有的 2FA 客户端都可以,比如微软的 Microsoft Authenticator 等。

制作密钥

哪个用户需要用 2FA 验证就先切换到哪个用户执行命令。

google-authenticator

Do you want authentication tokens to be time-based (y/n) y
Warning: pasting the following URL into your browser exposes the OTP secret to Google:
  https://www.google.com/chart?chs=200x200
Failed to use libqrencode to show QR code visually for scanning.
Consider typing the OTP secret into your app manually.
Your new secret key is: LCLU5TBRXKZ3624ELGWOBKCSLA
Enter code from app (-1 to skip): 
小贴士:Do you want authentication tokens to be time-based (y/n) 这个选项是询问是否启动以「时间」基准的令牌。建议选择是,但是需要将系统的时间进行校准,可以配置 ntp 或 chrony 服务。
小贴士:如果看到 Failed to use libqrencode to show QR code visually for scanning. 报错是因为没有安装 QRCode 生成的库,导致无法生成二维码,可以安装 libqrencode4 包然后重新生成,但是并不是很推荐,因为生成的二维码非常大大大大大大大大大大大大,推荐手动复制链接到浏览器访问,即可看到一个正常尺寸的二维码。

在客户端上扫码后将客户端上的六位数字输入后回车(000000 是例子)

Enter code from app (-1 to skip): 000000
Code confirmed
Your emergency scratch codes are:
  74460000
  19300000
  14370000
  66860000
  67900000

会提供给你五组「一次性安全码」,只能验证一次,每个使用后就会立即作废,一般用于没有手机或者其他特殊场景下使用。

然后会询问你以下四个问题:

1.是否允许更新此用户的配置文件?
2.是否要禁止多次使用相同的身份验证令牌?这将限制您大约每 30 秒登录一次,但它会增加您注意到甚至防止中间人攻击的机会。
3.默认情况下,移动应用程序每 30 秒生成一个新令牌。为了补偿客户端和服务器之间可能的时间偏差,我们允许在当前时间之前和之后一个额外的令牌。这允许一个身份验证服务器和客户端之间的时间偏差最大为 30 秒。 如果你遇到时间同步不好的问题,可以增加窗口从其默认大小的 3 个允许代码(一个以前的代码,当前的代码,下一个代码)到 17 个允许的代码(前 8 个代码,当前代码)代码,以及接下来的 8 个代码)。这将允许客户端和服务器之间最多存在 4 分钟的时间偏差。
4.如果您登录的计算机没有针对暴力破解的安全策略,您可以为身份验证模块启用速率限制。默认情况下,这会将攻击者限制为每30 秒不超过 3 次登录尝试。您要启用速率限制吗?

都选择 y 即可。

修改配置

然后修改系统 PAM 验证 /etc/pam.d/sshd 文件最后加上一行

auth required pam_google_authenticator.so

然后修改系统 SSH 配置 /etc/ssh/sshd_config 把参数 ChallengeResponseAuthenticationno 改成 yes

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no # CHANGE THIS TO YES

重启 SSHd 服务

sudo systemctl restart sshd.service
注意:如果启用了密钥对(RSA),那么是不需要验证 2FA 的。

附录

参考链接

本文撰写于一年前,如出现图片失效或有任何问题,请在下方留言。博主看到后将及时修正,谢谢!
禁用 / 当前已拒绝评论,仅可查看「历史评论」。