博客

容器安全基础知识: 编排

  乔丹·泽博尔

  洛里·麦克维蒂

2019 年 7 月 24 日发布

如果你刚刚开始阅读本系列,你可能想从头开始: 
容器安全基础知识: 介绍
容器安全基础知识: 管道

根据Tripwire 的 2019 年容器安全状况报告,目前大约三分之一 (32%) 的组织在生产中运行着超过 100 个容器。 较小比例(13%)的企业运营规模超过 500 家。 而真正热切采用该技术的用户中,有 6% 目前管理着超过 1000 个。 很少有组织能够在没有编排系统协助的情况下大规模运行容器。

容器安全的编排层专注于负责容器日常运行的环境。 根据今天可用的数据,如果您使用容器,那么您几乎肯定会利用 Kubernetes 作为编排器。

值得注意的是,还存在其他编排器,但它们中的大多数也利用了源自 Kubernetes 的组件和概念。 因此,我们将重点关注 Kubernetes 及其组件的安全性。

Kubernetes 环境

Kubernetes 由多个活动部件组成。 这使得安全性变得更具挑战性,不仅因为涉及的组件数量,还因为这些组件的交互方式。 有些通过 API 进行通信。其他则通过主机文件系统进行通信。 所有这些都是进入编排环境的潜在切入点,必须加以解决。 

基本 Kubernetes 环境

基本 Kubernetes 环境

需要注意的核心组件的快速概览:

  • API 服务器和 Kubelet
  • Pod
  • Etcd

这意味着去喝杯咖啡吧,这需要多花一点时间才能完成。

1. 身份验证不是可选的

敏锐的读者会注意到这听起来很熟悉。 你可能听说过它被称为第二条安全规则,又名 锁上门。 这是一个我们会不断重复的常见主题,因为它经常被忽视。 强身份验证是必须的。 我们发现,由于容器安全实践不佳而导致的安全事故数量持续上升。 其中一个常见原因就是未能使用身份验证,通常是在公共云中部署时。

需要强大的资质并且经常轮换。 访问 API 服务器(通过不安全的控制台)可能会导致“游戏结束”的情况,因为整个编排环境可以通过它进行控制。 这意味着部署 pod、更改配置以及停止/启动容器。 在 Kubernetes 环境中,API 服务器是“一个统治所有 API”,您希望将其远离恶意行为者的手中。

如何保护 API 服务器和 Kubelet

值得注意的是,这些建议基于当前的 Kubernetes 授权模型。 请始终查阅您所使用版本的最新文档。

  • 在所有地方启用 mTLS
    - 每个服务(k8s、etcd、应用)专用一个 CA
    - 轮换证书并注意磁盘上的私钥权限
  • 仅绑定到安全地址
    - 注意 API 配置“insecure-bind-address”和“insecure-port”
    - 将其应用于所有服务(SSH、Vault、etcd)
  • 禁用“匿名身份验证”
    - “匿名认证”听起来是个好主意吗?
    - 自 1.5 版起默认禁用,使用“--anonymous-auth=True”手动启用
  • 启用授权
    - 不要使用“--authorization-mode=AlwaysAllow”
    - API 服务器应该具有“--authorization-mode=RBAC,Node”
    - Kubelet 应该具有“--authorization-mode=Webhook”
    -限制Kubelet只能访问其自己节点上的资源。

值得注意的是,这些建议基于当前的 Kubernetes 授权模型。 请始终查阅您所使用版本的最新文档。 

2. Pod 和权限 

Pod 是容器的集合。 它们是最小的 Kubernetes 组件,并且依赖于容器网络接口 (CNI) 插件,所有 Pod 默认可以相互访问。 有一些 CNI 插件可以使用“网络策略”来对此默认行为实施限制。 这一点很重要,因为可以在不同的 Kubernetes 节点(类似于物理服务器)上安排 pod。 Pod 通常还会挂载秘密,这些秘密可以是私钥、身份验证令牌和其他敏感信息。 这就是它们被称为‘秘密’的原因。

这意味着存在一些与吊舱和安全相关的问题。 在 F5,当我们开始威胁建模时,我们总是假设一个被入侵的 pod。 这是因为 pod 是应用工作负载部署的地方。 由于应用工作负载最有可能暴露于不受信任的访问,因此它们是最有可能受到攻击的点。 这一假设引发了四个基本问题,以便规划出如何减轻潜在威胁。 

  1. 如果攻击者可以访问某个 pod,他可以看到其他 pod 什么,或者对其他 pod 做什么?
  2. 攻击者可以访问集群中的其他服务吗?
  3. 哪些秘密是自动安装的?
  4. 已授予 pod 服务账户哪些权限?

如果攻击者获得集群内 pod 的访问权限,这些问题的答案就会暴露出可能被利用的风险。 减轻 pod 入侵威胁需要采取多方面的方法,包括配置选项、权限控制和系统级限制。 请记住,多个 pod 可以部署在同一个(物理或虚拟)节点上,从而共享操作系统访问权限 - 通常是 Linux 操作系统。

如何缓解 Pod 威胁
Kubernetes 包含一个 Pod 安全策略资源,用于控制 Pod 的敏感方面。 它使操作员能够定义 pod 必须在什么条件下运行才能被允许进入系统,并为 pod 安全上下文强制执行基线。 永远不要假设默认值是安全的。 实施安全基线并验证预期以防范 pod 威胁。

Pod 安全策略的具体选项应解决以下问题:

  • 避免特权容器
    • 在 kube-api 和/或 kubelet 上查找“—allow-privileged”设置
    • 在 pod 规范中查找“privileged: true”。
    • 使用“--allow-privileged=false”降低安全风险
  • Docker 的默认容器用户是 root
    • 避免以 root 身份运行任何工作负载
    • Pod 安全策略可以使用“runAsUser”、“runAsGroup”和“runAsNonRoot: true”
    • 可以在 Dockerfile 中定义类似的选项
  • 禁止容器内的特权升级
    • “允许特权升级:false”
  • 使用 SELinux/AppArmor
    • SELinux 将利用多类别安全性来限制容器之间的相互联系
    • 保持启用状态并解决拒绝问题
    • 禁用或更改为宽容模式会严重降低安全性
  • 防止符号链接/入口点攻击
    • 攻击者可以覆盖入口点二进制文件或创建坏符号链接
    • 通过设置“readOnlyRootFilesystem: true”来避免这种情况
  • 避免 host* 配置选项
    • 有权访问主机资源的攻击者更有可能进一步攻击主机和/或相邻的容器
    • 避免使用 hostPID、hostIPC、hostNetwork、hostPorts 等选项
  • 只读 hostPath 挂载
    • 如果有必要配置主机的读/写功能,请谨慎部署,并且不要将其作为默认做法
    • 在所有允许的主机路径上使用“readOnly”来避免攻击
  • Seccomp 配置文件
    • 通过限制允许的系统调用来减少威胁面
    • Docker 默认会减少一些但是它是一个通用配置文件
    • application特定配置文件将提供最大的安全优势

3. Etcd

Etcd 是配置和机密的存储库。 此处的入侵可能会导致敏感数据被提取或者恶意数据被注入。 两者都不好。 减轻对 etcd 的威胁意味着控制访问。 最好的方法是强制执行 mTLS 。 Kubernetes 将机密以 base64 编码的形式存储在etcd中。 考虑使用 alpha 功能“加密提供程序” ,以便在存储敏感机密时获得更强大的选项,或者考虑使用 HashiCorp Vault。

阅读本系列的下一篇博客: 
容器安全基础知识: 工作量