chroot的作用及详解

chroot的作用及详解

2023年7月6日发(作者:)

chroot的作⽤及详解什么是 chrootchroot,即 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. 准备切换的⽬录结构$ pwd/home/wstone/Build/work$ tree ..|-- bin| |-- ash -> busybox| |-- bash| `-- busybox|-- etc`-- newhomebusyboxBusybox 被称为是嵌⼊式 Linux 中的瑞⼠军⼑。Busybox 包含了许多有⽤的命令,如 cat、find 等,但是它的体积却⾮常的⼩。这⾥使⽤了静态编译后的 busybox 来提供必要的命令,使⽤静态编译仅是为了避免动态库⽂件的拷贝。当然我们也可以拷贝旧系统的下的命令到新的⽬录结构中使⽤,但是那些命令通常是动态编译的,这就意味着我们不得不拷贝相关的动态库⽂件到相应的⽬录结构中。同时这⾥的 bash 也⾮真正的 Bourne Again shell,⽽是⼀个执⾏ ash 的 shell 脚本。在中,展⽰了位于旧系统中的 chroot 命令的使⽤。需要注意的是在使⽤ chroot 时,要求拥有相关的操作权限。清单 2. 位于系统中的 chroot 的使⽤$ pwd/home/wstone/Build/work# chroot .# pwd/# lsash: ls: not found# busybox lsbin etc newhome3 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 [][2] chroot OPTION刚才我们使⽤的是⽅式[2]。这将在没有给定环境时,默认执⾏ `/bin/sh`,但是当给定环境后,将运⾏ `${SHELL} –i`,即与环境相同的可交互的 shell。我们的⽬录结构中并没有包含sh,显然中的 chroot 运⾏了 `${SHELL} –i`。当然我们也可以在进⾏切换时指定需要的命令,即使⽤⽅式[1]。清单 4. chroot 另⼀种⽅式的使⽤# chroot . /bin/ash#在 中,尝试了在经过 chroot 后,执⾏新⽬录结构下的 ash shell。不得不说的是,如果新根下的⽬录结构和⽂件准备的够充分,那么⼀个新的简单的 Linux 系统就可以使⽤了。其实更为常见的是在初始 RAM 磁盘 (initrd)中使⽤chroot,以此来执⾏系统的

init。 中,展⽰的是在 Linux 2.4 内核 initrd 中使⽤ chroot。清单 5. 在 Linux 2.4 内核 initrd 中使⽤ chroot 的⽰例mount /dev/hda1 /new-rootcd /new-rootpivot_root . old-rootexec chroot . /sbin/init dev/console 2>&1umount /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 完成了类似中的功能,删除 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 int chroot(const char *path);int chdir(const char *path);chroot() 将切换参数 path 所指位置为根⽬录 (/),chdir() ⽤来将当前的⼯作⽬录改变成以参数path 所指的⽬录。以此我们可以编写⼀个⾮常粗略的 `chroot`。清单 8. 粗略的 `chroot`#include int main(int argc, char *argv[]){ chroot("."); chdir("/"); char *arrays[]={"ash",NULL}; execvp("ash", arrays); return 0;}这个粗略的 `chroot` 仅能切换当前位置为根⽬录,同时默认执⾏ ash shell,不包含任何的错误处理及警告。编写并保存代码为

test.c。在,展⽰了这个粗略 `chroot` 的使⽤情况,成功的进⾏了根⽬录的切换。清单 9. 粗略 `chroot` 的使⽤$ gcc -Wall test.c -o test# ./test# lsash: ls: not found# busybox lsbin etc newhome test test.c下⾯给出功能将近完整的 chroot ,加上了⼀些错误处理并新增了可执⾏指定命令的功能。当在没有给出 chroot 切换后要执⾏的命令时,默认执⾏ `/bin/sh`,同时检测环境以确认使⽤何种 shell。清单 10. 功能完整的 chroot#include #include #include int main(int argc, char *argv[]){ if(argc<2){ printf("Usage: chroot NEWROOT [] n"); return 1; } printf("newroot = %sn", 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/ashnewroot = .#结束语在 Linux 系统初始引导的过程中,通常都有使⽤ chroot。但是 chroot 的好处不仅于此,它还增加了系统的安全性等。⽽通过本⽂后半部分对 chroot 的认识,我相信读者可以更好的发挥chroot 的作⽤。

发布者:admin,转转请注明出处:http://www.yc00.com/web/1688592052a153113.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信