©
本文档使用
php.cn手册 发布
在审查Docker安全性时,需要考虑四个主要方面:
内核的内在安全性及其对命名空间和cgroups的支持;
Docker守护进程本身的攻击面;
容器配置文件中的漏洞,默认情况下或用户自定义时。
内核的“hardening”安全功能以及它们如何与容器交互。
Docker容器与LXC容器非常相似,并且它们具有类似的安全功能。当你启动一个容器时docker run
,Docker会在后台创建一组容器的命名空间和控制组。
命名空间提供了第一个也是最直接的隔离形式:在容器中运行的进程看不到,甚至更少影响在另一个容器或主机系统中运行的进程。
每个容器也都有自己的网络堆栈,这意味着容器不会获得对另一个容器的套接字或接口的特权访问。当然,如果主机系统相应设置,容器可以通过各自的网络接口相互交互 - 就像他们可以与外部主机进行交互一样。当您为容器指定公共端口或使用链接时,容器之间允许IP流量。它们可以互相ping通,发送/接收UDP数据包,并建立TCP连接,但如果需要可以限制它们。从网络体系结构的角度来看,给定Docker主机上的所有容器都位于网桥接口上。这意味着它们就像通过普通以太网交换机连接的物理机器一样; 不多也不少。
提供内核命名空间和专用网络的代码有多成熟?在内核版本2.6.15和2.6.26之间引入了内核命名空间。这意味着自2008年7月(2.6.26发布日期)以来,命名空间代码已在大量生产系统上得到运用和审查。还有更多:命名空间代码的设计和灵感甚至更老。命名空间实际上是为了重新实现OpenVZ的功能,以便它们可以在主流内核中合并。OpenVZ最初于2005年发布,因此设计和实现都相当成熟。
控制组是Linux容器的另一个关键组件。他们实施资源会计和限制。它们提供了许多有用的度量标准,但它们也有助于确保每个容器获得其公平的内存,CPU和磁盘I/O份额; 更重要的是,单个容器不能耗尽这些资源中的一个来降低系统的性能。
因此,尽管它们不能阻止一个容器访问或影响另一个容器的数据和进程,但它们对抵御一些拒绝服务攻击至关重要。它们对于多租户平台尤其重要,例如公共和私有PaaS,即使在某些应用程序开始出现故障时也能保证一致的正常运行时间(和性能)。
控制组也有一段时间了:代码是在2006年开始的,最初被合并到内核2.6.24中。
使用Docker运行容器(和应用程序)意味着运行Docker守护进程。这个守护进程当前需要root
特权,因此你应该知道一些重要的细节。
首先,应该只允许受信任的用户来控制你的Docker守护进程。这是一些强大的Docker功能的直接后果。具体来说,Docker允许您在Docker主机和访客容器之间共享一个目录; 它允许您在不限制容器访问权限的情况下这样做。这意味着您可以启动一个容器,其/host
目录将成为/
主机上的目录; 容器将能够不受任何限制地改变你的主机文件系统。这与虚拟化系统如何允许文件系统资源共享类似。没有什么能够阻止你与虚拟机共享你的根文件系统(甚至你的根块设备)。
这具有很强的安全意义:例如,如果您通过Web服务器来监控Docker以通过API配置容器,则应该比平时更加仔细地进行参数检查,以确保恶意用户无法传递制作的参数,从而导致Docker创建任意容器。
出于这个原因,Docker 0.5.2中更改了REST API端点(由Docker CLI用于与Docker守护进程通信),现在使用UNIX套接字而不是127.0.0.1上绑定的TCP套接字(后者容易发生如果您碰巧在您的本地机器上直接运行Docker,而不是在虚拟机之外),则可以发起跨站请求伪造攻击。然后,您可以使用传统的UNIX权限检查来限制对控制套接字的访问。
如果您明确决定这么做,您还可以通过HTTP公开REST API。但是,如果您这样做,意识到上述安全隐含意义,则应确保它只能从可信网络或VPN访问; 或受到例如stunnel
和客户端SSL证书的保护。您还可以使用HTTPS和证书保护他们。
守护进程也可能容易受到其他输入的影响,例如从磁盘docker load
或从网络加载磁盘的映像docker pull
。从Docker 1.3.2开始,图像现在在Linux/Unix平台的chrooted子进程中提取,这是实现特权分离更广泛工作的第一步。从Docker 1.10.0开始,所有图像都通过其内容的加密校验和进行存储和访问,从而限制了攻击者与现有图像发生冲突的可能性。
最终,预计Docker守护进程将运行受限特权,将操作委托给审核良好的子进程,每个子进程都有其自己的(非常有限的)Linux功能范围,虚拟网络设置,文件系统管理等。也就是说,大多数很可能,Docker引擎本身的部分将运行在容器内部。
最后,如果您在服务器上运行Docker,则建议在服务器上专门运行Docker,并将所有其他服务移动到由Docker控制的容器中。当然,保留你最喜欢的管理工具(可能至少是一个SSH服务器)以及现有的监控/监督流程(如NRPE和collectd)是很好的。
默认情况下,Docker使用一组受限制的功能启动容器。那是什么意思?
功能将二元“root/non-root”二分法转变为一个细粒度的访问控制系统。只需要在1024以下的端口上绑定的进程(如Web服务器)不必以root用户身份运行:他们可以net_bind_service
改为授予权限。对于几乎所有需要root权限的特定领域,还有许多其他功能。
这对于容器安全意义重大。让我们看看为什么!
您的平均服务器(裸机或虚拟机)需要以root身份运行一系列进程。那些通常包括SSH,cron,syslogd; 硬件管理工具(例如加载模块),网络配置工具(例如处理DHCP,WPA或VPN)等等。容器是非常不同的,因为几乎所有这些任务都由容器周围的基础设施处理:
SSH访问通常由Docker主机上运行的单个服务器管理;
cron
在必要时应该作为用户进程运行,专门针对需要其调度服务的应用程序专门定制,而不是作为平台范围的设施;
日志管理通常也会交给Docker,或者由Loggly或Splunk等第三方服务提供;
硬件管理是无关紧要的,这意味着你永远不需要udevd
在容器中运行或等效的守护进程;
网络管理发生在容器的外面,执行关注点分离尽可能的,这意味着一个容器不应该需要执行ifconfig
,route
或IP命令(当容器被特别设计,以表现得象一个路由器或防火墙除外,当然) 。
这意味着,在大多数情况下,容器将不再需要“真正的” root特权可言。因此,集装箱可以运行一个能力较低的集合;这意味着容器中的“根”比真正的“根”要少得多。例如,有可能:
否认所有“mount”操作;
拒绝访问原始套接字(以防止数据包欺骗);
拒绝访问某些文件系统操作,如创建新设备节点,更改文件所有者或更改属性(包括不可变标志);
拒绝模块加载;
和其他许多。
这意味着即使入侵者设法在容器内升级到根目录,对于造成严重破坏或升级到主机也将变得更加困难。
这不会影响常规的网络应用程序; 但恶意用户会发现他们可以使用的武器库大大缩小!默认情况下,Docker将删除除所需功能之外的所有功能,即白名单而不是黑名单方法。您可以在Linux手册页中看到完整的可用功能列表。
运行Docker容器的一个主要风险是给容器默认的一组功能和挂载可能会独立提供不完全的隔离,或者与内核漏洞结合使用。
Docker支持添加和删除功能,允许使用非默认配置文件。这可能会通过删除功能使Docker更安全,或者通过增加功能降低Docker的安全性。对于用户来说,最好的做法是去除除了他们的进程明确需要的所有功能。
功能只是现代Linux内核提供的众多安全功能之一。还可以利用Docker等现有知名系统,如TOMOYO,AppArmor,SELinux,GRSEC等。
虽然Docker目前仅支持功能,但不会干扰其他系统。这意味着有很多不同的方法来加固Docker主机。这里有一些例子。
您可以使用GRSEC和PAX运行内核。这将在编译时和运行时增加许多安全检查; 它也会击败许多漏洞,这要归功于地址随机化等技术。它不需要特定于Docker的配置,因为这些安全特性适用于系统范围,独立于容器。
如果您的发行版带有Docker容器的安全模型模板,您可以直接使用它们。例如,我们发布了一个可与AppArmor配合使用的模板,而Red Hat提供了适用于Docker的SELinux策略。这些模板提供了一个额外的安全网(尽管它与功能重叠)。
您可以使用您最喜欢的访问控制机制来定义自己的策略。
就像有很多第三方工具来扩充Docker容器,例如特殊网络拓扑或共享文件系统一样,您可以期望看到工具来强化现有的Docker容器,而不会影响Docker的核心。
从Docker 1.10起,Docker守护进程直接支持用户命名空间。此功能允许将容器中的根用户映射到容器外部的非uid-0用户,这有助于减轻容器突破的风险。该工具可用,但默认情况下不启用。
有关此功能的更多信息,请参阅命令行参考中的守护程序命令。有关Docker中用户命名空间实现的其他信息可以在此博客文章中找到。
默认情况下,Docker容器非常安全; 特别是如果你照顾在容器内运行你的进程作为非特权用户(即非root
)。
您可以通过启用AppArmor,SELinux,GRSEC或您最喜欢的强化解决方案来添加额外的安全层。
最后但并非最不重要的一点是,如果您在其他集装箱系统中看到有趣的安全功能,这些内核功能也可能在Docker中实现。我们欢迎用户提交问题,提出请求并通过邮件列表进行沟通。
使用可信映像
Seccomp Docker的安全配置文件
适用于Docker的AppArmor安全配置文件
关于集装箱安全(2014年)
Docker群集模式覆盖网络安全模型