Kubernetes 信息安全
随着更多的组织开始拥抱云原生技术,Kubernetes 已成为容器编排领域的行业标准。向 Kubernetes 转变的这股潮流,很大程度上简化了容器化应用程序的部署、扩展和管理,并实现了自动化,为传统的单体式系统提供了胜于传统管理协议的众多优势。
然而,管理大规模的 Kubernetes 带来了一系列独特挑战,包括加固集群、保护供应链以及运行时检测威胁。本文结合云原生计算基金会(CNCF)、美国国家安全局(NSA)以及网络安全和基础设施安全局(CISA)的诸多最佳实践,整理出 Kubernetes 安全加固的 6 个建议,帮助组织降低风险。
集群设置和加固
保护 Kubernetes 环境从加固集群开始。对于使用托管 Kubernetes 服务(比如 GKE、EKS 或 AKS)的用户而言,由相应的云提供商管理主节点安全,并为集群实施各种默认安全设置。GKE Autopilot 采取了额外措施,实施 GKE 加固准则和 GCP 安全最佳实践。但即使对于 GKE Standard 或 EKS/AKS 用户而言,云提供商也有一套准则,以保护用户对 Kubernetes API 服务器的访问、对云资源的容器访问以及 Kubernetes 升级。
准则如下:GKE 加固指南 EKS 安全最佳实践指南 AKS 集群安全至于自我管理的 Kubernetes 集群(比如 kube-adm 或 kops),kube-bench 可用于测试集群是否符合 CIS Kubernetes Benchmark 中规定的安全准则。主要的建议包括:加密存储在静态 etcd 中的机密信息、使用 TLS 证书保护控制平面通信以及开启审计日志功能。
网络和资源策略
默认情况下,Kubernetes 允许从任何 pod 到同一集群中另一个 pod 的通信。虽然这对于发现服务而言很理想,但没有提供网络分离,不法分子或中招的系统可以无限制地访问所有资源。如果团队使用命名空间作为 Kubernetes 内部多租户的主要手段,这就成为非常严重的问题。
为了控制 pod、命名空间和外部端点之间的流量,应使用支持 NetworkPolicy API 的 CNI 插件(比如 Calico、Flannel 或针对特定云的 CNI),用于网络隔离。遵照零信任模型,最佳实践是实施默认一概拒绝的策略,阻止所有出入流量,除非另一项策略特别允许。
除了网络策略外,Kubernetes 还提供两个资源级别的策略:LimitRange 和 ResourceQuotas。LimitRanges 可用于限制单个资源的使用(如每个 pod 最多有 2 个 CPU),而 ResourceQuota 控制聚合资源的使用(如在 dev 命名空间中总共有 20 个 CPU)。
RBAC 和服务账户
强大的网络和资源策略到位后,下一步是强制执行 RBAC 授权以限制访问。Kubernetes 管理员可以对用户和用户组强制执行 RBAC 以访问集群,以及限制服务访问集群内外的资源(如云托管的数据库)。另外,企业使用创建时挂载到每个 pod 的默认服务账户时须谨慎。pod 可能被授予过大的权限,这取决于授予默认服务账户的权限。如果不需要与 Kubernetes 服务进行任何特定的通信,将 automountServiceAccountToken 设置为 false,以防止挂载。
系统加固
鉴于集群已安全,下一步是尽量缩小系统的攻击面。这适用于节点上运行的操作系统以及容器上的内核。选择为运行容器而优化的专用操作系统,如 AWS Bottlerocket 或 GKE COS,而不是选择通用的 Linux 节点。接下来,充分利用 Linux 内核安全功能,如 SELinux、AppArmor(自 1.4 起是测试版)及/或 seccomp(自 1.19 起是稳定版)。AppArmor 为 Linux 用户或用户组定义了将程序限制于一组有限资源的权限。一旦定义了 AppArmor 配置文件,带有 AppArmor 标注的 pod 将强制执行这些规则。
即使没有 seccomp 配置文件,用户仍然可以限制容器免受各种权限提升攻击。在安全上下文中,Kubernetes 允许配置容器是否可以以特权或 root 身份来运行,或者将权限升级到 root。用户还可以限制 hostPID、hostIPC、hostNetwork 和 hostPaths。所有这些设置都可以通过 Pod Security Policy(v1.21 中已被弃用)或使用其他开源工具(比如 K-Rail、Kyverno 和 OPA/Gatekeeper)来执行。
最后,如果需要额外的安全保证,可以配置自定义的 RuntimeClass,以便充分利用硬件虚拟化(如 gVisor 或 Kata)。在节点层面定义 RuntimeClass,并在 pod 定义部分指定它。
供应链安全
即使集群和系统安全,为保证整个应用程序的端到端安全,也必须考虑到供应链。若是内部开发的应用程序,请遵循创建容器的最佳实践,即使用最小基础镜像以减小攻击面、固定软件包版本,并使用多阶段构建以创建小镜像。此外,定义容器运行所需的非 root 用户,或使用 podman 构建无 root 容器,以限制 root 访问。
下一步,使用开源工具(如 Trivy、Clair 或 Anchore)或者商用工具扫描所有镜像,以查找漏洞。一些工具还允许对镜像进行签名和验证签名,以确保容器在构建和上传过程中未被篡改。最后,定义 Kubernetes 可以使用 ImagePolicyWebhook 或上面提到的任何策略执行工具从中提取镜像的白名单注册表。
监控、日志和运行时安全
至此,我们有了一个供应链严加保护的安全集群,可以生成干净的、经过验证的镜像,有限的访问权限。然而环境是动态的,安全团队需能够响应运行环境中的事件。首先,将 readOnlyRootFilesystem 设置为 true,并将 tmp 日志文件存储到 emptyDir,以此确保容器在运行时不变。除了典型的应用程序监控(如 Prometheus/Grafana)或日志(如 EFK)存储外,还可以使用 Falco 或 Sysdig 来分析系统调用进程和 Kubernetes API 日志。
这两种工具都可以在运行时解析来自内核的 Linux 系统调用,并在违反规则时触发警报。示例规则包括:权限提升时发出警报,已知目录上检测到读/写事件时发出警报,或调用 shell 时发出警报。最后,将 Kubernetes API 审计日志与现有日志聚合和警报工具整合起来,以监控集群中的所有活动。这包括 API 请求历史记录、性能指标、部署、资源消耗、操作系统调用和网络流量。
总结由于云原生系统很复杂,需要采用多层方法来保护 Kubernetes 环境。建议 Kubernetes 做好云原生安全的 4C:云、集群、容器和代码。首先,加固集群,并遵循云安全最佳实践;其次,严加保护容器,减小攻击面,限制访问,并确保运行时不变;再次,保护供应链,分析代码和容器以查找漏洞。最后,监控运行时的所有活动,将防御机制融入 Kubernetes 内运行的每一层软件中。
版权声明: 本文为 InfoQ 作者【CTO技术共享】的原创文章。
原文链接:【http://xie.infoq.cn/article/17bd0ea4a1f5d85999d552fd5】。文章转载请联系作者。
评论