Linux/Unix:chroot命令示例
如何更改命令的根目录?
如何使用chroot命令更改进程(例如Web服务器)的根目录以隔离文件系统?
如何使用chroot恢复密码或者修复损坏的基于Linux/Unix的环境?
Linux和类似Unix的系统上的每个进程/命令都有当前的工作目录,称为进程/命令的根目录。
您可以使用" chroot"命令来更改命令的根目录,该命令最终会更改当前正在运行的进程及其子进程的根目录。
无法访问根目录之外的文件。
这种修改后的环境通常称为入狱目录或者chroot入狱。
只有特权进程和root用户才能使用chroot命令。
这对以下操作很有用:
- 非特权进程(如Web服务器或者DNS服务器)的特权分离。
- 设置测试环境。
- 运行旧程序或者ABI不兼容程序,而不会导致应用程序或者系统崩溃。
- 系统恢复。
- 重新安装引导程序,例如Grub或者Lilo。
- 密码恢复重设忘记的密码等等。
目的
chroot命令(将其当前目录和根目录更改为提供的目录,然后运行命令)(如果提供)或者用户登录shell程序的交互式副本。
请注意,并非每个应用程序都可以被chroot。
语法
基本语法如下:
chroot /path/to/new/root command
或者
chroot /path/to/new/root /path/to/server
或者
chroot [options] /path/to/new/root /path/to/server
chroot命令示例
在此示例中,仅使用bash和ls命令构建用于测试目的的微型 Jail。
首先,使用mkdir命令设置 Jail位置:
$ J=$HOME/jail
在$J中创建目录:
$ mkdir -p $J $ mkdir -p $J/{bin,lib64,lib} $ cd $J
使用cp命令将/bin/bash和/bin/ls复制到$J/bin /位置:
$ cp -v /bin/{bash,ls} $J/bin
将所需的库复制到$J中。
使用ldd命令为bash打印共享库依赖项:
$ ldd /bin/bash
输出示例:
linux-vdso.so.1 - (0x00007fff8d987000) libtinfo.so.5 - /lib64/libtinfo.so.5 (0x00000032f7a00000) libdl.so.2 - /lib64/libdl.so.2 (0x00000032f6e00000) libc.so.6 - /lib64/libc.so.6 (0x00000032f7200000) /lib64/ld-linux-x86-64.so.2 (0x00000032f6a00000)
从上面的输出中正确复制$J中的库:
$ cp -v /lib64/libtinfo.so.5 /lib64/libdl.so.2 /lib64/libc.so.6 /lib64/ld-linux-x86-64.so.2 $J/lib64/
输出示例:
`/lib64/libtinfo.so.5' -> `/home/Hyman/jail/lib64/libtinfo.so.5' `/lib64/libdl.so.2' -> `/home/Hyman/jail/lib64/libdl.so.2' `/lib64/libc.so.6' -> `/home/Hyman/jail/lib64/libc.so.6' `/lib64/ld-linux-x86-64.so.2' -> `/home/Hyman/jail/lib64/ld-linux-x86-64.so.2'
将必需的库复制到$J中以用于ls命令。
使用ldd命令为ls命令打印共享库依赖项:
$ ldd /bin/ls
输出示例:
linux-vdso.so.1 - (0x00007fff68dff000) libselinux.so.1 - /lib64/libselinux.so.1 (0x00000032f8a00000) librt.so.1 - /lib64/librt.so.1 (0x00000032f7a00000) libcap.so.2 - /lib64/libcap.so.2 (0x00000032fda00000) libacl.so.1 - /lib64/libacl.so.1 (0x00000032fbe00000) libc.so.6 - /lib64/libc.so.6 (0x00000032f7200000) libdl.so.2 - /lib64/libdl.so.2 (0x00000032f6e00000) /lib64/ld-linux-x86-64.so.2 (0x00000032f6a00000) libpthread.so.0 - /lib64/libpthread.so.0 (0x00000032f7600000) libattr.so.1 - /lib64/libattr.so.1 (0x00000032f9600000)
您可以一个一个地复制库,也可以尝试bash shell进行循环,如下所示:
list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')" for i in $list; do cp -v "$i" "${J}${i}"; done
输出示例:
`/lib64/libselinux.so.1' -> `/home/Hyman/jail/lib64/libselinux.so.1' `/lib64/librt.so.1' -> `/home/Hyman/jail/lib64/librt.so.1' `/lib64/libcap.so.2' -> `/home/Hyman/jail/lib64/libcap.so.2' `/lib64/libacl.so.1' -> `/home/Hyman/jail/lib64/libacl.so.1' `/lib64/libc.so.6' -> `/home/Hyman/jail/lib64/libc.so.6' `/lib64/libdl.so.2' -> `/home/Hyman/jail/lib64/libdl.so.2' `/lib64/ld-linux-x86-64.so.2' -> `/home/Hyman/jail/lib64/ld-linux-x86-64.so.2' `/lib64/libpthread.so.0' -> `/home/Hyman/jail/lib64/libpthread.so.0' `/lib64/libattr.so.1' -> `/home/Hyman/jail/lib64/libattr.so.1'
最后,将chroot插入您的新 Jail:
$ sudo chroot $J /bin/bash
尝试浏览/etc或者/var:
# ls / # ls /etc/ # ls /var/
chroot的bash和ls应用程序被锁定到名为$HOME/$J的特定目录中,并且无法在目录树的其余部分中徘徊,并且将该目录视为其/(根)目录。
如果配置正确,这将极大地提高安全性。
我如何从chrooted Jail退出?
$ exit
查明服务是否在chroot Jail中
您可以使用以下两个命令轻松地确定Postfix邮件服务器是否为chroot:
pid=$(pidof -s master) ls -ld /proc/$pid/root
我的基于Linux的服务器的示例输出:
lrwxrwxrwx. 1 root root 0 Mar 9 11:16 /proc/8613/root -> /
指向/(根目录)的PID 8613,即应用程序的根目录未更改或者更改为chroot。
这是一种无需打开配置文件即可快速发现应用程序是否被chroot的快捷方法。
这是来自chroot的nginx服务器的另一个示例:
pid=$(pidof -s master) ls -ld /proc/$pid/root
输出示例:
lrwxrwxrwx 1 nginx nginx 0 Mar 9 11:17 /proc/4233/root -> /nginxjail
应用程序的根目录已更改为/nginxjail。
使用chroot抢救并修复软件RAID系统
我假设基于软件RAID的Linux系统没有启动。
因此,您可以使用Live CD或者基于网络的远程救援内核模式来引导系统来修复系统。
在此示例中,我使用实时Linux DVD/CD和chroot将基于RHEL的系统引导到/dev/sda1和/或者/dev/md0中以解决此问题:
## Recover data, at live cd prompt type the following commands. ## ## /dev/sda1 main system partition ## ## /dev/md0 /data partition ## # Set jail dir d=/chroot mkdir $d # Mount sda1 and required dirs mount /dev/sda1 $d mount -o bind /dev $d/dev mount -o bind /sys $d/sys mount -o bind /dev/shm $d/dev/shm mount -o bind /proc $d/proc # Mount software raid /dev/md0 mount /dev/md0 $d/data # Chroot to our newly created jail. This allows us to fix bootloader or grab data before everything goes to /dev/null chroot $d # Can you see? ls df # Get files to safe location rsync -avr /path/to/my_precious_data_dir [email protected]:/path/to/dest # Get out of chrooted jail and reboot or format the server as per your needs ;) exit umount {dev,sys,[...],} reboot
chroot命令选项
在chroot(8)命令手册页中:
--userspec=USER:GROUP specify user and group (ID or name) to use --groups=G_LIST specify supplementary groups as g1,g2,..,gN --help display this help and exit --version output version information and exit