Create a minimal SSH-accessible chroot jail with Dropbear and BusyBox on CentOS

Sometimes you just need some kind of setup which is not so standard. This was the case which lead to this post. For some testing, I needed a minimal environment containing only a BusyBox shell and that was accessible via Dropbear SSH-server. Probably this setup is quite useless for daily use but it can be used as a base for testing with a minimum set of libraries available. Using this setup gives you the flexibility to experiment with a minimal environment without rebuilding small Linux images.

First of all, it might be a good idea to elaborate a little more on the setup. My goal was to create a Linux system that was accessible via SSH (it had to be Dropbear, an alternative to OpenSSH-server) and to have as less as possible libraries in it. Since you do need a shell, BusyBox seemed to be a good choice. BusyBox is a single executable that contains alternatives for common Linux utilities. One of the options would be to build a small system from scratch. I chose to use an existing installation and start my test-environment in a chroot jail. A chroot jail is an isolated environment running on top of another one. The name itself actually tells you what it is, it runs processes under a changed root (a subdirectory of the original root).

How I see this graphically, if it could help:

chroot

As you can see, Dropbear will be running under the chroot jail. The root filesystem for dropbear is actually /chroot/jail. Access to the SSH-server in the jail can be done using the same IP and the port that Dropbear is listening on. While this environment is in place, we can easily add or remove libraries to check for dependencies or compatibility. These libraries do not need to match with the ones in the real /lib.

To start the setup, we need a CentOS or RHEL (or other distro if you prefer) installation. For this post, I used a minimal CentOS 7.1.

Chroot preparation

First thing to do is to create the root filesystem structure which we need for a minimal system under the directory which we chose as our root jail. In this example: /chroot/busybox.

Besides the directory structure, we also need some devices and link to the original /dev/pts and /proc directory:

Since we want to login to the chroot, we’ll need some other files too:

Dropbear compilation for chroot

Now that the base of our chroot is ready, we can compile the latest Dropbear version for the chroot.

First of all, let’s install all components which we’ll need to compile Dropbear, we need a compiler, make and some dependencies.

Let’s download the source of Dropbear and extract it. You can find the source for the latest version at: https://matt.ucc.asn.au/dropbear/releases/.

At this point, we need to run ./configure to generate an options.h and makefile to do the compilation. We set the prefix to the location of the chroot jail.

As the output of ./configure suggests, we’ll edit options.h to disable X-forwarding. This would require us to have Xauth and some dependencies. Since we want to have a minimal set of dependent libraries, I wanted to avoid that.

After editing the file, feel free to look at all definitions in the file to customize a little more if you feel like. After the changes, we can compile Dropbear and install it in the chroot jail:

All that’s left to do for the Dropbear part, is to generate some keys which will be used by Dropbear. Dropbear has it’s own key format so it’s better to use those utilities:

One last thing that is required in order to be able to run Dropbear in the chroot, is to check which libraries Dropbear needs:

We can simply copy those libraries and some extra libraries required for login (and shadow passwords) to the lib (or lib64) of our chroot jail:

BusyBox installation

Next part of the setup is to “install” BusyBox. Install is between quotes since installing BusyBox isn’t more than downloading a binary from the internet. You can find the latest version of BusyBox here: https://busybox.net/downloads/binaries/.

Let’s get BusyBox, rename it and give it enough permissions:

That’s basically all it takes to “install” BusyBox.

User configuration

Now that we have Dropbear and BusyBox installed in our jail, it’s time to configure a user that will have access trough Dropbear. The easiest method is to create a normal user with useradd and then generate the necessary files based on the lines that were created by useradd. Another option is to create and write the files manually.

As you can see in the last line of the above output. The /etc/passwd file in the chroot jail contains one user, test, with a home directory /home/test and shell /bin/bash. The home directory doesn’t exist in the jail and neither does /bin/bash. So let’s change that:

We need to replace the shell of our user test to BusyBox. In order to invoke BusyBox as a shell and not as a single command, it’s possible to create a symbolic from /bin/sh to /bin/busybox. For the user, we replace /bin/bash to /bin/sh to use that symlink:

As you can see in the above output, it’s important to create the link from the correct path in order to have the relative path as the link for sh in /bin of the chroot jail.

Start the chroot jail

The installation of our testjail is a good as complete. The only thing that lasts is to start our jail and test if we can connect to port 44 with SSH.

In the above output, we can see that Dropbear got started, I explicitely asked to output messages to stdout with option -E, and that it’s listening on port 44. The next step is a test to port 44 for user test. As a result, you can see that the connection succeeds and we end up in a BusyBox shell.

After a reboot

In case you want to start the chroot jail after a reboot, you will need to remount the bind mounts:

And if you would like it to start automatically on boot, just add the above three commands to /etc/rc.d/rc.local :)

Leave a Reply

Your email address will not be published. Required fields are marked *