docker入门实战8 安全
十九、docker安全
docker是在Linux操作系统层面上的虚拟化实现,运行在容器内的进程,跟运行在本地系统中的进程,本质上并无区别,不合适的安全策略将可能给本地系统带来风险。
docker容器的安全性,很大程度上依赖于Linux系统自身,因此在评估docker的安全性时,主要考虑下面几个方面:
1)Linux内核的命名空间机制提供的容器隔离安全。
2)Linux控制组机制对容器资源的控制能力安全。
3)Linux内核的能力机制所带来的操作权限安全。
4)docker程序(特别是服务端)本身的抗攻击性。
5)其他安全增强机制(包括AppArmor、SELinux等)对容器安全性的影响。
19.1 命名空间隔离的安全
docker容器和LXC容器在实现上很相似,所提供的安全特性也基本一致。当用docker run启动一个容器时,docker将在后台为容器创建一个独立的命名空间。
命名空间提供了最基础也是最直接的隔离,在容器中运行的进程不会被运行在本地主机上的进程和其它容器通过正常渠道发现和影响。
通过命名空间机制,每个容器都有自己独有的网络栈,意味着它们不能访问其他容器的套接字socket或接口。当然,容器默认可以与本地主机网络连通,如果主机系统上做了相应的交换设置,容器可以像跟主机交互一样的和其它容器交互。启动容器时,指定公共端口或使用连接系统,容器可以相互通信(用户可以根据配置来限制通信的策略)。
从网络架构的角度来看,所有的容器实际上是通过本地主机的网桥接口(docker0)进行相互通信,就像物理机器通过物理交换机通信一样。
19.2 控制组资源控制的安全
控制组是Linux容器机制中的另外一个关键组件,它负责实现资源的审计和限制。当用docker run启动一个容器时,docker将在后台为容器创建一个独立的控制组策略集合。
控制组机制提供了很多有用的特性;以及确保各个容器可以公平地分享主机的内存、CPU、磁盘IO等资源;当然,更重要的是,控制组确保了当发生在容器内的资源压力不会影响到本地主机系统和其它容器。
尽管控制组不负责隔离容器之间相互访问、处理数据和进程,但是它在防止拒绝服务攻击DDoS方面是必不可少的。尤其是在多用户平台上,控制组十分重要。例如,当某些应用容器出现异常的时候,可以保证本地系统和其它容器正常运行而不受影响。
19.3 内核能力机制
能力机制(Capability)是Linux内核一个强大的特性,可以提供细粒度的权限访问控制。传统的Unix系统对进程权限只有根权限(用户id为0,即为root用户)和非根权限(用户非root用户)两种。
Linux内核自2.2版本起支持能力机制,它将权限划分为更加细粒度的操作能力,既可以作用在进程上,也可以作用在文件上。
默认情况下,docker启动的容器被严格限制只允许使用内核的一部分能力,包括chown、dac_override、fowner、kill、setgid、setpcap、net_bind_service、net_raw、sys_chroot、mknod、setfcap、audit_write等。
容器并不需要真正的“root”权限,容器只需要少数的能力即可。为了加强安全,容器可以禁止一些没必要的权限。
1)完全禁止任何文件挂载操作。
2)禁止直接访问本地主机的套接字。
3)禁止访问一些文件系统的操作,比如创建新的设备、修改文件属性等。
4)禁止模块加载。
默认情况下,docker采用“白名单”机制,禁用“必须功能”之外的其它权限。当然,用户也可以根据自身需求来为docker容器启用额外的权限。
19.4 docker服务端的防护
docker服务的运行目前还需要root权限的支持,因此服务端安全性十分关键。
为了加强对服务端的保护,docker的RESTAPI(客户端用来跟服务端通信的接口)在0.5.2之后使用本地的Unix套接字机制替代了原先绑定在127.0.0.1上的TCP套接字,因为后者容易遭受跨站脚本攻击。现在用户使用Unix权限检查来加强套接字的访问安全。
目前,docker自身改进安全防护的目标是实现以下两个重要安全特性:
1)将容器的root用户映射到本地主机上的非root用户,减轻容器和主机之间因权限提升而引起的安全问题。
2)允许docker服务端在非root权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程将只允许在限定范围内进行操作,例如仅仅负责虚拟网络设定或文件系统管理、配置操作等。
19.5 其它安全特性
除了能力机制之外,还可以利用一些现有的安全软件或机制来增强使用docker的安全性。