大鳄教程搜集整理的这篇文章主要介绍了linuxchroot,大鳄教程大鳄感觉挺不错的中标linux,如今分享给你们linux查看进程,也给你们做个参考。
chroot,即Changerootdirectory(修改root目录)。在linux中,系统默认的目录结构都是以/,即以根(root)开始的。而在使用chroot以后,系统的目录结构将以指定的位置作为/位置。
基本句型
chrootNEWROOT[COMMAND[ARG]...]
具体用法请参考本文的demo。
为何要使用chroot
降低了系统的安全性,限制了用户的权利:在经过chroot以后,在新根下将访问不到旧系统的根目录结构和文件,这样就提高了系统的安全性。通常会在用户登陆前应用chroot,把用户的访问能力控制在一定的范围之内。
构建一个与原系统隔离的系统目录结构,便捷用户的开发:使用chroot后,系统读取的是新根下的目录和文件,这是一个与原系统根下文件不相关的目录结构。在这个新的环境中,可以拿来测试软件的静态编译以及一些与系统不相关的独立开发。
切换系统的根目录位置linux chroot,引导Linux系统启动以及急救系统等:chroot的作用就是切换系统的根位置,而这个作用最为显著的是在系统初始引导c盘的处理过程中使用,从初始RAMc盘(initrd)切换系统的根位置并执行真正的init,本文的最后一个demo会详尽的介绍这些用法。
通过chroot运行busybox工具
busybox包含了丰富的工具,我们可以把这种工具放置在一个目录下,之后通过chroot构造出一个mini系统。简单起见我们直接使用docker的busybox镜像打包的文件系统。先在当前目录下创建一个目录rootfs:
$ mkdir rootfs
之后把busybox镜像中的文件释放到这个目录中:
$ (docker export $(docker create busybo | tar -C rootfs -xvf -)
通过ls查看rootfs文件夹下的内容:
$ ls rootfs
title="linuxchroot命令"alt="linuxchroot命令"src="">
万事俱备,让我们开始吧!
执行chroot后的ls命令
$ sudo chroot rootfs /bin/ls
title="linuxchroot命令"alt="linuxchroot命令"src="">
尽管输出结果与刚刚执行的lsrootfs命令形同,然而此次运行的命令却是rootfs/bin/ls。
运行chroot后的pwd命令
$ sudo chroot rootfs /bin/pwd
title="linuxchroot命令"alt="linuxchroot命令"src="">
哈,pwd命令真把rootfs目录当根目录了!
不带命令执行chroot
$ sudo chroot rootfs
title="linuxchroot命令"alt="linuxchroot命令"src="">
此次出错了,由于找不到/bin/bash。我们晓得busybox中是不包含bash的,而且chroot命令为何会找bash命令呢?原先,假若不给chroot指定执行的命令,默认它会执行'${}-i',而我的系统中${SHelL}为/bin/bash。既然busybox中没有bash,我们只得指定/bin/sh来执行sHell了。
$ sudo chroot rootfs /bin/sh
title="linuxchroot命令"alt="linuxchroot命令"src="">
运行sh是没有问题的,但是我们复印出了当前进程的PID。
检测程序是否运行在chroot环境下
其实我们做了好几个实验,并且肯定会有同学心存疑惑,如何能证明我们运行的命令就是在chroot目录后的路径中呢?显然,我们可以通过/proc目录下的文件检测进程的中的根目录,例如我们可以通过下边的代码检测里面运行的/bin/sh命令的根目录(请在另外一个sHell中执行):
$ pid=$(pidof -s sh) $ sudo ls -ld /proc/$pid/root
title="linuxchroot命令"alt="linuxchroot命令"src="">
输出中的内容明晰的强调PID为46644的进程的根目录被映射到了/tmp/rootfs目录。
通过代码理解chroot命令
下边我们尝试自己实现一个chroot程序,代码中涉及到两个函数,分别是chroot()函数和chdir()函数,虽然真正的chroot命令也是通过调用它们实现的:
#include #include #includeint main(int argc,char *argv[])
if(argc<2)
printf("Usage: chroot NEWROOT [COMMAND...] n"
return 1;
}
<span style="color: #0000ff">if(<span style="color: #0000ff">chroot(argv[<span style="color: #800080">1<span style="color: #000000">]))
perror(<span style="color: #800000">"<span style="color: #800000">chroot<span style="color: #800000">"<span style="color: #000000">
return <span style="color: #800080">1<span style="color: #000000">;
}
<span style="color: #0000ff">if(chdir(<span style="color: #800000">"<span style="color: #800000">/<span style="color: #800000">"<span style="color: #000000">))
perror(<span style="color: #800000">"<span style="color: #800000">chdir<span style="color: #800000">"<span style="color: #000000">
return <span style="color: #800080">1<span style="color: #000000">;
}
<span style="color: #0000ff">if(argc == <span style="color: #800080">2<span style="color: #000000">)
<span style="color: #008000">//<span style="color: #008000"> hardcode /bin/sh for my busybox tool
argv[<span style="color: #800080">0] = (<span style="color: #0000ff">char *)<span style="color: #800000">"<span style="color: #800000">/bin/sh<span style="color: #800000">"<span style="color: #000000">;
argv[<span style="color: #800080">1] = (<span style="color: #0000ff">char *) <span style="color: #800000">"<span style="color: #800000">-i<span style="color: #800000">"<span style="color: #000000">;
argv[<span style="color: #800080">2] =<span style="color: #000000"> NULL;
} <span style="color: #0000ff">else<span style="color: #000000">
argv += <span style="color: #800080">2<span style="color: #000000">;
}
execvp (argv[<span style="color: #800080">0<span style="color: #000000">],argv
printf(<span style="color: #800000">"<span style="color: #800000">chroot: cot run command `%s`n<span style="color: #800000">",*<span style="color: #000000">argv
return <span style="color: #800080">0<span style="color: #000000">;
把里面的代码保存到文件mychroot.c文件中,并执行下边的命令进行编译:
$ gcc -Wall mychroot.c -o mychroot
mychroot的用法和chroot基本相同:
$ sudo ./mychroot ./rootfs
title="linuxchroot命令"alt="linuxchroot命令"src="">
非常之处是我们的mychroot在没有传递命令的情况下执行了/bin/sh,缘由其实是为了支持我们的busybox工具集,笔者在代码中hardcode了默认的sHell:
argv[0] = (char *)"/bin/sh";
从代码中我们也可以见到,实现chroot命令的核心逻辑虽然并不复杂。
实例:通过chroot重新设置root密码
忘掉了root密码该如何办?接出来的demo将演示怎么通过chroot命令重新设置centos7中被忘掉了的root密码。systemd的管理机制中,rescure模式和emeryency模式是难以直接取得root权限的,须要使用root密码能够步入rescure和emeryency环境。所以我们须要通过其他方法来设置root密码。我们可以为内核的启动指定"rd.break"参数,进而让系统在启动的初期停出来,此时我们可以通过使用root权限并结合chroot命令完成设置root密码的操作。下边我们一上去看具体的操作过程。
在系统启动过程中步入开机菜单时按下字母键e进程开机菜单的编辑模式:
title="linuxchroot命令"alt="linuxchroot命令"src="">
这就是系统的开机菜单,按下e后步入编辑界面:
title="linuxchroot命令"alt="linuxchroot命令"src="">
找到以"linux16/vmlinuz-"开头的行。假如默认没有看见该行,须要按向上键把它滚动下来。之后定位到该行结尾处,输入一个空格和字符串"rd.break",如右图所示:
title="linuxchroot命令"alt="linuxchroot命令"src="">
接着按下ctrl+x以该设置继续启动,启动过程中操作系统会停出来,这是系统启动过程中的一个特别早的时间点:
title="linuxchroot命令"alt="linuxchroot命令"src="">
所以系统的根目录还挂载在RAMdisk上(就是显存中的一个文件系统),我们可以通过mount命令检测系统当前挂载的文件系统linux chroot,下边是我们比较关心的两条:
title="linuxchroot命令"alt="linuxchroot命令"src="">
上图中mount命令输出的第一行说明此时的根目录在一个RAMdisk中,即rootfs。图中输出的第二行说明我们的文件系统此时被挂载到了/sysroot目录,但是是只读的模式:
/dev/mapper/centos-root on /sysroot type xfs (ro,relatime,attr2,inode64,noquota)
而在我们正常登录系统的情况下,系统根目录的挂载情况如下:
/dev/mapper/centos-root on / type xfs (rw,seclabel,noquota)
该时间点的最大优势是我们具有root权限!所以让我们开始设置新的root密码吧。
先通过下边的命令把/sysroot重新挂载为可读写的模式:
switch_root:/# mount -o remount,rw /sysroot
之后用下边chroot命令把根目录切换到我们原先的环境中:
switch_root:/# chroot /sysroot
此时可以理解为:我们以root权限登入了原先的系统,更改密码就很容易了!用下边的命令为root用户设置新的密码:
sh-4.2# echo "new_root_pw" | passwd --stdin root
接出来还要处理SELinux相关的问题。因为当前的环境中SELinux并未启动,所以我们对文件的更改可能导致文件的context不正确。为了确保开机时重新设定SELinuxcontext,必須在根目录下添加隐藏文件.autorelabel:
sh-4.2# touch /.autorelabel
最后从chroot中退出,并重启系统:
sh-4.2# exit switch_root:/# reboot
重新步入登录界面时就可以使用刚刚设置的密码以root登录了!
总结
chroot是一个很有意思的命令,我们可以用它来简单的实现文件系统的隔离。但在一个容器技术繁荣的时代,用chroot来进行资源的隔离实在是low了点。所以chroot的主要用途还是集中在系统搜救、维护等一些特殊的场景中。
参考:理解chrootLinux–RedHat7/CentOS7忘掉root密码更改
大鳄总结
以上是大鳄教程为你搜集整理的linuxchroot命令全部内容,希望文章才能帮你解决linuxchroot命令所遇见的程序开发问题。
假如认为大鳄教程网站内容还不错,欢迎将大鳄教程推荐给程序员好友。
本文原创地址://q13zd.cn/dljcsjzlcyxb.html编辑:刘遄,审核员:暂无