User namespace of docker principle (2)

Lianhuasheng 2021-05-04 14:53:45
user namespace docker principle

1. user namespace

user namespace It mainly isolates the security related identifier and attribute , Include users ID, User group ID,key and capabilities etc. . Same user id In different user namespace There will be different permissions in . such as , The process belongs to an ordinary user , But it creates user namespace It belongs to the super user with all the permissions . Use unshare establish user namespace:

chunqiu@chunqiu:/root/chunqiu/docker/mount/disk1$ unshare --user -r --mount /bin/bash
root@chunqiu:/root/chunqiu/docker/mount/disk1# id
uid=0(root) gid=0(root) groups=0(root)
root@chunqiu:/root/chunqiu/docker/mount/disk1# echo $$

Open another shell window , Check the process 13905 Users :

root@chunqiu:~/chunqiu/docker/mount/disk1# ps -ef | grep 13905 | grep -v grep
chunqiu 13905 13880 0 08:26 pts/0 00:00:00 /bin/bash

As can be seen from the above example , process 13905 In the container (user namespace) It belongs to an ordinary user , But in user namespace But it belongs to me root user .

Continue to dig deep into the above example ,unshare Of -r The options indicate user namespace Mapping between users and users outside the container , see uid_map and gid_map:

root@chunqiu:/root/chunqiu/docker/mount/disk1# cat /proc/13905/uid_map
0 1002 1
root@chunqiu:/root/chunqiu/docker/mount/disk1# cat /proc/13905/gid_map
0 1002 1

You can see user namespace Internal root(0) user / Group and user namespace External chunqiu(1002) user / Group mapping . therefore , stay user namespace The privileged users in are just user namespace The average user , cannot access “ Not enough permissions ” The file of / Folder . Such as :

// user namespace Outside
root@chunqiu:~/chunqiu/docker/mount/disk1# ls -l
total 1
-rw-r----- 1 root root 21 May 3 08:20 rootfile
// user namespace Inside
root@chunqiu:/root/chunqiu/docker/mount/disk1# ls -l
total 1
-rw-r----- 1 nobody nogroup 21 May 3 08:20 rootfile
root@chunqiu:/root/chunqiu/docker/mount/disk1# cat rootfile
cat: rootfile: Permission denied

-r Option set up user namespace User mapping inside and outside . If not -r Options It needs to be filled in manually uid_map and gid_map, Implement user mapping . establish user namespace as follows :

chunqiu@chunqiu:~$ unshare --user --mount /bin/bash
nobody@chunqiu:~$ id
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
nobody@chunqiu:~$ echo $$

here user namespace Of users are nobody , It's because no user mapping has been established . modify uid_map and gid_map file , Note that the process of writing these two files must be the user namespace The father of namespace Or son namespace:

In the father user namespace Write the document in Chinese uid_map,gid_map:

chunqiu@chunqiu:~$ echo '0 1002 1' > /proc/14641/uid_map
-su: echo: write error: Operation not permitted
chunqiu@chunqiu:~$ echo '0 1002 1' > /proc/14641/gid_map
-su: echo: write error: Operation not permitted
chunqiu@chunqiu:~$ ls -l /proc/14641/uid_map
-rw-r--r-- 1 chunqiu chunqiu 0 May 3 08:57 /proc/14641/uid_map
chunqiu@chunqiu:~$ ls -l /proc/14641/gid_map
-rw-r--r-- 1 chunqiu chunqiu 0 May 3 08:57 /proc/14641/gid_map

Try to write uid_map and gid_map Show no permissions , But these two files do belong to the user chunqiu. View the current process's capability:

chunqiu@chunqiu:~$ cat /proc/$$/status | egrep 'Cap(Inh|Prm|Eff)'
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000

see capability Do you know the current process CAP_SETUID and CAP_SETGID jurisdiction , Write it again with permission :

chunqiu@chunqiu:~$ sudo setcap cap_setgid,cap_setuid+ep /bin/bash
chunqiu@chunqiu:~$ echo '0 1002 1' > /proc/14641/uid_map
chunqiu@chunqiu:~$ echo '0 1002 1' > /proc/14641/gid_map

In the child user namespace In the implementation of bash To view the user :

nobody@chunqiu:~$ exec bash
root@chunqiu:~# id
uid=0(root) gid=0(root) groups=0(root)

You can see nobody Changed to users root, Realized user namespace Mapping of internal and external users .

One thing to note is when user namespace And other namespace Mixed use , Still need root jurisdiction . The solution is to run as a normal user first user namespace, And then in user namespace China and Israel root Identity running other namespace. The kernel will guarantee user namespace Execute first .

2. docker In container uid and gid

docker It's not used by default user namespace, The container it creates is the same as the host user namespace. signify ,docker Users of the host and container are not isolated .

stay docker There are two ways to specify user identity in :

  1. Dockerfile Specify the user identity in
  2. Command line arguments specify the user identity

Here is the second command line parameter that specifies the user's identity :

# docker run -d --user 9999:9999 --name chunqiu 32c400c35bc2 sleep infinity
[root@chunqiu ~ (Master)]# docker ps | grep chunqiu
c588d1c1487a 32c400c35bc2 "sleep infinity" 11 seconds ago Up 8 seconds chunqiu
[root@chunqiu ~ (Master)]# ps -ef | grep sleep | grep -v grep
9999 3212381 3212189 2 13:53 ? 00:00:00 /usr/bin/sleep infinity
[root@chunqiu ~ (Master)]# readlink /proc/$$/ns/user

Use... In command line arguments --user Designated user id User group id. View the user that the process belongs to outside the container id Is the user specified by the command line parameter 9999, Get into container View user information in :

[root@chunqiu ~ (Master)]# docker exec -it chunqiu /bin/bash
bash-5.0$ ps -ef
9999 1 0 0 05:53 ? 00:00:00 /usr/bin/sleep infinity
9999 7 0 10 05:54 pts/0 00:00:00 /bin/bash
9999 13 7 0 05:54 pts/0 00:00:00 ps -ef
bash-5.0$ id
uid=9999 gid=9999 groups=9999
bash-5.0$ readlink /proc/$$/ns/user

Enter the container and find user namespace And the host user namespace It's the same . meanwhile , The container used PID namespace, Outside the container 3212381 A process is inside a container PID by 1 Of init process , And the user of the process is the user specified by the command line parameter .

The container and the host share the same kernel , The kernel uses uid and gid, Instead of user names and group names , So it works without specifying a user name . The kernel will send the user 9999 Treat as an ordinary user , Set up file view 9999 Access rights of :

[root@chunqiu ~ (Master)]# docker exec -it chunqiu /bin/bash
bash-5.0$ ls
commonfile chunqiufile
bash-5.0$ ls -l
total 0
-rw-rw----. 1 7779 7779 0 May 3 10:18 commonfile
-rw-rw-r--. 1 7779 7779 0 Apr 30 05:31 chunqiufile
bash-5.0$ cat chunqiufile
bash-5.0$ cat commonfile
cat: commonfile: Permission denied

Will file commonfile and chunqiufile mount Go into the container , The user and user group of the file are changed to 7779, It's on the host chunqiu Ordinary users , Here we are id The form shows . Found that users can only read chunqiufile, Because it opens read access to other users who don't belong to its user group .

2.1 kubernetes Appoint uid and gid The way

stay kubernetes By configuring security Context To configure the Pod Or container container Of uid and gid,kubernetes It is not used by default user namespace Of .
Create container Belongs to uid and gid:

runAsUser: 9999
runAsGroup: 9999

For more information here

3. docker and user namespace

Last section said docker Not on by default user namespace, actually docker The relevant functions have been realized , see here For configuration use , This article will not go into details ~


  1. Help, Java how to get all the current processes of the system
  2. Has anyone ever used JMeter or written tests in httpUnit????
  3. Living in a mountain village in late spring
  4. Partridge day, spring of HKUST
  5. JavaScript异步编程4——Promise错误处理
  6. 海康摄像SDK开发笔记(一):海康威视网络摄像头SDK介绍与模块功能
  7. JavaScript asynchronous programming 4 -- promise error handling
  8. Haikang video SDK development notes (1): introduction and module functions of Hikvision webcam SDK
  9. JOP:用于FPGA的嵌入式实时系统中的Java优化处理器内核
  10. Spring Boot源码:使用MongoDB MongoTemplate公开REST在几分钟内实现CRUD功能
  11. Spring Boot应用程序事件教程 - reflectoring
  12. 带有Resilience4j断路器的Spring云网关 - rome
  13. 经验分享:Apache Kafka的缺点与陷阱 - Emil Koutanov
  14. 通过Spring Boot Webflux实现Reactor Kafka
  15. 从Java 8升级到Java 11应该注意的问题
  16. Jop: Java optimized processor core for FPGA embedded real time system
  17. Spring boot source code: use mongodb mongotemplate to open rest to realize crud function in a few minutes
  18. Spring boot application event tutorial - reflecting
  19. Spring cloud gateway with resilience4j circuit breaker - ROM
  20. Experience sharing: shortcomings and pitfalls of Apache Kafka - Emil koutanov
  21. Realization of reactor Kafka through spring boot Webflux
  22. RPC框架设计----Socket与I/0模型
  23. Problems in upgrading from Java 8 to Java 11
  24. RPC framework design -- socket and I / 0 model
  25. RPC框架设计----I/0模型
  26. RPC framework design: I / 0 model
  27. RPC框架设计----NIO编程缓冲区Buffer
  28. RPC框架设计----NIO编程缓冲区Buffer
  29. RPC framework design -- NiO programming buffer
  30. RPC framework design -- NiO programming buffer
  31. Java多线程基础
  32. Java multithreading Foundation
  33. 码农飞升记-00-Java发展历程
  34. Development history of coder-00-java
  35. 码农飞升记-00-Java发展历程
  36. Development history of coder-00-java
  37. Spring and Autumn Moon
  38. Node.js与Spring Boot比较? - Ryan Gleason
  39. Spring WebFlux的明显陷阱 - ŁukaszKyć
  40. Spring创始人Rod大叔对YAML的真实想法
  41. Compare node.js with spring boot- Ryan Gleason
  42. Obvious pitfalls of spring Webflux- Ł ukaszKy ć
  43. Spring founder uncle rod's real thoughts on yaml
  44. 码农飞升记-02-OracleJDK是什么?OracleJDK的版本怎么选择?
  45. What is manong feisheng-02-oracle JDK? How to choose the version of Oracle JDK?
  46. Spring tide surging Xinanjiang
  47. Linux内核软中断
  48. Linux kernel soft interrupt
  49. Linux内核软中断
  50. Linux kernel soft interrupt
  51. Java multithreading Foundation
  52. The construction of Maven private library nexus
  53. I / O stream in Java
  54. JDK 16:Java 16的新功能 - InfoWorld
  55. 在Java中本地进行线程间数据传输的三种方式和源码展示
  56. jdon导致cpu 99%最后tomcat死掉---banq给予回复
  57. 用领域事件模拟AOP注入
  58. JDK 16: new function of Java 16 - InfoWorld
  59. Cartoon: from JVM lock to redis distributed lock
  60. Spring 3.1 终于加入了Cache支持