Seccomp 与 Kubernetes

Seccomp 代表安全计算模式(secure computing mode),自 Linux 内核 2.6.12 版本以来一直是其一个特性。它可以用于沙箱化进程的特权,限制其从用户空间向内核发起的调用。Kubernetes 允许你自动将加载到节点上的 Seccomp Profile 应用到你的 Pod 和容器。

Seccomp 字段

特性状态: Kubernetes v1.19 [stable]

有四种方式为Pod指定 Seccomp Profile

apiVersion: v1
kind: Pod
metadata:
  name: pod
spec:
  securityContext:
    seccompProfile:
      type: Unconfined
  ephemeralContainers:
  - name: ephemeral-container
    image: debian
    securityContext:
      seccompProfile:
        type: RuntimeDefault
  initContainers:
  - name: init-container
    image: debian
    securityContext:
      seccompProfile:
        type: RuntimeDefault
  containers:
  - name: container
    image: docker.io/library/debian:stable
    securityContext:
      seccompProfile:
        type: Localhost
        localhostProfile: my-profile.json

上述示例中的 Pod 以 Unconfined 模式运行,而 ephemeral-containerinit-container 明确定义了 RuntimeDefault。如果临时容器或 Init 容器没有显式设置 securityContext.seccompProfile 字段,则该值将从 Pod 继承。这同样适用于容器,它运行一个 Localhost Profile my-profile.json

一般来说,(临时)容器中的字段优先级高于 Pod 级别的设置,而未设置 seccomp 字段的容器则会继承 Pod 的 Profile。

seccompProfile.type 可能的值如下:

Unconfined
工作负载在没有任何 Seccomp 限制的情况下运行。
RuntimeDefault
应用由容器运行时定义的默认 Seccomp Profile。默认 Profile 旨在提供一套强大的安全默认设置,同时保留工作负载的功能。不同的容器运行时及其发布版本可能具有不同的默认 Profile,例如,比较 CRI-Ocontainerd 的默认 Profile。
Localhost
将应用 localhostProfile,该 Profile 必须在节点磁盘上可用(在 Linux 上路径为 /var/lib/kubelet/seccomp)。容器运行时在创建容器时会验证 Seccomp Profile 的可用性。如果 Profile 不存在,则容器创建将失败并报 CreateContainerError 错误。

Localhost Profile

Seccomp Profile 是遵循OCI 运行时规范定义的方案的 JSON 文件。Profile 主要定义基于匹配的系统调用(syscall)的动作,但也允许将特定值作为参数传递给系统调用。例如:

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "defaultErrnoRet": 38,
  "syscalls": [
    {
      "names": [
        "adjtimex",
        "alarm",
        "bind",
        "waitid",
        "waitpid",
        "write",
        "writev"
      ],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

上述 Profile 中的 defaultAction 定义为 SCMP_ACT_ERRNO,并将作为 syscalls 中定义的操作的备用方案返回。错误通过 defaultErrnoRet 字段定义为代码 38

通常可以执行以下操作:

SCMP_ACT_ERRNO
返回指定的错误代码。
SCMP_ACT_ALLOW
允许执行系统调用。
SCMP_ACT_KILL_PROCESS
杀死进程。
SCMP_ACT_KILL_THREADSCMP_ACT_KILL
仅杀死线程。
SCMP_ACT_TRAP
抛出 SIGSYS 信号。
SCMP_ACT_NOTIFYSECCOMP_RET_USER_NOTIF
通知用户空间。
SCMP_ACT_TRACE
通知跟踪进程指定的值。
SCMP_ACT_LOG
在操作已记录到 syslog 或 auditd 后,允许执行系统调用。

某些操作(例如 SCMP_ACT_NOTIFYSECCOMP_RET_USER_NOTIF)可能不受支持,具体取决于使用的容器运行时、OCI 运行时或 Linux 内核版本。可能还存在其他限制,例如 SCMP_ACT_NOTIFY 不能用作 defaultAction 或用于某些系统调用(如 write)。所有这些限制都由 OCI 运行时(runccrun)或 libseccomp 定义。

syscalls JSON 数组包含一个对象列表,这些对象通过各自的 names 引用系统调用。例如,动作 SCMP_ACT_ALLOW 可用于创建允许的系统调用白名单,如上例所示。也可以使用动作 SCMP_ACT_ERRNO 但指定不同的返回 (errnoRet) 值来定义另一个列表。

还可以指定传递给某些系统调用的参数(args)。有关这些高级用例的更多信息,请参阅OCI 运行时规范Seccomp Linux 内核文档

延伸阅读

上次修改时间 September 17, 2024 at 10:57 AM PST: 添加专门的 Seccomp 节点参考 (c2b49fee37)