Using Chroot in OpenSSH

Everything Linux, A.I, IT News, DataOps, Open Source and more delivered right to you.
"The best Linux newsletter on the web"


OpenSSH provides many features to harden a SSH server. One of them is the ability to restrict a SSH user session to within a directory using chroot. In this article, I am going to describe how to use this feature in OpenSSH.

So to get started, we first need to understand how this works.

What’s a Chroot?

A chroot is the operation where the root directory of a process is changed to a specified directory. Therefore, a process running inside a chroot (can also be called a jail) will not be able to escape beyond its root directory. In other words, if a process is inside a jail of /mnt/chroot/, then it will not be able to go to /mnt or any other directories above /mnt/chroot/. Needless to say, any jail we create will need the appropriate device nodes, shells, and other programs that a jailed user might need. We’ll have to do this since we’re going to be jailing our SSH users.

Populating Chroot Directories

We first need to create the home directories for our restricted users. Here, I am going to restrict the user pratik within the /mnt/chroot/pratik/ directory.

Let’s create that first.
# mkdir -p /mnt/chroot/pratik/

I have defined pratik‘s home directory to be /home/pratik (in the /etc/passwd file). When the user logs in, they are expected to have that directory. This means, we need to create that directory.

# mkdir -p /mnt/chroot/pratik/home/pratik

Our chroot requires at least a shell and few utilities. Now, we could copy the host’s binaries and all of the dynamically linked libraries it needs, but that’s too much effort. Instead, we can just use busybox which comes as a statically-linked binary.

Assuming you have it installed, let’s copy the busybox binary to our chroot directory.
Note: Make sure the user’s shell is set to /usr/bin/sh

# mkdir -p /mnt/chroot/pratik/{sbin,usr/bin}
# cp /usr/bin/busybox /mnt/chroot/pratik/sbin/sh
# cp /usr/bin/busybox /mnt/chroot/pratik/sbin/busybox

Now we can chroot into the directory and have busybox install other utilities.

Populating a chroot using Busybox

Now, let’s setup the device nodes.
# mkdir -p /mnt/chroot/pratik/dev
# mount --bind /dev /mnt/chroot/pratik/dev

Creating Device Nodes for a Chroot

Just to be sure, set appropriate permissions on the chroot directory.
# chown root:root /mnt/chroot/
# chmod 755 /mnt/chroot/pratik

Finally, let’s add some system-wide configuration files for our jailed users.
# mkdir /mnt/chroot/pratik/etc
# echo "pratik:x:1000:1000::/home/pratik:/sbin/sh" > /mnt/chroot/pratik/etc/passwd
# cp /etc/{resolv.conf,hosts,localtime,locale.conf} /mnt/chroot/pratik/etc/

Assigning Chroot Directories

Now we have to configure /etc/ssh/sshd_config to use our chroots. This is done by modifying the ChrootDirectory keyword. However, it will take a single argument, but we might have different users who have their own jail directories.

OpenSSH has a feature called tokens which will come very handy here. Tokens are special symbols – prepended by a % – that represent some variable. The %u token represents the username.

First let’s create a group jailedusers and assign our users there. Then we’ll edit sshd_config.
# groupadd jailedusers && usermod -aG jailedusers pratik

Make the following modifications at the end of /etc/ssh/sshd_config:


And that’s it. Now we can use restrict users to within certain directories.

Everything Linux, A.I, IT News, DataOps, Open Source and more delivered right to you.
"The best Linux newsletter on the web"
Pratik Devkota
Pratik Devkota
Software engineering student interested in UNIX (GNU/Linux, *BSD, etc.), security as well as free and open-source software.


Please enter your comment!
Please enter your name here

Latest articles

Join us on Facebook