服务器之家:专注于服务器技术及软件下载分享
分类导航

Linux|Centos|Ubuntu|系统进程|Fedora|注册表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

服务器之家 - 服务器系统 - Linux - linux chroot命令详解

linux chroot命令详解

2022-03-03 17:17sparkdev Linux

这篇文章主要介绍了linux chroot命令详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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

基本语法

?
1
chroot newroot [command [arg]...]

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

为什么要使用 chroot 命令

增加了系统的安全性,限制了用户的权力:

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

建立一个与原系统隔离的系统目录结构,方便用户的开发:

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

切换系统的根目录位置,引导 linux 系统启动以及急救系统等:

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

通过 chroot 运行 busybox 工具

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

?
1
$ mkdir rootfs

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

?
1
$ (docker export $(docker create busybox) | tar -c rootfs -xvf -)

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

?
1
$ ls rootfs

linux chroot命令详解

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

执行 chroot 后的 ls 命令

?
1
$ sudo chroot rootfs /bin/ls

linux chroot命令详解

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

运行 chroot 后的 pwd 命令

?
1
$ sudo chroot rootfs /bin/pwd

linux chroot命令详解

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

不带命令执行 chroot

?
1
$ sudo chroot rootfs

linux chroot命令详解

这次出错了,因为找不到 /bin/bash。我们知道 busybox 中是不包含 bash 的,但是 chroot 命令为什么会找 bash 命令呢? 原来,如果不给 chroot 指定执行的命令,默认它会执行 '${shell} -i',而我的系统中 ${shell} 为 /bin/bash。

既然 busybox 中没有 bash,我们只好指定 /bin/sh 来执行 shell 了。

?
1
$ sudo chroot rootfs /bin/sh

linux chroot命令详解

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

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

虽然我们做了好几个实验,但是肯定会有朋友心存疑问,怎么能证明我们运行的命令就是在 chroot 目录后的路径中呢?
其实,我们可以通过 /proc 目录下的文件检查进程的中的根目录,比如我们可以通过下面的代码检查上面运行的 /bin/sh 命令的根目录(请在另外一个 shell 中执行):

?
1
2
$ pid=$(pidof -s sh)
$ sudo ls -ld /proc/$pid/root

linux chroot命令详解

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

通过代码理解 chroot 命令

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#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 文件中,并执行下面的命令进行编译:

?
1
$ gcc -wall mychroot.c -o mychroot

mychroot 的用法和 chroot 基本相同:

?
1
$ sudo ./mychroot ./rootfs

linux chroot命令详解

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

?
1
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 进程开机菜单的编辑模式:

linux chroot命令详解

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

linux chroot命令详解

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

linux chroot命令详解

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

linux chroot命令详解

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

linux chroot命令详解

上图中 mount 命令输出的第一行说明此时的根目录在一个 ram disk 中, 即 rootfs。
图中输出的第二行说明我们的文件系统此时被挂载到了 /sysroot 目录,并且是只读的模式:

 

复制代码 代码如下:
/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 重新挂载为可读写的模式:

?
1
switch_root:/# mount -o remount,rw /sysroot

然后用下面 chroot 命令把根目录切换到我们原来的环境中:

?
1
switch_root:/# chroot /sysroot

此时可以理解为:我们以 root 权限登录了原来的系统,修改密码就很容易了!用下面的命令为 root 用户设置新的密码:

?
1
sh-4.2# echo "new_root_pw" | passwd --stdin root

接下来还要处理 selinux 相关的问题。由于当前的环境中 selinux 并未启动,所以我们对文件的修改可能造成文件的 context 不正确。为了确保开机时重新设定 selinux context,必須在根目录下添加隐藏文件 .autorelabel:

?
1
sh-4.2# touch /.autorelabel

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

?
1
2
sh-4.2# exit
switch_root:/# reboot

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

总结

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://www.cnblogs.com/sparkdev/p/8556075.html

延伸 · 阅读

精彩推荐
  • Linuxlinux top命令详解

    linux top命令详解

    这篇文章主要介绍了linux top命令详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    sparkdev5622022-03-01
  • Linux理解 Linux/Unix 登录脚本的技巧

    理解 Linux/Unix 登录脚本的技巧

    有一些常见的情况,例如从Debian的包管理程序到Iaas的管理中,很多任务需要设置环境变量才能正常运行。 有时,程序通常只需要在 登陆时运行一次,例如...

    未知1042023-05-12
  • Linux将 Linux 终端与 Nautilus 文件管理器结合起来

    将 Linux 终端与 Nautilus 文件管理器结合起来

    Nautilus 是 GNOME 桌面环境中的图形化文件浏览器。你可以使用它来访问和管理系统中的文件和文件夹。 尽管并非所有人都喜欢使用终端来管理文件和目录,...

    未知812023-08-08
  • LinuxLinux系统下无法卸载挂载的目录怎么办?

    Linux系统下无法卸载挂载的目录怎么办?

    我们在日常运维中经常性会遇到需要进行磁盘的扩容、卸载、挂载等操作,但是有时候这个系统上跑的应用并没有停止或者有其他的运维同事在操作这个目...

    今日头条10302020-12-30
  • Linuxlinux驱动程序开发详细介绍

    linux驱动程序开发详细介绍

    前提,一般来说内核代码的错误可能会引起一个用户进程的死亡,或者整个系统的瘫痪,更严重的后果,可能导致磁盘损伤~因此建议最好有一台实验机进行...

    Linux教程网5392019-12-17
  • Linuxlinux设置tomcat自启动的方法

    linux设置tomcat自启动的方法

    这篇文章主要介绍了linux设置tomcat自启动的方法,需要的朋友可以参考下...

    Linux教程网8512021-10-10
  • Linux在Linux系统中创建新的亚马逊AWS访问密钥的方法

    在Linux系统中创建新的亚马逊AWS访问密钥的方法

    如何在Linux系统中创建新的亚马逊AWS访问密钥?我在配置一个需要访问我的亚马逊AWS帐号的应用时被要求提供AWS访问密钥ID和秘密访问密钥,我怎样创建一个...

    Linux教程网6182019-10-30
  • Linuxssh 登录很慢该如何解决

    ssh 登录很慢该如何解决

    这篇文章主要介绍了ssh 登录很慢该如何解决的相关资料,这里提供了两种方法,DNS反向解析及关闭ssh的gssapi认证的解决办法,需要的朋友可以参考下...

    linuxeye9922021-12-16