什么是Seccomp?

Seccomp(全称:secure computing mode)在2.6.12版本(2005年3月8日)中引入linux内核,是一种限度零碎调用的平安机制。在严格模式下,将过程可用的零碎调用限度为四种:readwriteexitsigreturn,其余的零碎调用都会杀死过程。过滤模式下,能够指定容许那些零碎调用,Seccomp进行过滤的形式是基于应用SECCOMP_MODE_FILTER模式的BPF过滤器,并且零碎调用过滤的形式与对数据包的过滤形式雷同。例如,您可能心愿为过程提供CAP_NET_ADMIN性能,但通过阻塞accept和accept4零碎调用的形式不容许它承受套接字上的连贯。

从linux/seccomp.h 的内核源代码中看,seccomp_data构造的样子如下:

    struct seccomp_data {             int nr;            __u32 arch;            __u64 instruction_pointer;            __u64 args[6];    };

通过该构造能够看出,咱们能够基于syscall,基于其参数或基于它们的组合进行过滤。

kubernetes中的seccomp

Seccomp在Kubernetes 1.3版本中作为Alpha性能引入,应用PodSecurityPolicy上的正文将Seccomp配置文件利用于所需的Pod。

例如咱们要将一个seccomp profile 设置到某个pod范畴:

annotations:  seccomp.security.alpha.kubernetes.io/pod: "localhost/profile.json"

或者咱们设置到容器范畴:

annotations:  container.security.alpha.kubernetes.io/<container-name>: "localhost/profile.json"

在1.19版中,Seccomp 性能 GA,将新的seccompProfile字段增加到pod和容器的securityContext对象中。

apiVersion: v1kind: Podmetadata:  name: audit-pod  labels:    app: audit-podspec:  securityContext:    seccompProfile:      type: RuntimeDefault  containers:  - name: test-container    image: hashicorp/http-echo:0.2.3    args:    - "-text=just made some syscalls!"    securityContext:      allowPrivilegeEscalation: false

此处咱们能够看到咱们应用了RuntimeDefault, 该type是k8s默认的容器运行时profile。

此处可能的值为:

  • Unconfined - 如果没有其余抉择,Seccomp不会利用于容器过程(这是Kubernetes中的默认设置)。
  • RuntimeDefault - 应用默认的容器运行时配置文件。
  • Localhost - 指定自定有的profile文件。当type 为该值时,此时必须指定localhostProfile字段的值。

比方:

apiVersion: v1kind: Podmetadata:  name: violation-pod  labels:    app: violation-podspec:  securityContext:    seccompProfile:      type: Localhost      localhostProfile: profiles/fine-grained.json  containers:  - name: test-container    image: hashicorp/http-echo:0.2.3    args:    - "-text=just made some syscalls!"    securityContext:      allowPrivilegeEscalation: false 

咱们看下fine-grained.json的值:

{    "defaultAction": "SCMP_ACT_ERRNO",    "architectures": [        "SCMP_ARCH_X86_64",        "SCMP_ARCH_X86",        "SCMP_ARCH_X32"    ],    "syscalls": [        {            "names": [                "accept4",                "epoll_wait",                "pselect6",                "futex",                "madvise",                "epoll_ctl",                "getsockname",                "setsockopt",                "vfork",                "mmap",                "read",                "write",                "close",                "arch_prctl",                "sched_getaffinity",                "munmap",                "brk",                "rt_sigaction",                "rt_sigprocmask",                "sigaltstack",                "gettid",                "clone",                "bind",                "socket",                "openat",                "readlinkat",                "exit_group",                "epoll_create1",                "listen",                "rt_sigreturn",                "sched_yield",                "clock_gettime",                "connect",                "dup2",                "epoll_pwait",                "execve",                "exit",                "fcntl",                "getpid",                "getuid",                "ioctl",                "mprotect",                "nanosleep",                "open",                "poll",                "recvfrom",                "sendto",                "set_tid_address",                "setitimer",                "writev"            ],            "action": "SCMP_ACT_ALLOW"        }    ]}

请留神,对现有正文的反对已被弃用,并将在1.22版中删除。此外,作为确保Kubelet向后兼容的一部分,将以以下优先级程序执行Seccomp配置文件:

  • 容器Spec中通过seccompProfile 字段指定
  • 容器 正文指定
  • Pod Spec中通过seccompProfile 字段指定
  • Pod 正文指定

总结

Seccomp相似一个沙箱。

咱们通过指定seccompProfile, Kubernetes容许将加载到节点上的seccomp配置文件主动利用于Pod和容器。

这样咱们的应用程序就在一个沙箱中执行了,在安全性上有很大的晋升,并且Seccomp能够让你更加精细化控制系统调用。