使用Google Authenticator给ssh进行登录验证

普通情况下的服务器登录,是“服务器+密码”这种直白的验证方式,但是这种方式太过简单,一旦密码泄露,服务器就有危险,于是为了安全我们就要在登录上再加一把锁,那就是使用Google Authenticator(谷歌身份验证器)这个工具,在登录的时候进行一次验证,只有“验证通过了”+“密码正确”才能登陆服务器。

安装前准备

1)关闭Selinux :setenforce 0
2)安装依赖:yum -y install gcc make pam-devel libpng-devel libtool wget git
3)添加阿里云epel 源:

1
2
3
4
RHEL 6/Centos 6
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
RHEL 7/Centos 7
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

4)安装Qrencode,谷歌身份验证器需要调用该程序生成二维码并显示:yum install -y qrencode

安装谷歌身份验证器

这个时候很多教程会让你去执行git clone https://github.com/google/google-authenticator.git,然而现在这个git里面已经不再含有libpam这个文件夹了,下载下来是一个错误的包,那么这个时候你可以使用yum install google-authenticator,不过yum安装的身份验证器的版本很老,这个时候可以执行wget https://github.com/google/google-authenticator-libpam/archive/1.04.tar.gz

下载下来1.0.4版本的然后拆包解压缩,里面是这样几个文件:
办公室

然后就./bootstrap.sh && ./configure && make && make install进行编译和安装。

安装过程完毕之后,还要复制google身份验证器pam模块到系统下,命令是:cp /usr/local/lib/security/pam_google_authenticator.so /lib64/security/

调整登陆方式

1)编辑/etc/pam.d/sshd这个文件,我这个centos的版本是7.0的,里面的内容可能跟centos 6.x的优点不同,不过没关系,就需要插入黄色框内的auth required pam_google_authenticator.so,如图:
办公室

修改完毕之后,保存退出。

注意!修改了这步之后,服务器千万不能断开连接,否则再连是需要google验证码的,而我们现在还没有生成码,所以肯定是无法连接服务器,如果是云服务器,可以通过登陆控制台的方式把这个文件修改回来,如果是实体服务器,那就呵呵呵了。

2)编辑/etc/ssh/sshd_config,就修改一个地方:ChallengeResponseAuthentication yes
3)保存退出之后,重启一下ssh服务:

1
2
RHEL6 /Centos6:Service sshd restart
RHEL7 /Centos7:Systemctl resart sshd

生成登陆验证码

这次以root用户为例,那么切换成root用户执行下面的过程。
1)执行google-authenticator,由于我们之前已经安装了qrencode,那么这个时候会生成一个超级超级巨大的二维码,给各位感受一下:
办公室

红色内容是生成的密钥,很重要。绿色的内容是备用的紧急救助码,紧急救助码就是当你无法获取认证码时(比如手机丢了),可以当做认证码来用,每用一个少一个,但其实可以手动添加的,建议如果 root 账户使用 Google Authenticator 的话一定要把紧急救助码另外保存一份。

Do you want me to update your "/home/test/.google_authenticator" file? (y/n) y

是否更新用户的 Google Authenticator 配置文件,选择 y 才能使上面操作对当前用户生效,其实就是在对应用户的 Home 目录下生成了一个 .google_authenticator 文件,如果你想停用这个用户的 Google Authenticator 验证,只需要删除这个用户 Home 目录下的 .google_authenticator 文件就可以了。

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

每次生成的认证码是否同时只允许一个人使用?这里选择 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) n

是否增加时间误差?这里随便选择, ny都可以。

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

是否启用次数限制?这里选择 y,默认每 30 秒最多尝试登录 3 次。

如果想要写成脚本的话,那么上面交互式的设置也可用通过参数一次性设置:google-authenticator -t -f -d -l test@chen.super -i MR.chen -r 3 -R 30 -W

-I和-i是可以随便写的,但是-i后期可以改,-I不能改。

搭配手机端

如果手机是ios,就去apple store里搜索“Google Authenticator”,如果是安卓,就去应用商店搜索“谷歌动态口令”。

安装完后,打开App,点击“开始设置”,选择“扫描条形码”扫描上面google-authenticator命令生成的二维码,或者是选择“输入密钥”,然后手机上就能看到对应的六位数认证码了。

最后一步,返回xshell,修改登陆方式,设置登陆方法为Keyboard Interactive,如图:
办公室

这个时候,推荐各位保留原有的ssh不要动,在另外一个xshell窗口登陆一下看看效果,如果正常的话,这个时候会看到系统会让你先输入一个Verification code。这个值就是手机里的那个六位数,然后再输入密码,只有两个都是正确的,才能登陆!

至此整个配置完成,如果登陆时遇到问题,请查看日志文件/var/log/secure

更改存储位置

在生成二维码那一步的时候,如果你错过了记住密钥也不要怕,系统会自动把密钥和紧急救助码保存在~/.google_authenticator这个文件里。

如果想要改变密钥存储位置,请使用–secret参数:google-authenticator --secret="/文件路径/用户名"

然后更改/etc/pam.d/sshd内的路径配置:auth required pam_google_authenticator.so user=root secret=/PATH_FOLDER/${USER}

上面那句话里“user=root” 用于强制PAM使用root用户权限来搜索文件。

另外请注意,由于我们当时切换成了root用户,所以密钥文件的所有者是root,生成文件的用户只能读取文件(chmod: 400):

1
2
chown root.root /PATH_FILE/SECRET_KEY_FILES
chmod 400 /PATH_FILE/SECRET_KEY_FILES

-------------This article is over!Thanks for reading!-------------
感谢您请我喝咖啡!(o´ω`o)
0%