用 Google Authenticator 加强 VPS 及 WordPress 甚至桌面电脑的安全性
传统地用 SSH 登录 VPS 的时候,靠的只是一串字符密码,如果密码被泄露、被猜解、被暴力枚举成功,那么 VPS 就完全暴露在坏人手中了。安全意识高一些的用户会使用公私钥代替字符来登录,但是这样的缺点是如果在陌生的电脑上想要临时登录一下,由于没有私钥,也就没办法了。传统地登录 WordPress 的时候,更是只有一个密码,如果被泄露、猜解、暴力枚举,辛辛苦苦经营的博客就完蛋了。
本文介绍如何通过 Google Authenticator 构建“物理屏障”,最大限度地阻断来自网络的密码攻击。本文假定你已经了解 Google Authenticator 的工作原理。
一、前言
虽然从小就被教导说操作系统一定要设置强劲的密码,但实际上,小时候用的大多是“远程桌面连接”默认被禁用的盗版 Windows,且在家里上网时候总是在路由器后面,没有独立公网 IP,因此就算电脑设置为空密码,也没有什么大问题。
后来,上了大学了,网络环境也有所改变:在宿舍上网的时候,电脑能分配到独立公网 IP,并且能直接从校外网络连入(甚至可以跑 Apache 玩),而我的 Xubuntu 又装了 OpenSSH Server,所以这时候密码就非常重要了,如果密码不够强劲的话,别人可以在互联网的任何一个地方通过 SSH 完全控制我的电脑。这太可怕了。
虽然不是所有人的电脑都有公网 IP 可以方便地从外网连入,但是显然 VPS 是有公网 IP 的。我以前居然没有意识到 VPS 是多么地脆弱,但是某天突然灵光一现:如果 VPS 的 root 密码被泄露、猜解或是暴力枚举,那么任何人都可以通过 ssh root@wzyboy.im 来完全控制我的网站!
这么迟才想到这一点的确比较奇怪,但是好在,目前还没有“亡羊”,赶紧先“补牢”吧。个人又非常喜欢 Google Authenticator 这种二步验证工具(以前写过文章)于是便结合 Google Authenticator 折腾出了这篇简陋但是还算安全的教程。本教程中环境默认为:
- 服务器为 512MiB RAM 的 LAMP VPS,装着 Ubuntu 11.04 amd64。
- 客户机为装着 Xubuntu 11.10 amd64 的笔记本电脑。
- 验证器为装有 Android 版 Google Authenticator 的 HTC Desire Z (Vision)。
二、用 Google Authenticator 加强 SSH 登录安全性
安装相关 PMA 模块
首先需要在服务器上安装 libpam-google-authenticator 这个包。Ubuntu 11.10 及以上的官方源里自带了这个包,直接使用sudo apt-get install libpam-google-authenticator 命令便可自动解决依赖关系并安装。但是如果是 11.10 以下或者是其他发行版,就要自己的编译安装了。输入以下几条命令就行了:
sudo apt-get install libpam0g-dev libqrencode3 #这是它依赖的两个包,各发行版里大多带了。 git clone https://code.google.com/p/google-authenticator/ #下载源代码 cd google-authenticator/libpam/ make install #编译并安装
如果用着 Ubuntu 11.10 以下又不想自己编译的话(比如 VPS 是 11.04 的我),其实也有偷懒的办法的,就是直接拿官方源里编译好的 11.10 的二进制包来充数。这回是不需要 libpam0g-dev 这个包了,直接用下面的命令就好了:
sudo apt-get install libqrencode3 #这个包依然是要的 wget http://us.archive.ubuntu.com/ubuntu/pool/universe/g/google-authenticator/libpam-google-authenticator_20110413.68230188bdc7-1ubuntu1_amd64.deb #下载二进制包,如果是 32 位的操作系统的话请把 amd64 换成 i386 sudo dpkg -i libpam-google-authenticator_20110413.68230188bdc7-1ubuntu1_amd64.deb #安装之
配置 Google Authenticator
Google Authenticator 的服务器端已经安装好了,那么客户端呢?Android 用户请点这里安装,iOS 用户请点这里安装,其他智能手机用户也有相应的开源解决方案,请自行搜索下载。非智能手机用户暂时无解。:-( 不过,正在阅读本文的你一定早就用过 Google Authenticator 了吧?
Google Authenticator 其实是一套开源的解决方案,所以不仅在 Google 的网站上能用,在其他地方也能用的。然而,在 Google 的网站上,会直接给你一个 QR 码让你扫的,而自己配置的 Google Authenticator 则要自己生成了。
首先需要切换到对应的用户,如果 VPS 上只有一个用户的话,自然是可以省略这一步的,但是多用户的 VPS 需要先切换到对应的用户,再运行google-authenticator 命令,结果类似这样:
这个 QR 码自然是给 Google Authenticator 应用程序来扫描的,也可以访问上面的那个链接,用 Google Chart API 生成的 QR 码来扫描。还可以照着 QR 码下面的文字密钥手工输入。当 Google Authenticator 识别了这个账号之后,验证器就配置好了。在文字密钥下面还提供了几个应急码,为手机丢了等情况下所用的,可以妥善保管。
这时 Google Authenticator 虽然运行了,但是相关设置还没有保存,程序会问你Do you want me to update your "~/.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 and 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 1:30min to about 4min. Do you want to do so (y/n)
大意是问是否打开时间容错以防止客户端与服务器时间相差太大导致认证失败。这个可以根据实际情况来。我的 Android 设备时间很准(与网络同步的),所以答 n,如果一些 Android 平板电脑不怎么连网的,可以答 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。
问题答完了,家目录中多出一个 .google_authenticator 文件(默认权限为 400),这时客户端与服务端已经配套起来了,以后不用再运行google-authenticator 命令了,否则会重新生成一组密码。
配置 SSH 验证
此时虽然 Google Authenticator 已经配置好了,但是并没有任何程序会去调用它。所以需要设置 SSH 登录的时候去通过它验证。
打开 /etc/pam.d/sshd 文件,添加
auth required pam_google_authenticator.so
这一行,保存。再打开 /etc/ssh/sshd_config 文件,找到
ChallengeResponseAuthentication no
把它改成
ChallengeResponseAuthentication yes
并保存。最后,输入
sudo service ssh restart
来重启 SSH 服务以应用新的配置。
这时候再用 SSH 登录的话就会这样了:
wzyboy@vermilion:~$ ssh root@natatio Password:[输入密码] Verification code:[输入验证码] Welcome to Ubuntu 11.04 (GNU/Linux 2.6.38-8-generic x86_64)
于是就这样成功了。
当然,如果经常要登录 SSH 的话,每次这样输入未免太麻烦了,好在,这个额外的认证步骤与以前的公私钥认证是可以同时使用的。所以在自己的桌面电脑上可以做一下公私钥认证:
ssh-keygen #生成密钥对,一路回车即可,已经生成过的不用生成了 ssh-copy-id root@example.org #把公钥添加到 VPS 上
这样达到的效果是,以后在自己的电脑上 SSH 到 VPS 的时候,是不需要输入任何密码的,可以直接连接,而在陌生的电脑上需要管理 VPS 时,需要输入账户密码及 Google Authenticator 的验证码。而想要从网络上攻击你的 VPS 的坏人,就算猜出、枚举出 VPS 的密码由于没有手机上 Google Authenticator 的验证码,就没办法了……
三、用 Google Authenticator 增强 WordPress 安全性
SSH 登录已经有 Google Authenticator 保护了,但是服务器运行的程序还没有,比如 WordPress。相对于 MySQL 漏洞攻击等高难度操作,我觉得 WordPress 被攻破的可能性更大:毕竟也只有一个短短的密码保护着。好在由于 WordPress 是“大路货”,用的人很多,插件自然也不少,有人便开发出了 WordPress 用的 Google Authenticator 的插件。启用方法如下:
- 在 WordPress 后台搜索并安装 Google Authenticator 这个插件,启用之。
- 在 WordPress 后台个人 Profile 页面 Google Authenticator Settings 选项下,选中 Active,填好 Description(只是在手机上显示的名字而已),再点击 Show/Hide QR Code。
- 在 Google Authenticator 应用程序中扫描这个 QR 码以添加账号,或者手工输入 Secret 也行。
配置成功以后,再登录 WordPress 后台的时候就会是这样的:
不输入正确的 Google Authenticator code 是不能登录的。当然在自己的电脑上是可以勾选 Remember Me 以减少麻烦的。
四、用 Google Authenticator 增强桌面电脑的安全性?
本文第二节讲了如何把 Authenticator 用在 VPS 上以增强 SSH 登录时的安全性。自然,Authenticator 也是能用在装有 GNU/Linux 的桌面电脑上的。安装模块的方法和在 VPS 上是一样的,手机上配置也是一样,但是调用的时候是不同的。
进入 /etc/pam.d/ 目录,可以看到一些文件:
wzyboy@vermilion:/etc/pam.d$ ls atd common-password lightdm-autologin ppp chfn common-session login samba chpasswd common-session-noninteractive newusers sshd chsh cron other su common-account cups passwd sudo common-auth lightdm polkit-1 xscreensaver
这些文件从文件名就能看出它们是干嘛的:控制一些重要操作的认证。在 VPS 中,我们在 sshd 中添加了 auth required pam_google_authenticator.so 这一行,于是在 SSH 登录的时候就会调用 Authenticator 来认证。在别的文件中加入 auth required pam_google_authenticator.so 这一行的话,就会在相应的操作中调用 Authenticator 来认证了。下面是几个重要的:
- lightdm。这个会使通过图形界面登录的时候要求输入验证码,效果如下:
输入密码之后还要再输入验证码:
需要注意的是,lightdm 只是 Ubuntu 11.10 和 Xubuntu 11.10 及以上版本默认的显示管理器,其他的发行版可能是 gdm、kdm 等,请自行修改。 - xscreensaver。这个会使屏保解锁的时候也要输入密码和验证码,效果如下:
→ - login。这个会使在字符界面下(如 tty)登录的时候也会要求输入验证码。
- passwd。这个会使设置用户密码的时候要求输入验证码。
- sudo。这个会使普通用户试图提权执行系统操作的时候要求输入验证码。很适合给多人共享电脑用。
当然,如果你的电脑像我一样装了 OpenSSH Server 的话,也可以在 sshd 中加入 auth required pam_google_authenticator.so 这一行,使坏人无法从公网上登录你的电脑。
五、尾声
相对前几篇博客,这篇博客写得有一些仓促。并且,教程的内容并不怎么复杂,Linux 的高级用户肯定都会的,所以本文的目标读者只能是刚接触 Linux VPS 的用户了,希望能帮到他们。