浅谈Docker安全

引言​

在当今云计算和容器化技术盛行的时代,Docker 作为一款领先的容器化平台,被广泛应用于各类应用的开发、部署与管理。然而,随着其应用范围的不断扩大,安全问题愈发受到关注。

Docker 是在 Linux操作系统层面上的虚拟化实现,运行在容器内的进程,跟运行在本地系统中的进程,本质上并无区别,不合适的安全策略将可能给本地系统带来风险。因此Docker的安全性在生产环境中是十分关键的衡量因素。

Docker 容器的安全性,很大程度上其实依赖于Linux系统自身,因此在评估Docker的安全性时,主要考虑下面几个方面:

  • Linux 内核的命名空间机制提供的容器隔离安全。
  • Linux 控制组机制对容器资源的控制能力安全。
  • Linux内核的能力机制所带来的操作权限安全
  • Docker程序(特别是服务端)本身的抗攻击性
  • 其他安全增强机制(包括AppArmor、SELinux等)对容器安全性的影响

1、命名空间隔离的安全

Docker 容器和LXC容器在实现上很相似,所提供的安全特性也基本一致。当用docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间。
命名空间提供了最基础也是最直接的隔离,在容器中运行的进程不会被运行在本地主机上的进程和其他容器通过正常渠道发现和影响。
例如,通过命名空间机制,每个容器都有自己独有的网络栈,意味着它们不能访问其他容器的套接字(sockets)或接口。当然,容器默认可以与本地主机网络连通,如果主机系统上做了相应的交换设置,容器可以像跟主机交互一样的和其他容器交互。启动容器时,指定公共端口或使用连接系统,容器可以相互通信了(用户可以根据配置来限制通信的策略)。

从网络架构的角度来看,所有的容器实际上是通过本地主机的网桥接口(Docker0)进行相互通信,就像物理机器通过物理交换机通信一样。
那么,Linux内核中实现命名空间(特别是网络命名空间)的机制是否足够成熟呢?Linux内核从2.6.15版本(2008年7月发布)开始引人命名空间,至今经历了数年的演化和改进,并应用于诸多大型生产系统中。
实际上,命名空间的想法和设计提出的时间要更早,最初是OpenVz项目的重要特性OpenVz项目早在2005年就已经正式发布,其设计和实现更加成熟。
当然,与虚拟机方式相比,通过命名空间来实现的隔离并不是那么绝对。运行在容器中的应用可以直接访问系统内核和部分系统文件。因此,用户必须保证容器中应用是安全可信的(这跟保证运行在系统中的软件是可信的一个道理),否则本地系统将可能受到威胁。实际上,Docker自1.30版本起对镜像管理引人了签名系统,用户可以通过签名来验证镜像的完整性和正确性。

2、控制组资源控制的安全

控制组(Control Groups,简称 cgroups)是 Linux 内核的另一个重要特性,它允许管理员对一组进程所使用的资源进行限制和统计。Docker 利用 cgroups 来实现对容器资源的精细控制,包括 CPU、内存、磁盘 I/O、网络带宽等。

控制组是 Linux容器机制中的另外一个关键组件,它负责实现资源的审计和限制。当用docker run启动一个容器时,Docker 将在后台为容器创建一个独立的控制组策略集合。控制组机制始于2006年,Linux内核从2.6.24版本开始被引人。
它提供了很多有用的特性;以及确保各个容器可以公平地分享主机的内存、CPU、磁盘IO等资源;当然,更重要的是,控制组确保了当发生在容器内的资源压力不会影响到本地主机系统和其他容器。
尽管控制组不负责隔离容器之间相互访问、处理数据和进程,但是它在防止拒绝服务攻击(DDoS)方面是必不可少的。尤其是在多用户的平台(比如公有或私有的Paas)上,控制组十分重要。例如,当某些应用容器出现异常的时候,可以保证本地系统和其他容器正常运行而不受影响。

3、内核能力机制

Linux 内核能力(Kernel Capabilities)是一种细粒度的权限管理机制,它打破了传统的 “超级用户 - 普通用户” 二元权限模型。Docker 在运行容器时,可以根据实际需求为容器授予特定的内核能力,而不是让容器以 root 权限运行。

能力机制(Capability)是Linux内核一个强大的特性,可以提供细粒度的权限访问控制。传统的 Unix系统对进程权限只有根权限(用户id为0,即为root用户)和非根权限(用户非root 用户)两种。
Linux内核自2.2版本起支持能力机制,它将权限划分为更加细粒度的操作能力,既可以作用在进程上,也可以作用在文件上。
例如,一个Web服务进程只需要绑定一个低于1024的端口的权限,并不需要完整的root权限。那么它只需要被授权netbind service能力即可。此外,还有很多其他的类似能力来避免进程获取 root 权限。默认情况下,Docker启动的容器被严格限制只允许使用内核的一部分能力,包括chown、dac override、fowner、kill、setgid、setuid,setpcap、net bind service、 net raw、sys chroot、mknod、setfcap、audit write等。
使用能力机制对加强Docker容器的安全性有很多好处。通常,在服务器上会运行一堆需要特权权限的进程,包括有ssh、cron、syslogd、硬件管理工具模块(例如负载模块)、网络配置工具等等。容器跟这些进程是不同的,因为几乎所有的特权进程都由容器以外的支持系统来进行管理。

  • ssh 访问被宿主主机上的 ssh 服务来管理。

  • cron 通常应该作为用户进程执行,权限交给使用它服务的应用来处理。

  • 日志系统可由 Docker或第三方服务管理。

  • 硬件管理无关紧要,容器中也就无需执行 udevd 以及类似服务。

  • 网络管理也都在主机上设置,除非特殊需求,容器不需要对网络进行配置。
    从上面的例子可以看出,大部分情况下,容器并不需要“真正的”root权限,容器只需要少数的能力即可。为了加强安全,容器可以禁用一些没必要的权限。

  • 完全禁止任何文件挂载操作。

  • 禁止直接访问本地主机的套接字。

  • 禁止访问一些文件系统的操作,比如创建新的设备、修改文件属性等

  • 禁止模块加载。
    这样,就算攻击者在容器中取得了root权限,也不能获得本地主机的较高权限,能进行的破坏也有限。
    不恰当地分配了内核能力,会导致容器内应用获取破坏本地系统的权限。例如,早期的Docker版本曾经不恰当的继承CAPDACREADSEARCH能力,导致容器内进程可以通过系统调用访问到本地系统的任意文件目录。
    默认情况下,Docker采用“白名单”机制,禁用“必需功能”之外的其他权限。当然,用户也可以根据自身需求来为 Docker 容器启用额外的权限。

4、Docker服务端的防护

使用 Docker 容器的核心是 Docker 服务端。Docker 服务的运行目前还需要root 权限的支持,因此服务端安全性十分关键。
首先,必须确保只有可信的用户才可以访问到Docker服务。Docker允许用户在主机和容器间共享文件夹,同时不需要限制容器的访问权限,这就容易让容器突破资源限制。
例如,恶意用户启动容器的时候将主机的根目录/映射到容器的host目录中,那么容器理论上就可以对主机的文件系统进行任意修改了。事实上,几乎所有虚拟化系统都允许类似的资源共享,而没法阻止恶意用户共享主机根文件系统到虚拟机系统。
这将会造成很严重的安全后果。因此,当提供容器创建服务时(例如通过一个web服务器),要更加注意进行参数的安全检查,防止恶意的用户用特定参数来创建一些破坏性的容器。为了加强对服务端的保护,Docker的RESTAPI(客户端用来跟服务端通信的接口)在0.5.2之后使用本地的Unix套接字机制替代了原先绑定在127.0.0.1上的TCP套接字,因为后者容易遭受跨站脚本攻击。现在用户使用Unix权限检查来加强套接字的访问安全。用户仍可以利用HTTP提供RESTAPI访问。建议使用安全机制,确保只有可信的网络或VPN 网络,或证书保护机制(例如受保护的stunnel和ssl认证)下的访间可以进行。此外,还可以使用HTTPS和证书来加强保护。
最近改进的Linux命名空间机制将可以实现使用非root用户来运行全功能的容器。这将从根本上解决了容器和主机之间共享文件系统而引起的安全问题。
目前,Docker自身改进安全防护的目标是实现以下两个重要安全特性:

  • 将容器的root用户映射到本地主机上的非root用户,减轻容器和主机之间因权限提升而引起的安全问题。
  • 允许 Docker 服务端在非root权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程将只允许在限定范围内进行操作,例如仅仅负责虚拟网络设定或文件系统管理、配置操作等。

5、其他安全特性

除了能力机制之外,还可以利用一些现有的安全软件或机制来增强使用Docker的安全性,例如TOMOYO,AppArmor,SELinux,GRSEC 等。Docker 当前默认只启用了能力机制。用户可以选择启用更多的安全方案来加强Docker主机的安全,例如:

  • 在内核中启用GRSEC和PAX,这将增加更多的编译和运行时的安全检查;并且通过地址随机化机制来避免恶意探测等。启用该特性不需要Docker 进行任何配置。口使用一些有增强安全特性的容器模板,比如带AppArmor的模板和 Redhat带 SELinux策略的模板。这些模板提供了额外的安全特性。
  • 用户可以自定义更加严格的访问控制机制来定制安全策略。此外,在将文件系统挂载到容器内部时候,可以通过配置只读(read-only)模式来避免容器内的应用通过文件系统破坏外部环境,特别是一些系统运行状态相关的目录,包括但不限于 /proc/sys、/proc/irg、/proc/bus等等。这样,容器内应用进程可以获取所需要的系统信息但无法对它们进行修改。

6、本章小结

总体来看,基于Linux上成熟的安全机制以及Apparmor,SELinux,GRSEC等安全机制Docker 容器还是比较安全的,特别是在容器内不使用root权限来运行进程的话。
但是任何技术层面实现的安全都需要用户合理的使用才能得到巩固,在使用Docker过程中,需要注意如下几方面:

  • 在使用 Docker 容器运行应用的时候,一定要牢记容器自身所提供的隔离性其实并没有那么完善,需要加强对容器内应用的安全审查。容器即应用,保障应用安全的各种手段,都应该进行合理地利用。
  • 采用专用的服务器来运行 Docker 服务端和相关的管理服务(例如管理服务比如ssh监控和进程监控、管理工具 nrpe、collectd 等),并对该服务器启用最高级别的安全机制。而把其他的业务服务都放到容器中去运行。
  • 将运行 Docker 容器的机器划分为不同的组,互相信任的机器放到同一个组内;组之间进行安全隔离;同时进行定期的安全检查。
  • 随着容器大规模地使用和集成,甚至组成容器集群。需要考虑在容器网络上进行必备的安全防护,避免诸如 DDOS、ARP攻击、规则表攻击等网络安全威胁,这也是生产环境需要关注的重要问题。

期待您能关注公众号原宏Cloud运维栈每天带你进步一点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方、宏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值