Linux Virtualization – Chroot Jail

What is a chroot Jail?

A chroot on Unix operating systems is an operation that changes the apparent root directory for the current running process and its children. The programs that run in this modified environment cannot access the files outside the designated directory tree. This essentially limits their access to a directory tree and thus they get the name “chroot jail”.

The idea is that you create a directory tree where you copy or link in all the system files needed for a process to run. You then use the chroot system call to change the root directory to be at the base of this new tree and start the process running in that chrooted environment. Since it can’t actually reference paths outside the modified root, it can’t maliciously read or write to those locations.

Why is it required and how is it different from the virtual machines?
This is a Operating-system-level virtualization and is often used instead of virtual machines to create multiple isolated instances of the host OS. This is a kernel level virtualization and has practically no overhead as compared to Virtual Machines, which are a application layer virtualization, as a result it provides a very good method for creating multiple isolated instances on the same hardware. A virtual machine (VM) is a software implementation of a machine and they often exploit what is know as the Hardware Virtualization to render a virtual images of a working operating system.

How do i use it?
The basic command to create a chroot jail is as follows:

   chroot /path/to/new/root command
                OR
   chroot /path/to/new/root /path/to/server
                OR
   chroot [options] /path/to/new/root /path/to/server

Note: Only a root/privileged user can use the chroot system call. A non-privileged user with the access to the command can bypass the chroot jail.

Steps to create a mini-jail for the ‘bash’ and the ‘ls’ command

1. Create a directory which will act as the root of the command.

  $ mkdir jailed
  $ cd jailed

2. Create all the essential directories for the command to run:  Depending on your operating system, the required directories may change. Logically, we create all these directories to keep a copy of required libraries. To see what all directories are required, see Step 4.

  $ mkdir -p bin lib64/x86_64-linux-gnu lib/x86_64-linux-gnu

3.Run the ‘which’ command : Run the ‘which’ command to find the location of ls and bash command. After running which command, copy those binaries in the ‘bin’ directory of our jail. Make sure you don’t have any of these commands aliased. From now on, we would be referring to our directory as ‘Jailed’ directory for convenience.

  $ unalias ls     	 # Required only if you have aliased ls command
  $ unalias bash   	 # Required only if you have aliased bash command
  $ cp $(which ls) ./bin/
  $ cp $(which bash) ./bin/

4. Copy appropriate libraries/objects : For the executables in our Jailed directory to work we need to copy the appropriate libraries/objects in the JAILED directory. By default, the executable looks at the locations starting with ‘/’. To find the dependencies we use the command ‘ldd’

$ ldd $(which bash)
	linux-vdso.so.1 =>  (0x00007ffc75dd4000)
	libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f6577768000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6577564000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f657719a000)
	/lib64/ld-linux-x86-64.so.2 (0x000055979f3fd000)

Run the following commands to create appropriate directories.

$ cp /lib/x86_64-linux-gnu/libtinfo.so.5 lib/x86_64-linux-gnu/
$ cp /lib/x86_64-linux-gnu/libdl.so.2 lib/x86_64-linux-gnu/
$ cp /lib/x86_64-linux-gnu/libc.so.6 lib/x86_64-linux-gnu/
$ cp /lib64/ld-linux-x86-64.so.2 lib64/

Similarly for ls,

$ ldd $(which ls)
	linux-vdso.so.1 =>  (0x00007fff4f05d000)
	libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f9a2fd07000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9a2f93e000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f9a2f6cd000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9a2f4c9000)
	/lib64/ld-liux-x86-64.so.2 (0x000055e836c69000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9a2f2ac000)
$ cp /lib/x86_64-linux-gnu/libselinux.so.1 lib/x86_64-linux-gnu/
$ cp /lib/x86_64-linux-gnu/libc.so.6 lib/x86_64-linux-gnu/
$ cp /lib/x86_64-linux-gnu/libpcre.so.3 lib/x86_64-linux-gnu/
$ cp /lib/x86_64-linux-gnu/libdl.so.2 lib/x86_64-linux-gnu/
$ cp /lib64/ld-linux-x86-64.so.2  lib64/
$ cp /lib/x86_64-linux-gnu/libpthread.so.0 lib/x86_64-linux-gnu/

The final directory structure must be similar to this,Chroot Jail

5. Sudo chroot: Run this command  to change the root to the JAILED directory, along with the path to the shell. By default it will try to load ‘/bin/sh’ shell.

  $  cd ..
  $  sudo chroot jailed /bin/bash

You might face this error while running the chroot command,

chroot: failed to run command `/bin/bash': No such file or directory

This may be due to 2 reasons, either the file does not exist(which is obvious), or when the loading library fails or is not available. Double-Check if the libaries are in correct location.

6. A new shell must pop up: Its our jailed bash. We currently have only 2 commands installed, bash and ls. Fortunately cd and pwd are builtin commands in bash shell, and so you can use them as well.

Roam around the directory, try accessing ‘cd /../’ or something similar. Try to break the jail, probably you won’t be able to. 🙂

To exit from the jail,

	  $ exit

The most important and interesting part is that, when you run,

	$ ps aux

and find the process, you’ll find that there is only one process,

root     24958  …  03:21   0:00 /usr/bin/sudo -E chroot jailed/ /bin/bash

Interestingly, processes in the jailed shell run as a simple child process of this shell. All the processes inside the JAILED environment, are just simple user level process in the host OS and are isolated by the namespaces provided by the kernel, thus there is minimal overhead and as an added benefit we get isolation.

A copy of jailed-bash-directory explained here can be downloaded from here.

Similarly, you can add more commands to you virtual jailed environment. To add more complex programs, you might need to create more directories, like, ‘/proc’ and ‘/dev’. These increase the complexity of the process. Hopefully we do not require it for our purpose.

This is all you need to know about chroot and the jailing of directories. Our ultimate aim is to understand what are containers and how are services like AWS (Amazon Web Services), Google Cloud and Docker able to provide so many virtual instances of operating systems on demand. Also, how does sys-admin run multiple web-servers for multiple domains on a single physical machine. This was just one step towards understanding it 🙂

References:

About the Author:
Pinkesh Badjatiya hails from IIIT Hyderabad. He is a geek at heart with ample projects worth looking for. His project work can be seen here. 

If you also wish to showcase your blog here, please see GBlog for guest blog writing on GeeksforGeeks.

 

GATE CS Corner    Company Wise Coding Practice

Recommended Posts:







Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.