环境背景
Linux版本:linux-4.10.5
Linux namespace 作用:
Linux Namespace是一种Linux Kernel提供的资源隔离方案,提供Pid,Network,Ipc,Uts,Mount等资源的隔离,每个Namespace下的这些资源对于其他Namespace是不可见的
作用对象:进程
分析
对Linux namespace的分析会结合一些简单的源码做一些分析,代码只关注Linux namespace相关的部分,只是浅析逻辑,不涉及细节分析。有需要深入的可以自行跟踪源码分析。
好了,不多说,进入正文。
Linux namespace是作用于进程的,也就是说每个进程都有属于自己的namespce,所以在进程描述符中,就可以找到namespace的结构体信息。
代码目录:linux-4.10.5\include\linux\sched.h
struct task_struct {
...
/* namespaces */
struct nsproxy *nsproxy
...
}
# 由于这个结构体的信息比较多,这里只关注namespace相关的信息,所以直接搜索namespace或者nsproxy
这里的nssproxy结构体就是我们要分析的namespace的结构体,所以直接看它里面有什么东西(task_struct这个结构体也很值得大家去深入了解,会对进程有更加深刻的认识)
nsproxy
代码路径:linux-4.10.5\include\linux\nsproxy.h
struct mnt_namespace;
struct uts_namespace;
struct ipc_namespace;
struct pid_namespace;
struct cgroup_namespace;
struct fs_struct;
/*
* A structure to contain pointers to all per-process
* namespaces - fs (mount), uts, network, sysvipc, etc.
*
* The pid namespace is an exception -- it's accessed using
* task_active_pid_ns. The pid namespace here is the
* namespace that children will use.
*
* 'count' is the number of tasks holding a reference.
* The count for each namespace, then, will be the number
* of nsproxies pointing to it, not the number of tasks.
*
* The nsproxy is shared by tasks which share all namespaces.
* As soon as a single namespace is cloned or unshared, the
* nsproxy is copied.
*/
struct nsproxy {
atomic_t count;
struct uts_namespace *uts_ns;
struct ipc_namespace *ipc_ns;
struct mnt_namespace *mnt_ns;
struct pid_namespace *pid_ns_for_children;
struct net *net_ns;
struct cgroup_namespace *cgroup_ns;
};
extern struct nsproxy init_nsproxy;
大家仔细阅读以下上面的注释,就可以知道当一个fork出来的进程,nsproxy的信息也会被复制到新的进程中。
上面的nsproxy有6个主要的结构体,下面展示每个结构体中包含了哪些内容。
uts_namespace
代码路径:include/linux/utsname.h
UTS(UNIX Time-sharing System)namespace提供了主机名和域名的隔离。
struct uts_namespace {
struct kref kref;
struct new_utsname name;
struct user_namespace *user_ns;
struct ucounts *ucounts;
struct ns_common ns;
};
extern struct uts_namespace init_uts_ns;
这里又包含了很多个结构体,这里有个user_namespace是需要我们额外关注的(在Linux3.8才开始有)
user_namespace
代码路径:include\linux\user_namespace.h
主要用来隔离安全相关的标识符(idebtifier)和属性(attribute),包括用户ID、用户组ID、root目录、key(密钥)以及特殊权限。
struct user_namespace {
struct uid_gid_map uid_map;
struct uid_