Seccomp 和 Kubernetes
Seccomp 代表安全计算模式,自 Linux 内核 2.6.12 版本以来一直是 Linux 内核的一项特性。它可用于沙箱化进程的权限,限制其从用户空间到内核的调用。Kubernetes 允许您自动将加载到 节点 上的 seccomp 配置文件应用于您的 Pod 和容器。
Seccomp 字段
Kubernetes v1.19 [稳定]有四种方法可以为 pod 指定 seccomp 配置文件
- 使用
spec.securityContext.seccompProfile为整个 Pod - 使用
spec.containers[*].securityContext.seccompProfile为单个容器 - 使用
spec.initContainers[*].securityContext.seccompProfile为 (可重启 / sidecar) init 容器 - 使用
spec.ephemeralContainers[*].securityContext.seccompProfile为 ephemeral 容器
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-container 和 init-container 明确定义了 RuntimeDefault。如果 ephemeral 或 init 容器没有显式设置 securityContext.seccompProfile 字段,则该值将从 Pod 继承。容器也是如此,它运行一个 Localhost 配置文件 my-profile.json。
一般来说,(ephemeral) 容器中的字段比 Pod 级别的值具有更高的优先级,而未设置 seccomp 字段的容器则从 Pod 继承配置文件。
说明
不可能将 seccomp 配置文件应用于在容器的securityContext 中设置了 privileged: true 的 Pod 或容器。特权容器始终运行为 Unconfined。seccompProfile.type 的以下值是可能的
Unconfined- 工作负载在没有任何 seccomp 限制的情况下运行。
RuntimeDefault- 应用了 容器运行时 定义的默认 seccomp 配置文件。默认配置文件旨在提供强大的安全默认设置,同时保留工作负载的功能。默认配置文件可能因容器运行时及其发布版本而异,例如比较 CRI-O 和 containerd 之间的差异。
Localhost- 将应用
localhostProfile,该配置文件必须在节点磁盘上可用(在 Linux 上为/var/lib/kubelet/seccomp)。容器运行时 在容器创建期间验证 seccomp 配置文件的可用性。如果配置文件不存在,则容器创建将失败并出现CreateContainerError。
Localhost 配置文件
Seccomp 配置文件是遵循 OCI 运行时规范 方案的 JSON 文件。配置文件基本上定义了基于匹配的 syscalls 的操作,但也允许将特定值作为参数传递给 syscalls。例如
{
"defaultAction": "SCMP_ACT_ERRNO",
"defaultErrnoRet": 38,
"syscalls": [
{
"names": [
"adjtimex",
"alarm",
"bind",
"waitid",
"waitpid",
"write",
"writev"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
上述配置文件的 defaultAction 定义为 SCMP_ACT_ERRNO,并将作为 syscalls 中定义的动作的后备。错误代码通过 defaultErrnoRet 字段定义为 38。
通常可以执行以下操作
SCMP_ACT_ERRNO- 返回指定的错误代码。
SCMP_ACT_ALLOW- 允许执行 syscall。
SCMP_ACT_KILL_PROCESS- 杀死进程。
SCMP_ACT_KILL_THREAD和SCMP_ACT_KILL- 仅杀死线程。
SCMP_ACT_TRAP- 抛出
SIGSYS信号。 SCMP_ACT_NOTIFY和SECCOMP_RET_USER_NOTIF。- 通知用户空间。
SCMP_ACT_TRACE- 使用指定的值通知跟踪进程。
SCMP_ACT_LOG- 在将操作记录到 syslog 或 auditd 后允许执行 syscall。
根据使用的容器运行时、OCI 运行时或 Linux 内核版本,某些操作(如 SCMP_ACT_NOTIFY 或 SECCOMP_RET_USER_NOTIF)可能不受支持。也可能存在进一步的限制,例如 SCMP_ACT_NOTIFY 不能用作 defaultAction 或用于某些 syscalls(如 write)。所有这些限制都由 OCI 运行时 (runc、crun) 或 libseccomp 定义。
syscalls JSON 数组包含一个对象列表,这些对象通过各自的 names 引用 syscalls。例如,可以使用操作 SCMP_ACT_ALLOW 创建允许的 syscalls 白名单,如上例所示。也可以使用操作 SCMP_ACT_ERRNO 定义另一个列表,但使用不同的返回值 (errnoRet)。
也可以指定传递给某些 syscalls 的参数 (args)。有关这些高级用例的更多信息,请参阅 OCI 运行时规范 和 Seccomp Linux 内核文档。