linux unshare 命令,详解Linux Namespace之User

User namespace 是 Linux 3.8 新增的一种 namespace,用于隔离安全相关的资源,包括 user IDs and group IDs,keys, 和 capabilities。同样一个用户的 user ID 和 group ID 在不同的 user namespace 中可以不一样(与 PID nanespace 类似)。换句话说,一个用户可以在一个 user namespace 中是普通用户,但在另一个 user namespace 中是超级用户。

User namespace 可以嵌套(目前内核控制最多32层),除了系统默认的 user namespace 外,所有的 user namespace 都有一个父 user namespace,每个 user namespace 都可以有零到多个子 user namespace。 当在一个进程中调用 unshare 或者 clone 创建新的 user namespace 时,当前进程原来所在的 user namespace 为父 user namespace,新的 user namespace 为子 user namespace。

说明:本文的演示环境为 ubuntu 16.04。

创建 user namespace

我们可以通过 unshare 命令的 --user 选项来创建新的 user namespace:

$ unshare -user -r /bin/bash

ee548d48463d5aa0e76f14959db0e701.png

通过 -r 参数,我们把新的 user namespace 中的 root 用户映射到了外面的 nick 用户(接下来会介绍映射相关的概念)。在新的 user namespace 中,root 用户是有权限创建其它的 namespace 的,比如 uts namespace。这是因为当前的 bash 进程拥有全部的 capabilities:

bdcc56b1999e5f05d628f374ac51a924.png

下面我们创建一个新的 uts namespace 试试:

$ unshare --uts /bin/bash

48b6ede3d0327d33ae4d51ee2e660595.png

我们看到,新的 uts namespace 被顺利的创建了。这是因为除了 user namespace 外,创建其它类型的 namespace 都需要 CAP_SYS_ADMIN 的 capability。当新的 user namespace 创建并映射好 uid、gid 了之后, 这个 user namespace 的第一个进程将拥有完整的所有 capabilities,意味着它就可以创建新的其它类型 namespace。

其实没有必要把上面的操作(创建两个 namespace)分成两步,我们可以通 unshare 一次创建多个 namespace:

8cb1c71c32bfd60260bde7d3dc7ad0a8.png

在 unshare 的实现中,其实就是传入了 CLONE_NEWUSER | CLONE_NEWUTS,大致如下:

unshare(CLONE_NEWUSER | CLONE_NEWUTS);

在上面这种情况下,内核会保证 CLONE_NEWUSER 先被执行,然后执行剩下的其他 CLONE_NEW*,这样就使得不用 root 用户而创建新的容器成为可能,这条规则对于clone 函数也同样适用。

理解 UID 和 GID 的映射

在前面的演示中我们提到了用户在 user namespace 之间的映射,下面我们同样通过演示来理解映射是什么。我们先查看下当前用户的 ID 和 user namespace 情况:

c5748218961e7c4a1ad548ffb954408b.png

然后执行 unshare --user /bin/bash 命令创建一个新的 user namespace,注意这次没 -r 参数:

$ unshare --user /bin/bash

d774b4af9702d9a07219d5971a1cc0d4.png

在新的 user namespace 中,当前用户变成了 nobody,并且 ID 也变成了 65534。

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

如果没有映射,当在新的 user namespace 中用 getuid() 和 getgid() 获取 user ID 和 group ID 时,系统将返回文件 /proc/sys/kernel/overflowuid 中定义的 user ID 以及 proc/sys/kernel/overflowgid 中定义的 group ID,它们的默认值都是 65534。也就是说如果没有指定映射关系的话,会默认会把 ID 映射到 65534。

下面我们来完成 nick 用户在新的 user namespace 中的映射。

映射 ID 的方法就是添加映射信息到 /proc/PID/uid_map 和 /proc/PID/gid_map (这里的 PID 是新 user namespace 中的进程 ID,刚开始时这两个文件都是空的)文件中。这两个文件中的配置信息的格式如下(每个文件中可以有多条配置信息):

ID-inside-ns ID-outside-ns length

比如 0 1000 500 这条配置就表示父 user namespace 中的 1000~1500 映射到新 user namespace 中的 0~500。

对 uid_map 和 gid_map 文件的写入操作有着严格的权限控制,简单点说就是:这两个文件的拥有者是创建新的 user namespace 的用户,所以和这个用户在一个 user namespace 中的 root 账号可以写;这个用户自己是否有写 map 文件的权限还要看它有没有 CAP_SETUID 和 CAP_SETGID 的 capability。注意:只能向 map 文件写一次数据,但可以一次写多条,并且最多只能 5 条。

我们把刚才打开的 shell 窗口称为第一个 shell 窗口开始执行用户的映射操作(把用户 nick 映射为新 user namespace 中的 root)。

第一步,先在第一个 shell 窗口中查看当前进程的 ID:

3a99f25e246ddd51dbb5e7d402dc9eab.png

第二步,新打开一个 shell 窗口,我称之为第二个 shell 窗口。查看进程 3049 的映射文件属性:

72004b3207536326eaeeee6c08cfa7e4.png

用户 nick 是这两个文件的所有者,让我们尝试向这两个文件写入映射信息:

a6a5b355137b1ebc077d806332148a39.png

看上去很奇怪呀,明明是文件的所有者,却没有权限向文件中写入内容!其实根本的原因在于当前的 bash 进程没 CAP_SETUID 和 CAP_SETGID 的权限:

afd580371557ce8484f68a790e8076b2.png

下面我们为 /bin/bash 程序设置相关的 capabilities:

$ sudo setcap cap_setgid,cap_setuid+ep /bin/bash

$ sudo setcap cap_setgid,cap_setuid+ep /bin/bash

然后重新加载 bash,就可以看到相应的 capabilities 了:

1aed0e63651ed2fc33678d2c5a302844.png

现在重新向 map 文件写入映射信息:

$ echo '0 1000 500' > /proc/3049/uid_map

$ echo '0 1000 500' > /proc/3049/gid_map

这次的写入成功了。后面就不需要我们手动写入映射信息了,所以我们通过下面的命令把 /bin/bash 的 capability 恢复为原来的设置:

$ sudo setcap cap_setgid,cap_setuid-ep /bin/bash

6072348ea6a658b133dae68e183907ca.png

第三步,回到第一个 shell 窗口

重新加载 bash,并执行 id 命令:

1dfb431036b0784b939d70ba6badba8e.png

当前用户已经变成了 root(新的 user namespace 中的 root 用户)。在看看当前 bash 进程具有的 capability:

9f2ff66b5df371c2d76645db2739f1d0.png

0000003fffffffff 表示当前运行的 bash 拥有所有的 capability。

第四步,在第一个 shell 窗口中

查看 /root 目录的访问权限:

dbec49772e10350bb586e171f7111efa.png

没权限啊!尝试修改主机的名称:

766a6095300d4e20e177f4fd33106ce4.png

依然是没有权限啊!看来这个新 user namespace 中的 root 用户在父 user namespace 里面不好使。这也正是 user namespace 所期望达到的效果,当访问其它 user namespace 里的资源时,是以其它 user namespace 中的相应用户的权限来执行的,比如这里 root 对应父 user namespace 的用户是 nick,所以改不了系统的 hostname。

普通用户 nick 没有修改 hostname 的权限,那把默认的 user namespace 中的 root 用户映射为子 user namespace 中的 root 用户后可以修改 hostname 吗?答案是,不行!那是因为不管怎么映射,当用子 user namespace 的用户访问父 user namespace 的资源的时候,它启动的进程的 capability 都为空,所以这里子 user namespace 的 root 用户在父 user namespace 中就相当于一个普通的用户。

User namespace 与其它 namespace 的关系

Linux 下的每个 namespace,都有一个 user namespace 与之关联,这个 user namespace 就是创建相应 namespace 时进程所属的 user namespace,相当于每个 namespace 都有一个 owner(user namespace),这样保证对任何 namespace 的操作都受到 user namespace 权限的控制。这也是为什么在子 user namespace 中设置 hostname 失败的原因,因为要修改的 uts namespace 属于的父 user namespace,而新 user namespace 的进程没有老 user namespace 的任何 capabilities。

以 uts namespace 为例,在 uts_namespace 的结构体中有一个指向 user namespace 的指针,指向它所属的 user namespace(笔者查看的 v4.13内核,uts_namespace 结构体的定义在 /include/linux/utsname.h 文件中):

0a9793afa2799aa7e248cb9aa15614b8.png

其它 namespace 的定义也是类似的。

总结

相对其它的 namespace 而言,user namespace 稍显复杂。这是由其功能决定的,涉及到权限管理的内容时,事情往往会变得不那么直观。笔者在本文中也只是介绍了 user namespace 的基本概念,更多丰富有趣的内容还有待大家自行发掘。

参考:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512019.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从更高到更好 2021阿里双11背后的技术亮点

简介: 今年,是阿里巴巴第13个双11。今年双11,阿里巴巴大促峰值的计算成本相比去年下降50%;截至11日,小蛮驴无人车在双11期间累计配送快递已超过100万件。更多的阿里自研技术投入到双11,在芯片、服务器等硬核…

博时基金基于RocketMQ的基金数字化陪伴体系的架构实践

简介&#xff1a; 本文以博时基金的金融场景为案例&#xff0c;阐述RocketMQ在提升客户陪伴效率和丰富金融场景化能力等方面的提升作用。 <本文已参与 RocketMQ Summit 优秀案例征文活动&#xff0c;点此了解详情> 基于RocketMQ的基金数字化陪伴体系的架构实践 博时基金…

面对DNS劫持,只能坐以待毙吗?

简介&#xff1a; 借助 ARMS-云拨测&#xff0c;我们可实时对网站进行监控&#xff0c;实现分钟级别的监控&#xff0c;及时发现 DNS 劫持以及页面篡改。 作者&#xff1a;白玙 DNS 劫持作为最常见的网络攻击方式&#xff0c;是每个站长或者运维团队最为头疼的事情。苦心经营…

linux写程序四则运算,Shell编程之变量及四则运算

Shell的学习目标Shell的基本语法结构&#xff1a; 如&#xff1a;变量的定义、条件判断、循环语句(for、until、while)、分支语句、函数和数组等。基本正则表达式的应用文件处理&#xff1a;grep、sed、awk工具的使用使用shell脚本完成复杂的任务&#xff1a;服务搭建、批量处理…

博时基金基于 RocketMQ 的互联网开放平台 Matrix 架构实践

简介&#xff1a; 随着近两年业绩的抢眼&#xff0c;公募基金迎来了乘风破浪式的发展&#xff0c;截至 2021 年 1 月底&#xff0c;资产管理规模已破 20 万亿&#xff0c;创下了历史新高。 ​ <本文已参与 RocketMQ Summit 优秀案例征文活动&#xff0c;点此了解详情> 作…

首次 统一调度系统规模化落地,全面支撑阿里巴巴双 11 全业务

简介&#xff1a; 今年双 11 首次规模化亮相的统一调度&#xff0c;通过一套调度协议、一套系统架构&#xff0c;统一管理底层的计算、存储、网络资源&#xff0c;超大规模、高效率、自动化的资源弹性&#xff0c;实现了业界新的突破。在离线混部、离在线混部、新的快上快下技术…

日志服务Dashboard加速

简介&#xff1a; 阿里云日志服务致力于为用户提供统一的可观测性平台&#xff0c;同时支持日志、时序以及Trace数据的查询存储。用户可以基于收集到的各类数据构建统一的监控以及业务大盘&#xff0c;从而及时发现系统异常&#xff0c;感知业务趋势。但是随着收集到的数据量不…

明明还有空间,硬盘却写不进去了!

作者 | 阮一峰一、inode是什么&#xff1f;文件储存在硬盘上&#xff0c;硬盘的最小存储单位叫做"扇区"&#xff08;Sector&#xff09;。每个扇区储存512字节&#xff08;相当于0.5KB&#xff09;。操作系统读取硬盘的时候&#xff0c;不会一个个扇区地读取&#xf…

Dataphin核心功能(四):安全——基于数据权限分类分级和敏感数据保护,保障企业数据安全

简介&#xff1a; 《数据安全法》的发布&#xff0c;对企业的数据安全使用和管理提出了更高的要求。Dataphin提供基于数据分级分类和数据脱敏的敏感数据识别和保护能力&#xff0c;助力企业建立合规的数据安全体系&#xff0c;保障企业数据安全。本篇&#xff0c;我们就来聊聊D…

Quick BI产品核心功能大图(四):Quick引擎加速--十亿数据亚秒级分析

简介&#xff1a; 随着数字化进程的深入&#xff0c;数据应用的价值被越来越多的企业所重视。基于数据进行决策分析是应用价值体现的重要场景&#xff0c;不同行业和体量的公司广泛依赖BI产品制作报表、仪表板和数据门户&#xff0c;以此进行决策分析。 在利用BI产品进行数据分…

云厂商靠不靠谱?“国家级标准”鉴定结果来啦

近日&#xff0c;中国电子工业标准化技术协会信息技术服务分会&#xff08;ITSS分会&#xff09;正式公布最新一批通过信息技术服务标准符合性评估的企业名单。作为云计算领域首个权威分级评估体系&#xff0c;也是目前最健全的云服务能力评估体系&#xff0c;ITSS云服务能力符…

Spring Cloud Gateway一次请求调用源码解析

简介&#xff1a; 最近通过深入学习Spring Cloud Gateway发现这个框架的架构设计非常简单、有效&#xff0c;很多组件的设计都非常值得学习&#xff0c;本文就Spring Cloud Gateway做一个简单的介绍&#xff0c;以及针对一次请求Spring Cloud Gateway的处理流程做一个较为详细的…

函数计算GB镜像秒级启动:下一代软硬件架构协同优化

简介&#xff1a; 优化镜像加速冷启动大致分为两种做法&#xff1a;降低绝对延迟和降低冷启动概率。自容器镜像上线以来我们已经通过镜像加速技术&#xff0c;分阶段降低了绝对延迟。本文在此基础上&#xff0c;介绍借助函数计算下一代IaaS底座神龙裸金属和安全容器&#xff0c…

源码级别的广播与监听实现

作者 | 阿Q来源 | 阿Q说代码闲来无事&#xff0c;又翻了遍Spring的源码。不翻不知道&#xff0c;一翻吓一跳&#xff0c;之前翻过的源码已经吃进了肚子里&#xff0c;再见亦是陌生人。今天就带大家从源码的角度来分析一下广播与监听的底层实现原理。源码解析 为了实现广播与监听…

用代码玩剧本杀?第3届83行代码大赛剧情官方解析

简介&#xff1a; 由阿里云云效主办的2021年第3届83行代码挑战赛已经收官。超2万人围观&#xff0c;近4000人参赛&#xff0c;85个团队组团来战。大赛采用游戏闯关玩儿法&#xff0c;融合元宇宙科幻和剧本杀元素&#xff0c;让一众开发者玩得不亦乐乎。 说到剧本杀&#xff0c…

阿里大规模业务混部下的全链路资源隔离技术演进

简介&#xff1a; 本文作为混部实践系列开篇&#xff0c;本篇文章将介绍资源隔离技术在混部中的重要性、其落地挑战及我们的应对思路。 作者&#xff1a;钱君、南异 混部顾名思义&#xff0c;就是将不同类型的业务在同一台机器上混合部署起来&#xff0c;让它们共享机器上的 …

探索PCIe 3.0峰值性能,长江存储推新消费级固态硬盘致态TiPlus5000

2022年4月8日&#xff0c;长江存储推出新款消费级固态硬盘产品致态TiPlus5000。该产品采用基于晶栈 2.0&#xff08;Xtacking 2.0&#xff09;架构的长江存储第三代三维闪存芯片&#xff0c;支持PCIe Gen3x4接口、NVMe 1.3协议&#xff0c;顺序读取速度高达3500 MB/s&#xff0…

“敏捷版”全链路压测

简介&#xff1a; PTS 结合 10 多年来阿里的全链路压测的经验&#xff0c;让阿里云的用户可以如同享用满汉全席般的享用全套标准的全链路压测&#xff0c;也可以根据自己的需求&#xff0c;选择最适合自己的方式。 作者&#xff1a;子矜 客户的故事 全链路压测被誉为大促备战…

linux传输tcp命令,Linux tcpdump命令帮助和示例

Tcpdump是用于网络数据包分析的基本命令行实用工具。它显示网络上的TCP/IP和其他传输的网络数据包&#xff0c;tcpdump 适用于大多数的类Unix系统操作系统(如Linux,BSD等)。类Unix系统的 tcpdump 需要使用libpcap这个捕捉数据的库就像 Windows下的WinPcap。Tcpdump使用libpcap库…

离线实时一体化数仓与湖仓一体—云原生大数据平台的持续演进

简介&#xff1a; 阿里云智能研究员 林伟 &#xff1a;阿里巴巴从湖到仓的演进给我们带来了湖仓一体的思考&#xff0c;使得湖的灵活性、数据种类丰富与仓的可成长性和企业级管理得到有机融合&#xff0c;这是阿里巴巴最佳实践的宝贵资产&#xff0c;是大数据的新一代架构。 林…