Logo
Section 1 / 2

Docker 安全:漏洞与最佳实践

使用 Docker 时遵循最佳实践的指南

导入

Docker 安全:漏洞与最佳实践

使用 Docker 时遵循最佳实践的指南

Docker 相较于传统虚拟机带来了巨大的优势。然而,其大多数组件与主机内核共享。如果未采取适当的安全措施,主机系统可能面临被攻破的风险,攻击者甚至可能完全控制主机。

在本课程中,我们将了解一些 Docker 的安全漏洞、最佳实践以及实用的安全建议。

风险

使用 Docker 容器和镜像存在多种风险。

主机访问权限

由于容器共享主机的内核来运行进程,一旦容器内核被攻破,攻击者就可能利用或攻击整个主机系统。

容器逃逸

如果用户能够突破容器的命名空间限制,该容器将可以与主机上的其他进程交互,甚至停止或终止这些进程。

资源过度占用

若未对容器的资源使用进行限制,容器可能耗尽主机的所有资源,导致其他服务无法运行而中断。

使用不受信任镜像带来的攻击风险

Docker 允许运行 Docker Hub 上的所有镜像以及本地构建的镜像。当从不可信来源运行镜像时,攻击者恶意程序可能获得对内核的访问权限,或窃取容器及挂载卷中的全部数据。

降低风险的最佳实践

无论采取何种措施,安全都可能在任何层面被突破,没有人能完全消除安全风险。但通过遵循一些最佳实践,我们可以有效降低风险,确保关闭所有可能让攻击者访问主机系统的入口。

容器生命周期管理

通过容器生命周期管理流程,建立创建、更新和删除容器的审查机制。在创建容器时即落实各项安全措施。当更新容器时,不应仅审查更新层,而应重新审查所有层。

信息安全管理

切勿在镜像中推送任何敏感信息,如密码、SSH 密钥、令牌、证书等。这些信息应加密并存储在密钥管理工具中。只有在服务运行时才应明确授予其访问权限。

禁止以 root 权限运行

容器绝不应以 root 权限运行。采用基于角色的访问控制(RBAC)可减少误操作导致对同一命名空间中其他进程的访问。许多组织通过 Active Directory 实施权限控制,并根据用户角色分配相应权限。

通常,我们可以使用 Linux 内置命令动态创建临时非 root 用户。

1FROM python:3.5 2RUN groupadd -r myuser && useradd -r -g myuser myuser 3<在此处执行需要 root 权限的操作,例如安装包> 4USER myuser

或者在运行容器时指定:

1docker run -u 4000 python:3.5

这将使容器以非 root 用户身份运行。

使用可信的镜像源

在从 Docker Hub 拉取镜像时,务必验证其真实性。使用 Docker 内容信任来验证镜像的真实性。Docker 内容信任是 Docker 1.8 引入的新功能,默认处于禁用状态。启用后,可验证来自 Docker Hub 的所有镜像的完整性、真实性和发布日期。

通过 export DOCKER_CONTENT_TRUST=1 启用 Docker 内容信任,尝试拉取一个未签名的镜像:

1$ docker pull jpetazzo/clock 2Using default tag: latest 3Error: remote trust data does not exist for docker.io/jpetazzo/clock: notary.docker.io does not have trust data for docker.io/jpetazzo/clock

Docker 将检查镜像是否可信,若不可信则会报错。

限制资源使用

Docker 最受喜爱的功能之一是能够为容器预设资源使用策略。此功能仅在 Swarm 模式下支持。还记得我们 docker-compose.yml 文件中的 deploy 部分吗?

我们可以在 deploy 部分中声明容器允许使用的 CPU 限额。以下是官方文档中的示例:

1version: "3.8" 2services: 3 redis: 4 image: redis:alpine 5 deploy: 6 resources: 7 limits: 8 cpus: '0.50' 9 memory: 50M 10 reservations: 11 cpus: '0.25' 12 memory: 20M

这样可以确保任何容器都不会超过设定的资源阈值,从而保障主机上其他服务的正常运行。

谨慎使用 Docker 套接字

在可视化服务中,我们已将 Docker 套接字 /var/run/docker.sock 挂载到容器中。绑定挂载 Docker 守护进程套接字会使容器拥有强大的控制能力,因为它可以直接操控 Docker 守护进程。因此必须谨慎使用,仅对可信赖的容器开放。许多第三方工具在使用时要求挂载该套接字。

在使用此类服务前,应通过 Docker 内容信任和漏洞管理流程进行验证。

我们在可视化服务容器中挂载 Docker 套接字,是因为该镜像是 Docker 官方镜像,可通过 Docker 内容信任和 Docker 安全基准测试 进行验证。

以只读方式挂载卷

最佳实践之一是:如果容器不需保存数据,应将主机文件系统以只读方式挂载。只需在使用 -v 参数时添加 ro 标志,或在使用 --mount 参数时添加 readonly 选项即可实现。

示例:

1$ docker run -v volume-name:/path/in/container:ro python:3.5

或

1$ docker run --mount source=volume-name,destination=/path/in/container,readonly python:3.5

在下一课中,你将在部署 Flask 应用为生产环境应用时实际看到这一做法。

这些最佳实践已被各组织纳入标准开发流程,开发者需严格遵守。作为独立开发者,遵循这些实践同样有助于提升代码质量。在下一课中,我们将对应用进行必要的调整,使其具备生产环境部署条件。当你掌握本课内容后,即可进入最后一课,完成生产环境部署。

了解 Docker Swarm

使用 Nginx 部署 Flask 微服务