Linux/Unix:chroot命令示例

时间:2020-01-09 10:45:57  来源:igfitidea点击:

如何更改命令的根目录?
如何使用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