本文译自Docker官方文档:https://docs.docker.com/articles/security/
在审查Docker的安全时,需要斟酌3个主要方面:
?容器内在的安全性,由内核命名空间和cgroup中实现;
?docker守护程序本身的攻击面;
?加固内核安全特性,和它们如何与容器中互动。
Docker容器中非常类似LXC容器,并且它们都具有类似的安全功能。当您以“docker run”启动1个容器,后台Docker为容器创建1组命名空间和控制组的集合。
命名空间提供隔离的最初也是最简单的情势:1个容器中运行的进程看不到运行在另外一个容器中或在主机系统中的进程,乃至它们之间更少的影响,。
每一个容器也都有自己的网络协议栈,这意味着容器没有得到特权访问另外一个容器的套接字或接口。固然,如果主机系统是设置因此,容器中可以相互通过各自的网络接口进
行交互 - 就像他们可以与外部的主机进行交互。当您为您的容器中或使用链路指定公共端口则IP通讯允许容器之间。他们可以相互ping通,发送/接收UDP数据包,并建立
TCP连接,但可以在必要时会遭到限制。从1个网络架构来看,给定Docker主机上的所有容器都坐在桥接接口。这意味着,他们只是想通过1个普通的以太网交换机连接的物
理机器;不多,不会少。
代码是如何成熟提供内核命名空间和专用网络?内核命名空间的内核版本2.6.15和2.6.26之间进行了介绍。这意味着,自2008年7月(2.6.26发布日期,现在5年前),命名
空间代码已实行和审查上有大量的生产系统。还有更多:设计灵感的命名空间代码,乃至更老。命名空间实际上是为了重新实现的,由于它们可能被主流内核内合并这样
的方式的OpenVZ的特性。OpenVZ的最初发布于2005年,所以在设计和履行都相当做熟。
控制组是Linux的容器的另外一重要组成部份。他们实行资源核算和限制。他们提供了很多非常有用的指标,但他们也有助于确保每一个容器取得其公平的内存,CPU,磁盘同享
I/O;并且,更重要的是,1个单1的容器不能用尽这些资源中的1个而使系统瘫痪。
因此,虽然它们不起到避免1个容器访问或影响数据和另外一个容器的进程的作用,它们是必不可少的,以抵挡谢绝服务的1些攻击。他们是在多租户平台,像公共和私有
PaaS尤其重要,以保证正常运行时间1致(和性能),即便1些利用开始胡作非为。
控制组已存在了1段时间,和:代码在2006年已开始,并在内核2.6.24开始合并。
运行容器(和利用程序)与Docker意味着运行Docker守护进程。此守护进程目前需要root权限,因此,你应当知道的1些重要的细节。
首先,只有受信任的用户应当可以控制你的Docker守护进程。这是直接造成1些强大的Docker功能。具体来讲,Docker可让你分享的Docker主体和客体容器之间的目录;它
允许你这样做不限制容器的访问权限。这意味着,你可以开始1个容器,其中/host目录将是你的主机上的/目录下;并且容器将能够改变你的主机文件系统没有任何限制。这
听起来很疯狂?好吧,你要知道,所有的虚拟化系统允许文件系统资源同享的行动方式相同。没有甚么能禁止你从1个虚拟机同享您的根文件系统(乃至是你的root块装备
)。
这具有很强的安全性含义:例如,如果从通过API的Web服务器来提供容器中工具Docker,你应当比平常使用参数检查多加谨慎,以确保歹意用户没法通过精雕细琢的参数引
起Docker创建任意容器。
出于这个缘由,所述的REST API端点(所使用的DockerCLI与Docker守护程序进行通讯)中Docker0.5.2改变,现在采取的是UNIX套接字代替结合在127.0.0.1 TCP套接字(后
者是容易跨站点脚本攻击,如果你碰巧直接在本地计算机上运行Docker,1个VM以外)。然后,您可使用传统的UNIX权限检查限制访问控制套接字。
您也能够通过暴露在HTTP REST API,如果你明确决定等。但是,如果你这样做,意想到上述的安全含义,你应当确保它会到达只能从1个可信任的网络或VPN;或受保护的如
与安全通道和客户真个SSL证书。你也能够保证他们HTTPS和证书。
在Linux的命名空间中的最新改进将很快允许没有root权限运行全功能的容器中,这要归功于新的用户空间。这是覆盖在这里详细。另外,这将解决由同享主机和客户之间的
文件系统的问题,由于用户命名空间允许容器(包括root用户)内的用户被映照到在主机系统的其他用户。
因此,终究目标是Docker要实现两个额外的安全性改进:
?映照容器的root用户的Docker主机的非root用户,以减少容器到主机的权限提升的效果;
? 允许docker守护程序没有root权限运行,并拜托操作要求这些特权和审计的子流程,每一个都有自己的(非常有限)适用范围:虚拟网络设置,文件系统管理,等等。
最后,如果在服务器上运行Docker,建议以在服务器上运行专门Docker,并且通过Docker控制容器中内移动的所有其他服务。固然,这是好的,让您最喜欢的管理工具(可
能最少SSH服务器),和现有的监测/监控进程(例如,NRPE,collectd等)。
默许情况下,Docker开始容用具有非常有限的功能集。这意味着甚么?
功能打开2进制“root/非root”2分法成细粒度的访问控制系统。进程(如Web服务器),仅仅需要绑定低于1024的端口上没有以root身份运行:他们可以被授与
net_bind_service能力来代替。而且还有很多其他功能,几近所有的地方,通常都需要root权限的具体领域。
这意味着许多为docker的安全;让我们来看看为何!
1般的服务器(裸机或虚拟机)都需要运行1堆流程作为root。这些通常包括SSH,cron,syslogd;硬件管理工具(如加载模块),网络配置工具(如处理DHCP,WPA或VPN)
的,等等。容器是非常不同的,由于几近所有的这些任务由容器周围的基础设施进行处理:
?SSH访问通常由Docker主机运行的单个服务器进行管理;
?cron,必要的时候,应当运行作为1个用户进程,敬业,专为需要它的调度服务,而不是作为1个平台性的装备利用程序;
?日志管理层也通常会被交给Docker,或由第3方服务,如Loggly或Splunk的;
?硬件管理是无关紧要的,这意味着你永久不需要容器中运行udevd会或同等守护进程;
?网络管理产生在容器外,履行的尽量多的分离关注点,这意味着容器不应当需要履行ifconfig,route,或IP命令(除当1个容器是专为像1个路由器或防火墙,固然
)。
这意味着,在大多数情况下,容器将不会在所有需要的“真实”root特权。因此,容器可使用减少的能力集运行;这意味着“root”在1个容器内具有比真实的“root”少很多特
权。例如,它是可能的:
?谢绝所有“装载”操作;
?谢绝访问原始套接字(避免数据包欺骗);
?谢绝访问某些文件系统操作,如创建新的装备节点,改变文件的所有者,或改变属性(包括不可变标志);
?谢绝模块加载;
?和等等。
这意味着,即便入侵者想法升级到root的容器内,这将是非常困难做严重破坏,或升级到主机。
这不会影响常规的网络利用;但歹意的用户会发现,军工厂在他们的处置大幅降落!默许情况下,Docker滴除那些需要的,白名单,而不是黑名单的方式全部功能。你可以
看到在Linux中提供联机帮助功能的完全列表。
固然,你可以随时启用额外的功能,如果你真的需要它们(举例来讲,如果你想使用FUSE为基础的文件系统),但默许情况下,Docker容器使用默许的核心能力,只有白名
单。
Capabilities 能力是现代Linux内核提供了许多安全特性之1。另外,也能够利用现有的,公知的系统,如TOMOYO,AppArmor,SELinux,GRSEC等使用Docker。
而Docker目前只允许功能,它不干扰其它系统。这意味着,有许多不同的方式来加固Docker主机。下面是1些例子。
?您可以运行GRSEC和PAX内核。这将增加很多安全检查,不管是在编译时和运行时;它也将打败很多漏洞,这要归功于像地址随机化技术。它不需要Docker特定的配置中,由
于这些安全功能适用全系统,独立的容器中。
?如果你的发行版自带的Docker容器安全模型模板,你可使用它们的开箱即用。举例来讲,推出1个与AppArmor工作和Red Hat自带SELinux策略Docker的模板。这些模板提
供了1个额外的安全网(即便它大大堆叠使用能力)。
?您可使用自己喜欢的访问控制机制,定义自己的策略。
就像有许多第3方工具来增强Docker容器如特殊的网络拓扑结构或同享文件系统,你可以期望看到的工具来强化现有的Docker容器,而不会影响Docker的核心。
Docker容器,默许情况下,相当安全的;特别是如果你把你的运行进程容器非特权用户内部的护理(即非root)。
您可以通过启用AppArmor中,SELinux,GRSEC,或你最喜欢的加固解决方案中添加额外的安全层。
最后但并不是最不重要的,如果你看到在其他容器化系统,有趣的安全功能,您将能够实现它们,和使用Docker,由于1切不管如何都是由内核提供。
欲了解更多情况下,特别是与虚拟机和其他容器系统的比较,也请看到原来的博客文章:http://blog.docker.com/2013/08/containers-docker-how-secure-are-they/。