How to Use the chroot Command on Linux

How to Use the chroot Command on Linux

The chroot command can send you to jail, keep your development or test environments isolated.

With chroot you can set up and run programs or interactive shells such as Bash in an encapsulated filesystem that is prevented from interacting with your regular filesystem.

When Should You Use a chroot?

A chroot environment provides functionality similar to that of a virtual machine, but it is a lighter solution.
It does not need to have a kernel installed in the system. This system shares your existing kernel.

If a Linux installation becomes inoperable, you can use chroot to mount the damaged filesystem to a mount point on a Live CD.
This allows you to work in the damaged system and attempt to fix it as though it were mounted normally at root /.
This means the expected file paths within the damaged system will be correctly referenced from the root directory, and not from the mount point of the Live CD.

Creating a chroot Environment

We need a directory to act as the root directory of the chroot environment.
Define a shorthand way of referring to that directory:

$ chr=$HOME/testroot
$ mkdir -p $chr
create directories to hold the portions of the operating system our chroot environment will require

$ mkdir -p $chr/{bin,lib,lib64}
copy the binaries that we need in our minimalist Linux environment from your regular “/bin” directory into our chroot “/bin” directory.

$ cd $chr
$ cp -v /bin/{bash,touch,ls,rm} $chr/bin
'/bin/bash' -> '/home/jerry/testroot/bin/bash'
'/bin/touch' -> '/home/jerry/testroot/bin/touch'
'/bin/ls' -> '/home/jerry/testroot/bin/ls'
'/bin/rm' -> '/home/jerry/testroot/bin/rm'
The -v (verbose) option makes cp tell us what it is doing as it performs each copy action.

These binaries will have dependencies. We need to discover what they are and copy those files into our environment as well,


$ list="$(ldd /bin/bash | egrep -o '/lib.*\.[0-9]')"
$ for i in $list; do cp -v --parents "$i" "${chr}"; done
/lib/x86_64-linux-gnu -> /home/jerry/testroot/lib/x86_64-linux-gnu
'/lib/x86_64-linux-gnu/libtinfo.so.6' -> '/home/jerry/testroot/lib/x86_64-linux-gnu/libtinfo.so.6'
'/lib/x86_64-linux-gnu/libdl.so.2' -> '/home/jerry/testroot/lib/x86_64-linux-gnu/libdl.so.2'
'/lib/x86_64-linux-gnu/libc.so.6' -> '/home/jerry/testroot/lib/x86_64-linux-gnu/libc.so.6'
'/lib64/ld-linux-x86-64.so.2' -> '/home/jerry/testroot/lib64/ld-linux-x86-64.so.2'

$ list="$(ldd /bin/touch | egrep -o '/lib.*\.[0-9]')"
$ for i in $list; do cp -v --parents "$i" "${chr}"; done
'/lib/x86_64-linux-gnu/libc.so.6' -> '/home/jerry/testroot/lib/x86_64-linux-gnu/libc.so.6'
'/lib64/ld-linux-x86-64.so.2' -> '/home/jerry/testroot/lib64/ld-linux-x86-64.so.2'

$ list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')"
$ for i in $list; do cp -v --parents "$i" "${chr}"; done
'/lib/x86_64-linux-gnu/libselinux.so.1' -> '/home/jerry/testroot/lib/x86_64-linux-gnu/libselinux.so.1'
'/lib/x86_64-linux-gnu/libc.so.6' -> '/home/jerry/testroot/lib/x86_64-linux-gnu/libc.so.6'
'/lib/x86_64-linux-gnu/libpcre2-8.so.0' -> '/home/jerry/testroot/lib/x86_64-linux-gnu/libpcre2-8.so.0'
'/lib/x86_64-linux-gnu/libdl.so.2' -> '/home/jerry/testroot/lib/x86_64-linux-gnu/libdl.so.2'
'/lib64/ld-linux-x86-64.so.2' -> '/home/jerry/testroot/lib64/ld-linux-x86-64.so.2'
'/lib/x86_64-linux-gnu/libpthread.so.0' -> '/home/jerry/testroot/lib/x86_64-linux-gnu/libpthread.so.0'


We’re ready to use the chroot command.


$ sudo chroot $chr /bin/bash
[sudo] password for jerry: 
bash-5.0# pwd
/
bash-5.0# ls
bin  lib  lib64
bash-5.0# ls /home/jerry
ls: cannot access '/home/jerry': No such file or directory
bash-5.0# 

Application: How to Use ‘fsck’ to Repair File System Errors in Linux

Prepare the chroot folder

  • Copy system binaries
  • 
    FSCK_ROOT=$HOME/fsck_root
    mkdir -p $FSCK_ROOT
    mkdir -p $FSCK_ROOT/{bin,usr/sbin,usr/bin,lib,lib64}
    cd $FSCK_ROOT
    
    cp -v /bin/bash $FSCK_ROOT/bin
    list="$(ldd /bin/bash | egrep -o '/lib.*\.[0-9]')"
    for i in $list; do cp -v --parents "$i" "${FSCK_ROOT}"; done
    
    cp -v /usr/sbin/fsck $FSCK_ROOT/usr/sbin
    list="$(ldd /usr/sbin/fsck | egrep -o '/lib.*\.[0-9]')"
    for i in $list; do cp -v --parents "$i" "${FSCK_ROOT}"; done
    ln -s usr/sbin/fsck usr/sbin/fsck.ext2
    ln -s usr/sbin/fsck usr/sbin/fsck.ext3
    ln -s usr/sbin/fsck usr/sbin/fsck.ext4
    
    cp -v /usr/sbin/fsck.fat $FSCK_ROOT/usr/sbin
    list="$(ldd /usr/sbin/fsck.fat | egrep -o '/lib.*\.[0-9]')"
    for i in $list; do cp -v --parents "$i" "${FSCK_ROOT}"; done
    ln -s usr/sbin/fsck.fat usr/sbin/fsck.msdos
    ln -s usr/sbin/fsck.fat usr/sbin/fsck.vfat
    
    cp -v /usr/sbin/fdisk $FSCK_ROOT/usr/sbin
    list="$(ldd /usr/sbin/fdisk | egrep -o '/lib.*\.[0-9]')"
    for i in $list; do cp -v --parents "$i" "${FSCK_ROOT}"; done
    
    cp -v /usr/bin/mount $FSCK_ROOT/usr/bin
    list="$(ldd /usr/bin/mount | egrep -o '/lib.*\.[0-9]')"
    for i in $list; do cp -v --parents "$i" "${FSCK_ROOT}"; done
    
    cp -v /usr/bin/ls $FSCK_ROOT/usr/bin
    list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')"
    for i in $list; do cp -v --parents "$i" "${FSCK_ROOT}"; done
    
    cp -v /usr/bin/df $FSCK_ROOT/usr/bin
    list="$(ldd /bin/df | egrep -o '/lib.*\.[0-9]')"
    for i in $list; do cp -v --parents "$i" "${FSCK_ROOT}"; done
    
    
    		
  • Bind run-time systems
  • 
    mkdir {proc,sys,dev,dev/pts,run}
    sudo mount -t proc proc proc
    sudo mount -t sysfs sys sys
    sudo mount -o rbind /dev dev/
    sudo mount -o rbind /dev/pts dev/pts/
    sudo mount -o rbind /run run/
    
    cp -v /dev/sda* $FSCK_ROOT/dev/
    
    		
  • Enter the chroot environment
  • 
    sudo chroot ${FSCK_ROOT}  /bin/bash
    	

fsck Available options

  • -A
  • Used for checking all filesystems. The list is taken from /etc/fstab.
  • -C
  • Show progress bar.
  • -l
  • Locks the device to guarantee no other program will try to use the partition during the check.
  • -M
  • Do not check mounted filesystems.
  • -N
  • Only show what would be done – no actual changes are made.
  • -P
  • If you want to check filesystems in parallel, including root.
  • -R
  • Do not check root filesystem. This is useful only with ‘-A‘.
  • -r
  • Provide statistics for each device that is being checked.
  • -T
  • Does not show the title.
  • -t
  • Exclusively specify the filesystem types to be checked. Types can be comma separated list.
  • -V
  • Provide description what is being done.

Understanding fsck exit codes


0      No errors
1      Filesystem errors corrected
2      System should be rebooted
4      Filesystem errors left uncorrected
8      Operational error
16     Usage or syntax error
32     Checking canceled by user request
128    Shared-library error 

Fix the filesystems

In order to run fsck, you will need to ensure that the partition you are going to check is not mounted.
  • View Mounted Disks and Verify Disk Location
  • 
    df -h    
        
  • 
    sudo fdisk -l   
        

How to execute fsck on the Root Filesystem using During Reboot

If you are performing a fsck on a non-root file system, you can just unmount that partition and perform fsck.
If you run a fsck to check your root filesystem, you’ll get the following error message, as /dev/sda1 is mounted, and your cannot perform fsck on a mounted filesystem.

# fsck /dev/sda1
fsck from util-linux-ng 2.17.2
e2fsck 1.41.12 (17-May-2010)
/dev/sda1 is mounted.
e2fsck: Cannot continue, aborting.
  1. Get the last time fsck performed a check on the root filesystem
  2. 
    $ sudo tune2fs -l /dev/sda3 | grep -i check
    [sudo] password for ubuntu: 
    Last checked:             Tue Mar 30 11:57:30 2021
    Check interval:           0 (<none>)    
        
  3. Create /forcefsck File to Force Check Root Filesystem
  4. This force fsck to perform the filesystem when the system is starting up before the root filesystem is mounted by the kernel.
    
    $ sudo touch /forcefsck    
        
  5. Reboot then fsck will be performing the check on the / filesystem during the reboot.
  6. After the check, fsck will automatically delete the /forcefsck file created.
    
    $ sudo tune2fs -l /dev/sda3 | grep -i check
    [sudo] password for ubuntu: 
    Last checked:             Sun Apr 25 05:29:15 2021
    Check interval:           0 (<none>)    
        

fakeroot

fakeroot - run a command in an environment faking root privileges for file manipulation.

~$ whoami
~$ fakeroot /bin/bash
# whoami
root
~# pwd
/home/jerry
~# mknod hda3 b 3 1
~# ls -l hda3
brw-r--r-- 1 root root 3, 1  九  28 14:51 hda3
~# exit
~$ ls -l hda3
-rw-r--r-- 1 jerry jerry 0  九  28 14:51 hda3

fakeroot runs a command in an environment wherein it appears to have root privileges for file manipulation. This is useful for allowing users to create archives (tar, ar, .deb etc.) with files in them with root permissions/ownership. Without fakeroot one would need to have root privileges.

留言

熱門文章