客串文章,最初发表在Fugue的博客上,作者是Becki Lee

Fugue最近在Regula中发布了对Kubernetes的支持,Regula是我们用于检查基础设施即代码的开源策略引擎。Regula不仅可以检查你的Terraform和CloudFormation文件的安全和合规性,现在还可以检查Kubernetes的YAML清单!

在这篇博文中,我们将演示如何在Kubernetes清单上运行Regula来检测一个不安全的pod,然后我们将保护它。作为奖励,清单的最终版本将符合CIS Kubernetes Benchmark v1.6.1,这是一套关于保护Kubernetes环境安全的建议。

准备好了吗?那就开始吧

开始吧

首先,安装Regula。Homebrew用户可以执行以下命令。

brew tap fugue/regula
brew install regula

你也可以为你的平台安装一个预构建的二进制文件,或者,如果你愿意,用Docker运行Regula

在写这篇文章时,我们使用了Regula v1.5.0。

接下来,请看我们的GitHub gist,选择下载ZIP按钮,然后提取文件。有两个。

当我们解释如何修复每个违规行为时,你可以在家里手动编辑pod.yaml,或者你可以直接参考安全的pod-compliant.yaml版本。

审查清单

我们的清单声明了一个名为 hello 的简单pod和一个同样名为 hello 的BusyBox容器。

apiVersion: v1
类型。Pod
元数据。
  名称: hello
spec:
  容器。
    - 名称:hello
      Image: busybox
      命令。['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']

看起来并不不安全,对吗?但让我们运行Regula来确定一下。

运行Regula

在你的终端,cd到包含你下载的文件的目录。我们将在pod.yaml上运行Regula,使用--format compact标志以节省空间。

regula run pod.yaml --format compact

我们看到下面的输出。

example of running regula

Yikes!我们的pod肯定没有那么安全。Regula发现了6个问题。

不用担心--我们可以把它们都解决掉!让我们来看看每一个违规行为,这样我们就可以把它们解决掉了。让我们来看看每一个违规行为,这样我们就可以补救了。

纠正违规行为

服务账户令牌

违规行为。"服务账户'automountServiceAccountToken'应该被设置为'false'[中]"

CIS Kubernetes v1.6.1控制:5.1.6,"确保服务账户令牌仅在必要时被挂载"

为什么重要? 服务账户令牌用于验证集群内进程对Kubernetes API服务器的请求。默认情况下,服务账户令牌会在所有豆荚中自动挂载。然而,如果一个坏的行为者能够破坏一个荚,他们有可能使用其服务账户令牌来发动特权升级攻击,并获得对整个集群的控制。

因此,如果一个工作负载不需要与API服务器通信,最好避免自动挂载服务账户令牌。这符合最小特权的安全原则。

如何解决这个问题。在pod规范中把automountServiceAccountToken设置为false

spec:
  automountServiceAccountToken:false

pod-compliant.yaml的第10行

根用户

的违反。"Pod不应该以根用户的身份运行容器[中]"

CIS Kubernetes v1.6.1控制:5.2.6,"尽量减少根容器的接纳"

为什么它很重要。在没有必要的情况下,以root身份运行几乎是一个普遍的坏主意。如果一个容器以root身份运行,攻击者可以在容器突破的情况下获得主机系统的root权限。

如何解决这个问题。将runAsUser设置为pod规范中任何非零的用户ID,因为0是root。

spec:
  securityContext。
    runAsUser: 1001

参见pod-compliant.yaml中的第8-9行

你将需要确保这里指定的用户在Docker镜像中被定义。通常情况下,一个非root用户是通过在Dockerfile中运行Linux useradd命令创建的,然后通过USER命令指定用户ID。

Linux能力

接下来的两个违规行为密切相关,在我们的例子中,可以用同样的方法解决。

该违规行为。"Pod不应该运行具有NET_RAW能力的容器[中]"

CIS Kubernetes v1.6.1控制:5.2.7,"尽量减少具有NET_RAW能力的容器的接纳"

违反规定。"Pod不应运行分配有默认能力的容器[中]"

CIS Kubernetes v1.6.1的控制:5.2.9,"尽量减少分配了能力的容器的接纳"

为什么它很重要。当一个Linux容器运行时,它被授予一组默认的能力,这些能力授予进程特定的根权限。NET_RAW能力特别危险,因为攻击者可以用它来监视网络流量或用欺骗的地址产生IP流量。

许多服务不需要所有的默认功能,所以最好先把它们全部放弃,然后再把需要的功能加进去。在这个例子中,我们没有添加任何回来,但你可以用添加的方式来做。["FOO"]

如何解决这个问题。为容器设置一个securityContext,用drop来指定能力。["ALL"] 来一次性补救这两种违规行为(或者如果需要的话,用 drop: ["NET_RAW"] 来只补救 5.2.7)。

spec:
  容器。
    - 名称: hello
      securityContext:
        能力。
          drop:["ALL"]  

pod-compliant.yaml第15-17行

Seccomp简介

违反规定。"Pod seccomp profile应该被设置为'docker/default'[中]"

CIS Kubernetes v1.6.1控制:5.7.2,"确保seccomp配置文件在你的pod定义中被设置为docker/default"

为什么它很重要。在Linux中,安全计算模式(seccomp)限制了哪些系统调用(syscalls)被允许。Docker等容器运行系统通常提供一个默认的seccomp配置文件,可以禁用一些系统调用,提高安全性。

请注意,docker/default配置文件在Kubernetes 1.11中被弃用,所以尽管CIS Kubernetes v1.6.1说,最好使用runtime/default来代替。

如何解决这个问题。根据你的Kubernetes版本,有几种方法可以做到这一点,但在v1.19之前的版本中,你可以通过pod元数据中的seccomp.security.alpha.kubernetes.io/pod 注释来实现。

metadata:
  注释。
    seccomp.security.alpha.kubernetes.io/pod。"runtime/default"

见pod-compliant.yaml的第5-6行

安全背景

的违反。"Pods和容器应该应用安全上下文[中]"

CIS Kubernetes v1.6.1控制:5.7.3,"为你的Pod和容器应用安全上下文"

它为什么重要。吊舱或容器的安全上下文定义了与访问控制、Linux能力和权限有关的各种安全设置。设置与你的特定使用情况有关的参数是明智的。

如何解决这个问题。你可以在pod级别或容器级别设置安全上下文。如果设置在两个级别上都被定义了,并且重叠了,那么容器的设置就会覆盖pod的设置

早些时候,我们在pod级别设置了一个securityContext,以防止以root身份运行,在容器级别设置了一个securityContext,以放弃所有的能力,所以我们已经补救了这个违规行为。

参见pod-compliant.yaml中的第8-915-17行

再次运行Regula

现在我们已经纠正了所有6个违规行为,让我们看看Regula对我们新的安全豆荚有什么评价。这是更新后的清单,我们以pod-compliant.yaml的形式方便地提供给你。

apiVersion: v1
类型。Pod
元数据。
  name: hello
  注释。
    seccomp.security.alpha.kubernetes.io/pod。"runtime/default" 
规格。
  securityContext:
    runAsUser: 1001
  automountServiceAccountToken:false
  容器。
    - name: hello
      image: busybox
      命令。['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
      securityContext:
        capabilities:
          丢弃。["ALL"]

如果你一路上一直在编辑pod.yaml,请运行你之前运行的相同命令。

regula run pod.yaml --format compact

如果你没有编辑过pod.yaml(没有判断力!),你可以直接在pod-compliant.yaml清单上运行Regula。

regula run pod-compliant.yaml --format compact

我们会看到这样的输出。

没有发现问题。成功了。

Ta-dah!我们已经成功地补救了Regula在我们不安全的pod上发现的所有问题。干得好!

下一步是什么?

现在你已经学会了如何使用Regula来保护Kubernetes清单,请阅读Kubernetes安全的一些其他最佳实践

你可以在regula.dev了解更多关于Regula的信息。在那里,你会发现我们所有的Kubernetes规则的列表。你还可以了解如何放弃一个规则结果,甚至是完全禁用一个规则,如果它与你的组织不相关。

顺便说一下,Fugue使你能够通过对基础设施应用与代码和运行时资源相同的策略,来确保整个开发生命周期的安全了解更多关于Fugue平台的信息,以及它如何帮助你在不违反规则的情况下在云中更快地发展。