特殊路径挂载导致的容器逃逸

当例如宿主机的内的 /, /etc/, /root/.ssh 等目录的写权限被挂载进容器时,
在容器内部可以修改宿主机内的 /etc/crontab、/root/.ssh/、/root/.bashrc 等文件执行任意命令,就可以导致容器逃逸

# docker 运行示范
docker run -it -v /:/tmp/rootfs ubuntu bash

创建测试环境

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-host-rootfs
  namespace: default
  labels:
    app: ubuntu-host-rootfs
spec:
  containers:
    - name: ubuntu
      image: 192.168.101.99:80/base/ubuntu:latest
      # Docker 里 bash 挂在前台;K8s 中需常驻进程,进入交互用 kubectl exec
      command: ["/bin/bash", "-c", "sleep infinity"]
      volumeMounts:
        - name: host-root
          mountPath: /tmp/rootfs
  volumes:
    - name: host-root
      hostPath:
        path: /
        type: Directory
  restartPolicy: Always

操作

[root@k8s-node1 ~]# kubectl get pods 
NAME                 READY   STATUS    RESTARTS   AGE
ubuntu-host-rootfs   1/1     Running   0          32s
[root@k8s-node1 ~]# 
[root@k8s-node1 ~]# kubectl exec -it ubuntu-host-rootfs /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@ubuntu-host-rootfs:/# cd /tmp/rootfs/
root@ubuntu-host-rootfs:/tmp/rootfs# ls etc/kubernetes/
admin.conf  controller-manager.conf  manifests  scheduler.conf
backup      kubeadm-config.yaml      pki        super-admin.conf
config      kubelet.conf             plugins

防御建议

避免将敏感目录挂载到容器中,特别是带有写权限
使用只读挂载(ro选项)当需要共享宿主机文件时
实施严格的卷挂载策略,明确定义允许挂载的路径
使用Pod Security Policies限制卷挂载

更多推荐