chroot jail

时间:2023-03-08 16:33:32

注意,原标题是:Linux Virtualization using Chroot Jail,我实在不知道怎么翻译,所以,自作主张,选了chroot jail作为标题。原文地址


chroot jail是什么?

在unix/类unix操作系统上,默认的根目录都是‘/’,而chroot就是为改变正在运行的进程(程序)以及它的进程(子程序)的根目录而生。假设,某个程序的根目录从原先的默认的系统根目录‘/’,被你修改到/home目录下,这个/home目录就变成这个程序的逻辑根目录,那么,这个被修改了根目录环境的程序,就不能进入这个逻辑根目录以外的路径。本质上,这就是限制某个程序所能进入的目录树,所以,被称为chroot*。(即chroot jail)。

chroot jail

因此,这个程序的活动范围就从本来的整个系统"/",到后来的逻辑根“/home”。


建立方法

通过创建一个目录(树),并且将程序运行时所需要的系统文件复制/链接到这个目录树里,就可以为程序设定chroot jail。之后,通过chroot系统调用,将程序默认的系统根目录切换到你刚刚创建的,并且具有程序运行环境的目录树中。因为程序不能访问目录树(即上文提到的逻辑根)以外的路径,所以,这就起到了保护系统,防止别人修改你系统文件的作用。通常,被用在ftp和Nginx等服务器中。简单来说,chroot jail就是将你限制在某个路径中,你所能访问的最大范围就是这个路径,所以,逻辑上,这个路径,就是你的根目录。

那么现在有一个问题:

chroot jail技术与虚拟机制有什么不同?

Chroot Jail是操作系统级别(Operating-system-level)的虚拟化技术,通常被用于在主机系统上创建多个相互独立的实例( instances)。和工作在应用层的虚拟机(Virtual Machines)相比,它是内核级别的虚拟化,几乎不占用的系统开销,所以在相同的硬件上,它比用虚拟机来创建多个独立实例(isolated instances)要好得多。虚拟机(VM)则是机器的软件实现,它们经常利用所谓的硬件虚拟化来呈现正在工作的操作系统的虚拟映像。


使用方法

创建chroot jail最基本的命令是(当然,现在这些命令还不能使用,还得将命令运行所需要的系统文件复制到/path/to/new/root下才行):

chroot /path/to/new/root command
chroot /path/to/new/root /path/to/server
chroot [options] /path/to/new/root /path/to/server

注意:只有有权限/root用户才能使用这个命令

说了那么就,现在我们就来为bash和ls命令(程序/进程)创建一个小*(mini-jail):

  1. 为命令创建一个逻辑根目录并进入里面:
mkdir jailed
cd jailed
  1. 创建运行命令的所有必需目录:根据你的操作系统,所需的目录可能会更改。 逻辑上,我们创建所有这些目录来保存所需的库的副本。 要查看所需的所有目录,请参阅步骤4(根据步骤4,我的系统需要lib。bin这个是必须的就不用多说了吧?):
mkdir -p bin lib/
  1. 运行'which'命令:运行'which'命令查找ls和bash命令的位置。 运行该命令后,将这些二进制文件复制到我们的jailed的'bin'目录中。 确保你这些命令没有任何别名。
unalias ls
unalias bash
cp $(which ls) ./bin/
cp $(which bash) ./bin/

这一步中,如果你的命令有别名,那么恭喜你,会发生下列情况:

cp: unrecognized option `--color=tty''
Try `cp --help' for more information.
  1. 复制适当的库/对象(libraries/objects):为了我们的Jailed目录中的可执行文件工作,我们需要复制相应的库/对象到JAILED目录中。默认情况下,可执行文件从'/'开始查找这些库/对象。 为了找到依赖关系,我们使用命令'ldd'。

    执行ldd $(which ls):
linux-gate.so.1 =>  (0x001f8000)
librt.so.1 => /lib/librt.so.1 (0x004bf000)
libacl.so.1 => /lib/libacl.so.1 (0x00464000)
libselinux.so.1 => /lib/libselinux.so.1 (0x004ca000)
libc.so.6 => /lib/libc.so.6 (0x00302000)
libpthread.so.0 => /lib/libpthread.so.0 (0x0048f000)
/lib/ld-linux.so.2 (0x002de000)
libattr.so.1 => /lib/libattr.so.1 (0x007d4000)
libdl.so.2 => /lib/libdl.so.2 (0x0045d000)
libsepol.so.1 => /lib/libsepol.so.1 (0x004e4000)

执行ldd $(which bash):

linux-gate.so.1 =>  (0x0011a000)
libtermcap.so.2 => /lib/libtermcap.so.2 (0x0748a000)
libdl.so.2 => /lib/libdl.so.2 (0x0045d000)
libc.so.6 => /lib/libc.so.6 (0x00302000)
/lib/ld-linux.so.2 (0x002de000)

运行下面的命令来创建适当的目录(这里我演示bash命令,ls命令操作一样):

cp /lib/libtermcap.so.2 lib/
cp /lib/libdl.so.2 lib/
cp /lib/libc.so.6 lib/
cp /lib/ld-linux.so.2 lib/

此时,应有下列文件结构:

.
|-- bin
| |-- bash
| `-- ls
`-- lib
|-- ld-linux.so.2
|-- libacl.so.1
|-- libattr.so.1
|-- libc.so.6
|-- libdl.so.2
|-- libpthread.so.0
|-- librt.so.1
|-- libselinux.so.1
|-- libsepol.so.1
`-- libtermcap.so.2

运行命令

到了这里,就是测试你前面努力成果的时刻了!!!

先试一下最基础的命令:chroot /path/to/new/root command:

chroot jail

再来,用chroot /root/jailed /bin/bash来弹出一个新的bash,在这了bash中,根目录就是原先的/root/jailed/目录:

chroot jail