什么是Seccomp?
Seccomp(全稱:secure computing mode)在2.6.12版本(2005年3月8日)中引入linux內核,是一種限制系統調用的安全機制。在嚴格模式下,將進程可用的系統調用限制為四種:read
,write
,exit
,sigreturn
,其他的系統調用都會殺死進程。過濾模式下,可以指定允許那些系統調用,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: v1
kind: Pod
metadata:
name: audit-pod
labels:
app: audit-pod
spec:
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: v1
kind: Pod
metadata:
name: violation-pod
labels:
app: violation-pod
spec:
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可以讓你更加精細化控制系統調用。