Open Source

Using Apache and chroot to trap hackers

Is there such a thing as a totally secure server? Probably not, but there are many steps you can take to make your Apache server as close to intruder-proof as possible. We'll show you one easy trick using the UNIX chroot command.


Is there such a thing as a totally secure server? Perhaps not, but there are many steps you can take to make your Apache server as close to intruder-proof as it’s possible to be today. Many of these efforts require a considerable investment of time and energy. But there’s one that's ridiculously easy to do and extremely effective.

There’s a funny moment in a recent Woody Allen film when Allen and some cohorts, in an effort to dig a tunnel into a bank, wind up digging a tunnel into a flower shop instead. In addition to being ineffective, it was humiliating. You can inflict this same humiliation on a would-be intruder. Here’s how to do it.

Restrict Apache's access to the file system
Since Apache itself can be compromised by a clever and determined hacker, the trick is to restrict Apache to a limited portion of the file system. An intruder cracking Apache gains absolutely nothing—except digging a tunnel that leads into a jail cell. The attack is confined to this restricted area, and the attacker has no access to any other files!

The chroot() UNIX system call changes the root directory of whatever process calls it. It can be used only by root and is executed like this:
# chroot /tmp/root/directory    /bin/bash

where /tmp/root/directory is the root directory you want to use. What’s happening here is the chroot command is changing the root directory of the calling process to /tmp/ and executing /bin/bash there. The beauty of this sleight-of-hand substitution is that /bin/bash doesn’tknow it’s been confined! It sees its root directory but doesn’t see the leading subdirectory—so it can’t escape!

If a "chrooted" program has been handed off in this way and is confined to a subdirectory, then any damage it may do upon execution is confined to that directory. And, of course, you can set up your “trap” directory in such a way that an intruder program, when trapped there, can’t do any damage. For instance, you can make certain that no file-handling programs or compilers or any other file-manipulative software can be executed from the directory.

Locking up Apache
To begin with, you certainly don’t want to lock Apache up in /tmp/—we just used it above as an example. It wouldn’t make sense to put Apache there, because all users have write access to /tmp/. Instead, make a trap directory under /root, and put the appropriate dynamic library files in that directory:
# mkdir /trap

Now create the necessary subdirectories under /trap:
usr
usr/local
usr/lib
usr/bin
lib
dev
tmp
etc

Set permissions for the /trap/tmp subdirectory to 777 (with the chmod command; everyone has read/write access) and +t (restricting any created files to privileged users). Copy user and group config files (these include passwd, shadow, and group) into the /etc subdirectory.

You now want to generate dummy passwd, shadow, and group files with # cat. Use the name "prisoner" if you like. You’re setting up your eventual prisoner to run as a nonuser without a valid shell. (There will be no shell in the directory and no login program.)

Copy these configuration files from /lib to /trap/lib. Be sure to use the –p option on the cp command to preserve permissions. The files you want are:
/lib/libnss_files.so.1
/lib/libnss_files.so.2
/lib/libnss_dns.so.1
/lib/libnss_dns.so.2

You’ll also need these files from the /etc directory copied to /trap/etc:
/etc/nsswitch.conf
/etc/hosts
/etc/resolv.conf

Create an nsswitch.conf file, directing passwd, shadow, group, and hosts to find files in /etc. Create your /etc/hosts with the echo command, saving localhost.localdomain to /trap/etc/hosts. Finally, copy the resolv.conf file to /trap/etc.

You’re almost there! Finally, you need to copy over the dynamic library files, from /lib to /trap/lib. Copy them with –p to preserve permissions. The files you want are:
libgdbm.so.2 (this one is actually in /usr/lib, not /lib)
/i686/libm.so.6
/i686/libpthread.so.0
/i686/libc.so.6
libcrypt.so.1
libnsl.so.1
libdl.so.2
ld-linux.so.2

Walking Apache into the trap
Apache is ready to run in the trap. However, chrooting at this point will fail, because Apache’s script can’t run from the /trap directory; it needs a /bin file it can’t find. To fix this, have the script chroot the httpd file below, and you're ready to go:
HTTPD=’chroot /trap /usr/local/apache2/bin/httpd’

Starting Apache from the trap
Remember that all you need from Apache in the trap is to get the server started. Anything else defeats the purpose of creating a minimal environment, wherein a trapped intruder can do no harm.

Run the config file and start Apache:
# /trap/usr/local/apache2/bin/apachect1 start

Your trap is set. There are other aspects of the chroot trap that come into play if you make use of it as a serious counter-hacker measure. You must manage your logs and get Apache starting at boot. You must consider whether PHP or Perl is required, and get it working in the /trap environment, as well. In addition, there are more stringent security measures that can be taken, including creating your trap with a separate partition.

About Scott Robinson

Scott Robinson is a 20-year IT veteran with extensive experience in business intelligence and systems integration. An enterprise architect with a background in social psychology, he frequently consults and lectures on analytics, business intelligence...

Editor's Picks

Free Newsletters, In your Inbox