namespaces之 User Namespace机制

本文深入探讨了Linux USER Namespace机制,它允许用户ID和组ID的隔离,使得容器内的进程可以在user namespace中拥有root权限,而在宿主机上保持非特权状态。通过uid_map和gid_map文件实现映射,以及测试CAP_SETUID权限,阐述了如何在用户命名空间中设置和管理用户和组ID。然而,实际操作中遇到 gid 映射未成功的问题,尚待解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

USER Namespaces

主要是对用户和用户组进行隔离。它是从Linux 3.8内核才慢慢支持的,现在有些linux发行版还不支持user namespaces(主要是因为还不完全成熟,处于对安全的担心,在编译内核时并未开启USER Namespaces,Centos 7就不支持,后边的测试基于Ubuntu 14.04). 
User namespaces允许每个命名空间中User ID和 group ID的映射。在容器上下文环境中,这就意味着User和User Group 在容器中的操作可以拥有特权,在容器外边没有。换句话说,一个进程在user namespace中操作的权限设置不同于在宿主系统中的权限设置。user namespace一个特定的目标就是允许一个进程在容器中的操作拥有root特权,与此同时,在托管容器的宿主机上是一个无特权的正常进程。 
为了支持这种行为,每个进程的UID实际上有两种值:容器中的是一种,容器外是另一种。Group ID和进程UID相似。这种对偶性通过维护每个 User namespace用户ID的映射完成的:每个用户命令空间有一张表,这张表中记录着宿主机中用户ID对应namespace 的用户ID。这种映射是通过读写/proc/PID/uid_map(/proc/PID/gid_map gid映射文件)伪文件来设置,其中PID是user namespace这个进程的进程ID。例如,宿主机中UID为1000的用户被映射到namespace中可能会为0,用户ID为1000的进程在宿主机中是一个常态的用户(普通用户),但是它在namespace中将拥有root特权。如果在宿主机系统中没有为特定用户ID提供映射,在user namespace中,这个user ID会映射到/proc/sys/kernel/overflowuid(gid文件为overflowgid)文件提供的值(这个文件中默认的值是65534)。

测试使,只需要在clone函数中添加CLONE_NEWUSER标志即可:

 
clone(child_main, child_stack + STACK_SIZE, CLONE_NEWUSER | SIGCHLD, NULL);

编译后,普通用户(ty)就可以执行,先查看该用户ID:

 
ty@ubuntu:~$ id
uid=1000(ty) gid=1000(ty) groups=1000(ty)

使用clone函数创建进程,激活user namespace:

 
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
 
#define STACK_SIZE (1024 * 1024)
 
static char child_stack[STACK_SIZE];
 
int child_main(void* arg) {
char path[256];
printf("Child inside Namespace\n");
printf("euid=%d, egid=%d, pid=%d\n",geteuid<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值