Docker是基于Linux操作系统实现的应用虚拟化。
运行在容器内的进程,跟运行在本地系统的进程本质上并无区别,
配置不合适的安全策略将可能给本地系统带来安全风险,
因此,Docker的安全性在生产环境中是十分关键的衡量因素。
Docker容器的安全性很大程度上依赖于Linux系统本身,主要考虑下面几个方面:
(1)Linux内核的命名空间机制提供的容器隔离安全;
(2)Linux控制组机制对容器资源的控制能力安全;
(3)Linux内核的能力机制所带来的操作权限安全;
(4)Docker程序(特别是服务端)本身的抗攻击性;
(5)其它安全增强机制(包括AppArmor、SELinux等)对容器安全性的影响;
(6)通过第三方工具(如:Docker Bench)对Docker环境的安全性进行评估;
Docker容器和LXC容器在实现上很相似,所提供的安全特性也基本一致。
当用docker run创建一个新的容器时,Docker将在后台为容器创建一个独立的命名空间。
命名空间提供了最基础的也是最直接的隔离,
在容器中运行的进程不会被运行在本地主机上的进程和其它容器通过正常程序发现和影响。
例如,通过命名空间机制,每个程序都有自己独有的网络栈,
意味着它们不能访问其他容器的套接字(socket)或接口。
当然,容器默认可以与本地主机的网络连通,如果主机系统上做了相应的交换设置,
容器可以像跟主机交互一样和其他容器交互。
启动容器时,指定公共端口或使用连接系统,容器就可以相互通信了。
从网络架构的角度来看,所有的容器实际上是通过本地主机的网桥接口docker0进行相互通信,
就像物理机器通过物理交换机通讯一样。
Linux内核从2.6.15版本(08年)开始引入命名空间,经历了数次的演化和改进。
与虚拟机相比,通过命名空间来实现的安全隔离并不是那么绝对。
运行在容器内的应用可以直接访问到系统内核和部分系统文件。
因此用户必须保证运行在容器内的应用是安全可信的,(这和直接运行在系统中的软件是一样的)
否则本地系统将可能受到威胁,所以必须保证镜像的来源和自身可靠。
Docker从1.13开始对镜像管理引入的签名系统,加强了对镜像安全性的防护,
用户可以通过签名来验证镜像的完成性和正确性。
控制组时Linux容器机制中的另一个关键组建,它负责实现资源的审计和限制。
当使用docker run创建启动一个容器的时候,Docker将通过Linux的相关调用,
在后台为容器创建一个独立的控制组策略集合,该集合将限制容器内的应用对资源的消耗。
控制组提供了很多有用的特性,它确保了各个容器可以公平的分享主机的内存、CPU、磁盘IO等资源,
当然,更重要的是,通过控制组,可以限制容器对资源的占用,
确保了当某个容器对资源消耗过大时,不会影响到本机系统和其它容器的运行。
尽管控制组不负责隔离容器之间的相互访问、处理数据和进程,
但是它在防止而已攻击特别是服务器攻击(DDos)方面是十分有效的。
对于支持多用户的服务平台,特别是paas、容器云这类服务,控制组尤其重要。
能力机制(Capability)是Linux内核一个强大的特性,可以提供细颗粒度的权限访问控制。
传统的Unix系统对进程权限只有根权限(root用户)和非根权限(非root用户)两种粒度的区别。
Linux内核从2.2版本其支持能力机制,它将权限分为更加细粒度的操作能力,既可以作用在进程上,也可以作用在文件上。
例如,一个Web服务器只需要绑定一个低于1024端口的权限,并不需要完整的root权限。
那么,它只需要被授权net_bind_service能力即可。此外,还有许多其它类似能力避免进程获取root权限。
默认情况下,Docker启动的容器默认只能使用一部分内核的功能。
使用能力机制对加强Docker容器的安全性有很多好处。
通常在服务器上需要运行一推需要特权权限的进程。
包括SSH、cron、syslogd、硬件管理工具模块、网络配置工具等,
容器跟这些进程是不相同的,因为几乎所有的特权进程几乎由容器以外的支持系统来进行管理。
例如:
ssh访问被宿主机上的ssh服务来管理;
cron通常应该作为用户进程来执行,权限交给使用它服务的应用来处理;
日志系统可以由Docker或第三方服务管理;
网络管理也在主机上设置,除非特殊需求,容器不需要对网络进行配置
大部分情况下,容器不需要真正的root权限,容器只需要少数的能力即可。
未来加强安全,容器可以禁用一些没必要的权限。包括:
禁止任何文件挂载操作;
禁止直接访问本地主机的套接字;
禁止访问一些文件系统的操作,比如创建新的设备、修改文件属性等;
禁止模块加载;
这样,就算攻击者获取了root权限,在容器中所作的操作也有限。
不恰当的分配了内核能力,会导致容器内应用获取破坏本地系统的权限。
默认情况下,Docker采用白名单机制,禁用了必须的一些能力之外的其它权限。
当然,用户也可以根据自身的需求启用额外的权限。