FreeBSD Jailsby Mike DeGraw-Bertsch
What is a Jail?
Those familiar with Java recognize the security concept of a sandbox. For those that aren't, it's the concept that everyone gets a unique, well-equipped sandbox to play in, and a person in
one sandbox isn't allowed into anyone else's sandbox, not even to share
anything with anyone else. On FreeBSD, jails implement this concept —
they keep processes in their own part of the system, denying access to anything
else. A jail requires its own dedicated IP address, though, which can make life
difficult for those with limited address space. If this presents you with a
hardship, consider at least using
won't afford you as much security, but it does help.
How does this help security? Take, for example, a box with an external FTP server and the company extranet. An exploit for the server is discovered, and a cracker manages to gain root access through the FTP daemon. If the FTP server is not run in a sandbox or jail, the cracker will have access to everything on the machine, including sensitive information destined for the company's partners through the extranet. If, however, the FTP server is run in a jail, the cracker will only have access to the FTP files.
There are, of course, still potential risks. If you run at secure level
0, the cracker can simply access the raw disk device and read data
from there. The solution is obvious — on a box sensitive enough to require
jails, use appropriate secure levels as well. This will eliminate a cracker's
ability to read from or write to raw disk devices.
Configuring a Jail
Configuring a jail is pleasantly simple.
First, ensure that your system environment is jail-friendly. Because each
jail requires its own IP address, the services on your box must be configured
to listen to specific addresses, not just every available address. For
example, if the box's addresses are
188.8.131.52 (main) and
184.108.40.206 (jail), to get
inetd to listen only on
inetd_flags="-wW -a 220.127.116.11" to /etc/rc.conf. If you fail to do this, conflicts may occur over the aliased IP address.
For some daemons, this is not an easy process —
rpcbind are two examples. If you're using these services on
your box, you might consider simply running them inside of a jail of their own.
After configuring all of the non-jailed daemons to listen to a specific address,
reboot the machine. This will put everything into a known state, eliminating
any potential for confusion.
With the proper host environment in place, create the directory that will house the jail. In this example, it's /usr/jail/ftp. Now go to /usr/src and run:
# make world DESTDIR=/usr/jail/ftp # cd etc # make distribution DESTDIR=/usr/jail/ftp # cd /usr/jail/ftp/dev # sh # MAKEDEV jail # cd .. # ln -sf /dev/null kernel
These commands build the jail and populate it with all of the tools that your
processes will need to run. Actually, they put in a lot more than just what your
processes will need. For example,
sendmail will all be installed, but you probably don't need them
in your jail. Keep in mind, though, that it's a lot easier to take stuff out
until something breaks than it is to put stuff back in until everything
To configure the jail environment, you might want to copy
/stand/sysinstall into /usr/jail/ftp/stand, to
provide you with an easy configuration interface. I'll show you how to use it
in just a second.
With the system rebooted, you're now ready to configure the jail environment. Start the jail for the first time by running:
# jail /usr/jail/ftp jail.hostname.com 18.104.22.168 /bin/sh
This will put you at a shell prompt in your jail environment. From here, you
/stand/sysinstall (literally, since
refers to the jail's root directory, not the system's.)
There are several configuration tasks to perform, such as setting the root
password (don't make it the same as the main system root password!), adding
user accounts, and configuring /etc/resolv.conf. Read
jail for more configuration tasks that you'll need to perform. Keep in
mind that you want to be able to log in to the environment, so consider running
an SSH daemon inside the jail.
Once you're done configuring the jail environment, exit the shell and the jail will be shut down.
You're almost ready to start the jail "for real." First, add the appropriate IP address alias. For our example, this is done via:
ifconfig fxp0 inet alias 22.214.171.124 255.255.255.255
You can configure this in /etc/rc.conf to be done automatically at boot.
Now, let's start the jail! This is done with two commands:
# mount -t procfs proc /usr/jail/ftp/proc # jail /usr/jail/ftp jail.hostname.com 126.96.36.199 /bin/sh /etc/rc
You'll see some warning messages scroll by, but don't worry about them. You
can now see all the daemons running inside the jail, as indicated by the
J flag shown in the
ps output. If you enabled SSH
within the jail, you can
ssh to the jail environment.
Since normal shutdown commands like
halt don't work in the
jail, you must take a special measure to shut the jail down. First, log in to
the environment and become
root. You can then kill all the
processes inside the jail via
kill -TERM -1 or
kill t -KILL
-1. You can also do this from outside the jail by manually killing any
PID within the jail.
You should now be able comfortably to create and use jails to secure everything from FTP daemons to DNS servers. Before we finish, there's just one more note.
jail.set_hostname_allowed on pre-5.0 machines)
sysctl variable determines whether or not the superuser
within the jail can set the hostname. This is enabled by default, and you might consider disabling it by placing
security.jail.set_hostname_allowed=0 in /usr/jail/ftp/etc/sysctl.conf. Remember that it's
jail.set_hostname_allowed=0 on machines running FreeBSD-4.x!
You've now seen both how jails work and how to set one up. Whether you're running multiple public services from the same box, providing login shells to untrusted users, or offering a public service on an otherwise private machine, using jails properly will help you sleep at night.
Mike DeGraw-Bertsch is a security and Unix system administration consultant in the Boston, Mass. area. When he's not at a job, writing, hacking with Perl, or playing with his wireless network, he can usually be found playing goal in ice hockey.
Return to the BSD DevCenter.