使用Google Authenticator为su添加二步验证
Update:实际运用中发现给sudo加这个东西没什么意义-应急一次性密码可以在自己的home里面的.google_authenticator里面看到,即使删除了还可以利用那个secret生成一次性密码。su的话勉强还有一点,不过这年头直接用su的应该很少了吧。
年底国内的密码门事件闹得沸沸扬扬,查了下泄漏的密码库里面还真有中招的,于是把手里的所有密码都重新生成了一遍。密码管理器换用LastPass之后确实很方便,可以生成指定长度的复杂密码,并且LastPass密码库本身还可以通过使用Google Authenticator进行保护。Google Authenticator是一个一次性密码生成器,支持HOTP(HMAC-based one time password,由RFC 4226定义)和TOTP(Time-based one time password)。
Google Authenticator在Android、iOS和Blackberry上面都有原生的客户端,同时还有人开发了j2me版本的客户端,因而基本上市面上的所有手机/移动设备都可以使用。GA同时还提供了PAM模块,因而也可用于*nix的验证工作。本着折腾到底的精神,我在服务器上面装了GA的PAM,为sudo/su添加了一次性密码保护。有两个原因导致我没有给SSH也添加Google Authenticator认证:
-
SSH使用的是公钥/私钥对,从安全性上来讲基本杜绝了被穷举的可能性
-
OpenSSH默认不支持同时使用公钥认证和PAM,也就是说两者不共存(使用公钥时不会触发PAM,反之亦然)
平台是Debian Stable (6.0.3)
首先需要安装Google Authenticator及其需要的一些库。Debian stable目前没有GA的PAM,不过testing里面有,所以也用不着去编译了,wget下载下来用dpkg装。之前需要安装qrcode的支持:
apt-get install libqrencode3
Ubuntu(11.04)是有这个包的,可以直接安装:
apt-get install libpam-google-authenticator
装完之后变成root,输入google-authenticator,会生成一个条形码,用手机扫描下来。没有摄像头的使用手动输入,类型选基于时间,然后输入那个secret key。
接下来就是在系统中启用Google Authenticator PAM。注意由于验证码是基于时间的,所以服务器和手机的时间必须一致!(可以有时差,但是分钟数不能差得太多),建议使用rdate同步下时间,特别是KVM的VPS在重启后时间会差很远,我是装的ntpdate可以在开机时自动同步时间。手机是Android的可以用Clocksync同步时间,其他的没试过。
修改/etc/pam.d/common-auth:
找到如下段落:
# here are the per-package modules (the "Primary" block)
auth [success=1 default=ignore] pam_unix.so nullok_secure
将其改为
# here are the per-package modules (the "Primary" block)
auth required pam_google_authenticator.so
auth [success=1 default=ignore] pam_unix.so nullok_secure
注意一定要把GA的PAM放在最前面。一定要保证root的home下存在.google_authenticator这个文件,否则pam认证会失败。最好另外开一个ssh来测试结果,以免万一设置错误的情况下退出root就进不来了。