本访客文章最初发表在ARMO的博客上,作者是Armo的CTO兼联合创始人Leonid Sandler。
对于在共享基础设施上运行的容器化应用程序来说,安全是至关重要的。随着越来越多的组织将其容器工作负载转移到Kubernetes,K8s已经成为容器协调的首选平台。而随着这一趋势,威胁和新的攻击方式也越来越多,有必要加强所有的安全层。
在Kubernetes中,安全问题有两个方面:集群安全和应用安全。我们已经在另一篇文章中介绍了集群安全。在这篇文章中,我们将探讨如何确保Kubernetes部署和一般应用程序的安全。
0x01 基础回顾
在这里,我只想快速回顾一下基础知识。Pod是逻辑原子单元,在集群中运行一个或多个容器;它被其他资源包裹着,如ReplicaSet、Deployment、StatefulSets等。有各种方法来提高在Kubernetes中运行的应用程序的安全态势。
在Kubernetes部署中,模板部分包含pod规格,它定义了这个部署要运行的工作负载。在下面的模板中,有几个与安全有关的部分用黑体字突出显示。
现在,让我们仔细看一下pod规格中的这些部分。
0x02 服务账户
当容器内的进程与API服务器进行通信时,你应该使用服务账户进行验证。如果你没有为pod定义一个服务账户,那么将使用默认的账户。建议创建一个特定于应用程序的服务账户,该账户具有执行该功能所需的最小权限。如果你选择给默认的服务账户赋予角色,这些特权将对每个没有在规格中定义服务账户的pod可用。这可能会无意中允许对其他应用程序的过度许可,因此不建议这样做。在Kubernetes 1.6及以上版本中,你可以通过设置退出为容器中的服务账户自动装载API令牌。
0x03 安全环境
安全环境定义了pod和容器中的权限和访问控制设置。下面是几个安全环境的重要内容。
- seLinuxOptions(安全增强型Linux):此应用提供更细化的访问和控制策略的机制。
- runAsUser和runAsGroup:特定的UserID或GroupID(UID和GID)来运行容器进程的入口点;如果没有指定,则各自默认为镜像元数据中指定的用户(在Windows容器中都不适用)。
- privileged:以特权模式运行容器,默认为假;与主机上的root(具有所有能力)相同。
- runAsNonRoot:容器必须以非root用户的身份运行(如果Kubelet在运行时验证的UID为0,容器将无法启动)。
- 能力:在运行容器时添加或删除能力;容器运行时授予能力,这是默认的。
- procMount:指定容器的proc mount类型,默认为DefaultProcMount;这使用容器运行时默认的只读和屏蔽的路径。
- AppArmor:与SELinux类似,可以通过配置文件限制单个程序的能力。
- seccompProfile:容器要使用的secomp选项;过滤进程的系统调用。
- readOnlyRootFilesystem:将容器中的根文件系统挂载为只读,默认为假。
- AllowPrivilegeEscalation:决定一个进程是否可以获得比它的父进程更多的权限;如果容器以特权运行或具有CAP_SYS_ADMIN能力,它总是为真。这个字段必须明确设置为false,因为它的默认行为可以在PSP中被改变。
0x04 图像
源图像通常取自各种公共资源库;开发人员将他们的应用程序代码放在这些基础图像之上。你也可以直接从流行的公共注册中心部署OOTB应用程序。
关于图像有三件事要记住,我们将在下面讨论。
1、图像的来源
确保你从一个受信任的注册中心获得图像。攻击者可以在公共注册表中放置一个恶意的图像,这反过来会导致数据泄漏或攻击者获得对你的集群的访问权等问题。一些公共图像也被发现被加密货币矿工所感染。
作为一个组织,你可以创建基础镜像的黄金镜像,并与开发人员分享,然后他们可以从内部存储库中安全地使用这些镜像。
2、无分布式和容器优化的图像
这些镜像是安全的,并且经过优化,可以在容器中运行,为潜在的攻击提供了一个较小的表面积。它们只包含你的应用程序和依赖的库,而软件包管理器、外壳和通常在Linux操作系统上可用的程序被删除。
3、持续的漏洞扫描
强烈建议实施持续的图像扫描,以检测容器图像中的漏洞、恶意软件和其他安全威胁(例如,未经授权连接到不信任的网络)。有许多可用的安全解决方案,包括Kubescape。
0x05 Pod安全准入
你可能听说过PodSecurityPolicies,它现在已经被弃用,并将在Kubernetes 1.25中被删除。Pod Security Admission(PSA)将取代它,处理安全和其他安全相关的要求。它为pod定义了不同的隔离级别,如特权、基线和限制。PSA目前在1.23的测试阶段。
这些级别在Kubernetes的Pod安全标准中有详细描述,但下面是Kubernetes自己文档中的摘要。
Pod Security admission与内置的Pod Security admission控制器一起工作;你需要在集群中使用-feature-gate="...,PodSecurity=true "或通过使用pod admission webhook来启用它。它是在命名空间级别应用的,标签如下。
0x06 秘密信息使用
如果你有敏感信息(如凭证、令牌、加密密钥和证书)在应用程序中可用,请使用Kubernetes Secrets。你可以用字面值或文件创建Secrets,然后将其挂载到pod中。不要在容器镜像和Git存储库中存储此类信息。
在使用Secrets时,最好不要使用环境变量将凭证投射到容器中,而是使用文件。
请记住,Secrets是base64编码的值。它们没有被加密,所以对安全对象的访问必须受到限制,而且你应该在API服务器中写入时启用加密功能。
0x07 总结
Kubernetes提供了各种方法来改善你的组织的安全态势。开发人员需要考虑这些结构,使他们的应用程序更安全。
扼要重述:
- 为每个应用程序使用服务账户,并将服务账户与最小的角色和权限要求绑定,以实现你的目标。
- 如果你的应用程序中不需要服务账户令牌,就不要自动安装它。
- 使用安全上下文来实现各种技术,例如防止容器在特权模式下作为根用户运行,使用SELinux或AppArmor配置文件等。
- 确保你的容器镜像的来源是值得信赖的,如果可能的话,将它们存储在私有注册表中。
- 尽量使用容器优化的镜像,减少表面积,以减少威胁。
- 部署一个持续的漏洞扫描解决方案,不仅在CI/CD中,而且在集群中,可以实时监测和采取行动。
- 使用Pod Security接纳配置文件和模型,为你的工作负载提供不同的隔离级别。
- 使用Secrets来存储敏感信息,并应用最小权限的RBAC来限制用户/SA的秘密访问。
这对于应用程序开发人员来说,可能会显得有些力不从心。像Kubescape这样的工具可以帮助进行风险分析,在CI/CD中执行安全标准,易于理解的RBAC可视化,自动漏洞扫描,以及更多。Kubescape协助开发人员实现其应用程序的安全部署。
本文为翻译文章,原文链接:https://www.cncf.io/blog/2022/05/02/how-to-secure-deployments-in-kubernetes/