Kubernetes SecurityContext 安全上下文 容器添加禁用内核功能及阻止对容器根文件系统的写入
过去, 传统的 UNIX 实现只区分特权和非特权进程, 但是经过多年的发展, Linux已经可以通过内核功能支持更细粒度的权限系统。
相比于让容器运行在特权模式下以给予其无限的权限, 一个更加安全的做法是只给予它使用真正需要的内核功能的权限。
Kubernetes允许为特定的容器添加内核功能, 或禁用部分内核功能, 以允许对容器进行更加精细的权限控制, 限制攻击者潜在侵入的影响。
例如,一个容器通常不允许修改系统时间(硬件时钟的时间)。 可以通过在pod-with-defaults-pod中修改设定时间来验证:
$ kubectl exec -it pod-with-defaults -- date +尧T -s "12:00:00"
date: can'七 se七 date: Operation not permitted
如果需要允许容器修改系统时间, 可以在容器的capabilites里add 一项名为CAP_SYS_TIME的功能, 如以下代码清单所示。
[root@k8s-master ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-add-settime-capability
spec:
containers:
- name: main
image: alpine
command: ["/bin/sleep","9999999"]
securityContext:
capabilities:
add:
- SYS_TIME
在内核功能 securityContext中添加或禁用,在这里添加了 SYS_TIME功能
在新的容器中运行同样的命令,可以成功修改系统时间:
[root@k8s-master ~]# kubectl exec -it pod-add-settime-capability sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # date
Mon Aug 9 01:35:37 UTC 2021
/ # date +%T -s "12:00:00"
12:00:00
/ # date
Mon Aug 9 12:00:02 UTC 2021
/ # exit
为了阻止容器的此种行为, 需要如以下代码清单所示, 在容器securiyContext.capability.drop 列表中加入此项, 以禁用这个修改文件所有者的内核功能。
[root@k8s-master ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-drop-chown-capability
spec:
containers:
- name: main
image: alpine
command: ["/bin/sleep","9999999"]
securityContext:
capabilities:
drop:
- CHOWN
[root@k8s-master ~]# kubectl exec -it pod-drop-chown-capability sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/
# chown guest /tmp
chown: /tmp: Operation not permitted
这里已经对容器安全上下文的大部分选项研究完毕。 下面再介绍一个选项。
阻止对容器根文件系统的写入
因为安全原因你可能需要阻止容器中的进程对容器的根文件系统进行写入,仅允许它们写入挂载的存储卷。
假如你在运行一个有隐藏漏洞, 可以允许攻击者写入文件系统的 PHP 应用。 这些 PHP 文件在构建时放入容器的镜像中, 并且在容器的根文件系统中提供服务。 由于漏洞的存在, 攻击者可以修改这些文件, 在其中注入恶意代码。
这一类攻击可以通过阻止容器写入自己的根文件系统(应用的可执行代码的通常储存位置)来防止。 可以如以下代码清单所示, 将容器的 securityContext.readOnlyRootFilesystem 设置为 true来实现。
[root@k8s-master ~]# cat test1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-readonly-filesystem
spec:
containers:
- name: main
image: alpine
command: ["/bin/sleep", "999999"]
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: my-volume
mountPath: /volume
readOnly: false
volumes:
- name: my-volume
emptyDir: {}
这个容器的根文件系统不允许写入,但是向/volume写入是允许的, 因为这个目录挂载了一个存储卷。
这个pod中的容器虽然以root用户运行, 拥有/目录的写权限, 但在该目录下写入一个文件会失败:
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-with-readonly-filesystem 1/1 Running 0 2m40s
[root@k8s-master ~]# kubectl exec -it pod-with-readonly-filesystem sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # touch /newfile
touch: /newfile: Read-only file system
另 一方面, 对挂载的卷的写入是允许的:
/ # touch /volume/newfile
/ # exit
如以上例子所示, 如果容器的根文件系统是只读的, 你很可能需要为应用会写入的每一个目录(如日志、 磁盘缓存等)挂载存储卷。
提示为了增强安全性, 请将在生产环境运行的容器的readOnlyRootFilesystem选项设置为true。
相关文章
- Kubernetes详解(四十六)——statefulset控制器实战
- 使用Prometheus的Node-exporter监控Kubernetes的Node节点失败问题解决
- Kubernetes statefulset有状态应用
- kubernetes 服务发现 Node_Exporter 监控 Kubernetes 集群节点
- 通过 describe 命令学习 Kubernetes 的 pod 属性详解
- 【云原生 | Kubernetes 系列】----HPA自动伸缩
- kubernetes 二进制安装(v1.20.16)(三)容器运行时
- 【云原生 • Kubernetes】kubernetes 核心技术 - Ingress
- Kubernetes CentOS7.4 系统内核升级 修复 K8S 内存泄露问题
- Kubernetes inotify watch 耗尽
- 【云原生 | Kubernetes 系列】---Skywalking部署和监控
- Kubernetes部署_使用kubernetes部署Mysql主从结构(Kubernetes工作实践类)