突然想到了这个问题。
首先说一下我的基础理论,不知道是不是错的:
docker 执行的用户是宿主机的用户,一般来说是 root 用户。这对吗?
但是这引来了我的一个问题,求解答,如果 docker 中的用户名交dockeruser
宿主机没有这个用户,他是怎么映射的呢?按照 uid 吗?
说回正题,我给我的 dev 账户也开放了 docker 的使用权限。
因为 docker 会把本地的用户在 docker 容器中提升为 root 用户,所以在容器内就是 root 权限了,因此如果把一个本来没有权限的目录挂载到容器中就实现了提权。。
之前都没注意和这个问题,我觉得这是一个需要关注的事情吧?怎么避免呢?
关于这个 docker 用户的问题,大概需要了解的相关知识有:linux user namespace,docker 中的 uid 和 gid。 不过明天还有事,回头我会好好看看。大家有什么知道的想法也可以说说哈
1
wweir 2019-02-26 08:42:36 +08:00 via Android 1
很久以前就想过这问题,没想出啥好办法。而且,没见别人关心过这问题,使用中也没遇到类似的困境,就没管它。
来爆几个之前遇到的问题: /proc 目录隔离不够,容器内 shutdown 直接导致宿主机关机; 任意目录映射进容器实现文件系统的提权; 提权之后一通操作,宿主机对应目录属主变为 /root,不可读。 |
2
yujincheng08 2019-02-26 09:32:09 +08:00 via Android
我就曾经映射过 /etc 进去把自己宿主用户加到 sudoer。这个没什么办法。基本上给了 docker 组就相当于给了 sudo。
|
3
codehz 2019-02-26 10:08:54 +08:00 via Android 2
docker 组和 root 已经没区别了。。。因为实际上 docker 客户端只是 rpc,用 gid 做鉴权而已。。。dockerd 一直都是 root 权限,并不会使用非特权容器跑你的东西
|
4
ksc010 2019-02-26 10:19:18 +08:00 1
1. 宿主机器中的用户 和 docker 容器里面的用户 可以说没有任何关系
2. 宿主机器中的用户 是通过 sock 文件和 docker daemon 通讯的 也就是 若有该文件的 读写权限 就能 控制任何 docker 容器或镜像 3. docker daemon 是在宿主机器上是以 root 身份运行的 |
5
song4 2019-02-26 11:25:15 +08:00 1
先回答第一个问题:
> 如果 docker 中的用户名交 dockeruser 宿主机没有这个用户,他是怎么映射的呢?按照 uid 吗? 是的,按照 uid 来映射。默认从 uid=0 开始映射,宿主机的 uid=0,1,2,... 映射为容器的 uid=0,1,2,...。你可以通过 `--userns-remap` 选项来改变这个行为,比如说可以指定宿主机的 uid=1000,1001,1002,... 映射为容器的 uid=0,1,2,...。 第二个问题: > 所以在容器内就是 root 权限了,怎么避免呢? 事实确实是这样的,你可以参考 LWN 的这篇文章:[User namespaces + overlayfs = root privileges]( https://lwn.net/Articles/671641/)。这一点其实在 Docker 官方给出的 [Docker daemon attack surface]( https://docs.docker.com/engine/security/security/) 中也已经指出来了: > Docker allows you to share a directory between the Docker host and a guest container; and it allows you to do so without limiting the access rights of the container. This means that you can start a container where the /host directory is the / directory on your host; and the container can alter your host filesystem without any restriction. This is similar to how virtualization systems allow filesystem resource sharing. Nothing prevents you from sharing your root filesystem (or even your root block device) with a virtual machine. 那么,怎么避免呢?一种方案是,可以在运行容器的时候通过 `--user` 选项指定非 root 用户名和组。另外,挂载 volumes 的时候遵循 Principle of Least Privilege 是一个好习惯:尽量避免挂载系统重要的目录或文件,如果实在需要,不妨使用只读挂载。 |