User namespace

uid和gid其实很简单,主要是为了填充文件的uid和gid,这些都是静态的,那么用户执行程序这又是什么意思呢?那么进程的权限又是指什么呢?

http://blog.51cto.com/skypegnu1/1622707

既然进程需要代替我们去完成某些动作,当我们需要访问资源的时候,必须给相应的进程赋予权限。【也就是说进程必须要携带发起这个进程用户的身份信息】,才能够进行合法操作。

【进程也是有属主和属组的】。

 Unix系统通过进程的有效用户ID和有效用户组ID来决定进程对系统资源的访问权限。

而进程在执行过程中经常涉及到文件访问操作等
1.一个运行中的进程究竟可以访问哪些资源,而不能访问哪些资源?
2.一个进程运行过程中如何实现在某个执行阶段拥有一些权限而在另一个阶段又具备另外一种权限呢?
上述状况对应于进程的访问权限以及进程执行中不同权限的切换。这一切都和进程实际用户ID,进程有效用户ID,进程保存设置用户ID有关联。
 
 
下面这个文档告诉怎么生成一个新的user namespace
 
使用unshare --user /bin/bash之后,显示的是nobody,还需要手动地去设置namespace内外的映射关系:

很奇怪,为什么上面例子中显示的用户名是nobody,它的id和gid都是65534?

“这是因为我们还没有映射父user namespace的user ID和group ID到子user namespace中来,这一步是必须的,因为这样系统才能控制一个user namespace里的用户在其他user namespace中的权限。(比如给其他user namespace中的进程发送信号,或者访问属于其他user namespace挂载的文件

user namespace 很奇怪呢,在新的usernamespace下:

uid和gid是文件Inode上固有的一个属性,是写入磁盘的,不管在哪个user namespace下,这个值应该是不会变的吧。。。。但是如下来看,好像是变化了:!

nobody@machine:/home/hon/codebox/namespace$ ls -al
总用量 12
drwxrwxr-x  2 nobody nogroup 4096 2月  25 23:25 .
drwxrwxr-x 43 nobody nogroup 4096 2月  25 23:20 ..
-rw-rw-r--  1 nobody nogroup  407 2月  25 23:25 user_ns.go

nobody@machine:/home/hon/codebox/namespace$ stat user_ns.go
  文件:'user_ns.go'
  大小:407           块:8          IO 块:4096   普通文件
设备:806h/2054d    Inode:11939834    硬链接:1
权限:(0664/-rw-rw-r--)  Uid:(65534/  nobody)   Gid:(65534/ nogroup)
最近访问:2018-02-25 23:25:50.359071444 +0800
最近更改:2018-02-25 23:25:47.434014956 +0800
最近改动:2018-02-25 23:25:47.466026943 +0800
创建时间:-
------------------

看源码,内核当中有:

384     tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);
385     tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);

------->

162 static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid)
163 {
164     uid_t uid = from_kuid(to, kuid);
165     if (uid == (uid_t)-1)
166         uid = overflowuid;
167     return uid;
168 }
--------->

 304 uid_t from_kuid(struct user_namespace *targ, kuid_t kuid)
 305 {  
 306     /* Map the uid from a global kernel uid */
 307     return map_id_up(&targ->uid_map, __kuid_val(kuid));
 308 }
 309 EXPORT_SYMBOL(from_kuid);
 

看到这里基本就明白了,我们看到的执行权限的问题,其实都被封装了一层,都被current_user_ns给过滤掉了一层,通过当前进程的user namespace做了一层的映射而完成的,然后在表里面查,这个文件的uid和gid在当前的条件下应该映射给谁。。

注意,这里是current_user_ns,是指当前进程的映射表

所以最主要的操作就是如何作user namespace这个表的映射了。

进程的ID和系统中其他的ID是一直都在的,但是被namespace给屏蔽掉了,所以当echo "0 0 4294967295” > /proc/<pid>/uid_map    echo "0 0 4294967295" > /proc/<pid>/gid_map的时候,进程ID和文件系统上文件的ID就被映射过来了,这就是内核中user的namespace。那么现在一个大胆的想法,我想着把uns外面的test3号进程给映射到ns里的0,这样不就可以尽情操作任何文件了么

不可以的;

应该从虚拟机的角度来看namespace,username是让你用户看到这个系统中有的用户都是有谁的,说白了就是叫日月换新天,让你这个namespace中的用户完全不同于实际宿主机上的用户,《奇葩说》里有一期辩题是世界黑白颠倒,黑的当白的,臭的当香的。在公司(宿主机)里你是一个小喽啰,但是回了家(namespace)你就有了很多的特权了,你可以作威作福颐指气使,但是出了namespace,在大社会里,你还是不能侵占国有资产等等等等。

所以说到这里,基本也了解namespace有啥用了,一个大的作用就是进程的自我欺骗!给神经病用的,如果进程通过syscall调查自己是啥身份,那么返回root,但是实际上,你啥也不能干,因为真正发生写操作的时候,检查的是你在宿主机上的权限。

https://segmentfault.com/a/1190000006913195

这篇文章中算是对user name使用场景做了一个很重要的描述:单打独斗好像真是没有什么应用场景,但是和uts结合起来,你就会发现自己竟然可以改主机名了,这真是一个不大不小的虚拟化呀。

原文地址:https://www.cnblogs.com/honpey/p/8471062.html