移动安全 安全管理 应用案例 网络威胁系统安全 应用安全 数据安全 云安全
当前位置: 主页 > 信息安全 > 系统安全 >

为Apache和SSH搭建双因子验证系统

时间:2014-06-04 13:23来源:TuZhiJiaMi企业信息安全专家 点击:
如果你在运行一台公众可以访问,但仅供自己使用的Web服务器(咱们实话实说吧,如果你在阅读本文,很有可能运行这样一台服务器),那么你该如何着手限制有人访问你网站、搞破坏活动的风险
Tags系统安全(735)SSH(4)apache(6)  

  如果你在运行一台公众可以访问,但仅供自己使用的Web服务器(咱们实话实说吧,如果你在阅读本文,很有可能运行这样一台服务器),那么你该如何着手限制有人访问你网站、搞破坏活动的风险?SSH又如何呢?SSH是更大的隐患!在如今这个环境下,有必要考虑你面临的风险,并采取必要的措施,尽可能减小风险。

  我在本教程中将详细介绍具体的步骤,以便实施一套自行搭建的双因子验证系统,以便用于访问你的网站和用于SSH访问。

  基础设施和“挑战”

  运行自己的硬件可能令人讨厌。你在处理风扇失效、电源失效和硬盘坏掉等各种硬件故障后,最终可能决定丢弃你在托管中心或自家卧室的机柜和硬件,毅然决然地投入弹性计算的怀抱。亚马逊的EC2平台就是这样一种选择,该平台提供了众多Linux版本,拥有市面上最可靠、最成熟的云平台之一。我可不是亚马逊的代表,但我还是要说试一试。这个产品很出色,微实例(micro instance)可以免费使用一年。

  在针对本文的测试场景下,我使用了一台运行Ubuntu 12.04 LTS的亚马逊EC2服务器,来托管运行几个Web应用程序。如果你使用不同的Linux版本,那么操作步骤只需稍加改动,就能满足你的具体要求。假设这些应用程序多半仅供个人使用。要是只从办公场所或家里访问网站,你只要创建防火墙规则,只允许从那些IP地址访问Web流量,就可以为网站保驾护航。捎带提一下,这正是你确保SSH安全的做法。

  不过,假设这个做法并不适合你的Web应用程序,因为你频繁出差,出门在外时需要也能够访问那些应用程序,所以单单几个防火墙规则帮不了你。另外假设,你的应用程序有自己的安全系统,但是你仍想要一层额外的安全机制。

  你可以搭建一台虚拟专用网(VPN)服务器,但你可能想让家庭成员访问其中一个网站,所以VPN方法行不通。

  可以考虑的另一个方法是使用谷歌身份验证器(Google Authenticator),实现真正的双因子验证。你当然可以选择走这条路,但你寻求的是能自己动手做的系统,独立的、属于你的系统。

  就跟Linux领域的许多事情一样,只要有意愿,办法总归有的!结果证明,你很容易就能组建自己的双因子验证解决方案,并用它来控制对你的Web应用程序和SSH的访问,同时又可以允许其他用户偶尔访问你的网站。

  Apache验证和授权

  由于本例子中的Web服务器是Apache服务器,不妨充分利用该服务器的验证和授权功能,要求用户先提供一系列登录凭证,之后你的任何网站才提供服务给用户。

  为了力求简单,又由于你会遵守最佳实践,只允许https流量进出你的Web服务器,不妨使用mod_auth_basic模块用于验证。

  首先成为根用户,在你全新安装的Ubuntu上安装Apache:

  sudo su

  apt-get install apache2

  假设你的Web应用程序在主www文档文件夹的子文件夹中运行。这样你只要在http服务器的根文件夹里面创建一个.htaccss文件,就可以管理你的所有网站:

  vim /var/www/.htaccess

  现在,不妨添加几行,命令Apache要求验证、哪里寻找密码文件:

  AuthType Basic

  AuthName "restricted area"

  AuthUserFile /home/ubuntu/.htpasswd

  require valid-user

  这一步完成后,现在你需要更改文件的所有权,以便Apache进程能读取文件内容:

  chown www-data:www-data /var/www/.htaccess

  下一步,你需要创建在.htaccess文件中参照的.htpasswd文件,并且配置其所有权,以便Web服务器能读取该文件:

  htpasswd -cb /home/ubuntu/.htpasswd jameslitton test123

  chown www-data:www-data /home/ubuntu/.htpasswd

  现在,你需要命令Apache要求验证、使用用于验证的mod_auth_basic模块:

  vim /etc/apache2/sites-available/default-ssl

  然后,你需要将AllowOverride None改成AllowOverride AuthConfig:

  Service apache2 restart

  现在访问你的网站会提示输入用户名和密码(见图1)。

为Apache和SSH搭建双因子验证系统

  图1:来自mod_auth_basic的验证请求

  每天一次的密码/PIN

  我在这里要采用的方法是,让你的辅助验证密码每天更改一次,而不是更频繁地更改。这让上述的mod_auth_basic方法得以奏效。我不会在此深入探讨细节,但就一句话:每当密码更改,就需要立即重新验证,这可不是你所需要的那种行为。

  假设我们采用一个六个数的数字PIN码,在每天半夜这个时段将该PIN发送到手机上。我非常喜欢Pushover,这项服务可以从你自己的脚本和应用程序,将即时通知迅速发送到手机和平板电脑上。

  为了实现这个机制,创建一个bash脚本:

  vim /home/ubuntu/2fac.sh

  现在,添加下面几行:

  1 #!/bin/bash2 ppwd=`od -vAn -N4 -tu4 < /dev/urandom | tr -d '\n' | tail -c 6`3 curl -s -F "token=id" -F "user=id" -F "message=$ppwd" &rarrhk;https://api.pushover.net/1/messages.json4 htpasswd -b /home/ubuntu/.htpasswd jameslitton $ppwd5 echo $ppwd | base64 >/home/ubuntu/.2fac

  第2行生成一个随机性的六位数PIN码,并将其分配给一个名为ppwd的变量。第3行将PIN发送到Pushover服务,以便进而将PIN发送到你的手机。第4行用新密码更新.htpasswd文件;最后但并非最不重要的是,第5行以一种可以恢复的方式保存PIN的副本,你在后文会有所看到。

  现在,保存脚本,让它成为可执行脚本:

  chmod +x /home/ubuntu/2fac.sh

  想完成该解决方案的最后一步,你只要通过计划任务(cron),安排脚本在每天半夜运行:

  crontab -e

  00 00 * * * /home/ubuntu/2fac.sh

  让它可以通过Web访问

  当然你可以不用管它,就算大功告成,但假设你没有收到PIN码、想要强行更改。或者可能你之前允许某人临时访问你的网站,但现在想强行更改密码,确保那个人再也无法访问网站。你总是可以使用SSH连接到服务器,并且手动运行脚本,但这太费劲了。不妨创建一个可以通过Web访问的PHP脚本,让它替你处理这一切。

  首先,更改2fac.sh脚本的所有权,那样你的Web服务器就能运行它:

  chown www-data:www-data /home/Ubuntu/2fac.sh

  现在,你需要创建一个新的文件夹来放置脚本,并创建PHP脚本本身,允许新的“密钥”可以手动运行:

  mkdir /vaw/www/twofactorvim /var/www/twofactor/index.php1

  由于这可以想象:由于未收到之前的密钥,你需要强行使用一个新密钥,就需要确保放置该脚本的那个文件夹不需要验证。为此,你需要改动Apache配置:

  vim /etc/apache2/sites-available/default-ssl

  现在,在/var/www的Directory命令下面添加下面内容:

   satisfy any

  现在不妨配置所有权、重启Apache:

  chown -R www-data:www-data /var/www/twofactorService apache2 restart

  所以彻底考虑这点后,可以想象:Pushover服务可能完全无法使用。这会让你面临糟糕的情形:你无法访问自己的网站。应该针对这种场景为紧急情况做好准备。

  为此,不妨建立第二个脚本,以便获取你PIN的副本(别忘了之前保存的.2fac文件),然后通过电子邮件发给你。在本例中,不妨使用移动运营商的电子邮件至短信网桥功能,以短信方式将信息发给你。

  开始安装mailutils,如果你之前还没有安装的话;务必要选择互联网选项:

  apt-get install mailutils

  现在,创建第二个脚本:

  vim /home/Ubuntu/2fac2.sh

  然后,添加代码:

  #!/bin/bashppwd=`cat /home/ubuntu/.2fac | base64 --decode`echo " " | mail -s $ppwd xxx5551212@vtext.com

  别忘了更改文件的所有权:

  chown www-data:www-data /home/ubuntu/2fac2.shchown www-data:www-data /home/ubuntu/.2fac

  完成这一步后,现在你需要改动PHP脚本:

  vim /var/www/twofactor/index.php

  把第2行换成下列:

  2 if (isset($_GET["sms"])) {3 exec('/home/ubuntu/2fac2.sh');4 } else {5 exec('/home/ubuntu/2fac.sh');6 }

  然后,创建两个书签,那样无论何时你想生成一个新的PIN,并通过Pushover发送给自己,只需点击链接,就大功告成了。万一出现Pushover服务无法使用这种小几率情形,第二个书签会将现有PIN的副本发送到你所选择的电子邮件地址。

  2Factor = https://www.thelittonfamily.com/twofactor/index.php 2Factor-SMS = https://www.thelittonfamily.com/twofactor/index.php?sms=1

  扩展到SSH

  扩展该解决方案以涵盖SSH其实相当简单。关键在于使用sshd_config文件中不大知名的ForceCommand命令。这迫使SSH守护程序在生成终端会话之前运行脚本。

  不妨从这个脚本开始:

  vim /home/ubuntu/tfac-ssh.sh

  现在,添加下面几行:

  1 #!/bin/bash2 code=`cat .2fac | base64 --decode`3 echo -ne "Enter PIN: "4 while IFS= read -r -s -n1 pass; do5 if [[ -z $pass ]]; then6 echo7 break8 else9 echo -n '*'10 input+=$pass11 fi12 done13 if [ $code = $input ];14 then15 sleep 116 clear17 /bin/bash18 else19 sleep 120 curl -s -F "token=id" -F "user=id" -F "message=$input" &rarrhk;https://api.pushover.net/1/messages.json21 fi

  第2行将PIN装入到一个变量。第3行至第12行提示输入PIN,并针对每次按键回送一个星号。第13行将用户输入的PIN与PIN进行比对。如果两者匹配,第14行至第17行就会清空屏幕,启动bash会话。要是用户输入的PIN与PIN不匹配,第18行至第21行就发送通知到Pushover,那样你知道发生了故障,然后结束会话。

  不妨配置SSH守护程序以运行脚本:

  vim /etc/ssh/sshd_config

  现在,将下面这一行添加到文件顶部:

  ForceCommand /home/ubuntu/tfac-ssh.sh

为Apache和SSH搭建双因子验证系统

  图2:来自SSH的双因子验证请求

  这个方法很管用。唯一的局限在于没有退格。如果你按错了键,会话就会被终结,你就只好重新试一下。

  就这样,这是一种简易的双因子验证系统,根本不需要花多大力气;根据我的经验,它运行起来非常可靠!

------分隔线----------------------------

推荐内容