返回 登录
0

Docker上的安全性:如何配合无间

阅读5690

当然Docker镜像因其简洁实用而闻名,Docker的安全性到底如何却仍然是一个未知的迷。Docker的专家Dustin Huptas和Andreas Schmidt给我们展示了一些要构建安全的Docker系统必须了解的安全功能。

越来越多的公司开始向Docker容器技术迁移,并且在他们的技术栈中引入基于Docker的解决方案。围绕开发人员向Docker技术的靠近迟早会影响到生产环境的变化。因为这里会有很多的安全性方面的考量,操作团队以及那些开发运营背景的人会想要为实际生产中运行Docker准备好。幸运的是,Docker的引擎提供非常多的调整和层级选项来支持系统安全性,并且博客系统有发表非常多相关文章阐述如何正确配置,所有这些综合才能得到安全的Docker环境。但是大多数人都会在众多配置的可选项中迷失,Docker的daemon、镜像、容器等等安全配置。那么当我们从零开始构建安全的Docker系统时,什么是我们需要注意的安全问题?

这篇文章将会聚焦于服务器系统和Docker相关的安全功能上(关于网络层安全方面的考量也同样重要,但是我们会在其他专门的文章中去阐述)。相反,本文章的目标是要考虑在生产环境中使用Docker环境时提供的几个核心安全措施。让我们从主机层开始然后逐步深入,从而保证Docker守护进程的安全。Docker最受欢迎的方面之一就是它的简洁性和从Docker hub获取镜像的方便普及。因此,已经有相当多优秀的实践在反复增进这部分的安全性。此外,我们也会注意通过各个已有参数调整在容器运行阶段的安全改进。最终,我们总结得出这个文章里关于监控部署安全的Docker配置运行环境的一些思想。

确保Docker主机的安全性

首先,容器的宿主机器应该是安全并且可靠的。我们的目的是最小化主机系统作为被攻击源的风险,因为在它之上可能同时跑着大量不同的容器。假如这些来自于不同团队和客户的跑在同一主机上的容器之一有缺陷并被攻破,那么其他所有容器都有暴露在攻击下的风险。这里包含了一系列通用的步骤来增强系统安全,比如删除一切不必要的服务和软件包,从而进一步降低可攻击目标以及锁定用户权限。这里有很多工具可以帮助完善这些任务(比如OpenSCAP),并且有许多新工具正在开发中(比如Hardening,一种IO配置管理工具,或者是Lynis)

一台主机上的所有容器都是运行在相同的共享内核上,所以在内核安全上的投资是非常合理且必要的。Linux内核非常复杂并且包含一系列虚拟化主机系统所不必要的模块。

Grsecurity可以用于大量不同版本的内核打补丁,这可以从内核代码本身角度来增进多个不同方面系统的稳定性。这些补丁在在内核被编译和安装之前就手工应用于vanilla(这意味着未修改过的从kernel.org下载的,没有额外的linux发行版本)内核。对于内核熟悉的管理员而言,这提供了一个实现定制化的安全可控的容器运行环境。同时它也引入了需要额外管理的软件包依赖层。

确保Docker守护进程的安全性

在主机层的顶层驻守着Docker的守护进程/API,通过它攻击者可以获取容器甚至主机的访问权限。增进这一层级通信和验证的安全性可以降低潜在的攻击可能。或许确保Docker安装最好的起点就是确保你使用的版本库。版本库的流量数据安全是基于https的保护,除非有明确的不安全模式的版本库提供给Docker守护进程。因此一个简单的安全增进步骤就是确保非安全模式永远都不会被设置。另外,使用版本库镜像注册时也要确保只允许使用https。

这个概念可以继续扩展-比如哪个用户可以访问Docker实例的REST API根用户权限。Docker允许以root用户权限来启动容器,这里也包含一系列和容器化无关的系统资源分配,比如网络和进程空间(如:-net=host,-pid=host等)。只要API没有包含更细粒度的授权模式,干脆限制对它的访问权限是一个好的开始。当使用套接字选项时(/var/run/docker.sock)应检查访问权限(如:只对root用户和Docker用户组可写),特别是当Docker用户组不包含不必须的用户时。理想的情况下,没有用户被分配给Docker用户组或者sock套接字的访问是被同时禁止的。一个好的方法来通过网络访问这些API是使用TLS。这种情况下,客户端的TLS证书和和密钥被分发给各个机器和用户用于访问主机。并且TLS的证书应通过限制文件访问权限来保护。TLS安装时不应强制使用TLS加密模式开关,也应该允许tlsverify参数来允许用户验证方式登录。证书和密钥需要被公布到Docker的如下清单中:比如/etc/default/docker。有一个好的建议是:给你的服务器绑定一个特定的IP地址,而不是使用0.0.0.0:

DOCKER_OPTS="$DOCKER_OPTS --tlsverify --tlscacert=/etc/docker-tls/cacert.pem
         --tlscert=/etc/docker-tls/certs/server-cert.pem --tlskey=/etc/docker-tls/private/
                                    server-key.pem -H=192.168.0.10:2376"

SELinuxh或者AppArmor功能开启的系统提供了一个额外的隔离层。安装基于RHEL7或者Fedora-21,SELinux就已经默认启动,并且Docker的守护进程通常会跑在一个特殊的SELinux域内。基于Debian的系统,AppArmor配置文件也是默认启动来提高一个类似的隔离层。例如,在基于SELinux的系统中你可以用一些基本命令的- Z 选项来检查Docker是否跑在一个受限的领域内,比如netstat和ps:

# ps -efZ | grep docker
system_u:system_r:docker_t:SystemLow root 1873 1 2 07:21 ? 00:00:00 /
usr/bin/docker -d --selinux-enabled

第一列显示的是安全上下文。docker_t是一个特殊的权限受限的域类型。并且请注意对于docker守护进程的–selinux-enabled参数。

确保Docker镜像和镜像执行期的安全性

现在主机和Docker守护进程已经被保护,只有必要的资源访问权限被分配。接下来我们需要关注同级的安全,比如防止当我们从非信任或者未知的源下载并且执行木马等。在镜像创建过程创建可验证的信任链来保证容器运行的镜像总是可信任的。
每个Docker容器的制作过程往往都开始于从Docker hub的公共版本库上下载镜像。由于这代表了一个用户级的操作系统安装,安全强化主题在这里也适用。这会影响例如安装的软件包的数量 - 越少越好。最近的镜像,例如Fedora镜像甚至不再包含/bin/ip。可信任的仓库如Ubuntu或CentOS都在维护着它们的文档:如何更新基础镜像,如何滚动更新,如何给镜像打补丁等。

当谈到构建镜像,一些推荐做法已经存在于Docker的网站文档中。有关于各种如何写更稳定和安全的dockerfiles的提示。另一个好方法是看那些可信赖的仓库是如何实现它们的dockerfiles,那里有广泛的安全最佳实践。

最后它需要从可信赖的没有任何已知漏洞的来源来获取基础镜像。管理员们不会希望依赖于那些使用debootstrap或者applicance-creator从零开始定制化的容器镜像。

从Docker 1.8开始生效,alternatively作为一个可信任内容的中间地带。这个功能限制docker客户只能使用哪些在docker版本库中被发布者设置标签的镜像。这个功能可以通过如下环境参数激活:

root@debian-jessie:~# export DOCKER_CONTENT_TRUST=1

或者直接传递如下参数至各个命令:

root@debian-jessie:~# env DOCKER_CONTENT_TRUST=1 docker pull (...)

当这个内容信任功能被启用后,只有那些有发布者标签的镜像可以从版本库下载,否则用户会收到如下错误提示:

root@debian-jessie:~# env DOCKER_CONTENT_TRUST=1 docker pull dewiring/ trustit:latest
no trust data available

当发布者设置镜像标签后,这些镜像才可以被成功下载。当客户端想要在内容信任功能启用的环境中运行镜像时,只有这些有标签的镜像才是对于docker客户端有效的。标签设置可以在离线状态下完成,标签密钥会在第一次上传时创建。所有密钥都被存储在客户端,只有时间戳和签名会和镜像标签一起以元数据存储到docker的版本库中。更多关于如何上传签名镜像信息可以通过如下命令在可信任内容中得到:

root@debian-jessie:~# env DOCKER_CONTENT_TRUST=1 docker pull dewiring/ trustit:latest Pull (1 of 1): dewiring/trustit:latest@sha256:c58ee9f9d1b1a0b59471cac2c089ac99 5dd559949ee088533fc6f4a0dcd2719f sha256:c58ee9f9d1b1a0b59471cac2c089ac995dd559949ee088533fc6f4a0dcd2719f: Pulling from dewiring/trustit 2c49f83e0b13: Already exists 4a5e6db8c069: Already exists 88ab9df21bce: Already exists 2c900b53c032: Already exists 8d86df29cb44: Already exists Digest: sha256:c58ee9f9d1b1a0b59471cac2c089ac995dd559949ee088533fc6f4a0d cd2719f Status: Downloaded newer image for dewiring/trustit@sha256:c58ee9f9d1b1a0b594 71cac2c089ac995dd559949ee088533fc6f4a0dcd2719f Tagging dewiring/trustit@sha256:c58ee9f9d1b1a0b59471cac2c089ac995dd559949e e088533fc6f4a0dcd2719f as dewiring/trustit:latest

原文链接:Docker and Security: How do they fit together?(译者/王旭敏 责编仲浩)
译者介绍:王旭敏,Nokia开发工程师,关注云计算、高性能或可用等架构、容器等。

评论