Docker Security
Last updated
学习和实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE) 学习和实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)
使用 Trickest 轻松构建和 自动化工作流,由世界上 最先进 的社区工具提供支持。 今天就获取访问权限:
Docker 引擎 利用 Linux 内核的 Namespaces 和 Cgroups 来隔离容器,提供基本的安全层。通过 能力丢弃、Seccomp 和 SELinux/AppArmor 提供额外保护,增强容器隔离。一个 auth 插件 可以进一步限制用户操作。
Docker 引擎可以通过 Unix 套接字本地访问或通过 HTTP 远程访问。对于远程访问,使用 HTTPS 和 TLS 确保机密性、完整性和身份验证至关重要。
Docker 引擎默认在 unix:///var/run/docker.sock
上监听 Unix 套接字。在 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 以增强安全性。更多详细信息可以在 这里 找到。
尝试在启用内容信任的情况下拉取未签名的镜像会导致 "No trust data for latest" 错误。
在第一次之后的镜像推送中,Docker 会要求输入存储库密钥的密码短语以签署镜像。
要备份您的私钥,请使用以下命令:
当切换 Docker 主机时,必须移动根和存储库密钥以维持操作。
使用 Trickest 轻松构建和 自动化工作流,由世界上 最先进 的社区工具提供支持。 立即获取访问权限:
Namespaces 是 Linux 内核的一个特性,它将内核资源进行分区,使得一组进程****看到一组资源,而另一组进程看到不同的资源。该特性通过为一组资源和进程使用相同的命名空间来工作,但这些命名空间指向不同的资源。资源可以存在于多个空间中。
Docker 利用以下 Linux 内核命名空间来实现容器隔离:
pid namespace
mount namespace
network namespace
ipc namespace
UTS namespace
有关命名空间的更多信息,请查看以下页面:
NamespacesLinux 内核特性cgroups提供了限制一组进程的资源,如 CPU、内存、IO、网络带宽的能力。Docker 允许使用 cgroup 特性创建容器,从而实现对特定容器的资源控制。 以下是一个用户空间内存限制为 500m,内核内存限制为 50m,CPU 共享为 512,blkio-weight 为 400 的容器。CPU 共享是控制容器 CPU 使用的比例。它的默认值为 1024,范围在 0 到 1024 之间。如果三个容器的 CPU 共享均为 1024,则在 CPU 资源争用的情况下,每个容器最多可以占用 33% 的 CPU。blkio-weight 是控制容器 IO 的比例。它的默认值为 500,范围在 10 到 1000 之间。
要获取容器的 cgroup,您可以执行:
有关更多信息,请查看:
CGroups能力允许对可以允许的根用户能力进行更细粒度的控制。Docker使用Linux内核能力特性来限制可以在容器内执行的操作,无论用户类型如何。
当运行docker容器时,进程会放弃敏感能力,以防止进程逃离隔离。这试图确保进程无法执行敏感操作并逃逸:
Linux Capabilities这是一种安全特性,允许Docker限制可以在容器内使用的系统调用:
SeccompAppArmor是一个内核增强,用于将容器限制在有限的资源集内,并具有每个程序的配置文件:
AppArmor标记系统:SELinux为每个进程和文件系统对象分配一个唯一的标签。
策略执行:它执行定义进程标签可以对系统内其他标签执行哪些操作的安全策略。
容器进程标签:当容器引擎启动容器进程时,通常会分配一个受限的SELinux标签,通常为container_t
。
容器内的文件标记:容器内的文件通常标记为container_file_t
。
策略规则:SELinux策略主要确保具有container_t
标签的进程只能与标记为container_file_t
的文件进行交互(读取、写入、执行)。
该机制确保即使容器内的进程被攻陷,它也仅限于与具有相应标签的对象进行交互,从而显著限制此类攻陷可能造成的损害。
SELinux在Docker中,授权插件在安全性方面发挥着关键作用,通过决定是否允许或阻止对Docker守护进程的请求来实现。这一决定是通过检查两个关键上下文来做出的:
身份验证上下文:这包括有关用户的全面信息,例如他们是谁以及他们如何进行身份验证。
命令上下文:这包括与所发出请求相关的所有相关数据。
这些上下文有助于确保只有经过身份验证的用户的合法请求被处理,从而增强Docker操作的安全性。
AuthZ& AuthN - Docker Access Authorization Plugin如果您没有正确限制容器可以使用的资源,则被攻陷的容器可能会对其运行的主机造成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
和日志记录相关的风险。然而,根用户和具有 exec
访问权限的用户仍然可能访问这些机密。
Docker secrets 提供了一种更安全的方法来处理敏感信息。对于在镜像构建阶段需要机密的实例,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 启动服务时使用秘密。
在 Kubernetes 环境中,秘密是原生支持的,并且可以通过像 Helm-Secrets 这样的工具进一步管理。Kubernetes 的基于角色的访问控制 (RBAC) 增强了秘密管理的安全性,类似于 Docker Enterprise。
gVisor 是一个应用内核,使用 Go 编写,实施了 Linux 系统表面的相当大一部分。它包括一个名为 runsc
的 开放容器倡议 (OCI) 运行时,提供了 应用程序与主机内核之间的隔离边界。runsc
运行时与 Docker 和 Kubernetes 集成,使得运行沙箱容器变得简单。
Kata Containers 是一个开源社区,致力于构建一个安全的容器运行时,使用轻量级虚拟机,感觉和表现像容器,但提供 使用硬件虚拟化技术的更强工作负载隔离 作为第二道防线。
不要使用 --privileged
标志或在容器内挂载 Docker 套接字。 Docker 套接字允许生成容器,因此这是完全控制主机的简单方法,例如,通过使用 --privileged
标志运行另一个容器。
丢弃所有能力 (--cap-drop=all
),仅启用所需的能力 (--cap-add=...
)。许多工作负载不需要任何能力,添加它们会增加潜在攻击的范围。
使用“no-new-privileges”安全选项 防止进程获得更多权限,例如通过 suid 二进制文件。
限制容器可用的资源。 资源限制可以保护机器免受拒绝服务攻击。
使用 官方 Docker 镜像 并要求签名,或基于它们构建自己的镜像。不要继承或使用 后门 镜像。还要将 root 密钥、密码短语存放在安全的地方。Docker 计划通过 UCP 管理密钥。
定期 重建 镜像以 应用安全补丁到主机和镜像。
明智地管理您的 秘密,使攻击者难以访问它们。
如果您 暴露 Docker 守护进程,请使用 HTTPS,并进行客户端和服务器身份验证。
在您的 Dockerfile 中,优先使用 COPY 而不是 ADD。ADD 会自动提取压缩文件,并可以从 URL 复制文件。COPY 没有这些功能。尽可能避免使用 ADD,以免受到通过远程 URL 和 Zip 文件的攻击。
为每个微服务 使用单独的容器
不要在容器内放置 ssh,可以使用 “docker exec” 连接到容器。
拥有 更小的 容器 镜像
如果您 在 Docker 容器内 或者您有权访问 docker 组中的用户,您可以尝试 逃逸并提升权限:
Docker Breakout / Privilege Escalation如果您可以访问 Docker 套接字或有权访问 docker 组中的用户,但您的操作受到 Docker 身份验证插件的限制,请检查您是否可以 绕过它:
AuthZ& AuthN - Docker Access Authorization Plugin工具 docker-bench-security 是一个脚本,检查在生产中部署 Docker 容器的数十个常见最佳实践。所有测试都是自动化的,基于 CIS Docker 基准 v1.3.1。 您需要从运行 Docker 的主机或具有足够权限的容器中运行该工具。了解 如何在 README 中运行它: https://github.com/docker/docker-bench-security。
使用 Trickest 轻松构建和 自动化工作流,由世界上 最先进 的社区工具提供支持。 立即获取访问权限:
学习和实践 AWS 黑客攻击:HackTricks 培训 AWS 红队专家 (ARTE) 学习和实践 GCP 黑客攻击: HackTricks 培训 GCP 红队专家 (GRTE)