gpt4 book ai didi

open-policy-agent - 如何使用 Open Policy Agent Gatekeeper K8sPSPCapabilities 约束模板将容器列入白名单

转载 作者:行者123 更新时间:2023-12-04 15:00:15 28 4
gpt4 key购买 nike

我想在 K8sPSPCapabilities 约束模板中将一个容器列入白名单,但我在使用 rego 语言时遇到了一些困难。我想禁止除特定容器之外的所有容器的 NET_RAW 功能。如果有人能指出我正确的方向,我将不胜感激。

最佳答案

我相信您指的是 this template来自 Gatekeeper ConstraintTemplate 库,这是令人生畏的。不幸的是,如所写,ConstraintTemplate 不允许拒绝列出特定的 allowedCapabilities。让我们构建它。

如果您只是在寻找 Rego,here's it in the Rego Playground .

验证容器

我们将从内到外开始。首先,假设我们有一个 Container 并希望确保它在 .securityContext.capabilities.add 中没有 NET_RAW。首先,我们会将此列表的值收集到一个集合中。

capabilities := {c | c := container.securityContext.capabilities.add[_]}

这叫做 set comprehension .

由于您很可能希望拒绝多项功能,因此我们假设您希望将其设置为列表参数,而不是将其硬编码到您的 ConstraintTemplate 中。我们还需要将此列表从 input.parameters 转换为一个集合。

denied := {c | c := input.parameters.deniedCapabilities[_]}

我们现在要做的是构建 set intersection Container 中的 capabilitiesdenied 中的 capabilities 之间。

count(capabilities & denied) > 0

如果容器和拒绝功能列表中都有任何功能,则返回 true

我们必须考虑容器指定 '*' 的情况,这将隐式包含 NET_RAW 但与我们上面的逻辑不匹配。我们检查这种情况:

capabilities['*']

请注意,Rego 函数中的每个真值语句都隐含地进行了 AND 运算。所以下面会检查这两个条件,但我们想匹配其中一个:

count(capabilities & denied) > 0
capabilities['*']

我们可以通过为 has_disallowed_capabilities 提供两个定义来做到这一点:

has_disallowed_capabilities(container) {
capabilities := {c | c := container.securityContext.capabilities.add[_]}
denied := {c | c := input.parameters.deniedCapabilities[_]}
count(capabilities & denied) > 0
}

has_disallowed_capabilities(container) {
capabilities := {c | c := container.securityContext.capabilities.add[_]}
capabilities["*"]
}

如果我们在 Container 上调用 has_disallowed_capabilities,Rego 将自动检查两个定义并在至少一个返回 true 时返回 true。

验证 Pod

现在我们将实际编写 Gatekeeper 惯用的 violation 函数。

violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
has_disallowed_capabilities(container)
msg := sprintf("container <%v> has a disallowed capability. Denied capabilities are %v", [container.name, input.parameters.deniedCapabilities])
}

此违规行为首先创建一个 iterator , container,它将遍历 Pod 中的所有 Container。通过在迭代器上调用函数,我们隐式地在迭代器中的每个容器上调用该函数。

我们还必须检查 initContainers,因为它们也可能具有 NET_RAW 功能。它看起来与上面几乎相同:

violation[{"msg": msg}] {
container := input.review.object.spec.initContainers[_]
has_disallowed_capabilities(container)
msg := sprintf("initContainer <%v> has a disallowed capability. Denied capabilities are %v", [container.name, input.parameters.deniedCapabilities])
}

将容器列入白名单

快完成了。正如您上面所说,我们想要将特定容器列入白名单。回想一下,Rego 函数中的所有语句都是通过与运算组合在一起的,violation 函数必须返回 true 才能使 Container 验证失败。因此,如果我们创建一个语句,如果它与我们想要的容器匹配,则计算结果为 false,我们就完成了!

假设我们要忽略具有name: abc 的容器。我们可以匹配所有其他容器:

container.name != "abc"

这只需要进入我们的两个 violation 函数,我们就准备好了!

将一切放在一起

最后,我们将上面创建的所有内容放入 ConstraintTemplate 中:

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8spspdeniedcapabilities
annotations:
description: Denies Pod capabilities.
spec:
crd:
spec:
names:
kind: K8sPSPDeniedCapabilities
validation:
# Schema for the `parameters` field
openAPIV3Schema:
properties:
deniedCapabilities:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package capabilities

violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
container.name != "abc"
has_disallowed_capabilities(container)
msg := sprintf("container <%v> has a disallowed capability. Denied capabilities are %v", [container.name, input.parameters.deniedCapabilities])
}

violation[{"msg": msg}] {
container := input.review.object.spec.initContainers[_]
container.name != "abc"
has_disallowed_capabilities(container)
msg := sprintf("initContainer <%v> has a disallowed capability. Denied capabilities are %v", [container.name, input.parameters.deniedCapabilities])
}

has_disallowed_capabilities(container) {
capabilities := {c | c := container.securityContext.capabilities.add[_]}
denied := {c | c := input.parameters.deniedCapabilities[_]}
count(capabilities & denied) > 0
}

has_disallowed_capabilities(container) {
capabilities := {c | c := container.securityContext.capabilities.add[_]}
capabilities["*"]
}

以及实例化它的约束:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPDeniedCapabilities
metadata:
name: denied-capabilities
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
deniedCapabilities: ["NET_RAW"]

相反,如果您希望白名单容器是可配置的,您将遵循与我们用来制作 deniedCapabilities 的过程类似的过程。

关于open-policy-agent - 如何使用 Open Policy Agent Gatekeeper K8sPSPCapabilities 约束模板将容器列入白名单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67059926/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com