Docker Security
最后更新于
使用Trickest可以轻松构建和自动化工作流程,使用世界上最先进的社区工具。 立即获取访问权限:
Docker引擎利用Linux内核的命名空间和Cgroups来隔离容器,提供基本的安全层。通过Capabilities dropping、Seccomp和SELinux/AppArmor提供额外的保护,增强容器隔离性。认证插件可以进一步限制用户操作。
Docker引擎可以通过Unix套接字本地访问,也可以通过HTTP远程访问。对于远程访问,必须使用HTTPS和TLS来确保机密性、完整性和身份验证。
默认情况下,Docker引擎在Unix套接字上侦听unix:///var/run/docker.sock
。在Ubuntu系统上,Docker的启动选项定义在/etc/default/docker
中。要启用对Docker API和客户端的远程访问,请添加以下设置以通过HTTP套接字公开Docker守护程序:
然而,由于安全问题,不建议通过HTTP公开Docker守护程序。建议使用HTTPS来保护连接。保护连接的两种主要方法如下:
客户端验证服务器的身份。
客户端和服务器相互验证彼此的身份。
证书用于确认服务器的身份。有关这两种方法的详细示例,请参考此指南。
容器镜像可以存储在私有或公共存储库中。Docker为容器镜像提供了几种存储选项:
Docker Hub:Docker提供的公共注册服务。
Docker Registry:允许用户托管自己的注册表的开源项目。
Docker Trusted Registry:Docker的商业注册服务,具有基于角色的用户身份验证和与LDAP目录服务集成的功能。
容器可能存在安全漏洞,这可能是由于基础镜像或安装在基础镜像之上的软件导致的。Docker正在开发一个名为Nautilus的项目,用于对容器进行安全扫描并列出漏洞。Nautilus通过将每个容器镜像层与漏洞存储库进行比较来识别安全漏洞。
有关更多信息,请阅读此处。
docker scan
**docker scan
**命令允许您使用镜像名称或ID扫描现有的Docker镜像。例如,运行以下命令来扫描hello-world镜像:
Docker镜像签名确保容器中使用的镜像的安全性和完整性。以下是简要说明:
要激活Docker内容信任,请设置export DOCKER_CONTENT_TRUST=1
。此功能在Docker版本1.10及更高版本中默认关闭。
启用此功能后,只能下载已签名的镜像。首次镜像推送需要为根密钥和标记密钥设置密码,Docker还支持Yubikey以提高安全性。更多详细信息可在此处找到。
在启用内容信任的情况下尝试拉取未签名的镜像会导致“最新版本无信任数据”错误。
对于第一次之后的镜像推送,Docker会要求输入存储库密钥的密码以签署镜像。
要备份您的私钥,请使用以下命令:
在切换Docker主机时,需要移动根密钥和存储库密钥以保持运行。
使用Trickest轻松构建和自动化工作流,利用世界上最先进的社区工具。 立即获取访问权限:
命名空间是Linux内核的一个功能,将内核资源分区,使得一组进程看到一组资源,而另一组进程看到不同的资源。该功能通过为一组资源和进程使用相同的命名空间,但这些命名空间指向不同的资源来实现。资源可以存在于多个空间中。
Docker利用以下Linux内核命名空间来实现容器隔离:
pid命名空间
mount命名空间
network命名空间
ipc命名空间
UTS命名空间
有关命名空间的更多信息,请查看以下页面:
NamespacesLinux内核功能cgroups提供了限制资源(如CPU、内存、IO、网络带宽等)的能力。Docker允许使用cgroup功能创建容器,从而实现对特定容器的资源控制。 以下是一个使用用户空间内存限制为500m、内核内存限制为50m、CPU份额为512、blkioweight为400创建的容器。CPU份额是控制容器CPU使用率的比率。它的默认值为1024,范围在0到1024之间。如果三个容器的CPU份额都是1024,则在CPU资源争用的情况下,每个容器最多可以占用33%的CPU。blkio-weight是控制容器IO的比率。它的默认值为500,范围在10到1000之间。
要获取容器的 cgroup,您可以执行以下操作:
权限提升允许对root用户可以允许的权限进行更精细的控制。Docker使用Linux内核的权限功能来限制容器内可以执行的操作,无论用户类型如何。
当运行Docker容器时,进程会放弃敏感权限,这些权限可以用来逃离隔离。这样可以确保进程无法执行敏感操作并逃脱:
这是一个安全功能,允许Docker限制容器内可以使用的系统调用:
AppArmor是一个内核增强功能,用于将容器限制在一组有限的资源和每个程序的配置文件中:
标签系统:SELinux为每个进程和文件系统对象分配唯一标签。
策略执行:它执行定义了进程标签在系统中可以对其他标签执行什么操作的安全策略。
容器进程标签:当容器引擎启动容器进程时,它们通常被分配一个受限SELinux标签,通常是container_t
。
容器内的文件标签:容器内的文件通常被标记为container_file_t
。
策略规则:SELinux策略主要确保具有container_t
标签的进程只能与标记为container_file_t
的文件交互(读取、写入、执行)。
这种机制确保即使容器内的进程受到损害,也仅限于与具有相应标签的对象交互,从而显著限制了此类妥协可能造成的潜在损害。
在Docker中,授权插件通过决定是否允许或阻止对Docker守护程序的请求发挥着关键作用。这一决定是通过检查两个关键上下文来做出的:
认证上下文:包括有关用户的全面信息,例如他们是谁以及他们如何进行身份验证。
命令上下文:包括与正在进行的请求相关的所有相关数据。
这些上下文有助于确保只有经过身份验证的用户的合法请求才会被处理,增强Docker操作的安全性。
authz-and-authn-docker-access-authorization-plugin.md
如果您没有正确限制容器可以使用的资源,受损的容器可能会对其运行的主机进行DoS攻击。
CPU DoS
带宽 DoS
在下面的页面中,您可以了解**--privileged
标志意味着什么**:
如果您正在运行一个容器,攻击者设法以低权限用户的身份访问。如果您有一个配置错误的suid二进制文件,攻击者可能会滥用它并在容器内提升权限。这可能使他能够逃离容器。
使用启用了**no-new-privileges
选项运行容器将防止这种特权升级**。
要查看更多**--security-opt
**选项,请访问:https://docs.docker.com/engine/reference/run/#security-configuration
避免直接嵌入Docker镜像或使用环境变量存储机密信息至关重要,因为这些方法会使您的敏感信息暴露给通过诸如docker inspect
或exec
等命令访问容器的任何人。
Docker卷是一个更安全的替代方案,建议用于访问敏感信息。它们可以被用作内存中的临时文件系统,减轻了与docker inspect
和日志记录相关的风险。但是,root用户和具有对容器的exec
访问权限的用户仍然可以访问这些机密信息。
Docker机密提供了一种更安全的处理敏感信息的方法。对于在镜像构建阶段需要机密信息的情况,BuildKit提供了一个高效的解决方案,支持构建时机密信息,提高构建速度并提供额外功能。
要利用BuildKit,可以通过以下三种方式激活它:
通过环境变量:export DOCKER_BUILDKIT=1
通过命令前缀:DOCKER_BUILDKIT=1 docker build .
通过在Docker配置中默认启用它:{ "features": { "buildkit": true } }
,然后重新启动Docker。
BuildKit允许使用--secret
选项使用构建时机密信息,确保这些机密信息不包含在镜像构建缓存或最终镜像中,使用类似以下命令:
对于运行容器中需要的机密信息,Docker Compose 和 Kubernetes 提供了强大的解决方案。Docker Compose 利用服务定义中的 secrets
键来指定机密文件,示例在 docker-compose.yml
中展示:
这个配置允许在使用Docker Compose启动服务时使用secrets。
在Kubernetes环境中,secrets得到原生支持,并可以通过诸如Helm-Secrets等工具进一步管理。Kubernetes的基于角色的访问控制(RBAC)增强了秘钥管理安全性,类似于Docker Enterprise。
gVisor是一个用Go编写的应用内核,实现了Linux系统表面的大部分功能。它包括一个名为runsc
的Open Container Initiative (OCI)运行时,提供了应用程序和主机内核之间的隔离边界。runsc
运行时与Docker和Kubernetes集成,使得运行沙盒容器变得简单。
Kata Containers是一个开源社区,致力于构建一个安全的容器运行时,使用轻量级虚拟机,感觉和表现类似于容器,但通过硬件虚拟化技术提供更强大的工作负载隔离作为第二层防御。
不要使用--privileged
标志或在容器内挂载 Docker套接字。 Docker套接字允许生成容器,因此通过使用--privileged
标志运行另一个容器是获取主机完全控制的简单方法。
放弃所有功能 (--cap-drop=all
),仅启用所需功能 (--cap-add=...
)。许多工作负载不需要任何功能,添加功能会增加潜在攻击的范围。
使用“no-new-privileges”安全选项 防止进程获取更多权限,例如通过suid二进制文件。
限制容器可用的资源**。**资源限制可以保护机器免受拒绝服务攻击。
使用 官方Docker镜像 并要求签名,或者基于它们构建自己的镜像。不要继承或使用后门镜像。还要将根密钥、密码存储在安全位置。Docker计划使用UCP管理密钥。
定期 重建您的镜像以应用安全补丁到主机和镜像。
明智地管理您的secrets,使攻击者难以访问它们。
如果暴露Docker守护程序,请使用HTTPS进行客户端和服务器身份验证。
在Dockerfile中,优先使用COPY而不是ADD。ADD会自动解压缩文件并可以从URL复制文件。COPY不具备这些功能。尽量避免使用ADD,以免受到通过远程URL和Zip文件进行攻击的影响。
为每个微服务使用单独的容器
不要在容器内放置ssh,“docker exec”可用于ssh到容器。
使用更小的容器镜像
如果您在Docker容器内或者拥有docker组中的用户访问权限,您可以尝试越狱和提升权限:
Docker Breakout / Privilege Escalation如果您可以访问docker套接字或者拥有docker组中的用户访问权限,但您的操作受到docker身份验证插件的限制,请检查是否可以绕过它:
AuthZ& AuthN - Docker Access Authorization Plugin工具docker-bench-security是一个脚本,检查在生产环境中部署Docker容器时的数十种常见最佳实践。所有测试都是自动化的,基于CIS Docker Benchmark v1.3.1。 您需要从运行Docker的主机或具有足够权限的容器中运行该工具。了解如何在README中运行它:https://github.com/docker/docker-bench-security。
使用Trickest可以轻松构建和自动化工作流程,使用世界上最先进的社区工具。 立即获取访问权限: