影响到1.43亿客户记录的Equifax数据泄露事件,现在恐怕无人不知了。Equifax报告称,攻击者使用了编号为CVE-2017-5638的Apache Struts漏洞。
Equifax并没有在容器中运行其脆弱Struts应用,但如果他们这么做了呢?容器当然更加安全,于是整个糟糕的情况就可以避免掉了,对吧?
未必。
容器固有的基础设施即代码,具有多个安全优势。连续设置部署新容器是标准操作,因而部署补丁完善的软件所面临的宕机风险也就更小。一般都会从干净的容器开始,所以用不着修复已经被破坏的系统。这也意味着,通常情况下,容器的生命周期比服务器要短,攻击者能够使用驻留后门或继续深入网络的时间段,也就更短了。
另外,每部署一个新容器都要漏洞利用一次,反复进行漏洞利用,也会增加被其他安全解决方案发现的风险,比如IDS/IPS或者文件完整性监视等。
容器安全优势突出,特别是与主机进程和网络的隔离。然而,错误配置或疏忽大意,仍然会危及本应安全的态势。
保护Docker安全,与保障传统基础设施安全,有很多相通之处。不过,面临的挑战虽相似,Docker安全也有其独有的一些困难。
1. 提权攻击
Docker安全防御面临的一个常见威胁,就是提权攻击。攻击者的目标是突破容器,获得Docker主机的访问权;他们有大把机会这么做。
2. 漏洞
Linux内核中的漏洞,比如广为人知的“脏牛”漏洞,可被用于提权,从容器染指主机。应使用漏洞管理工具,来确保主机及其上容器均打完补丁,没有漏洞。
3. 文件系统挂载
将主机文件系统挂载到容器,容器便可以写入主机文件了。如果挂载太过宽泛,或者配置有误,攻击者会有大把机会利用各种文件写入方法来提权。重要的主机系统目录绝对不能挂载到容器中。
4. 特权用户
由于上述文件系统滥用可能性的存在,可以运行Docker容器的主机用户,便成了实际上的root用户。一定不能让非root用户来运行Docker容器,或者把他们加入到Docker用户组里。
Docker Daemon 具有为Docker进程指定用户名字空间的 -userns 选项。启用用户名字空间选项时,容器中的root用户会被映射成主机上的非特权用户。使用非特权用户名字空间,是抵御提权攻击的重要防御措施。
Docker运行时也提供 -user 选项,可用于以非特权用户在容器内执行命令,而不是以默认的root用户来执行。正如我们这数十年来习得的安全操作——没必要用root用户的时候就不要用。同样的逻辑也适用于容器使用。
5. 特权容器
以Docker的 -privileged 标记运行的容器,可以控制设备,并如上文所述进行基于文件系统的攻击;此类容器对主机资源的访问权,几乎与主机本身一样。特权容器可用于嵌套Docker-in-Docker,但使用该功能时必须极度小心。
6. 拒绝服务
默认情况下,容器对所使用的资源没有任何限制。这就很容易导致拒绝服务的情况。有必要对失控的资源使用采取缓解措施,比如Docker cgroup 功能。
7. CPU耗尽
失控的计算过程,可耗尽主机上所有可用CPU资源。可对每个容器定义 -cpus 或-cpu-quota,以限制该容器可用的最大主机处理器时间。
8. 内存耗尽
Docker提供 -memory 运行时选项,可以限制每个容器可用的最大内存。
9. ULIMITS
恶意或被入侵容器,可能采用简单的fork炸弹攻击,让主机系统完全无法响应。Docker提供了 -ulimit 运行时选项,对每个容器可打开文件及进程的数量加以限制,让它们无法搞瘫主机。
10. 横向移动
横向移动是描述攻击者在被黑系统间跳转的术语,用于横向移动的技术,同样适用于容器空间。默认情况下,所有Docker容器都能相互通信。使用Docker的 -icc、-link 和 -iptables 标识,你就对容器内相互通信有了细粒度控制,可以防止从被黑容器发起的网络攻击,让主机和网络更加安全。
总结
本文开头,我们提出了在容器中运行 Apache Struts 是否能避免1.43亿客户记录被泄的问题。
文中也提出了多种缓解措施,但我们无法确知哪些方法在我们设想的场景中被用到。使用容器,采用上述任何配置建议,都有可能阻碍或阻止攻击者,争取到更多的发现时间,或者干脆让他们放弃攻击而转向其他更容易得手的目标。
文中提到的漏洞,CVE-2017-5638,可使脆弱系统上的Webserver用户得以执行任意指令或运行任意程序。因此,可能的结果就是,只能以容器中受限Webserver用户权限执行指令的攻击者,却依然对客户记录拥有访问权。该Webserver用户必能访问数据,无论存储在本地,还是需要凭证和权限从数据库或网络中取得。
只有系统从一开始就是最新的,才有可能避免被黑。采用漏洞管理解决方案,比如 Tripwire IP360,有助确定主机及容器中是否存在漏洞。使用Docker的基础设施即代码和连续部署功能,可以增加部署出补丁完备容器的概率,或者更早发现攻击。
很明显,从一开始就确保系统和应用保持更新,是最佳防线。请务必从最初就考虑到安全,并在安全运维开发周期的每一阶段都严格应用安全方法。
于是,容器真的是安全救星吗?可能吧,看你怎么做了。