本文包括帮助您安全使用Docker如果你是的话Docker建议你先阅读我以前的新手Docker概念,Docker生态系统,Dockerfile,简化图像,常用命令和Docker文章中的数据。
如何关注你需要的Docker 这取决于安全性Docker是否内置了明智的安全功能。如果你使用官方功能Docker如果图像没有与其他计算机通信,则无需担心。
但是,如果你使用非官方镜像,提供文件或在生产环境中运行应用程序,情况就会有所不同。在这种情况下,你需要正确Docker对安全有更多的了解。
您的主要安全目标是防止恶意用户获取有价值的信息或造成严重损害。为此,我将在几个关键领域分享Docker最好的安全实践。 到本文结尾,你会看到20多个Docker安全提示!
在第一部分,我们将重点关注三个领域:
- 访问管理
- 镜像安全
- 机密管理
首先,让我们来看看限制容器的访问权限。
访问管理-限制权限
启动容器时,Docker创建一组命名空间。命名空间可以防止主机(包括其他容器)中的过程被看到或影响。 命名空间是Docker封锁一个容器和另一个容器的主要方法。
Docker还提供私有容器网络。这可以防止容器访问同一主机上其他容器的网络接口。
因此,Docker环境在某种程度上是孤立的,但对于你的用例,它可能不够孤立。
> Does not look safe
良好的安全意味着遵循最小的特权原则。您的容器应该有执行所需功能的能力,但没有其他能力。 困难的是,一旦您开始限制可以在容器中运行的过程,容器可能无法执行其合法操作。
调整容器权限的方法有几种。首先,避免root身份操作(如果必须的话)root如果身份运行,应重新映射)。 其次,使用–cap-drop和–cap-add调整功能。
大多数人需要做的是避免root并调整功能以限制特权。更先进的用户可能希望调整默认情况AppArmor和seccomp配置文件。 我将出版相关文件Docker这些内容在书中讨论,但这里已经排除在外,以防止本文如期膨胀。
避免以root身份运行
Docker默认设置是使图像中的用户root用户身份运行。许多人没有意识到它有多危险。这意味着攻击者更容易访问敏感信息和你的核心。
一般来说,最好的方法是不要让容器使用root运行用户身份。
> Roots
"防止容器内部特权升级攻击的最佳方法是将容器应用程序作为非特权用户配置。" — Docker文档。
在工时可指定root以他用户名,如下所示:
在上述示例中,1000是任何非特权用户标志。Linux通常在0到499之间保留用户ID。 选择500多个用户ID,避免作为默认系统用户运行。
最好从镜像开始root用户更改用户,而不是从命令行设置用户。这样,人们就不必记得在构建时进行更改。 只需要root附带功能的Dockerfile指令包含在图像中USER Dockerfile指令。
换句话说,首先安装所需的软件包,然后切换用户。
您可以通过更改功能来授予用户所需的特权。
能力
功能是允许的流程包。
使用–cap-drop和–cap-add通过命令行调整功能。最好的策略是使用它–cap-drop all删除容器的所有特权,并使用它–cap-add重新添加所需的特权。
> Stop or go
操作时可以调整容器的功能。例如,放弃使用kill为了停止容器的功能,可以删除默认功能,如下所示:
禁止容器在1到1023之间使用端口号更安全,因为大多数网络服务都在这个范围内运行。 未经授权的用户可以听取登录等内容,并运行未经授权的服务器应用程序。 这些较低的端口需要使用root用户身份运行或明确赋予CAP_NET_BIND_SERVICE功能。
要查找诸如容器是否具有特权端口访问权限之类的信息,可以使用inspect。使用docker container inspect my_container_name向您展示许多关于容器分配资源和安全配置文件的详细信息。
这是Docker参考,更多关于特权的信息。
与Docker与大多数事情一样,最好在自动自文档文件中配置容器。Docker Compose,您可以在服务配置中指定功能,如下所示:
Linux这里是功能的完整列表。
如果您想控制更细粒度的容器特权,请在我即将出版的书中查看我AppArmor和seccomp讨论。 订阅我的电子邮件通讯,以便在可用时得到通知。
> Closed road
访问管理-限制资源
最好限制容器的内存和内存CPU访问系统资源。容器可以使用所有可用内存,没有资源限制。 如果发生这种情况,Linux将抛出主机内核"内存不足"内核过程异常并被杀死。这可能会导致整个系统崩溃。 你可以想象攻击者如何使用这些知识来关闭应用程序。
如果您在同一台计算机上运行多个容器,您可以明智地限制任何容器可以使用的内存和内存CPU。如果您的容器内存不足,则关闭。 关闭容器可能会导致应用程序崩溃,这很有趣。然而,这种隔离可以防止主机内存不足,并防止主机上的所有容器崩溃。这是件好事。
> Wind resource
适用于Mac v2.1.0的Docker Desktop CE有默认资源限制。Docker图标->访问它们的首选。 然后单击"资源"选项卡。您可以使用滑块来调整资源限制。
> Resource settings on Mac
另外,您可以指定–memory标志或-m缩写限制命令行中的资源,然后跟随数字和测量单位。
4m表示4兆字节,是最小的容器内存分配。(MiB)略大于兆字节(1 MiB = 1.048576 MB)。 目前文档不正确,但希望维修人员在您阅读本文时接受我PR进行更改。
检查您的容器正在使用哪些资源,请在新的终端窗口输入命令docker stats。您可以在操作中定期刷新容器统计信息。
> Stats
在后台,Docker正在使用Linux控制组(cgroup)实现资源限制。该技术已通过实战测试。
了解这里的相关信息Docker更多关于资源限制的信息。
镜像安全
从Docker Hub抓取镜像就像邀请某人进入你的家。你可能想知道。
> Someone's home
使用值得信赖的镜像
镜像安全的规则之一是只使用你信任的镜像。你怎么知道哪些镜像可靠?
当然,流行的官方镜像相对安全。这种镜像包括alpine,ubuntu,python,golang,redis,busybox和node。 每个下载量超过1000万,很多人关注它们。
Docker解释:
与使用正式基础镜像有关,您可以使用最小基础镜像。
由于内部代码较少,安全漏洞的可能性较小。较小且不复杂的基本图像更透明。
与朋友的镜像(依赖于朋友的镜像,依赖于另一个基本镜像)相比,查看Alpine镜像中发生的事情要容易得多。短期内更容易解决。
> Tangled
同样,只安装您实际需要的软件包。这样可以减少攻击面,加快镜像下载和镜像构建。
图像镜像需要签名
您可以使用Docker信任内容,确保签名镜像。
Docker除非包含签名,否则内容信任阻止用户使用带标签的镜像。可信来源包括来自标签的来源Docker Hub的Official Docker Images以及用户可信来源的签名镜像。
> Signed
默认情况下禁止内容信任。如果要使用它,请使用它DOCKER_CONTENT_TRUST环境变量设置为1。在命令行中,操作以下命令:
Docker对其内容进行加密验证、存储和访问图像。这样可以防止攻击者产生图像冲突。内置安全功能很酷。
管理密码
您的访问受到限制,镜像安全,现在该管理您的密码了。"
管理敏感信息的规则1:请勿将其添加到您的镜像中。在代码存储库、日志和其他地方找到未加密的敏感信息并不难。
规则2:不要在敏感信息中使用环境变量。任何可以在容器中运行的东西docker inspect或exec人们可以找到你的密码。root任何操作身份的人都可以。希望我们已经做了一些配置,让用户不会这样做root用户身份运行,但冗余是良好安全性的一部分。 通常,日志也会存储环境变量值。您不希望您的敏感信息只泄露给任何人。
Docker卷得更好。建议使用它们。Docker访问您在文档中的敏感信息。您可以将卷作为存储在内存中的临时文件系统。docker inspect和日志记录风险。root用户仍然可以看到秘密,任何可以执行到容器中的人都可以看到秘密。一般来说,卷是一个很好的解决方案。
请使用比卷好的Docker Secret。Secret已加密。
> Secrets
一些Docker文件指出你只能在那里Docker Swarm使用机密。然而,你可以没有Swarm的情况下在Docker使用机密。
如果只需要图像中的秘密,可以使用BuildKit。BuildKit是目前用于构造的Docker图像构建工具的后端更好。 它大大缩短了施工时间,并具有其他良好的功能,包括支持施工时间秘密。
BuildKit相对较新-Docker Engine 18.09是BuildKit支持第一版附带。 有三种方法可以指定BuildKit后端,所以你可以立即使用它的功能。未来,它将是默认的后端。
- 使用export DOCKER_BUILDKIT = 1将其设置为环境变量。
- 使用DOCKER_BUILDKIT = 1启动构建或操作命令。
- 默认情况下启用BuildKit。使用以下命令将/etc/docker/daemon.json中间的配置设置为true:{" features":{" buildkit":true}}。然后重启Docker。
这些Secret最终图像不会存储。它们也被排除在图像构建缓存中。安全第一!
如果您需要操作容器中的容器Secret,而不仅仅是在构建图像时,请使用Docker Compose或Kubernetes。
使用Docker Compose,将secrets将键值添加到服务中并指定secret文件。重写以下示例。Docker Compose秘密的Stack Exchange回答技巧。
带有Secret的示例docker-compose.yml:
假如你用的是Kubernetes,它支持秘密。Helm-Secrets有助于简化K8秘密管理。K8和Docker Enterprise同样,它们都有基于角色的访问控制(RBAC)。RBAC访问团队秘密管理更容易管理,更安全。
Secret最好的方法是使用机密管理服务,例如Vault。Vault是HashiCorp用于管理机密访问的服务 Secret。你可以在这里找到相关信息Vault的Docker更多的图像信息。
AWS Secrets Manager类似于其他云提供商的产品也可以帮助您管理云中的机密。
> Keys
请记住,保持机密是管理机密的关键。千万不要把它们添加到你的镜像中,也不要把它们变成环境变量。
更新
像任何代码一样,保持镜像中的语言和库最新,从最新的安全修复程序中受益。
> Hopefully your security is more up to date than this lock
如果您在镜像中引用了基本镜像的特定版本,请确保它是最新的。
相关地,您应该使Docker保持最新版本,进行错误的修复和增强,以允许您实现新的安全功能。
最后,最新保持主机服务器软件。如果您使用托管服务,您应该完成此操作。
更好的安全意味着保持更新。
考虑Docker Enterprise
如果你的组织有一堆人和一堆人Docker容器,那么你可以从Docker Enterprise受益。管理员可以为所有用户设置战略限制。RBAC,监控和日志记录功能可能会使您的团队更容易安全管理。
借助Enterprise,您还可以在Docker Trusted Registry私有地托管自己的形象。Docker提供内置的安全扫描功能,的漏洞,提供内置的安全扫描功能。
Kubernetes有些功能是免费提供的,但是Docker Enterprise对容器和图像有额外的安全功能。最好的是,Docker Enterprise 3.0发布于2019年7月。"明智的安全默认设置"的Docker Kubernetes服务。
其他提示
- 除非你有特殊需要,否则永远不要以特权的形式操作容器,例如Docker容器中运行Docker,你知道你在做什么。
- 在Dockerfile建议使用COPY而不是ADD。ADD压缩文件可自动提取URL复制文件。COPY没有这些功能。 尽量避免使用ADD,这样,你就不会从远程得到它URL和Zip攻击文件。
- 如果您在同一服务器上运行任何其他过程,请在同一服务器上运行Docker它们在容器中运行。
- 如果使用网络服务器和API创建容器,请仔细检查参数,以免创建你不想要的新容器。
- 如果公开REST API,请使用HTTPS或SSH保护API端点。
- 考虑使用Docker Bench for Security检查以了解您的容器遵循其安全标准的程度。
- 将敏感数据存储在卷中而不是容器中。
- 如果单主机应用程序与网络一起使用,请不要使用默认的桥接网络。它有技术缺陷,不荐生产。 如果端口发布,可以访问桥接网络上的所有容器。
- 将Lets Encrypt用于HTTPS服务证书。在这里查看相关信息。NGINX的示例。
- 只有在需要阅读取卷时,才能将卷挂载为只读。请参阅这里的几种方法。
你知道很多使者Docker容器更安全。安全不是一成不变的。为了保证镜像和容器的安全,需要保持警惕。
> Keys
考虑安全时请记住AIM:
(1) 访问管理
- 避免作为超级用户运行。必须使用root,再次映射。
- 删除所有功能,然后重新添加所需功能。
- 如需调整细粒度的权限,请进入AppArmor。
- 限制资源。
- 使用官方、流行、最小的基本镜像。
- 不要安装不必要的东西。
- 要求签名镜像。
- 保持Docker,Docker图像和其他和Docker更新相关软件。
- 使用Secret或卷。
- 例如,考虑机密管理器vault。
> Bullseye!
保持Docker容器安全意味着实现安全的目标。
不要忘了让Docker,保持更新您的语言和库、图像和主机软件。最后,如果你是团队的一部分Docker,请考虑使用Docker Enterprise。
希望本文对Docker安全性有所帮助。如果您这样做了,请在您喜欢的论坛或社交媒体频道上与其他人分享它,以便您的朋友也可以找到它!