加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Linux Namespace : UTS

发布时间:2020-12-15 07:18:37 所属栏目:安全 来源:网络整理
导读:hostname 是用来标识一台主机的,比如登录时的提示,在 Shell 的提示符上,都可以显示出来,这样的话,使用者可以知道自己用的是哪台机器。比如下图中的 nick@tigger: _GNU_SOURCE .h> span style="color: #0000ff"#define errExit(msg) do { perror(msg);

hostname 是用来标识一台主机的,比如登录时的提示,在 Shell 的提示符上,都可以显示出来,这样的话,使用者可以知道自己用的是哪台机器。比如下图中的 nick@tigger:

_GNU_SOURCE<.h>

<span style="color: #0000ff">#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)

<span style="color: #008000">//<span style="color: #008000"> 调用 clone 时执行的函数
<span style="color: #0000ff">static <span style="color: #0000ff">int childFunc(<span style="color: #0000ff">void <span style="color: #000000">arg)
{
<span style="color: #0000ff">struct<span style="color: #000000"> utsname uts;
<span style="color: #0000ff">char
<span style="color: #000000">shellname;
<span style="color: #008000">//<span style="color: #008000"> 在子进程的 UTS namespace 中设置 hostname
<span style="color: #0000ff">if (sethostname(arg,strlen(arg)) == -<span style="color: #800080">1<span style="color: #000000">)
errExit(<span style="color: #800000">"<span style="color: #800000">sethostname<span style="color: #800000">"<span style="color: #000000">);

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 显示子进程的 hostname</span>
<span style="color: #0000ff"&gt;if</span> (uname(&amp;uts) == -<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;)
    errExit(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;uname</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);
printf(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;uts.nodename in child:  %sn</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;,uts.nodename);
printf(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;My PID is: %dn</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;,getpid());
printf(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;My parent PID is: %dn</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;,getppid());
</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 获取系统的默认 shell</span>
shellname = getenv(<span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;SHELL</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);
</span><span style="color: #0000ff"&gt;if</span>(!<span style="color: #000000"&gt;shellname){
    shellname </span>= (<span style="color: #0000ff"&gt;char</span> *)<span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;/bin/sh</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;;
}
</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 在子进程中执行 shell</span>
execlp(shellname,shellname,(<span style="color: #0000ff"&gt;char</span> *<span style="color: #000000"&gt;)NULL);

</span><span style="color: #0000ff"&gt;return</span> <span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;;

}
<span style="color: #008000">//<span style="color: #008000"> 设置子进程的堆栈大小为 1M
<span style="color: #0000ff">#define STACK_SIZE (1024 * 1024)

<span style="color: #0000ff">int main(<span style="color: #0000ff">int argc,<span style="color: #0000ff">char <span style="color: #000000">argv[])
{
<span style="color: #0000ff">char
<span style="color: #000000">stack;
<span style="color: #0000ff">char *<span style="color: #000000">stackTop;
pid_t pid;

</span><span style="color: #0000ff"&gt;if</span> (argc < <span style="color: #800080"&gt;2</span><span style="color: #000000"&gt;) {
    fprintf(stderr,</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;Usage: %s <child-hostname>n</span><span style="color: #800000"&gt;"</span>,argv[<span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;]);
    exit(EXIT_SUCCESS);
}

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 为子进程分配堆栈空间,大小为 1M</span>
stack = <span style="color: #0000ff"&gt;malloc</span><span style="color: #000000"&gt;(STACK_SIZE);
</span><span style="color: #0000ff"&gt;if</span> (stack ==<span style="color: #000000"&gt; NULL)
    errExit(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;malloc</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);
stackTop </span>= stack + STACK_SIZE;  <span style="color: #008000"&gt;/*</span><span style="color: #008000"&gt; Assume stack grows downward </span><span style="color: #008000"&gt;*/</span>

<span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 通过 clone 函数创建子进程
</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; CLONE_NEWUTS 标识指明为新进程创建新的 UTS namespace</span>
pid = clone(childFunc,stackTop,CLONE_NEWUTS | SIGCHLD,argv[<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;]);
</span><span style="color: #0000ff"&gt;if</span> (pid == -<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;)
    errExit(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;clone</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 等待子进程退出</span>
<span style="color: #0000ff"&gt;if</span> (waitpid(pid,NULL,<span style="color: #800080"&gt;0</span>) == -<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;)
    errExit(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;waitpid</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);
printf(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;child has terminatedn</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);

exit(EXIT_SUCCESS);

}

$ -Wall uts_clone.c -o uts_clone_demo

$ ./uts_clone_demo

_GNU_SOURCE

<span style="color: #0000ff">#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)

<span style="color: #0000ff">int main(<span style="color: #0000ff">int argc,<span style="color: #0000ff">char *<span style="color: #000000">argv[])
{
<span style="color: #0000ff">int<span style="color: #000000"> fd;

</span><span style="color: #0000ff"&gt;if</span> (argc < <span style="color: #800080"&gt;3</span><span style="color: #000000"&gt;) {
    fprintf(stderr,</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;%s /proc/PID/ns/FILE cmd args...n</span><span style="color: #800000"&gt;"</span>,argv[<span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;]);
    exit(EXIT_FAILURE);
}

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 打开一个现存的 UTS namespace 文件</span>
fd = open(argv[<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;],O_RDONLY);
</span><span style="color: #0000ff"&gt;if</span> (fd == -<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;)
    errExit(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;open</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 把当前进程的 UTS namespace 设置为命令行参数传入的 namespace</span>
<span style="color: #0000ff"&gt;if</span> (setns(fd,<span style="color: #800080"&gt;0</span>) == -<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;)        
    errExit(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;setns</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 在新的 UTS namespace 中运行用户指定的程序</span>
execvp(argv[<span style="color: #800080"&gt;2</span>],&amp;argv[<span style="color: #800080"&gt;2</span><span style="color: #000000"&gt;]);
errExit(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;execvp</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);

}

$ -Wall uts_setns.c -o uts_setns_demo

$ ./uts_clone_demo myhost

$ ./uts_setns_demo /proc//ns/uts ${SHELL}

_GNU_SOURCE

<span style="color: #0000ff">#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)<span style="color: #000000">

static void usage(<span style="color: #0000ff">char *<span style="color: #000000">pname)
{
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000">Usage: %s [options] program [arg...]n<span style="color: #800000">"<span style="color: #000000">,pname);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000">Options can be:n<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -i unshare IPC namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -m unshare mount namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -n unshare network namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -p unshare PID namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -u unshare UTS namespacen<span style="color: #800000">"<span style="color: #000000">);
fprintf(stderr,<span style="color: #800000">"<span style="color: #800000"> -U unshare user namespacen<span style="color: #800000">"<span style="color: #000000">);
exit(EXIT_FAILURE);
}

<span style="color: #0000ff">int main(<span style="color: #0000ff">int argc,<span style="color: #0000ff">char *<span style="color: #000000">argv[])
{
<span style="color: #0000ff">int<span style="color: #000000"> flags,opt;
flags = <span style="color: #800080">0<span style="color: #000000">;

</span><span style="color: #0000ff"&gt;while</span> ((opt = <span style="color: #0000ff"&gt;getopt</span>(argc,argv,<span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;imnpuU</span><span style="color: #800000"&gt;"</span>)) != -<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;) {
    switch (opt) {
    </span><span style="color: #0000ff"&gt;case</span> <span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;i</span><span style="color: #800000"&gt;'</span>: flags |=<span style="color: #000000"&gt; CLONE_NEWIPC;        break;
    </span><span style="color: #0000ff"&gt;case</span> <span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;m</span><span style="color: #800000"&gt;'</span>: flags |=<span style="color: #000000"&gt; CLONE_NEWNS;         break;
    </span><span style="color: #0000ff"&gt;case</span> <span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;n</span><span style="color: #800000"&gt;'</span>: flags |=<span style="color: #000000"&gt; CLONE_NEWNET;        break;
    </span><span style="color: #0000ff"&gt;case</span> <span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;p</span><span style="color: #800000"&gt;'</span>: flags |=<span style="color: #000000"&gt; CLONE_NEWPID;        break;
    </span><span style="color: #0000ff"&gt;case</span> <span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;u</span><span style="color: #800000"&gt;'</span>: flags |=<span style="color: #000000"&gt; CLONE_NEWUTS;        break;
    </span><span style="color: #0000ff"&gt;case</span> <span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;U</span><span style="color: #800000"&gt;'</span>: flags |=<span style="color: #000000"&gt; CLONE_NEWUSER;       break;
    default:  usage(argv[</span><span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;]);
    }
}

</span><span style="color: #0000ff"&gt;if</span> (optind >=<span style="color: #000000"&gt; argc)
    usage(argv[</span><span style="color: #800080"&gt;0</span><span style="color: #000000"&gt;]);

</span><span style="color: #0000ff"&gt;if</span> (unshare(flags) == -<span style="color: #800080"&gt;1</span><span style="color: #000000"&gt;)
    errExit(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;unshare</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);

execvp(argv[optind],</span>&amp;<span style="color: #000000"&gt;argv[optind]);
errExit(</span><span style="color: #800000"&gt;"</span><span style="color: #800000"&gt;execvp</span><span style="color: #800000"&gt;"</span><span style="color: #000000"&gt;);

}

$ -Wall uts_unshare.c -o uts_unshare_demo

SYSCALL_DEFINE2(gethostname, __user *,name, new_utsname *= (copy_to_user(name,u->= -

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读