因为上次某个机器上的遍历漏洞事件,还有我司同学基本不喜欢在ssh privatekey上加认证短语的坏习惯,所以推进google二次认证已经是很久以来的小心思。
网络上已经很多sshd如何结合google二次认证的文章,我就不累赘了,我就说说其中一些需要注意的地方。
(1)因为是直接使用opensshd7.2p1编译安装的,所以必须要加上编译参数 --with-pam ,否则会启用google二次认证失败。
(2)基于ubuntu linux,sshd认证是使用publickey+google二次认证,双重认证,缺一不可,但需要注意修改/etc/pam.d/sshd的时候,必须屏蔽掉这一行:
auth required pam_google_authenticator.so
# Standard Un*x authentication.
#@include common-auth #这一样必须屏蔽掉,不然老是会问你密码
(3)因为我司的ssh publickey公钥是用LDAP统一管理起来的,所以这次的google二次认证密钥对,自然也要用LDAP管理起来,N台机器,总不能每个人都要在每台机器上用google-authenticator都生成一次.google_authenticator吧。研究了一下.google_authenticator的格式并做了各种测试,发现第一行认证串才是有意义的,其他行基本不用管它。
34YJCN6AI4VZXFCF ##只需要关心这一行即可
" RATE_LIMIT 3 30 1458192284
" WINDOW_SIZE 17
" DISALLOW_REUSE 48606409
" TOTP_AUTH
51705923
97445880
16007746
47912956
24772162
所以只要搞清楚第一行认证串的生成方法,就能自己做一个中心“CA”了,而不需要依赖google-authenticator来生成。我的C功力很挫,半懂不懂的看了一下相关代码并做了各种实验,发现认证串规则很简单,只需要使用[2-7][A-Z]即可,最短16位。最后的方案是跟以前在LDAP中管理ssh publickey一样,在OA页面中加了一个选项,让每个人可以随时初始化自己的google认证串,然后直接在手机上生成新的钥匙即可。
当然你们也不用YY了,文中所有的认证串都已经被我重置了 :)
(4)接下来就是调通sshd了,让sshd在每次登陆的时候直接去找LDAP拿google认证串,跟之前做的问LDAP拿ssh publickey基本一样的做法,加了几行代码就行了。以下是sshd_config的配置案例,供参考:
UsePAM yes ###之前编译加with-pam选项就是为了启用这一项
AuthenticationMethods publickey,keyboard-interactive ###先publickey认证,然后google二次认证
UseDNS no
AuthorizedKeysCommand /foo/foo/foo.ejoy ###提取publickey和google认证串就是靠这个脚本了
AuthorizedKeysCommandUser nobody当然,因为google认证串是需要还原到.google_authenticator中的,所以这一部分虽然是加密保存在LDAP中的,但其实是可逆算法,在这一点上暂时想不到还有什么更好的方案。
(5)试一下登陆:
longweijin@xxxx$ ssh -i mykey.key -p 2222 myserver
Enter passphrase for key 'mykey.key':
Authenticated with partial success.
Verification code:XXXXXX ##就是这里输入手机上生成的google二次认证码
longweijin@myserver:~$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/kvm5--vg-root 534G 304G 204G 60% /
udev 16G 12K 16G 1% /dev
tmpfs 6.3G 704K 6.3G 1% /run
none 5.0M 0 5.0M 0% /run/lock
none 16G 140M 16G 1% /run/shm
/dev/sdb1 228M 95M 122M 44% /boot
cgroup 16G 0 16G 0% /sys/fs/cgroup
OK,整个流程就打通了,完美~~~~~~~