解析美国国安局 (NSA) 和 CISA 发布的 Kubernetes 强化指南

解析美国国安局 (NSA) 和 CISA 发布的 Kubernetes 强化指南

Kubernetes 作为容器化调度平台已经逐渐在许多企业和生产环境中属于不可或缺的基础设施一部分。然而,由于其复杂性,Kubernetes 的执行环境也面临着许多安全挑战和潜在的问题。美国国安局(NSA)与网络安全暨基础架构安全署(CISA)在 2022 年发布了一份名为 Kubernetes Hardening Guidance 的网络安全报告 1 (完整文件 2)。作为强化 Kubernetes 指南,指南中除了旨在为 NSA、CISA 以及对于美国联邦和公家机关作为运行 Kubernetes 集群关键基础设施的相关强化方针,更详述了 Kubernetes 环境潜藏的安全威胁,并提供了相关设定指引,以尽可能地降低其安全风险。对于 Kubernetes 管理者来说,该指南实则一份十分有用的参考资源。

提供 Kubernetes 强化指南的目的

这份指南的目旨在提供使用 Kubernetes 时的最佳安全实践,从而降低其面临的风险。在这份文件中,提及了各种主题,从身份验证、授权、网络安全以及监控策略,并提供了一些有用的工具和技术,以加强 Kubernetes Cluster 的安全措施。

这份指南在说什么?

在阅读这份文件后,可以注意到文件的概览部分直接提及了整份文件围绕的核心安全性议题,并且由后续数十页的内容,具体描述了如何设置和保护 Kubernetes 环境以及相关涉及的安全问题。在这份内容中,不但从集群系统管理员 (Cluster Admininstrator),也从系统开发人员的角度切入,提出相关的设定建议以避免常见的配置错误,并且涵盖了相关的实践、缓解和强化措施,主要包含:

  • 扫描容器和 Pod 以查找漏洞或设定错误
  • 使用最少的权限运行容器和 Pod
  • 使用网络隔离政策 (Network Policy) 来控制威胁的影响范围
  • 使用防火墙限制不必要的网络连接,并使用加密保护机密性
  • 使用健全的身份验证和授权机制来限制用户和管理员访问,以及限制可能的攻击范围
  • 记录和审视活动日志 (Audit Log),以便及时发现潜在的恶意活动
  • 定期审查所有 Kubernetes 的设定,并使用漏洞扫描工具确保风险得到适当的处理,并定期规划升级

Kubernetes 强化指南的主要内容

这份指南主要分为三部分:授权和身份验证、网络安全和监控

授权和身份验证 (Authentication and authorization)

授权和身份验证是保护 Kubernetes 环境的第一步。在这一部分中,指南介绍了一些最佳实践,包括使用适当的身份验证方法、限制对 Kubernetes API 的访问权限和使用适当的角色和权限。常见的设定策略为 Kubernetes 本身的 Role-Based Access Control (RBAC)。

通过多因素身份验证(MFA)进行访问保护 Kubernetes 环境。此外,对于权限的设定应遵循使用最小权限原则 (Least Privilege),以最小化攻击面。同时强调了使用适当的角色和权限的重要性 (Role-Based Access Control),以限制对 Kubernetes API 的访问。

网络安全 (Network separation and hardening)

在这一部分中,指南介绍了一些最佳实践,包括使用网络隔离、限制对 Kubernetes 网络的访问权限和使用加密通信。

在这份文件中,提及了数项建议以使用适当的网络策略,并限制 Pod 与 Pod 之间的通信。这份文件中也涵盖了使用加密通信的相关建议,以保护敏感数据。

监控和威胁侦测 (Audit Logging and Threat Detection)

监控是保护 Kubernetes 环境的关键。在这一部分中,指南介绍了一些最佳实践,包括使用适当的监控工具、关注重要的事件和警报并建立响应计划。

指南建议使用适当的监控工具,以监控 Kubernetes 环境的状态和行为。同时,强调了建立响应计划的必要性,以应对环境中的安全事件。指南提供了一些示例事件,以帮助企业更好地了解哪些事件可能对其环境造成风险。

Kubernetes 集群可能的威胁和弱点分析 (Threat Model)

随着 Kubernetes 可以承载的业务和运算量提高,有越来越多的应用程序和网络服务基于 Kubernetes 做为容器化调度基础平台运行。在这种情况下,这也意味着运行在 Kubernetes Cluster 中的内容将可能包含许多企业和组织关键的信息,使得 Kubernetes 逐渐成为攻击者对于数据或计算能力需求盗窃的高价值目标。例如:除了作为 DDoS (拒绝服务攻击) 的可能攻击目标外,一种常见的攻击手法用于部署恶意程序用于比特币或是加密货币的挖掘。CrowdStrike 更同时于今年发布一篇常见的攻击手法,指出挖掘攻击者将挖矿程序伪装成 Pause Container 使管理者不易察觉3

在这份文件中,针对现有 Kubernetes Cluster 进行威胁建模具体列出了最有可能遭受的一些威胁:

  • 供应链 (Supply Chain):上游和三方软件供应链的攻击向量多样且难以缓解。这包括帮助提供最终产品的产品组件、服务、人员甚至风险还可能包括用于建立和管理 Kubernetes Cluster 的第三方软件和供应商,影响包含多个层面:
    • 容器/应用程序级别:由于在 Kubernetes 中可以运行和调度任一种应用程序和容器,这使得一部分的安全威胁非常依赖第三方安全性、开发人员的可信度和对于软件本身的防御。一个恶意的容器或应用部署在 Kubernetes 中均有可能造成安全威胁。
    • 容器执行环境 (Container Runtime):为了运行容器,在每个工作节点 (Node) 上都必须具备容器所需要的执行环境 (Container Runtime),并且从映像 (Container Image) 来源的存储位置中下载。Container Runtime 对于容器的生命周期起到关键的作用,包含监控系统资源、为容器隔离可用的系统资源。Container Runtime 和相关虚拟化技术本身的漏洞可能导致这项隔离失效,甚至使攻击者能在系统上获取更高的权限。
    • 基础设施:运行 Kubernetes 的基础系统仍依赖底层硬件和固件。任何系统层或是 Kubernetes master node 相关的的漏洞都可能为恶意攻击提供立足点。
  • 恶意攻击者:恶意攻击者经常利用漏洞或从社交工程 (Social Engineering) 中窃取凭证并获取权限。 Kubernetes 本身在架构中公开了数项 API,使得攻击者可能进一步利用这些 API 进行恶意操作,包括:
    • Control Plane - Kubernetes 主节点 (Master Node) 有许多组件,若 API Server 并未适当的设定权限管理,攻击者则可能任意地存取 Kubernetes Cluster 进行相关的恶意操作。
    • 工作节点 (Node):除了运行容器引擎外,工作节点通常也运行了 kubelet 和 kube-proxy 等重要服务,若这些服务本身存在漏洞,则可能会被黑客利用。
    • 容器化应用程序:在 Cluster 内运行的应用程序是常见的攻击目标。
  • 内部威胁:一种可能的也包跨来自内部人员的威胁。内部攻击者可以利用在组织内工作时所给予的漏洞或特权进行非法访问及操作。
    • 集群管理员 (Administrator):Kubernetes 集群管理员可以控制运行的容器、Pod,包括在容器化环境中执行任意命令。这部分可以通过 Kubernetes 本身支持的 RBAC 机制,通过限制对敏感功能的访问,以减少可能的风险。但由于 Kubernetes 本身缺乏双人完整性控制 (注:好比要开一道门需要两把不同的钥匙,这两把钥匙在不同人身上)。此外,管理员甚至也可以通过物理性的方法直接访问系统本身或是虚拟化管理程序 (Hypervisor),这都可能破坏 Kubernetes 执行环境。
    • 用户 (User):容器化应用程序中的访问用户可能知道并拥有访问 Kubernetes Cluster 中的容器化服务的凭证,取得这项凭证后,可能基于软件本身的漏洞用于进阶的攻击。
    • 云端服务或基础设施提供商 (Cloud Service Provider, CSP):由于 Kubernetes Cluster 可能运行于其他服务提供商,CSP 经常需要具有多层技术和管理控制,以保护系统免受可能的威胁以及攻击。

各对应层面的强化建议摘要

Kubernetes Pod Security

运行非 root 权限身份的容器 (“Non-root” containers)

默认情况下,由于容器本身属于隔离执行环境,容器中的应用程序默认将使用 root 身份运行。在 Pod 安全性一节中,讨论了以非 Root (Non-root) 用户身份部署运行 Pod 执行环境的相关可能做法,并且在文件中提及一个 Dockerfile 的范例,通过相关命令在运行应用程序的同时,通过设定 Linux group 和用户身份,采用非 root 用户身份执行该进程 (process)。

FROM ubuntu:latest

#Update and install the make utility
RUN apt update && apt install -y make

#Copy the source from a folder called "code" and build the application with
the make utility
COPY . /code
RUN make /code

#Create a new user (user1) and new group (group1); then switch into that
user's context
RUN useradd user1 && groupadd group1
USER user1:group1

#Set the default entrypoint for the container
CMD /code/app

此外,Kubernetes 本身对于 Pod 部署提供了 securityContext 属性,可用于设定 Pod 运行时采用非 Root 身份运作,例如:

spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 1000

设定仅可读的文件系统 (Immutable container file systems)

默认情况下,Pod 本身内的应用具备权限对容器中的文件系统进行写入操作,攻击者将可以利用这项权限进行文件创建、下载恶意程序代码甚至更改应用程序代码等操作。在对于本身容器执行环境的文件系统属于仅读取的使用情境,Kubernetes 管理者可以为 Pod 本身设定为仅可读取,并通过挂载 Volume (emptyDir4) 将写入操作限制于用于暂存空间 (可为文件系统或是内存: tmpfs),并在容器终止后自动清除,以提高安全性。

spec:
  containers:
  - command: ["sleep"]
    args: ["999"]
    image: ubuntu:latest
    name: web
    securityContext:
        readOnlyRootFilesystem: true
    volumeMounts:
        - mountPath: /writeable/location/here
          name: volName
    volumes:
        - emptyDir: {}
          name: volName

创建安全的容器映像 (Building secure container images)

一种常见为创建安全的容器映像策略,通常是在映像 CI/CD 构建和推送过程中,增加 Image scanning 和弱点扫描的工作,例如:检查是否使用过期的程序函数库、依赖包、设定和配置问题、不当的权限和开放端口 (Port) 设定、可能的弱点及 CVEs 等。然而,在这份文件中也同时分享了一个采用 Kubernetes 原生的功能和 Adminission Webhook 机制在容器部署的同时触发相关的扫描工作,并且提供更为全面和弹性的安全性侦测机制和参考架构,主动阻断任何非法的映象部署,甚至在 Webhook 设计中阻止不合规的 Pod 部署设定 (例如:部署 Privilege Container)。

(图片来源:Kubernetes Hardening Guidance)

其他

以下是在该章节中中列举有关 Pod 安全性的其他建议:

  • 增强 Pod 安全性:常见的策略为套用 Pod Security Policies (PSPs - 在季芹的 Kubernetes 版本中已经弃用)、Kubernetes 1.23 开始默认采用的 Pod Security Admission 等

  • 保护 Pod Service Account Token:针对不需要存取 Pod Service Account Token 的执行环境关闭设定 Service Account Token 的挂载 (automountServiceAccountToken: false)

  • 在系统层强化容器执行和虚拟化环境安全:例如启用 Kernel 本身支持的 seccomp、Hypervisor 本身支持的安全虚拟化技术运行容器执行环境等

网络隔离和强化 (Network separation (isolation) and hardening)

Kubernetes 网络安全性是非常重要的一环,通过对于 Kubernetes 中各个网络元件的隔离和强化,可以大幅降低网络攻击的风险,以下在这个章节中主要提及可采用的措施:

网络隔离

Kuberentes 支持的 NetworkPolicy 来设定 Pod 之间的网络存取规则,并且限制网络存取来源和目的地,以减少攻击风险。要设定 Network Policy 之前,通常需要通过将应用部署在不同的 Kubernetes Namespaces 实现进一步的隔离,并且也需要确保使用的 CNI (Container Network Interface) Plugin 对于 NetworkPolicy 支持5

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: example-access-nginx
  namespace: <NAMESPACE_NAME>
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
    - podSelector:
      matchLabels:
        access: "true"

设定资源使用政策

Kubernetes 支持使用 LimitRanges6 (用于单一 Namespace 中限制个别 Pod、Container 可使用的资源数量)、ResourceQuotas7 (可用于限制在 Namespace 中总体可以使用的 CPU、Memory、存储资源,甚至是限制物件数量,例如只能运行多少个 Pod) 和 Process ID (PID) 8 限制等方法针对特定 Kubernetes Namespace、Node 或是 Pod 达到控制可用资源的目的。

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-min-max-demo-lr
spec:
  limits
  - default:
      cpu: 1
    defaultRequest:
      cpu: 0.5
    max:
      cpu: 2
    min:
      cpu 0.5
    type: Container

另外一个文件没提的是,Kubernetes Pod 本身部署也同时支持相关的资源限制设定,例如:

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

控制平面强化 (Control Plane Hardening)

在这一节中主要讨论了几项针对 Kubernetes Master Node 相关的强化讨论,包含:

  • 启用 API Server 访问控制:通过 API Server 的 Role-Based Access Control (RBAC) 机制,可以设定哪些使用者或群组可以访问 API Server,并且限制访问权限,以减少不合法的 API Server 请求。

  • 网络加密:通过 HTTPS/TLS 或是其他网络加密方式。由于 etcd 属于整个 Kubernetes Cluster 最关键的元件,因此也包含为 etcd 以及 API Server 之间的传输启用加密技术。除了可以增加网络传输的安全性,更减少被窃听或攻击的风险。

  • 避免将 Kbuernetes API Server 暴露于网络上:API Server 默认使用了 6443 (有些使用 443),应对于这些相关的端口 (Port) 进行强化甚至加上关联的安全组规则,包含:

    • 2379-2380: etcd server client API
    • 10250: kubelet API
    • 10259: kube-scheduler
    • 10257: kube-controller-manager
    • 30000-32767: Ports that may be opened on a Worker Node when using NodePort
  • 针对 Secret 物件的加密:默认情况下,Kubernetes Secret 本身属于未加密的 base64 编码字串,任何具备 Kubernetes API 操作权限的人均有机会可以获取到相关的敏感信息。因此,可以通过三方的加密服务为 Secret 写入 etcd 时进行加密 (例如:AWS Key Management Service, KMS)、为 API Server 去启动参数中增加 --encryption-provider-config 设定加密提供服务 9 等来增加 Kubernetes Secret 的安全性。

保护敏感的云端服务基础设施信息 (Protecting sensitive cloud infrastructure)

许多组织会选择将 Kubernetes 运行在云端服务提供商的执行环境中,管理者可以,例如:以 AWS 为例,可以通过设定 EC2 本身的属性封锁 EC2 Metadata Service (IMDS) 的存取权限并且阻挡获取可能的凭证 (EC2 Instance IAM Role)。例如:以下是文件中没有提及使用 EC2 本身支持的设定或是通过 NetworkPolicy 实现。

(AWS CLI)

aws ec2 modify-instance-metadata-options --instance-id <value> --http-tokens required --http-put-response-hop-limit 1

(NetworkPolicy)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-metadata-access
  namespace: example
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 169.254.169.254/32

授权和身份验证 (Authentication and authorization)

授权和身份验证是保护 Kubernetes 环境的重要一环,在这一章节,指南介绍了一些最佳实践,包括使用适当的身份验证方法、限制对 Kubernetes API 的访问权限和使用适当的角色和权限。但主要围绕为 Kubernetes 本身的 Role-Based Access Control (RBAC) 设定以保护 Kubernetes 执行环境。例如:设定一个仅对于 Pod 可读取的 Role 身份。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: your-namespace-name
  name: pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "watch", "list"]

要启用这项设定,kube-apiserver 必须使用必要的参数 (--authorization-mode=RBAC) 以支持该方法。

总结 Kubernetes Hardening Guide

作为本篇内容的总结,以下是这份文件中对于每个部分的主要建议摘要:

  • Kubernetes Pod 安全
    • 运行非 root 权限身份的容器 (“Non-root” containers)
    • 设定仅可读的文件系统 (Immutable container file systems) 运行容器
    • 创建及扫描容器映像以找出可能的漏洞或设定错误
    • 使用相关技术和功能控制可能的安全性威胁,包括:
      • 防止运行 Privileged Container 容器
      • 降量避免频繁使用较不安全的功能和选项,例如 hostPID、hostIPC、hostNetwork、allowedHostPath
      • 通过 RunAsUser 属性避免以 root 用户运行应用
      • 在系统层可以考虑启用安全功能(例如: SELinux、AppArmor 和 seccomp)
  • 网络隔离和强化
    • 使用防火墙和基于角色的访问控制(RBAC)限制对控制平面节点的访问,并考虑在控制平面组件和节点之间使用单独的网络
    • 限制对 etcd 的访问
    • 配置控制平面组件使用通过传输层安全性(TLS)凭证进行身份验证、加密通信,包含将 etcd 加密并使用 TLS 协议通信
    • 考虑设定 NetworkPolicy 以隔离资源,并设定明确的网络安全性策略 (NetworkPolicy)
    • 将所有凭证和敏感信息加密存放在 Kubernetes Secrets 中,而不是在配置文件中。考虑启用 KMS 等服务加密 Kubernetes Secrets 资源
  • 认证和授权
    • 禁用匿名用户直接访问和操作 Kubernetes API Server(默认启用)
    • 启用 RBAC,并为用户、管理员、开发人员、Service Account 等建立个别身份的 RBAC 策略。
  • 记录文件和威胁检测
    • 为 API Server 启用 Audit log 操作记录文件(默认为关闭),并为 Kubernetes 事件记录以进行查阅和追踪
    • 为应用和容器设定一致性的日志收集、监控和警报系统
  • 升级和应用程序安全最佳实践
    • 及时更新 Kubernetes 版本和安全漏洞
    • 定期进行漏洞扫描和渗透测试
    • 从环境中移除和删除未使用的元件、部署

总的来说,在阅读完 NSA 和 CISA 发布的这份 Kubernetes Hardening Guide,我更感觉像是在重新复习一次 Kubernetes 本身对于安全性功能的支持,我认为作为一份 Security Checklist 再好不过,且的确是一份非常值得参考的文件。

当然,在很多实际应用中,Kubernetes 的部署和安全性都可能基于组织文化,甚至任何非人为可控制因素,使得无法针对所有的威胁进行一一的强化,但身为 Kubernetes 管理者,通过学习并且逐步实施这些最佳实践,某种程度上能够更好保护 Kubernetes 的执行环境,减少面临的可能安全性风险,同时建立一个持续改进的安全计划和引导组织文化提升,以应对不断变化的安全性威胁。

参考资源

Eason Cao
Eason Cao Eason is an engineer working at FANNG and living in Europe. He was accredited as AWS Professional Solution Architect, AWS Professional DevOps Engineer and CNCF Certified Kubernetes Administrator. He started his Kubernetes journey in 2017 and enjoys solving real-world business problems.
comments powered by Disqus