Most modern Linux distributions ship with various technologies to boost security. Amongst these technologies are such things as SELinux, AppArmor, ExecShield, iptables and disabling uneeded services by default. While these solutions have their benefits, the best and brightest hackers can typically find ways to work around them to compromise applications that are running on a server.
To minimize the chances that a given bug will lead to a full system compromise, applications can be installed in chroot jails. These jails provide a limited view of the system, and typically contain the minimum number of executables and libraries that are required to make the application work.
In this article I will discuss how to create a full root jail using the yum utility.
In a full root jail, an application package and all of its dependencies are installed. This is easy to do on CentOS, Fedora and Redhat Linux hosts, since rpm and yum allow you to install packages to an alternate root directory. This directory then acts as the root file system, and the bits that are loaded into this file system will be the only thing available to hackers if an application is compromised.
To build a full root jail for the Apache web server (httpd), we will first need to create an RPM package database inside the chroot directory (this article will use /chroot/webapp1 as the chroot home):
$ mkdir -p /chroot/webapp1/var/lib/rpm
$ rpm --root /chroot/webapp1 --initdb
These commands will create the RPM package database directories, and will initialize the RPM database. Once the database is initialized, we can download the release file for the distribution we are using:
$ yumdownloader --destdir=/var/tmp fedora-release
$ cd /var/tmp
$ rpm --root /chroot/webapp1 -ivh --nodeps fedora-release*rpm
The fedora-release (if you are using centos, you can use centos-release. If you are using RHEL, you can use redhat-release) contains the release files, which include the yum repositories and several files that are used by rpm and yum. If the release file installed correctly, we can run yum with the install and “–installroot” options to install the httpd package and all of its dependencies in the chroot directory:
$ yum --installroot=/chroot/webapp1 -y install httpd
Once the install completes, your chroot directory should have a layout similar to the base systems root file system:
$ cd /chroot/webapp1
$ ls -la
total 84
drwxr-xr-x 21 root root 4096 2009-08-08 09:44 .
drwxrwxrwt. 3 root root 4096 2009-08-08 09:40 ..
drwxr-xr-x 2 root root 4096 2009-08-08 09:45 bin
drwxr-xr-x 3 root root 4096 2009-08-08 09:45 boot
drwxr-xr-x 2 root root 4096 2009-08-08 09:44 dev
drwxr-xr-x 46 root root 4096 2009-08-08 09:45 etc
drwxr-xr-x 2 root root 4096 2009-03-04 08:13 home
drwxr-xr-x 7 root root 4096 2009-08-08 09:45 lib
drwxr-xr-x 5 root root 4096 2009-08-08 09:45 lib64
drwxr-xr-x 2 root root 4096 2009-03-04 08:13 media
drwxr-xr-x 2 root root 4096 2009-03-04 08:13 mnt
drwxr-xr-x 2 root root 4096 2009-03-04 08:13 opt
dr-xr-xr-x 2 root root 4096 2009-03-04 08:13 proc
drwxr-x--- 2 root root 4096 2009-03-04 08:13 root
drwxr-xr-x 2 root root 4096 2009-08-08 09:45 sbin
drwxr-xr-x 2 root root 4096 2009-03-04 08:13 selinux
drwxr-xr-x 2 root root 4096 2009-03-04 08:13 srv
drwxr-xr-x 2 root root 4096 2009-03-04 08:13 sys
drwxrwxrwt 2 root root 4096 2009-08-08 09:45 tmp
drwxr-xr-x 14 root root 4096 2009-08-08 09:45 usr
drwxr-xr-x 18 root root 4096 2009-08-08 09:45 var
The chroot environment will contain everything needed to run the application, and you will need to configure it prior to starting it up. To start the application in the chroot environment, you can run the chroot command and passing it the initialization script or executable to chroot:
$ chroot /chroot/webapp1 /usr/sbin/apachectl start
$ ps auxww | grep [h]ttpd
root 2365 0.2 0.0 171536 3732 ? Ss 09:51 0:00 /usr/sbin/httpd -k start
apache 2366 0.0 0.0 171536 2464 ? S 09:51 0:00 /usr/sbin/httpd -k start
apache 2367 0.0 0.0 171536 2464 ? S 09:51 0:00 /usr/sbin/httpd -k start
apache 2368 0.0 0.0 171536 2464 ? S 09:51 0:00 /usr/sbin/httpd -k start
apache 2369 0.0 0.0 171536 2464 ? S 09:51 0:00 /usr/sbin/httpd -k start
apache 2370 0.0 0.0 171536 2464 ? S 09:51 0:00 /usr/sbin/httpd -k start
apache 2371 0.0 0.0 171536 2464 ? S 09:51 0:00 /usr/sbin/httpd -k start
apache 2372 0.0 0.0 171536 2464 ? S 09:51 0:00 /usr/sbin/httpd -k start
apache 2373 0.0 0.0 171536 2464 ? S 09:51 0:00 /usr/sbin/httpd -k start
To verify the application is using the chroot we configured, we can run the pwdx utility passing it the pid of one of the httpd processes we started:
$ pwdx 2365
2365: /chroot/webapp1
If the application started up, you should be able to connect to the application to verify it’s working. Chroot environments built with yum will require periodic updating, and it’s especially important to minimize the number of packages that are installed into the chroot jail.
This article showed how to create a full root jail using yum. While full root jails aren’t the most secure way to create a chroot jail, they do provide a fairly good compromise between jail management and overall security.
The following references were used while writing this article: