Linux 利用Google Authenticator实现SSH登录双因素认证
1.介绍
双因素认证:双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统。双因素认证是一种采用时间同步技术的系统,采用了基于时间、事件和密钥三变量而产生的一次性密码来代替传统的静态密码。每个动态密码卡都有一个唯一的密钥,该密钥同时存放在服务器端,每次认证时动态密码卡与服务器分别根据同样的密钥,同样的随机参数(时间、事件)和同样的算法计算了认证的动态密码,从而确保密码的一致性,从而实现了用户的认证。因每次认证时的随机参数不同,所以每次产生的动态密码也不同。由于每次计算时参数的随机性保证了每次密码的不可预测性,从而在最基本的密码认证这一环节保证了系统的安全性。说白了,就像我们几年前去银行办卡送的口令牌,以及网易游戏中的将军令,在你使用网银或登陆游戏时会再让你输入动态口令的。
2.目的
实现登录Linux 服务器时,除了输入用户名密码外,需要输入一次性的动态口令才能验证成功。
3.Linux 安装
3.1 系统环境说明
#cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
3.2 同步时间
ntpdate ntp1.aliyun.com
3.3 安装依赖组件
yum install -y git automake libtool pam-devel
3.4 下载谷歌认证模块
[root@localhost ~]# git clone https://github.com/google/google-authenticator-libpam.git
[root@localhost ~]# ll
drwxr-xr-x 11 root root 4096 12月 27 16:29 google-authenticator-libpam
3.5 安装 Google Authenticator,配置PAM、SSH信息
[root@localhost ~]# cd google-authenticator-libpam/
[root@localhost google-authenticator-libpam]# ./bootstrap.sh
[root@localhost google-authenticator-libpam]# ./configure
[root@localhost google-authenticator-libpam]# make && make install
[root@localhost ~]# ln -s /usr/local/lib/security/pam_google_authenticator.so /usr/lib64/security/pam_google_authenticator.so
[root@localhost ~]# sed -i 'N;2a\auth required pam_google_authenticator.so no_increment_hotp' /etc/pam.d/sshd
[root@localhost ~]# sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
[root@localhost ~]# systemctl restart sshd
3.5 配置Google Authenticator
[root@localhost ~]# 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&chld=M|0&cht=qr&chl=otpauth://totp/meisapp@linux-node4.example.com%3Fsecret%3DDYU5JLRHKDKX7LN2NPALLNXWDU%26issuer%3Dlinux-node4.example.com
![](https://img2018.cnblogs.com/i-beta/1274745/201911/1274745-20191111160612193-2094456867.png)
Your new secret key is: DYU5JLRHKDKX7LN2NPALLNXWDU
Enter code from app (-1 to skip): -1
Code confirmation skipped
Your emergency scratch codes are:
83635863
31229975
69663959
15972751
62837290
Do you want me to update your "/root/.google_authenticator" file? (y/n) y
#你希望我更新你的“/root/.google_authenticator”文件吗(y/n)?
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秒, 但是这加大了发现或甚至防止中间人攻击的可能性(y/n)?
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个可通过验证码增加到17个可通过验证码,这将允许客户机与服务器之间的时差增加到4分钟。你希望这么做吗(y/n)?
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
#如果你登录的那台计算机没有经过固化,以防范运用蛮力的登录企图,可以对验证模块启用尝试次数限制。默认情况下,这限制攻击者每30秒试图登录的次数只有3次。 你希望启用尝试次数限制吗(y/n)?
4. Android客户端使用
(版本5.00,更新日期 2017年9月27日)
下载地址:https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=zh
CLSN镜像地址 https://clsn.io/files/google/com.google.android.apps.authenticator.apk
![](https://img2018.cnblogs.com/i-beta/1274745/201911/1274745-20191111162712776-633729986.png)
5.登录验证
![](https://img2018.cnblogs.com/i-beta/1274745/201911/1274745-20191111163118044-852696732.png)
6. 问题总结
6.1 pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
解决办法:注释uid >= 1000所在行
[root@localhost ~]# vim /etc/pam.d/password-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth required pam_faildelay.so delay=2000000
auth sufficient pam_unix.so nullok try_first_pass
#auth requisite pam_succeed_if.so uid >= 1000 quiet_success
auth required pam_deny.so
account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 1000 quiet
account required pam_permit.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so