docker-core-tech-chroot

Chroot

Introduction

Every process/command in Linux/Unix like systems has a current working directory called root directory. chroot changes the root directory for current running process as well as its children.

it creates a virtualized environment in a Unix(linux) operating system, separating it from the main operating system’s directory structure. This process essentially generates a confined space with its own root directory, to run software programs. This virtual environment runs separately from the main operating system's root directory.

Any software program run in this environment can only access files within its own directory tree. It cannot access files outside of that directory tree. This confined virtual environment is often called a "chroot jail".

Use cases

  • Privilege separation for unprivileged process such as Web-server or DNS server.
  • Setting up a test environment.
  • Run programs or ABI in-compatibility programs without crashing application or system. different apps in the same system can use different libraries, it’s what container image needs.
  • System recovery.
  • Reinstall the bootloader such as Grub or Lilo.
  • Password recovery – Reset a forgotten password and more.

Example to use chroot

Two ways to change root directory

  • chroot() system call(binary with CAP_SYS_CHROOT capability)
  • chroot linux command (super user)

let's use chroot as the example to show how we should do on linux

1
2
3
# format:
# command is the command(in new root) that will run after chroot, if not provided /bin/sh by default
$ chroot /path/to/new/root command (must run with super user)
Note: in order to run this command in new root dir, the new root dir must have such command and its dependency before chroot !!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ mkdir /tmp/new_root
$ mkdir -p /tmp/new_root/{bin,lib64,lib/x86_64-linux-gnu}
$ cp /bin/bash /tmp/new_root/bin

# check bash depends
$ ldd /bin/bash
linux-vdso.so.1 => (0x00007ffc6cd67000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f9bf4c85000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9bf4a81000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9bf46b7000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9bf4eae000)

# Copy required libs to new root
$ cp /lib/x86_64-linux-gnu/libtinfo.so.5 /lib/x86_64-linux-gnu/libdl.so.2 /tmp/new_root/lib/x86_64-linux-gnu
$ cp /lib/x86_64-linux-gnu/libc.so.6 /tmp/new_root/lib/x86_64-linux-gnu
$ cp /lib64/ld-linux-x86-64.so.2 /tmp/new_root/lib64
$
$ chroot /tmp/new_root /bin/bash

bash-4.3#

bash-4.3# ls
\command not found

bash-4.4# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

here we just copy bash, if you run ls, you need to copy ls and it dependency as well