chroot命令用于更改根目录,将指定的目录作为新的根目录,从而创建一个隔离的运行环境。这个功能常用于系统恢复、软件测试、安全隔离等场景。
chroot [选项] 新根目录 [命令]
exit命令或Ctrl+D| 参数 | 说明 |
|---|---|
新根目录 |
要作为新根目录的路径(必填) |
命令 |
在新根目录环境中执行的命令。如果不指定,默认执行SHELL环境变量指定的shell,或/bin/sh |
--userspec=用户:组 |
指定在新环境中使用的用户和组 |
--groups=组列表 |
指定辅助组列表 |
--skip-chdir |
不切换到新根目录作为工作目录 |
--help |
显示帮助信息 |
--version |
显示版本信息 |
创建一个简单的chroot环境:
# 创建chroot目录
$ sudo mkdir -p /chroot/test
# 复制必要的命令和库文件
$ sudo mkdir -p /chroot/test/{bin,lib,lib64}
# 复制bash和ls命令
$ sudo cp /bin/bash /chroot/test/bin/
$ sudo cp /bin/ls /chroot/test/bin/
# 复制依赖的库文件(使用ldd查看依赖)
$ ldd /bin/bash
linux-vdso.so.1 (0x00007fff8b9fe000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f8b5a4e0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8b5a0ef000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8b5a6a4000)
$ sudo cp /lib/x86_64-linux-gnu/libtinfo.so.6 /chroot/test/lib/
$ sudo cp /lib/x86_64-linux-gnu/libc.so.6 /chroot/test/lib/
$ sudo cp /lib64/ld-linux-x86-64.so.2 /chroot/test/lib64/
# 进入chroot环境
$ sudo chroot /chroot/test /bin/bash
bash-5.1# ls
bash-5.1# pwd
/
bash-5.1# exit
使用debootstrap创建完整的Debian/Ubuntu chroot环境:
# 安装debootstrap工具
$ sudo apt install debootstrap
# 创建Ubuntu 20.04 chroot环境
$ sudo mkdir /chroot/ubuntu2004
$ sudo debootstrap focal /chroot/ubuntu2004 http://archive.ubuntu.com/ubuntu
# 进入chroot环境
$ sudo chroot /chroot/ubuntu2004
# 在chroot环境中安装软件
root@host:/# apt update
root@host:/# apt install vim git curl
# 退出
root@host:/# exit
当系统无法启动时,使用Live CD或USB启动,然后用chroot修复:
# 从Live系统挂载原系统分区
$ sudo mkdir /mnt/original
$ sudo mount /dev/sda1 /mnt/original # 假设原系统在/dev/sda1
# 挂载必要的文件系统
$ sudo mount --bind /dev /mnt/original/dev
$ sudo mount --bind /proc /mnt/original/proc
$ sudo mount --bind /sys /mnt/original/sys
# 进入chroot环境
$ sudo chroot /mnt/original
# 现在可以修复系统了
root@host:/# grub-install /dev/sda
root@host:/# update-grub
root@host:/# apt install --reinstall broken-package
# 退出并卸载
root@host:/# exit
$ sudo umount /mnt/original/{dev,proc,sys}
$ sudo umount /mnt/original
使用--userspec参数指定用户:
# 在chroot环境中以特定用户身份执行命令
$ sudo chroot --userspec=testuser:testgroup /chroot/test /bin/bash
# 或者执行单个命令
$ sudo chroot --userspec=1000:1000 /chroot/test /bin/ls -la
使用--skip-chdir参数:
# 默认情况下,chroot会切换到新根目录
$ sudo chroot /chroot/test /bin/bash
bash-5.1# pwd
/
# 使用--skip-chdir不切换工作目录
$ sudo chroot --skip-chdir /chroot/test /bin/bash -c "pwd"
/home/user # 保持原工作目录
创建自动化chroot环境脚本:
#!/bin/bash
CHROOT_DIR="/chroot/myenv"
# 创建chroot目录结构
create_chroot() {
echo "创建chroot环境..."
sudo mkdir -p "$CHROOT_DIR"/{bin,lib,lib64,etc,home,usr,var,tmp}
# 复制基本命令
for cmd in bash ls cp mv rm cat echo; do
if [ -f "/bin/$cmd" ]; then
sudo cp "/bin/$cmd" "$CHROOT_DIR/bin/"
copy_libs "/bin/$cmd"
fi
done
# 复制基本配置文件
sudo cp /etc/passwd /etc/group "$CHROOT_DIR/etc/"
}
# 复制库文件依赖
copy_libs() {
local binary="$1"
ldd "$binary" | grep "=> /" | awk '{print $3}' | while read lib; do
if [ -f "$lib" ]; then
sudo cp "$lib" "$CHROOT_DIR/lib/"
fi
done
}
# 进入chroot环境
enter_chroot() {
echo "进入chroot环境..."
sudo chroot "$CHROOT_DIR" /bin/bash
}
# 主程序
case "$1" in
create)
create_chroot
;;
enter)
enter_chroot
;;
*)
echo "用法: $0 {create|enter}"
;;
esac
使用chroot测试软件在不同环境下的兼容性:
# 创建不同版本的chroot环境用于测试
$ sudo mkdir /chroot/{centos7,ubuntu1804,debian10}
# 分别安装不同发行版
$ sudo yum --installroot=/chroot/centos7 groupinstall "Development Tools"
$ sudo debootstrap bionic /chroot/ubuntu1804
$ sudo debootstrap buster /chroot/debian10
# 测试软件在不同环境中的编译
$ sudo chroot /chroot/centos7 /bin/bash -c "cd /source && ./configure && make"
$ sudo chroot /chroot/ubuntu1804 /bin/bash -c "cd /source && ./configure && make"
$ sudo chroot /chroot/debian10 /bin/bash -c "cd /source && ./configure && make"
使用chroot运行不受信任的应用程序:
#!/bin/bash
# 为不受信任的应用创建隔离环境
ISOLATED_DIR="/var/isolated/app1"
# 创建隔离环境
sudo mkdir -p "$ISOLATED_DIR"
sudo chown root:root "$ISOLATED_DIR"
sudo chmod 755 "$ISOLATED_DIR"
# 只复制必要的文件
sudo mkdir -p "$ISOLATED_DIR"/{bin,lib,app}
sudo cp /bin/sh "$ISOLATED_DIR/bin/"
sudo cp /usr/bin/python3 "$ISOLATED_DIR/bin/"
# 复制依赖库
copy_dependencies() {
for bin in "$ISOLATED_DIR/bin"/*; do
ldd "$bin" 2>/dev/null | grep "=> /" | awk '{print $3}' | while read lib; do
sudo cp --parents "$lib" "$ISOLATED_DIR"
done
done
}
copy_dependencies
# 以非特权用户运行
sudo chroot --userspec=nobody:nogroup "$ISOLATED_DIR" /bin/sh -c "cd /app && python3 untrusted_app.py"
在chroot环境中正确挂载proc、sys和dev:
# 进入chroot前挂载必要的文件系统
$ sudo mount -t proc proc /chroot/test/proc
$ sudo mount -t sysfs sysfs /chroot/test/sys
$ sudo mount -t devtmpfs devtmpfs /chroot/test/dev
$ sudo mount -t tmpfs tmpfs /chroot/test/dev/shm
$ sudo mount -t tmpfs tmpfs /chroot/test/tmp
# 创建必要的设备节点
$ sudo mknod -m 666 /chroot/test/dev/null c 1 3
$ sudo mknod -m 666 /chroot/test/dev/zero c 1 5
$ sudo mknod -m 666 /chroot/test/dev/random c 1 8
$ sudo mknod -m 666 /chroot/test/dev/urandom c 1 9
# 现在进入chroot环境
$ sudo chroot /chroot/test /bin/bash
# 退出后卸载
$ sudo umount /chroot/test/{proc,sys,dev/shm,dev,tmp}
debootstrap、rinse或mock创建chroot环境mount --bind共享目录到chroot环境ulimit和cgroups限制chroot中的资源使用A: chroot只隔离文件系统,而容器提供更完整的隔离,包括进程、网络、用户等。容器使用cgroups和命名空间技术,安全性更好。
A: 使用exit命令或按Ctrl+D。如果shell被挂起,可能需要按Ctrl+C再退出。
A: 可能没有复制命令本身或其依赖的库文件。使用ldd命令检查依赖,并复制所有必要的库文件。
A: 可以,但需要挂载X11 socket和必要的库文件。通常使用mount --bind /tmp/.X11-unix挂载X11。
A: 是的,除非挂载新的proc文件系统。chroot中的进程仍然可以通过/proc看到宿主系统的进程。
debootstrap - 创建Debian/Ubuntu chroot环境mount - 挂载文件系统(用于绑定挂载)ldd - 显示共享库依赖systemd-nspawn - systemd的容器工具(比chroot更强大)docker - 容器平台(现代替代方案)unshare - 运行程序在新的命名空间中schroot - 安全的chroot工具