天天看点

DockerCon 2016 深度解读: Docker安全前言容器技术Linux系统的安全技术Docker的安全Docker镜像安全安全生态总结

本文将介绍docker安全相关的一些技术,安全生态和最新的安全特性。

容器技术最早可以追述到1979年在unix上的chroot。linux的目录结构从根目录<code>/</code>开始,根目录下是<code>boot</code>, <code>usr</code>, <code>var</code>, <code>proc</code>等目录。chroot可以改变程序的根目录,对于程序来说它看的根目录并不是系统真正的根目录,只是管理员额外准备的一套目录结构。这么做的一个重要原因就是安全:chroot之后的程序没法访问真实系统的的目录结构和文件。

这种技术和思想经过发展,最后成为了linux上的<code>namespace</code>,除了文件系统之外,还可以隔离pid、ipc、网络等。namespace和用于管理资源cgroup一起构成了linux上的容器技术。容器技术也叫操作系统级虚拟化,对于运行在其中的进程来说,就像运行在一台单独的机器上一样,它只能看到自己容器的进程、只能看到自己的目录结构,只能看到自己的网络栈,甚至资源也是有限制的,占用的内存超过了就会被kill。除了虚拟化,允许同时运行多个应用而不相互干扰,容器技术还带来了巨大的安全性。

使用容器虽然增强了安全性,但还远远不够。没有哪个软件是完美的,linux内核也一样,容器也不能完全限制运行在其中的进程,曾经有漏洞允许进程可以突破容器访问到宿主机上的资源。除了程序漏洞之外,容器之间共享同一个linux内核,容器可以直接操作内核,可以通过内核漏洞对系统进行攻击。

docker刚出来的时候,我曾说过docker=容器+镜像,虽然完全是出于程序员的思维习惯,从技术实现的角度所作出的评价,不过有助于我们理解背后的原理。由于docker是基于容器的,天生具有容器带来的安全优势:可以虚拟一个隔离的运行环境,可以限制资源。但是对于容器不能解决的安全问题:逃逸和共享内核,docker解决了吗?有没有其他新的安全问题?

docker一直很关注安全的问题,早期的版本就支持设置capabilities,通过drop掉一些capabilities,可以削弱运行在容器中的进程权限。docker提供了方便和lsm集成的机制,可以更容易配置selinux或者apparmor,增强容器安全性。

DockerCon 2016 深度解读: Docker安全前言容器技术Linux系统的安全技术Docker的安全Docker镜像安全安全生态总结

上图是docker/lxc/coreos rkt所支持的安全特性对比。

对于镜像完整性,docker主要提供了两方面的功能:registry v2引入的内容可寻址镜像存储和镜像签名。继续之前,我们先简单的回顾下镜像下载过程(registry v2):

下载manifest,manifest里包含了镜像的一些元信息,以及所有组成这个镜像的层id。层id是层内容的sha256摘要(也就是内容可寻址)。

下载各个层。

客户端下载镜像之后,重新计算sha256,如果不匹配层id,则校验失败,这种方式既解决了传输过程中的数据篡改,也解决了层内容损坏。

镜像签名保证了镜像分发过程中的完整性。在分发过程中,中间人可以修改层内容,同时把manifest也改掉,对下载镜像的客户端来说,sha256校验完全没有问题,但是下载到的镜像已经不是期望中的那个镜像,里面不知道放了一些什么奇怪的东西。有了镜像签名之后,镜像构建者在manifest里加上自己的数字签名,客户端可以下载manifest之后根据签名验证manifest是否被篡改过。

twistlock和aqua的产品功能很像,都提供了镜像扫描、运行时容器扫描、访问控制等功能。这里的访问控制是接管了docker控制api,也就是说不直接访问docker,而是先访问twistlock或者aqua的程序,由它们把请求转发给docker,转发之前,会对请求进行一些权限检查等操作。

DockerCon 2016 深度解读: Docker安全前言容器技术Linux系统的安全技术Docker的安全Docker镜像安全安全生态总结

twistlock架构:由控制台和运行在docker机器上的agent组成

docker安全是个很大的话题,涉及从操作系统内核到企业安全策略,包括数据、网络、存储等各种安全方案,本文只能作为一个最简单的介绍。

总得来说,使用docker,首先千万不要把对daemon的访问不加防护的暴露到公网,就行本文开头提到的。其次,如果是多租户环境或者对运行环境安全要求高的场景,考虑各种内核安全方案配合使用,做到纵深防御。或者使用虚拟化+轻量级内核的方式。最后,使用镜像扫描工具,不要让对外提供的服务存在安全缺陷。