linux chroot 命令

linux chroot 命令chroot 即 change root directory 更改 root 目录 在 linux 系统中 系统默认的目录结构都是以 即以根 root 开始的 而在使用 chroot 之后 系统的目录结构将以指定的位置作为 位置 基本语法 chroot NEWROOT COMMAND ARG

大家好,我是讯享网,很高兴认识大家。

chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以 /,即以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为 / 位置。

基本语法

chroot NEWROOT [COMMAND [ARG]...]

具体用法请参考本文的 demo。

为什么要使用 chroot 命令

增加了系统的安全性,限制了用户的权力:
在经过 chroot 之后,在新根下将访问不到旧系统的根目录结构和文件,这样就增强了系统的安全性。一般会在用户登录前应用 chroot,把用户的访问能力控制在一定的范围之内。

建立一个与原系统隔离的系统目录结构,方便用户的开发:
使用 chroot 后,系统读取的是新根下的目录和文件,这是一个与原系统根下文件不相关的目录结构。在这个新的环境中,可以用来测试软件的静态编译以及一些与系统不相关的独立开发。

切换系统的根目录位置,引导 Linux 系统启动以及急救系统等:
chroot 的作用就是切换系统的根位置,而这个作用最为明显的是在系统初始引导磁盘的处理过程中使用,从初始 RAM 磁盘 (initrd) 切换系统的根位置并执行真正的 init,本文的最后一个 demo 会详细的介绍这种用法。

通过 chroot 运行 busybox 工具

busybox 包含了丰富的工具,我们可以把这些工具放置在一个目录下,然后通过 chroot 构造出一个 mini 系统。简单起见我们直接使用 docker 的 busybox 镜像打包的文件系统。先在当前目录下创建一个目录 rootfs:

$ mkdir rootfs

讯享网

然后把 busybox 镜像中的文件释放到这个目录中:

讯享网$ (docker export $(docker create busybox) | tar -C rootfs -xvf -)

通过 ls 命令查看 rootfs 文件夹下的内容:

$ ls rootfs


讯享网

万事俱备,让我们开始吧!

执行 chroot 后的 ls 命令

讯享网$ sudo chroot rootfs /bin/ls

虽然输出结果与刚才执行的 ls rootfs 命令形同,但是这次运行的命令却是 rootfs/bin/ls。

运行 chroot 后的 pwd 命令

$ sudo chroot rootfs /bin/pwd

哈,pwd 命令真把 rootfs 目录当根目录了!

不带命令执行 chroot

讯享网$ sudo chroot rootfs

$ sudo chroot rootfs /bin/sh

运行 sh 是没有问题的,并且我们打印出了当前进程的 PID。

检查程序是否运行在 chroot 环境下

讯享网$ pid=$(pidof -s sh) $ sudo ls -ld /proc/$pid/root

输出中的内容明确的指出 PID 为 46644 的进程的根目录被映射到了 /tmp/rootfs 目录。

通过代码理解 chroot 命令

下面我们尝试自己实现一个 chroot 程序,代码中涉及到两个函数,分别是 chroot() 函数和 chdir() 函数,其实真正的 chroot 命令也是通过调用它们实现的:

#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(int argc, char *argv[]) { if(argc<2){ printf("Usage: chroot NEWROOT [COMMAND...] \n"); return 1; } if(chroot(argv[1])) { perror("chroot"); return 1; } if(chdir("/")) { perror("chdir"); return 1; } if(argc == 2) { // hardcode /bin/sh for my busybox tools. argv[0] = (char *)"/bin/sh"; argv[1] = (char *) "-i"; argv[2] = NULL; } else { argv += 2; } execvp (argv[0], argv); printf("chroot: cannot run command `%s`\n", *argv); return 0; }

把上面的代码保存到文件 mychroot.c 文件中,并执行下面的命令进行编译:

讯享网$ gcc -Wall mychroot.c -o mychroot

mychroot 的用法和 chroot 基本相同:

$ sudo ./mychroot ./rootfs

特别之处是我们的 mychroot 在没有传递命令的情况下执行了 /bin/sh,原因当然是为了支持我们的 busybox 工具集,笔者在代码中 hardcode 了默认的 shell:

讯享网argv[0] = (char *)"/bin/sh";

从代码中我们也可以看到,实现 chroot 命令的核心逻辑其实并不复杂。

实例:通过 chroot 重新设置 root 密码

在系统启动过程中进入开机菜单时按下字母键 e 进程开机菜单的编辑模式:

这就是系统的开机菜单,按下 e 后进入编辑界面:

找到以 "linux16 /vmlinuz-" 开头的行。如果默认没有看到该行,需要按向下键把它滚动出来。
然后定位到该行结尾处,输入一个空格和字符串 "rd.break",如下图所示:

接着按下 ctrl + x 以该设置继续启动,启动过程中操作系统会停下来,这是系统启动过程中的一个非常早的时间点:

所以系统的根目录还挂载在 RAM disk 上(就是内存中的一个文件系统),我们可以通过 mount 命令检查系统当前挂载的文件系统,下面是我们比较关心的两条:

/dev/mapper/centos-root on /sysroot type xfs (ro,relatime,attr2,inode64,noquota)

而在我们正常登陆系统的情况下,系统根目录的挂载情况如下:

讯享网/dev/mapper/centos-root on / type xfs (rw,relatime,seclabel,attr2,inode64,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 不正确。为了确保开机时重新设定 SELinux context,必須在根目录下添加隐藏文件 .autorelabel:

讯享网sh-4.2# touch /.autorelabel

最后从 chroot 中退出,并重启系统:

sh-4.2# exit switch_root:/# reboot

重新进入登陆界面时就可以使用刚才设置的密码以 root 登陆了!

总结

chroot 是一个很有意思的命令,我们可以用它来简单的实现文件系统的隔离。但在一个容器技术繁荣的时代,用 chroot 来进行资源的隔离实在是 low 了点。所以 chroot 的主要用途还是集中在系统救援、维护等一些特殊的场景中。

参考:
理解 chroot
Linux – RedHat7 / CentOS 7 忘记root密码修改

作者:sparkdev

出处:sparkdev - 博客园

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

小讯
上一篇 2025-03-29 08:13
下一篇 2025-02-21 18:28

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/23905.html