关于借助 docker 获取 root 目录权限实现提权问题的探讨

2019-02-26 00:14:59 +08:00
 rizon

突然想到了这个问题。

首先说一下我的基础理论,不知道是不是错的:
docker 执行的用户是宿主机的用户,一般来说是 root 用户。这对吗?

但是这引来了我的一个问题,求解答,如果 docker 中的用户名交dockeruser宿主机没有这个用户,他是怎么映射的呢?按照 uid 吗?

说回正题,我给我的 dev 账户也开放了 docker 的使用权限。
因为 docker 会把本地的用户在 docker 容器中提升为 root 用户,所以在容器内就是 root 权限了,因此如果把一个本来没有权限的目录挂载到容器中就实现了提权。。

之前都没注意和这个问题,我觉得这是一个需要关注的事情吧?怎么避免呢?

关于这个 docker 用户的问题,大概需要了解的相关知识有:linux user namespace,docker 中的 uid 和 gid。 不过明天还有事,回头我会好好看看。大家有什么知道的想法也可以说说哈

4274 次点击
所在节点    程序员
6 条回复
wweir
2019-02-26 08:42:36 +08:00
很久以前就想过这问题,没想出啥好办法。而且,没见别人关心过这问题,使用中也没遇到类似的困境,就没管它。
来爆几个之前遇到的问题:
/proc 目录隔离不够,容器内 shutdown 直接导致宿主机关机;
任意目录映射进容器实现文件系统的提权;
提权之后一通操作,宿主机对应目录属主变为 /root,不可读。
yujincheng08
2019-02-26 09:32:09 +08:00
我就曾经映射过 /etc 进去把自己宿主用户加到 sudoer。这个没什么办法。基本上给了 docker 组就相当于给了 sudo。
codehz
2019-02-26 10:08:54 +08:00
docker 组和 root 已经没区别了。。。因为实际上 docker 客户端只是 rpc,用 gid 做鉴权而已。。。dockerd 一直都是 root 权限,并不会使用非特权容器跑你的东西
ksc010
2019-02-26 10:19:18 +08:00
1. 宿主机器中的用户 和 docker 容器里面的用户 可以说没有任何关系
2. 宿主机器中的用户 是通过 sock 文件和 docker daemon 通讯的 也就是 若有该文件的 读写权限
就能 控制任何 docker 容器或镜像
3. docker daemon 是在宿主机器上是以 root 身份运行的
song4
2019-02-26 11:25:15 +08:00
先回答第一个问题:

> 如果 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 是一个好习惯:尽量避免挂载系统重要的目录或文件,如果实在需要,不妨使用只读挂载。
qsnow6
2019-08-15 01:20:35 +08:00
@song4 #5 如果只是挂载网站的代码文件,是否存在提权到掌控宿主机的可能。

网站目录内目录可读写。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/538694

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX