首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是什么机制阻止我在与主机共享PID命名空间的容器中读取/proc/<PID>/environ?

问是什么机制阻止我在与主机共享PID命名空间的容器中读取/proc/<PID>/environ?
EN

Unix & Linux用户
提问于 2022-10-06 18:16:02
回答 1查看 459关注 0票数 4

在研究如何与容器共享PID命名空间时,我注意到了一些我不理解的有趣的东西。当容器与主机共享PID命名空间时,一些进程的环境变量受到保护,而其他进程则没有。

让我们以mysql为例。我将使用env变量集启动容器:

代码语言:javascript
复制
ubuntu@sandbox:~$ docker container run -it -d --env MYSQL_ROOT_PASSWORD=SuperSecret mysql
551b309513926caa9d5eab5748dbee2f562311241f72c4ed5d193c81148729a6

我将启动另一个容器,它共享主机PID命名空间并尝试访问environ文件:

代码语言:javascript
复制
ubuntu@sandbox:~$ docker container run -it --rm --pid host ubuntu /bin/bash

root@1c670d9d7138:/# ps aux | grep mysql
999        18212  5.0  9.6 2006556 386428 pts/0  Ssl+ 17:55   0:00 mysqld
root       18573  0.0  0.0   2884  1288 pts/0    R+   17:55   0:00 grep --color=auto mysql

root@1c670d9d7138:/# cat /proc/18212/environ
cat: /proc/18212/environ: Permission denied

有东西挡住了我读取环境变量的权限。我发现我需要CAP_SYS_PTRACE在一个容器中读取它:

代码语言:javascript
复制
ubuntu@sandbox:~$ docker container run -it --rm --pid host --cap-add SYS_PTRACE  ubuntu /bin/bash

root@079d4c1d66d8:/# cat /proc/18212/environ
MYSQL_PASSWORD=HOSTNAME=551b30951392MYSQL_DATABASE=MYSQL_ROOT_PASSWORD=SuperSecretPWD=/HOME=/var/lib/mysqlMYSQL_MAJOR=8.0GOSU_VERSION=1.14MYSQL_USER=MYSQL_VERSION=8.0.30-1.el8TERM=xtermSHLVL=0MYSQL_ROOT_HOST=%PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binMYSQL_SHELL_VERSION=8.0.30-1.el8

然而,并非所有进程都以这种方式受到保护。

例如,我将使用env变量集启动另一个容器ubuntu,并运行tail命令。

代码语言:javascript
复制
ubuntu@sandbox:~$ docker container run --rm --env SUPERSECRET=helloworld -d ubuntu tail -f /dev/null
42023615a4415cd4064392e890622530adee1f42a8a2c9027f4921a522d5e1f2

现在,当我使用共享pid命名空间运行容器时,我可以访问环境变量。

代码语言:javascript
复制
ubuntu@sandbox:~$ docker container run -it --rm --pid host ubuntu /bin/bash

root@3a774156a364:/# ps aux | grep tail
root       19056  0.0  0.0   2236   804 ?        Ss   17:57   0:00 tail -f /dev/null
root       19176  0.0  0.0   2884  1284 pts/0    S+   17:58   0:00 grep --color=auto tail

root@3a774156a364:/# cat /proc/19056/environ
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=42023615a441SUPERSECRET=helloworldHOME=/root

是什么机制阻止我读取mysqld环境变量而不是tail -f过程?

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2022-10-12 03:25:51

是什么机制阻止我读取mysqld环境变量而不是尾-f过程?

在第一种情况下,您使用的是不同的用户ID。如果我们开始你的两个例子:

代码语言:javascript
复制
docker run --name mysql -it -d --env MYSQL_ROOT_PASSWORD=SuperSecret mysql:latest
docker run --name tail -it -d --env MYSQL_ROOT_PASSWORD=SuperSecret ubuntu:latest tail -f /dev/null

然后看一看产生的过程:

代码语言:javascript
复制
$ ps -fe n |grep -E 'tail|mysqld' | grep -v grep
     999  422026  422005  2 22:50 pts/0    Ssl+   0:00 mysqld
       0  422170  422144  0 22:50 pts/0    Ss+    0:00 tail -f /dev/null

我们看到mysqld以UID 999的形式运行,而tail命令以UID 0的形式运行。当我们在主机pid命名空间中启动一个新容器时,我们只能为同一个UID和GID所拥有的进程读取environ。因此,这是可行的,因为默认情况下,容器使用UID 0运行:

代码语言:javascript
复制
$ docker run  --rm --pid host ubuntu:latest cat /proc/422170/environ | tr '\0' '\n'
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=e89c069d4674
TERM=xterm
MYSQL_ROOT_PASSWORD=SuperSecret
HOME=/root

但这是失败的:

代码语言:javascript
复制
$ docker run  --rm --pid host ubuntu:latest cat /proc/422026/environ | tr '\0' '\n'
cat: /proc/422026/environ: Permission denied

只有在具有environ功能的情况下,我们才能读取在不同UID或GID下运行的进程的CAP_SYS_PTRACE文件。此检查的逻辑位于内核中的ptrace_may_access函数中:

代码语言:javascript
复制
    if (uid_eq(caller_uid, tcred->euid) &&
        uid_eq(caller_uid, tcred->suid) &&
        uid_eq(caller_uid, tcred->uid)  &&
        gid_eq(caller_gid, tcred->egid) &&
        gid_eq(caller_gid, tcred->sgid) &&
        gid_eq(caller_gid, tcred->gid))
        goto ok;
    if (ptrace_has_cap(tcred->user_ns, mode))
        goto ok;

我们可以通过使用与mysql进程相同的UID和GID来运行这个失败的示例:

代码语言:javascript
复制
$ docker run -u 999:999 --rm --pid host ubuntu:latest cat /proc/422026/environ | tr '\0' '\n'
MYSQL_PASSWORD=
HOSTNAME=bde980104dcd
MYSQL_DATABASE=
MYSQL_ROOT_PASSWORD=SuperSecret
PWD=/
HOME=/var/lib/mysql
MYSQL_MAJOR=8.0
GOSU_VERSION=1.14
MYSQL_USER=
MYSQL_VERSION=8.0.31-1.el8
TERM=xterm
SHLVL=0
MYSQL_ROOT_HOST=%
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MYSQL_SHELL_VERSION=8.0.31-1.el8
票数 5
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/720050

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档