Chroot Jail

terminal logo

This article was written with an intention to help Linux users in understanding the Chroot Jail feature and setup one themselves, for experimenting.

Imprisoning users using “Chroot Jail”

To put it simple, it’s nothing but limiting what a process/user can see in your system. Now your guess is right. It’s a way to secure your system from various security attacks.

Now, to put it a little more technical, Chroot Jail is a feature to create a limited sandbox thus allowing a process to view only a single sub-tree of the filesystem.

Couldn’t get it? Not a problem. Continue reading and I’ll make it clear.


As the name implies, we’re going to create a jail within which the user/process are imprisoned. Now, let us decide where we want to have the jail. ie. In which location. Okay, I have decided to have it under root (/) directory.

Let’s name it; I am naming it as Chroot. Our jail name is Chroot and it is located under “/”. Clear?

# mkdir /Chroot

Next, even though it’s a jail the prisoners are supposed to enjoy few basic privileges at least.

Here; Privileges = Commands

Now, how this works. How we are imprisoning?

It’s quite simple. We’re going to fool the user saying that /Chroot = /.

In simple words, jailed user will think /Chroot is actually /.  By this way, the jailed user won’t have access above /Chroot or out of it. To be precise, jailed user won’t even know that there is a world outside the jail.

Now, how to assign the privileges to them?

For example, say I want the jailed user to execute only very few basic commands like “echo, ls, pwd, touch”. Now, all these commands are available outside the jail. So, to make it available to jail users we need to have a copy of it inside the jail, as well.

Now while copying, remember just copying the command alone won’t do. Libraries related to that particular command, also need to be copied:

# which echo          /*tells you the complete path of echo*/
/bin/echo          /*output*/
# ldd  /bin/echo          /*lists the libraries of echo command*/ =>  (0x00007ffff8ffd000) => /lib64/ (0x0000003dbc400000)
/lib64/ (0x0000003dbbc00000)            /*output*/

Along with libraries of echo, there is something else which is also displayed. The last line of output implies that my system is 64bit architecture.

In case of 32bit system, the output of the command:

# ldd /bin/echo

Would be something like: =>  (0x00007ffff8ffd000) => /lib/ (0x0000003dbc400000)
/lib/                                 /*output*/


# cp /bin/echo /Chroot/bin/echo             /*copies the echo command script*/
# cp /lib64/ /Chroot/lib64/       /*copying the libraries which we found using ldd command*/
# cp /lib64/ /Chroot//lib64/      /*copying the architecture library as well */

Echo command and relevant libraries of that along with the architecture library are copied inside /Chroot under same directory with same file names:

# ls –p /Chroot


Now, for ls and other commands, the process would be lengthy since these commands have more number of libraries. So, you shall make use of the script I have written to copy commands as well as libraries in one go:


for i in $( ldd "$@" |cut -d " " -f3 |sort -u |grep -v ':$')
cp --parents "$i" "$JAIL"
cp --parents "$@" "$JAIL"

#64-bit arch
if [ -f /lib64/ ]; then
cp --parents /lib64/ $JAIL

#32-bit arch
if [ -f /lib/ ]; then
cp --parents /lib/ $JAIL
echo "Chroot jail is ready. To access it execute: chroot $JAIL"

Give execute permission to the above script before proceeding. Now, to copy a command and all relevant libraries, including the architecture library, simply run:

# ./ command_name

For example:

# ./ /bin/ls          /*This will copy ls command script, as well as other relevant libraries to                                                                              “/Chroot” directory */
# ./{touch,cat}          /*This will copy touch & cat commands along with its libraries*/

Now, your jail is ready with just 2 privileges which are using the echo and ls commands.

How to test it?

# chroot jail_name


# chroot /chroot

bash-4.1#echo “success..!!”

bash: ifconfig: command not found

bash-4.1# exit

This will take you out of the jail.

We were able to run echo because we have copied echo command and its relevant libraries inside jail.

The Final touch

Consider the real time scenario, that I want a particular user to be imprisoned inside jail when he logs in through SSH.

Basically we’ll SSH when we login from another machine. So here, I want to prison the user only when he logs in from another machine.

How to achieve that?

# useradd  -G jail u1          /*creating a user called “u1” whose secondary group is “jail” */
# passwd u1          /*assigning passwd to the u1 */

Now, user tester is created with default home directory as /home/u1 and secondary group as “jail”.

# su – u1
$ pwd
/home/u1          /*He is under a normal environment where he can execute all commands */
$ exit

Now, you want to imprison “u1” only when he logs in through SSH. To achieve that, edit /etc/ssh/sshd_config:

# vi /etc/ssh/sshd_config

And append the following lines:

# Re-directing users from jail group to the jail at /Chroot
Match Group jail
ChrootDirectory /Chroot

Save the file and exit.

# service sshd restart

Now, test it:

# ssh u1@localhost
u1@localhost’s password:

Last login: Mon Jul 29 13:11:30 2013 from localhost.localdomain


So, whenever someone from other machine tries to login to your machine through SSH (in this case, only when he login as “u1” user), he will be imprisoned under /Chroot jail, so that he can’t access anything above or outside that. Also, he can use only those commands that are offered.

Thanks for reading. Cheers!