本文已超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已失效。

使用 OCI artifacts 分发 seccomp、SELinux 和 AppArmor 的安全配置文件

Security Profiles Operator (SPO) 使在 Kubernetes 中管理 seccomp、SELinux 和 AppArmor 配置变得前所未有的简单。它允许集群管理员在预定义的自定义资源 YAML 中定义配置,然后 SPO 将其分发到整个集群。安全配置的修改和删除也以相同方式由 operator 管理,但这只是其功能的一小部分。

SPO 的另一个核心功能是能够叠加 seccomp 配置。这意味着用户可以在 YAML 规范中定义一个 baseProfileName,该名称将由 operator 自动解析并合并 syscall 规则。如果一个基础配置有另一个 baseProfileName,那么 operator 将递归解析配置到一定深度。一个常见的用例是为低级容器运行时(如 runccrun)定义基础配置,这些配置包含运行容器在任何情况下都需要的 syscall。或者,应用程序开发人员可以为其标准分发容器定义 seccomp 基础配置,并在其上叠加应用程序逻辑的专用配置。通过这种方式,开发人员可以专注于维护更简单且仅限于应用程序逻辑的 seccomp 配置,而无需考虑整个基础设施设置。

但如何维护这些基础配置呢?例如,运行时的所需 syscall 数量在其发布周期内可能会发生变化,就像主应用程序一样。基础配置必须在同一集群中可用,否则主 seccomp 配置将无法部署。这意味着它们与主应用程序配置紧密耦合,这违背了基础配置的主要思想。将它们作为纯文本文件分发和管理感觉像是需要解决的额外负担。

OCI Artifacts 来救援

Security Profiles Operator 的 v0.8.0 版本支持将基础配置作为 OCI Artifacts 进行管理!可以将 OCI Artifacts 想象成轻量级的容器镜像,以与镜像相同的方式在层中存储文件,但没有要执行的进程。这些 Artifacts 可以像常规容器镜像一样,用于在兼容的注册表中存储安全配置。这意味着它们可以像常规容器镜像一样进行版本控制、命名空间化和注解。

要了解其工作原理,可以在 seccomp profile CRD 中指定一个以 oci:// 为前缀的 baseProfileName,例如:

apiVersion: security-profiles-operator.x-k8s.io/v1beta1
kind: SeccompProfile
metadata:
  name: test
spec:
  defaultAction: SCMP_ACT_ERRNO
  baseProfileName: oci://ghcr.io/security-profiles/runc:v1.1.5
  syscalls:
    - action: SCMP_ACT_ALLOW
      names:
        - uname

operator 将负责使用 oras 拉取内容,并验证 artifact 的 sigstore (cosign) 签名。如果 artifact 未签名,则 SPO 将拒绝它们。结果 profile test 将包含远程 runc profile 中的所有基础 syscalls 以及额外允许的 uname syscall。也可以通过 digest (SHA256) 引用基础配置,使拉取的 artifact 更具体,例如通过引用 oci://ghcr.io/security-profiles/runc@sha256:380…

operator 内部会缓存拉取的 artifact,对于 1000 个配置最多缓存 24 小时,这意味着如果达到该时间段、缓存已满或 operator 守护进程重新启动,它们将被刷新。

由于最终生成的 syscalls 对用户是隐藏的(在 SeccompProfile 中只列出了 baseProfileName,而不是 syscalls 本身),我将额外使用最终的 syscalls 注解该 SeccompProfile。

这是我添加注解后的 SeccompProfile 样子:

> kubectl describe seccompprofile test
Name:         test
Namespace:    security-profiles-operator
Labels:       spo.x-k8s.io/profile-id=SeccompProfile-test
Annotations:  syscalls:
                [{"names":["arch_prctl","brk","capget","capset","chdir","clone","close",...
API Version:  security-profiles-operator.x-k8s.io/v1beta1

SPO 维护者在 “Security Profiles” GitHub 组织 中提供所有公共基础配置。

管理 OCI 安全配置

好的,现在官方 SPO 提供了一系列基础配置,但我如何定义自己的呢?首先,我们必须选择一个可用的注册表。有许多注册表已经支持 OCI Artifacts:

Security Profiles Operator 附带了一个新的命令行界面 spoc,它是一个小辅助工具,用于管理 OCI 配置以及执行本博文范围之外的各种其他操作。但可以使用命令 spoc push 将安全配置推送到注册表:

> export USERNAME=my-user
> export PASSWORD=my-pass
> spoc push -f ./examples/baseprofile-crun.yaml ghcr.io/security-profiles/crun:v1.8.3
16:35:43.899886 Pushing profile ./examples/baseprofile-crun.yaml to: ghcr.io/security-profiles/crun:v1.8.3
16:35:43.899939 Creating file store in: /tmp/push-3618165827
16:35:43.899947 Adding profile to store: ./examples/baseprofile-crun.yaml
16:35:43.900061 Packing files
16:35:43.900282 Verifying reference: ghcr.io/security-profiles/crun:v1.8.3
16:35:43.900310 Using tag: v1.8.3
16:35:43.900313 Creating repository for ghcr.io/security-profiles/crun
16:35:43.900319 Using username and password
16:35:43.900321 Copying profile to repository
16:35:46.976108 Signing container image
Generating ephemeral keys...
Retrieving signed certificate...

        Note that there may be personally identifiable information associated with this signed artifact.
        This may include the email address associated with the account with which you authenticate.
        This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later.

By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs.
Your browser will now be opened to:
https://oauth2.sigstore.dev/auth/auth?access_type=…
Successfully verified SCT...
tlog entry created with index: 16520520
Pushing signature to: ghcr.io/security-profiles/crun

你可以看到该工具会自动为 artifact 签名,并将 ./examples/baseprofile-crun.yaml 推送到注册表,然后即可直接在 SPO 中使用。如果需要用户名和密码认证,可以使用 --username-u 标志或导出 USERNAME 环境变量。要设置密码,请导出 PASSWORD 环境变量。

可以通过多次使用 --annotations / -a 标志以 KEY:VALUE 格式向安全配置添加自定义注解。这些注解目前没有效果,但将来 operator 的一些附加功能可能会依赖它们。

spoc 客户端也能够从兼容 OCI Artifact 的注册表中拉取安全配置。为此,只需运行 spoc pull

> spoc pull ghcr.io/security-profiles/runc:v1.1.5
16:32:29.795597 Pulling profile from: ghcr.io/security-profiles/runc:v1.1.5
16:32:29.795610 Verifying signature

Verification for ghcr.io/security-profiles/runc:v1.1.5 --
The following checks were performed on each of these signatures:
  - Existence of the claims in the transparency log was verified offline
  - The code-signing certificate was verified using trusted certificate authority certificates

[{"critical":{"identity":{"docker-reference":"ghcr.io/security-profiles/runc"},…}}]
16:32:33.208695 Creating file store in: /tmp/pull-3199397214
16:32:33.208713 Verifying reference: ghcr.io/security-profiles/runc:v1.1.5
16:32:33.208718 Creating repository for ghcr.io/security-profiles/runc
16:32:33.208742 Using tag: v1.1.5
16:32:33.208743 Copying profile from repository
16:32:34.119652 Reading profile
16:32:34.119677 Trying to unmarshal seccomp profile
16:32:34.120114 Got SeccompProfile: runc-v1.1.5
16:32:34.120119 Saving profile in: /tmp/profile.yaml

该配置现在可以在 /tmp/profile.yaml 或指定的输出文件 --output-file / -o 中找到。我们可以以与 spoc push 相同的方式指定用户名和密码。

spoc 使得将安全配置作为 OCI Artifacts 进行管理变得简单,这些 Artifacts 然后可以直接由 operator 本身使用。

这是我们对 Security Profiles Operator 最新功能的简明介绍!如果您对此感兴趣、想提供反馈或寻求帮助,请随时通过 Slack (#security-profiles-operator)邮件列表 直接与我们联系。