Introduction
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.
Now, let’s setup the device nodes.# mkdir -p /mnt/chroot/pratik/dev
# mount --bind /dev /mnt/chroot/pratik/dev
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.