`

理解 chroot

 
阅读更多

什么是 chroot

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


图 1. Linux 系统的目录结构
Linux 系统的目录结构

为何使用 chroot

在经过 chroot 之后,系统读取到的目录和文件将不在是旧系统根下的而是新根下(即被指定的新的位置)的目录结构和文件,因此它带来的好处大致有以下3个:

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

    在经过 chroot 之后,在新根下将访问不到旧系统的根目录结构和文件,这样就增强了系统的安全性。这个一般是在登录 (login) 前使用 chroot,以此达到用户不能访问一些特定的文件。

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

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

  3. 切换系统的根目录位置,引导 Linux 系统启动以及急救系统等。

    chroot 的作用就是切换系统的根位置,而这个作用最为明显的是在系统初始引导磁盘的处理过程中使用,从初始 RAM 磁盘 (initrd) 切换系统的根位置并执行真正的 init。另外,当系统出现一些问题时,我们也可以使用 chroot 来切换到一个临时的系统。

chroot 的使用

为了更好的理解 chroot 发挥的作用,我们将尝试指定一个特定的位置进行根目录切换。但是由于在经过 chroot 之后,系统读取到的 bin/ 等与系统相关目录将不再是旧系统根目录下的,而是切换后新根下的目录结构和文件,因此我们有必要准备一些目录结构以及必要的文件。

清单 1. 准备切换的目录结构

busybox

Busybox 被称为是嵌入式 Linux 中的瑞士军刀。Busybox 包含了许多有用的命令,如 cat、find 等,但是它的体积却非常的小。


$ pwd
/home/wstone/Build/work
$ tree .
.
|-- bin
| |-- ash -> busybox
| |-- bash
| `-- busybox
|-- etc
`-- newhome

这里使用了静态编译后的 busybox 来提供必要的命令,使用静态编译仅是为了避免动态库文件的拷贝。当然我们也可以拷贝旧系统的下的命令到新的目录结构中使用,但是那些命令通常是动态编译 的,这就意味着我们不得不拷贝相关的动态库文件到相应的目录结构中。同时这里的 bash 也非真正的 Bourne Again shell,而是一个执行 ash 的 shell 脚本。在清单 2 中,展示了位于旧系统中的 chroot 命令的使用。需要注意的是在使用 chroot 时,要求拥有相关的操作权限。


清单 2. 位于系统中的 chroot 的使用

$ pwd
/home/wstone/Build/work

# chroot .
# pwd
/

# ls
ash: ls: not found

# busybox ls
bin      etc      newhome

3 directories, 3 files

 

我们可以看到当前路径(/home/wstone/Build/work/),在经过 chroot 后转变成了 `/` 目录,同时从新根下读取了与系统相关的目录结构。使用 ls 命令失败是由于我们创建的测试目录结构中并没有包含命令 ls ,但是我们成功的使用了 busybox 中的 ls 。以上看到的只是 chroot 的一种使用方式,其实标准的 chroot (Coreutils - GNU core utilities 提供的 chroot)使用方式有2种:


清单 3. 标准 chroot 的2种使用方式

[1] chroot NEWROOT [COMMAND...]
[2] chroot OPTION

 

刚才我们使用的是方式[2]。这将在没有给定环境时,默认执行 `/bin/sh `,但是当给定环境后,将运行 `${SHELL} –i `,即与环境相同的可交互的 shell。我们的目录结构中并没有包含sh,显然清单 2 中的 chroot 运行了 `${SHELL} –i `。当然我们也可以在进行切换时指定需要的命令,即使用方式[1]。

清单 4. chroot 另一种方式的使用


# chroot . /bin/ash
#

清单 4 中,尝试了在经过 chroot 后,执行新目录结构下的 ash shell。不得不说的是,如果新根下的目录结构和文件准备的够充分,那么一个新的简单的 Linux 系统就可以使用了。其实更为常见的是在初始 RAM 磁盘 (initrd)中使用 chroot,以此来执行系统的 init清单 5 中,展示的是在 Linux 2.4 内核 initrd 中使用 chroot。


清单 5. 在 Linux 2.4 内核 initrd 中使用 chroot 的示例

mount /dev/hda1 /new-root
cd /new-root
pivot_root . old-root
exec chroot . /sbin/init <dev/console >dev/console 2>&1
umount /old-root

 

由于 Linux 内核的升级,initrd 处理机制和格式发生了变化,在 Linux 2.6 内核 initrd 中不能再使用 pivot_root,因此一般也不再使用 chroot,而是选择使用 busybox 提供的 switch_root 或者 klibc 提供的 run-init 进行根目录的切换。(这并不是说不能在 Linux 2.6内核 initrd 中使用 chroot,选择 switch_root 或 run-init 仅是出于习惯和方便的考虑。)但是实质上,它们仅是将 chroot 的功能进行了封装,以此更加方便简单的切换根目录。


清单 6. 在 Linux 2.6 内核 initrd 中 chroot 的使用

[1] find -xdev / -exec rm '{}' ';
[2] cd /newmount; mount --move . /; chroot .

 

switch_root 和 run-init 完成了类似清单 6 中 的功能,删除 rootfs 的全部内容以释放空间,以及挂载新的根文件系统并进行切换。在 busybox 和 klibc中也有提供 chroot 命令,只是功能上与 Coreutils (GNU core utilities) 包含的 chroot 有稍许差异。

编写一个 chroot

上面介绍了 chroot 及其使用,但是编写一个简单的 chroot 并不复杂,下面我们就尝试编写chroot 以此来更好的认识 chroot 的处理过程,先编写一个粗略的 chroot 然后再完善它的功能。chroot 的编写涉及了2个函数,chroot() 以及 chdir(),它们都包含在 unistd.h 头文件中。


清单 7. 编写 chroot 涉及的2个函数

#include <unistd.h>
int chroot(const char *path);
int chdir(const char *path);

 

chroot() 将切换参数 path 所指位置为根目录 (/),chdir() 用来将当前的工作目录改变成以参数path 所指的目录。以此我们可以编写一个非常粗略的 `chroot`。


清单 8. 粗略的 `chroot`

#include <unistd.h>

int main(int argc, char *argv[])
{
    chroot(".");
    chdir("/");

    char *arrays[]={"ash",NULL};
    execvp("ash", arrays);

    return 0;
}

 

这个粗略的 `chroot` 仅能切换当前位置为根目录,同时默认执行 ash shell,不包含任何的错误处理及警告。编写并保存代码为 test.c 。在清单 9 中 ,展示了这个粗略 `chroot` 的使用情况,成功的进行了根目录的切换。


清单 9. 粗略 `chroot` 的使用

$ gcc -Wall test.c -o test

# ./test
# ls
ash: ls: not found

# busybox ls
bin      etc      newhome  test     test.c

 

下面给出功能将近完整的 chroot ,加上了一些错误处理并新增了可执行指定命令的功能。当在没有给出 chroot 切换后要执行的命令时,默认执行 `/bin/sh `,同时检测环境以确认使用何种 shell。


清单 10. 功能完整的 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;
    }

    printf("newroot = %s\n", argv[1]);
    if(chroot(argv[1])) {
        perror("chroot");
        return 1;
    }

    if(chdir("/")) {
        perror("chdir");
        return 1;
    }

    if(argc == 2) {
        argv[0] = getenv("SHELL");
        if(!argv[0])
            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;
}

 

保存以上代码为 newchroot.c 文件,编译后运行测试其功能。最后要指出的是,本文中的 `chroot` 并没有使用静态编译。如果有必要(如,在 initrd 中使用 chroot),chroot 应该使用静态编译,若是使用动态编译,那么要拷贝相关的动态库文件到相应目录结构中。


清单 11. `newchroot` 的测试

$ gcc -Wall newchroot.c -o newchroot

# ./newchroot . /bin/ash
newroot = .
#


 

结束语

在 Linux 系统初始引导的过程中,通常都有使用 chroot。但是 chroot 的好处不仅于此,它还增加了系统的安全性等。而通过本文后半部分对 chroot 的认识,我相信读者可以更好的发挥chroot 的作用。

分享到:
评论

相关推荐

    Chroot进入linux根文件系统以执行修复_Shell_下载.zip

    在Linux操作系统中,Chroot(Change Root)是一个强大的工具,它允许系统管理员创建一个隔离的环境,这个环境看起来就像是一个...通过理解和正确使用Chroot,你将能够提升你的系统管理技能,更好地应对各种复杂情况。

    PRoot, chroot,挂载绑定和没有特权/设置的binfmt_misc.zip

    在PRoot的场景中,binfmt_misc被用来使内核理解如何启动在不同架构上编译的程序,比如在一个x86_64系统上运行ARM架构的程序。通过在内核中注册一个新的二进制格式,PRoot可以欺骗系统,使其认为某个二进制文件应该在...

    pam_chroot-开源

    **PAM_chroot开源项目详解** PAM_chroot是一款开源软件,主要应用于Linux系统中,用于...然而,正确配置和维护是确保其有效性的关键,因此,管理员应当对PAM配置和chroot环境有深入理解,以充分利用这一开源解决方案。

    build-chroot:用于跨平台构建的QEMUchroot构建环境

    【标题】:“build-chroot:基于QEMU的跨平台构建工具” 在IT行业中,构建环境是软件开发过程中的重要组成...通过学习和使用`build-chroot`,开发者可以更好地理解和掌握跨平台构建的原理和技术,提升自己的开发技能。

    proot:chroot,mount --bind和binfmt_misc,没有Linux的特权设置

    首先,让我们理解`chroot`。`chroot`是一个系统调用,它改变当前进程的根目录到指定的新位置。这意味着在`chroot`之后,所有对`/`的访问都将相对于新设定的根目录进行。然而,`chroot`本身并不足以创建一个完全独立...

    Python-pmbootstrap复杂的chrootbuildflash工具来开发和安装postmarketOS

    **Python-pmbootstrap:复杂chroot、构建与...通过深入理解其背后的chroot、构建和固件管理机制,开发者可以更有效地为postmarketOS贡献代码,同时,普通用户也能更轻松地在他们的设备上体验开源操作系统带来的自由。

    arch-basestrap:从引导程序在 chroot 中构建 ArchLinux 基础

    **标题解析:** "arch-basestrap:从引导程序在 chroot 中构建 ArchLinux 基础" 这个标题表明我们讨论的是一个用于在 chroot 环境下构建 ArchLinux 操作系统基础部分的工具或方法,称为 "arch-basestrap"。...

    GentooInstaller:用于第 3 阶段 setup+chroot 的 Gentoo 安装程序

    首先,让我们理解“第3阶段”在Gentoo安装过程中的含义。Gentoo的安装分为三个主要阶段:第一阶段是引导系统,第二阶段是基础系统安装,而第三阶段则是配置和安装完整的系统。在这个阶段,你需要设置网络、分区、...

    实验3_1140320206_霍峻杰1

    【实验概述】 ...通过以上实验,我们可以深入理解UNIX系统中的权限管理和安全机制,学习如何利用chroot和capability提高服务的安全性和隔离性。这对于系统管理员和安全工程师来说是非常重要的知识。

    ldap-chrootjail:一个bash脚本,为可以通过SSH访问Linux系统的Microsoft AD用户创建chroot监狱

    **ldap-chrootjail** 是一个bash脚本,它的主要目标是为那些通过SSH(Secure Shell)连接到Linux...你应该仔细阅读这些内容,以便正确理解和使用这个工具。在实际操作前,建议先在非生产环境中进行试验,熟悉整个流程。

    jail-shell:Jail-shell是一种Linux安全工具,主要使用chroot,名称空间技术,限制用户执行特定命令以及访问单独目录

    **正文** Jail-shell,作为一个Linux安全工具,其核心功能在于提供一个安全受限的环境,以隔离用户并限制...对于任何需要在多用户环境下维护服务器安全的系统管理员来说,理解和掌握Jail-shell都是至关重要的技能。

    实验13:DNS服务(标注版).docx

    DNS(Domain Name System)服务是互联网上的一个关键组件,它负责将人类可读的域名转换成网络可识别的IP地址。在本实验中,我们将学习如何在...通过实际操作,可以加深对DNS工作原理的理解,并提升系统管理员的技能。

    MeeGo开发教程.docx

    - **API文档**:详细介绍了MeeGo提供的API接口,帮助开发者更好地理解如何利用这些API来构建应用程序。 #### 三、MeeGo SDK介绍 MeeGo SDK(软件开发工具包)是开发MeeGo应用的重要工具,它包括了一系列用于开发、...

    PyPI 官网下载 | pychroot-0.9.11.tar.gz

    《PyPI官网下载:深入理解pychroot-0.9.11.tar.gz》 PyPI(Python Package Index)是Python开发者广泛使用的软件仓库,它提供了丰富的Python库供用户下载和使用。在本文中,我们将深入探讨PyPI上下载的"pychroot-...

    0917Linux_DNS.docx

    DNS(Domain Name System)是互联网上的一种核心服务,它负责将域名转换为对应的IP地址,以便...理解这些步骤对于管理和维护DNS服务至关重要,特别是对于大型网络环境,DNS的配置和优化能显著提高网络性能和可用性。

    Linux中的FTP实验.docx

    通过这个实验,用户将深入理解如何在Red Hat Enterprise Linux 5上配置和管理FTP服务器,包括用户账户管理、权限控制、安全策略设置等关键环节。这有助于提高系统的安全性,确保每个用户只能访问他们应有权访问的...

    ftp相关内容的配置

    7. `chroot_list_enable=YES` 和 `chroot_list_file=/etc/vsftpd/chroot_list`:启用chroot列表,限制某些用户只能访问其主目录。 8. `use_localtime=YES`:使用本地时间而非GMT时间。 9. `dirmessage_enable=YES`:...

    Linux wine技术详解

    Wine(“Wine Is Not an Emulator”的首字母缩写)是一个开源软件,它提供了一个兼容层,使得Windows API调用可以在Linux环境下被理解和执行。本文将深入探讨Wine的核心原理、系统结构以及它在处理文件系统方面的...

Global site tag (gtag.js) - Google Analytics