searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享

容器UID和宿主机UID分析和安全建议

2023-03-28 10:58:55
30
0

不要以root用户启动docker进程

默认docker是没有开启user namespace的(开启需要修改docker配置文件),也就是说默认容器和宿主机用的是同一个user namespace,linux内核只认uid和gid,容器root(uid=0)用户和宿主机root(uid=0)是同一个,并没有隔离

  1. 如果不是必须以root用户运行,就不要以root用户运行。
  2. 如果root用户逃逸容器,很危险。我们很容易地错误地假设容器是“完全”隔离的,在一个容器中做的事情,不会影响到其他容器,也不会影响到宿主机。就像我们在云供应商上租用一个虚拟机(ECS)不会担心会被其他人的虚拟机影响到。但是相比虚拟机的隔离,容器的隔离是比较弱的。这就意味着,在一个容器内做的危险操作,可能会影响到其他容器,甚至影响到宿主机。这种突破容器的隔离性的行为也叫容器逃逸(container escape)。如果容器内以root用户运行,就会使得恶意攻击变得更加容易。

 

分析宿主机UID和容器UID关系

执行docker的用户,和真正运行起来的docker用户不一样

宿主机marc用户执行docker run命令启动docker进程,不指定-u指定用户,默认会用容器里的用户,通常是root命令启动docker进程

marc@server:~$ docker run -d ubuntu:latest sleep infinity
92c57a8a4eda60678f049b906f99053cbe3bf68a7261f118e411dee173484d10

marc@server:~$ ps aux | grep sleep
root 15638 0.1 0.0 4380 808 ? Ss 19:49 0:00 sleep infinity
  • 在宿主机上查看docker进程
    • 所属用户是root(uid=0)。。。这个权限变大了,所以容器里执行命令不建议用root,他的uid会映射到宿主机的root uid
  • 在容器内登录用户,指定id显示当前用户是root
    • 默认是root(uid=0)

 指定docker进程用户,再分析用户uid关系

宿主机用uid=1001(宿主机上用户名是marc)启动docker进程,在宿主机查看docker进程,是marc用户

FROM ubuntu:latest
RUN useradd -r -u 1001 -g appuser appuser
USER appuser
ENTRYPOINT [“sleep”, “infinity”]

marc@server:~$ docker run -d test
8ad0cd43592e6c4314775392fb3149015adc25deb22e5e5ea07203ff53038073

marc@server:~$ ps aux | grep sleep
marc 16507 0.3 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity

容器里面查看当前登录容器的用户,uid=1001(容器内用户名是appuser)

marc@server:~$ docker exec -it 8ad0 /bin/bash
appuser@8ad0cd43592e:/$ ps aux | grep sleep
appuser 1 0.0 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity
  • 总结:
    • 默认docker是没有开启user namespace的(开启需要修改docker配置文件)
    • 在没开启user namespace情况下,默认容器和宿主机用的是同一个user namespace,uid都是共享的,只是uid在不同的操作系统(容器操作系统rootfs和宿主机操作系统)对应的username不一样
      • uid=1001(容器内用户名是appuser)
      • uid=1001(宿主机上用户名是marc)
    • 为什么可以这样?
      • 因为username不是Linux kernel的一部分,只是属于外部工具,在rootfs上面
      • That’s because the username (and group names) that show up in common linux tools aren’t part of the kernel, but are managed by external tools (/etc/passwd, LDAP, Kerberos, etc). So, you might see different usernames, but you can’t have different privileges for the same uid/gid, even inside different containers

 

指定docker启动用户的两种方式:

方式一:在dockerfile上指定

在Dockerfile中创建用户和用户组,并指定以该用户和用户组运行。

指定容器USER为appuser

FROM ubuntu:latest
RUN useradd -r -u 1001 -g appuser appuser
USER appuser
ENTRYPOINT [“sleep”, “infinity”]

宿主机启动docker进程,docker进程用户1001(marc)

marc@server:~$ docker run -d test
8ad0cd43592e6c4314775392fb3149015adc25deb22e5e5ea07203ff53038073

marc@server:~$ ps aux | grep sleep
marc 16507 0.3 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity

查看容器内登录用户:uid=1001(appuser)

marc@server:~$ docker exec -it 8ad0 /bin/bash
appuser@8ad0cd43592e:/$ ps aux | grep sleep
appuser 1 0.0 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity

方式二:在docker run -u上指定

$ docker run  --user www-data busybox id
uid=33(www-data) gid=33(www-data)

docker run -u(--user)[user:group] 或 --group-add 参数方式

-u表示,创建容器时,创建对应用户和用户组,也可以指定uid.(如果用户已存在则不创建)

 

 

0条评论
作者已关闭评论
q****n
20文章数
0粉丝数
q****n
20 文章 | 0 粉丝
q****n
20文章数
0粉丝数
q****n
20 文章 | 0 粉丝

容器UID和宿主机UID分析和安全建议

2023-03-28 10:58:55
30
0

不要以root用户启动docker进程

默认docker是没有开启user namespace的(开启需要修改docker配置文件),也就是说默认容器和宿主机用的是同一个user namespace,linux内核只认uid和gid,容器root(uid=0)用户和宿主机root(uid=0)是同一个,并没有隔离

  1. 如果不是必须以root用户运行,就不要以root用户运行。
  2. 如果root用户逃逸容器,很危险。我们很容易地错误地假设容器是“完全”隔离的,在一个容器中做的事情,不会影响到其他容器,也不会影响到宿主机。就像我们在云供应商上租用一个虚拟机(ECS)不会担心会被其他人的虚拟机影响到。但是相比虚拟机的隔离,容器的隔离是比较弱的。这就意味着,在一个容器内做的危险操作,可能会影响到其他容器,甚至影响到宿主机。这种突破容器的隔离性的行为也叫容器逃逸(container escape)。如果容器内以root用户运行,就会使得恶意攻击变得更加容易。

 

分析宿主机UID和容器UID关系

执行docker的用户,和真正运行起来的docker用户不一样

宿主机marc用户执行docker run命令启动docker进程,不指定-u指定用户,默认会用容器里的用户,通常是root命令启动docker进程

marc@server:~$ docker run -d ubuntu:latest sleep infinity
92c57a8a4eda60678f049b906f99053cbe3bf68a7261f118e411dee173484d10

marc@server:~$ ps aux | grep sleep
root 15638 0.1 0.0 4380 808 ? Ss 19:49 0:00 sleep infinity
  • 在宿主机上查看docker进程
    • 所属用户是root(uid=0)。。。这个权限变大了,所以容器里执行命令不建议用root,他的uid会映射到宿主机的root uid
  • 在容器内登录用户,指定id显示当前用户是root
    • 默认是root(uid=0)

 指定docker进程用户,再分析用户uid关系

宿主机用uid=1001(宿主机上用户名是marc)启动docker进程,在宿主机查看docker进程,是marc用户

FROM ubuntu:latest
RUN useradd -r -u 1001 -g appuser appuser
USER appuser
ENTRYPOINT [“sleep”, “infinity”]

marc@server:~$ docker run -d test
8ad0cd43592e6c4314775392fb3149015adc25deb22e5e5ea07203ff53038073

marc@server:~$ ps aux | grep sleep
marc 16507 0.3 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity

容器里面查看当前登录容器的用户,uid=1001(容器内用户名是appuser)

marc@server:~$ docker exec -it 8ad0 /bin/bash
appuser@8ad0cd43592e:/$ ps aux | grep sleep
appuser 1 0.0 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity
  • 总结:
    • 默认docker是没有开启user namespace的(开启需要修改docker配置文件)
    • 在没开启user namespace情况下,默认容器和宿主机用的是同一个user namespace,uid都是共享的,只是uid在不同的操作系统(容器操作系统rootfs和宿主机操作系统)对应的username不一样
      • uid=1001(容器内用户名是appuser)
      • uid=1001(宿主机上用户名是marc)
    • 为什么可以这样?
      • 因为username不是Linux kernel的一部分,只是属于外部工具,在rootfs上面
      • That’s because the username (and group names) that show up in common linux tools aren’t part of the kernel, but are managed by external tools (/etc/passwd, LDAP, Kerberos, etc). So, you might see different usernames, but you can’t have different privileges for the same uid/gid, even inside different containers

 

指定docker启动用户的两种方式:

方式一:在dockerfile上指定

在Dockerfile中创建用户和用户组,并指定以该用户和用户组运行。

指定容器USER为appuser

FROM ubuntu:latest
RUN useradd -r -u 1001 -g appuser appuser
USER appuser
ENTRYPOINT [“sleep”, “infinity”]

宿主机启动docker进程,docker进程用户1001(marc)

marc@server:~$ docker run -d test
8ad0cd43592e6c4314775392fb3149015adc25deb22e5e5ea07203ff53038073

marc@server:~$ ps aux | grep sleep
marc 16507 0.3 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity

查看容器内登录用户:uid=1001(appuser)

marc@server:~$ docker exec -it 8ad0 /bin/bash
appuser@8ad0cd43592e:/$ ps aux | grep sleep
appuser 1 0.0 0.0 4380 668 ? Ss 20:02 0:00 sleep infinity

方式二:在docker run -u上指定

$ docker run  --user www-data busybox id
uid=33(www-data) gid=33(www-data)

docker run -u(--user)[user:group] 或 --group-add 参数方式

-u表示,创建容器时,创建对应用户和用户组,也可以指定uid.(如果用户已存在则不创建)

 

 

文章来自个人专栏
云技术专栏
20 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0