写点什么

云原生系列三:K8s 应用安全加固技术

作者:叶秋学长
  • 2022-11-08
    福建
  • 本文字数:3250 字

    阅读完需:约 11 分钟

今天叶秋学长带领大家学习云原生系列三:10 大 K8s 应用安全加固技术~

本文译自 Top 10 Kubernetes Application Security Hardening Techniques[1]。作者:Rory McCune



将应用部署到 K8s 集群时,开发者面临的主要挑战是如何管理安全风险。快速解决此问题的一个好方法是在开发过程中对应用清单进行安全加固。本文,将介绍 10 种开发者可以对应用程序应用加固的方法。

以下技术允许在开发过程中测试强化版本,从而降低在生产环境中应用的控件对运行工作负载造成不利影响的风险。此外,没有强制性控制的集群中,比如 Pod 安全策略,自愿加固可以帮助降低容器突破攻击的风险。

一般方法

在编写 K8s 工作负载清单时,无论是 pod 对象还是部署 daemonset 之类的更高级别的东西,清单中都有一个名为 securityContext 的部分,允许您指定应该应用于工作负载的安全参数。

例如,下面的代码显示了一个更改其功能



下面将详细介绍这些不同部分的工作原理,但从这里你可以看到使用的一般结构。

runAsUser, runAsGroup

默认情况下,Docker 容器以 root 用户的身份运行,从安全角度看这并不理想。虽然对容器内部的访问权限仍有限制,但在过去一年中,出现了多个容器漏洞,只有在容器以 root 用户身份运行时才能利用这些漏洞,确保所有容器以非 root 用户身份运行是一个很好的加固步骤。

在基本层面上,在 pod 清单中配置这个是相当简单的。最好的方法是将 security Context 中的 runAsUser 和 runAsGroup 字段设置为非 0 值。



然而,在执行此操作时,重要的是要确保容器在以非 root 用户身份运行时能够正常工作。如果原始容器镜像被设计为以 root 身份运行,并且有限制性的文件权限,可能会导致应用程序的运行出现问题。

最好的办法是确保在容器的 Dockerfile 中设置相同的 UID/GID 组合,以便在整个开发和测试过程中使用该组合运行。可以通过在 Dockerfile 中设置 USER 指令来做到这一点。按照上面的示例,此行将设置相同的 UID 和 GID 组合:



Privileged

Docker 和类似的容器运行时提供 Privileged 标志,作为从容器中移除安全隔离的便捷方法。这不应该在应用工作负载中使用,而应该只在完全必要的情况下使用。

一般来说,Linux 容器有相当灵活的安全模型,因此如果容器的运行需要特定的权限,则可以添加该权限,而无需使用总括 Privileged 设置。

在设计容器清单时,关键是在每个清单的 securityContext 中默认将 privileged 设置为 false,这样就可以清楚地看到它应该在没有这些权限的情况下运行。



Capabilities

Linux 能力是用于为进程提供传统上为 root 用户保留的一个或多个方面的权限。默认情况下,Docker 和其他容器运行时将为容器提供可用能力的子集。

一个好的加固步骤是仅允许应用程序特别需要的能力。如果你的应用程序设计为以非 root 用户身份运行,那么它根本不需要任何能力。

一般来说,对能力的处理方法应该是首先删除所有的能力,如果你的应用需要这些能力,再把特定的能力加回来。举个例子,如果你需要 CHOWN 能力,你会有这样的 securityContext:



Read Only Root File system

你可以使用这个设置来利用容器的短暂性。通常,运行中的容器不应该在容器文件系统中存储有关应用程序的任何状态。这是因为它们可能随时被降速并在集群的其他地方创建新版本。

在这种情况下,你可以在工作负载清单中设置 readOnlyRootFilesystem 标志,这将使容器的根文件系统成为只读。这可能会让那些在发现应用漏洞后试图在容器中安装工具的攻击者感到沮丧。

与此设置有关的一个常见问题是如何处理应用程序进程运行时需要的临时文件。处理这些的最佳方法是在容器中挂载一个 emptyDir 卷,允许文件被写入某个位置,然后在容器被销毁时自动删除。

设置 readOnlyRootFilesystem 是 securityContext 中一个简单的布尔值。



AllowPrivilegeEscalation

Linux 内核公开的另一个安全设置,这通常是一个很好的、低影响的加固选项。此标志控制子进程是否可以获得比其父进程更多的权限,对于在容器中运行的应用进程来说,它们的运行很少需要这样做。



Seccomp

清单最后一个值得关注的安全层是 Seccomp。Seccomp 配置文件可以阻止访问可能导致安全风险的特定 Linux 系统调用。默认情况下,Docker 等容器运行时提供了一个系统调用过滤器,可以阻止对一些特定调用的访问。但是,在 K8s 下运行时,该过滤器在默认情况下是禁用的。

因此,确保重新启用过滤器是对工作负载清单的重要补充。你可以使用运行时的默认配置文件,或者(如 AppArmor 和 SELinux)提供一个自定义的配置文件。



​ 在 1.19 及更高版本中,seccomp 过滤器已被集成到 securityContext 字段中,因此要设置一个 pod 使用默认的 seccomp 过滤器,你可以使用下面的方法:



Resource limits

由于 K8s 工作负载共享底层节点,因此确保单个容器不能使用节点上的所有资源非常重要,这可能会导致集群中运行的其他容器出现性能问题。在容器层面,可以设置资源限制,指定容器所需的资源数量以及允许的资源数量限制。

一个容器资源请求的示例如下。这不是在 securityContext 中设置的,而是在通用容器规范中设置的。



​编辑虽然内存请求和限制是相当直截了当的,但 CPU 的限制可能不那么明显。它们实际上是以 "毫秒 "为单位的,其中 1,000 等于一个 CPU 核心或超线程。因此,在上面的例子中,请求是针对一个核心的 25%,而限制是针对一个内核的 50%。设计资源限制时要注意的另一件事是,容器运行时超出限制将如何反应。对于 CPU 来说,进程将受到限制,有效地降低了它的性能。然而,如果超过了内存限制,容器可能会终止进程,所以确保限制符合应用程序在正常操作中可能合理的请求内容非常重要。


imageTag

Docker 风格的容器通常是通过提供镜像名称和标签名称来指定。Docker 有一个特殊情况,就是如果没有指定标签,就会使用 "latest "标签。然而,随着镜像注册表的更新,使用的确切的镜像可能会改变。例如,如果一个操作系统有了新的版本,最新的标签可能会改变为新版本。

这种缺乏固定目标的情况下使得指定要在 pod 中使用的容器镜像时,使用未指定的标签或特别是 "latest "标签是个坏主意。相反,使用一个明确的标签,你可以使用注册表中存在的命名标签,或者使用唯一标识它的 SHA-256 哈希值来指定一个镜像,来做到这一点。

使用第一个选项,为每个容器指定镜像和标签。这种方法,仍然依赖于维护者不以损害部署的方式修改镜像,因为标签通常是可变的指针,可以被重定向到另一个镜像。



​编辑如果你指定了 SHA-256 哈希值,则仅使用与该哈希值特别对应的镜像。但这是一个高维护选项,因为每次修补镜像时都必须更新清单以反映新的哈希值。 

在撰写本文时,与上述指定镜像等效的是:



AppArmor

该选项适用于使用 AppArmor 的 Linux 发行版(主要是 Debian 衍生的发行版本)。AppArmor 可以增加一个强制性的安全执行级别,即使其他隔离层失败或被攻击者绕过,也能提供保护。

如果你不指定 AppArmor 策略,容器运行时的默认值将适用,因此在许多情况下,无需向应用程序清单添加明确的声明。但是,如果你确实想添加自定义的 AppArmor 配置文件来进一步加固你的容器,则需要注意的是,与大多数其他加固设置不同,它不在 securityContext 字段中设置。相反,它是通过清单元数据中的自定义注解来完成的(在 K8s 的未来版本中有一个更改此行为的提案)。

指定的配置文件必须提前放在集群节点上,然后在下面的例子中代替指定。



SELinux

这个选项适用于使用 SELinux 的 Linux 发行版(主要是 Red Hat 系列)。SELinux 的工作方式类似于 AppArmor,为进程增加了额外的安全层。

但是,配置策略稍微复些,而且它将取决于容器运行时和主机操作系统的组合是否启用。

与 AppArmor 一样,创建自定义 SELinux 策略在安全性更高的环境中可能很有用,但在大多数情况下,使用默认策略将提供有用的额外安全层。

总结

创建一个安全的 K8s 环境有很多方面,从控制平面到集群上运行的应用程序。主动加固用于部署工作负载的 K8s 清单是这一过程的重要组成部分,如果在开发生命周期的早期完成,可以显著提高安全性并降低漏洞风险。

引用链接

[1]

原文链接: https://blog.aquasec.com/kubernetes-hardening-techniques

本期分享到期为止,关注博主不迷路,叶秋学长带你上高速~~ 

发布于: 刚刚阅读数: 4
用户头像

叶秋学长

关注

还未添加个人签名 2022-07-01 加入

全栈JAVA领域创作者

评论

发布
暂无评论
云原生系列三:K8s应用安全加固技术_#k8s_叶秋学长_InfoQ写作社区