CentOS7.6 使用Google Authenticator 实现ssh登录双因素认证
1.SSH + Google Authenticator 安全加固
SSH本身是一个非常安全的认证连接方式。由于人过等方面的原因,难免会造成密码的泄露;非专业人员登录后端服务器误操作等情况导致服务异常,业务异常等问题我们不妨给SSH再加一把锁。
当然,增加这层锁的方式有很多种。例如:knockd、S/KEY、OPIE/OPTW、Two-factor authentication等。
2.Google Authenticator
Google身份验证器是一款基于时间与哈希的一次性密码算法的两步验证软件令牌,此软件用于Google的认证服务。此项服务所使用的算法已列于 RFC 6238 和 RFC 4226 中。
Google身份验证器给予用户一个六位到八位的一次性密码用于进行登录Google或其他站点时的附加验证。其同样可以给第三方应用生成口令,例如密码管家程序或网络硬盘。
3.系统环境说明
cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
4.安装 Google Authenticator
yum -y install wget gcc make pam-devel libpng-devel autoconf automake libtool libffi
## Google Authenticator PAM插件安装
wget https://github.com/google/google-authenticator/archive/1.02.tar.gz
tar xf 1.02.tar.gz
cd google-authenticator-1.02/libpam/
./bootstrap.sh
./configure
make && make install
安装完成后会在 /usr/local/lib/security/pam_google_authenticator.so生成一个 库文件。
cp /usr/local/lib/security/pam_google_authenticator.so /lib64/security/
系统还会多在/usr/local/bin目录生成一个google-authenticator可执行文件,通过运行该命令进行配置。
5.初始配置 Google Authenticator
[root@localhost libpam]# cd /usr/local/bin/
[root@localhost bin]# ls
google-authenticator
[root@localhost bin]# ./google-authenticator
Do you want authentication tokens to be time-based (y/n) y
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/root@localhost.localdomain%3Fsecret%3D3EYNFB6ASGNXHJ6QVUPTNW6TEI%26issuer%3Dlocalhost.localdomain
Your new secret key is: 3EYNFB6ASGNXHJ6QVUPTNW6TEI
Your verification code is 306089
Your emergency scratch codes are:
13863682
29344666
21274758
39606177
47497684
Do you want me to update your "/root/.google_authenticator" file? (y/n) Y
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
By default, tokens are good for 30 seconds. 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. If you experience problems with
poor time synchronization, you can increase the window from its default
size of +-1min (window size of 3) to about +-4min (window size of
17 acceptable tokens).
Do you want to do so? (y/n) y
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
6.SSH调用及客户端配置
添加pam认证,在第一行添加
[root@localhost]# vim /etc/pam.d/sshd
auth required pam_google_authenticator.so
#%PAM-1.0
auth required pam_sepermit.so
auth substack password-auth
auth include postlogin
# Used with polkit to reauthorize users in remote sessions
-auth optional pam_reauthorize.so prepare
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
# Used with polkit to reauthorize users in remote sessions
-session optional pam_reauthorize.so prepare
7.修改sshd配置
[root@localhost]# vim /etc/ssh/sshd_config
ChallengeResponseAuthentication yes #把上面配置改成
## 重启服务
# systemctl restart sshd.service
8.谷歌身份验证器客户端
5.1 Android客户端
(版本5.00)
下载地址: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
手机浏览器直接扫描二维码,或者输入密钥都可以
浏览器客户端
获取30秒一次的动态码的客户端是浏览器(仅支持chrome、firefox)、Android设备、苹果IOS设备、Blackberry、WP手持设备。各自程序的下载地址为:
1. chrome google-authenticator插件
Python 客户端
import hmac, base64, struct, hashlib, time
def calGoogleCode(secretKey):
input = int(time.time())//30
key = base64.b32decode(secretKey)
msg = struct.pack(">Q", input)
googleCode = hmac.new(key, msg, hashlib.sha1).digest()
o = ord(googleCode[19]) & 15
googleCode = str((struct.unpack(">I", googleCode[o:o+4])[0] & 0x7fffffff) % 1000000)
if len(googleCode) == 5:
googleCode = '0' + googleCode
return googleCode
secretKey = '***这里填秘钥***'
print calGoogleCode(secretKey)
作者:一毛
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。
不管遇到了什么烦心事,都不要自己为难自己;无论今天发生多么糟糕的事,都不应该感到悲伤。记住一句话:越努力,越幸运。