FreeBSD: Building Jails

Jail in FreeBSD is utility which imprisons a process and all future descendants. This was the theory. But what is the reality of jails, why we should use them and how successfully set them up will be the core of this article.

Main reason why I decided to use jails on my FreeBSD machines was security point of view. There are no doubts that jails can dramaticaly improve security of FreeBSD machine. If you build up a jail and set up all services (e.g. HTTP, FTP, SMTP, DNS etc.) on it, you isolate any security implications in there. When all setup is done correctly, there is really ultra minimal chance to compromise your main machine.

FreeBSD jail has its own IP and from the outside it seems to be a separate system. There is almost impossible to find out from the world that services are running on a jail. If an attacker compromise a jail somehow, he/she would be very disappointed because his/her rights inside will be very limited regarding the jail and none concerning main FreeBSD host. If he/she would be successfull in destroying any of running services in jail, next jail could substitute that service if configured properly and users (web visitors) won’t notice almost anything.

I could write about this cool utility natively supported by FreeBSD much more, but I would like to focus on installation and setup of jail. Following procedures will assume FreeBSD 6.2-RELEASE installed on machine. Detailed information about jails is available in man pages, so we will use this as a guidance, officialy supported by the FreeBSD group. I will do all my best to guide you step by step through full process of installation and set up of FreeBSD jail system.

First step in installation of jail (Jail hereafter) we have to do is get rady the main machine (Host hereafter). Then we create one jail from FreeBSD source code which can be used for another jails later on and finaly I show you basic setup of freshly builded jail. I’m not going to explain or describe every step because it would be a long story, I use code instead.

Preparing Host

1. You must have more IP-s assigned by your ISP
2. Set all services running on Host to listen on Host IP only
3. Configure kernel sysctl variables. I suggest following values:

security.jail.set_hostname_allowed: 0
security.jail.socket_unixiproute_only: 1
security.jail.sysvipc_allowed: 0
security.jail.enforce_statfs: 2
security.jail.allow_raw_sockets: 0
security.jail.chflags_allowed: 0
security.jail.jailed: 0

You can check all stated above values by typing this:

root@server# sysctl -a | grep ‘jail’

Settings of these variables should be automatically performed after boot. This could by provided by /etc/sysctl.conf or /etc/rc.conf entries of Host (you will see later on).

Building Jail

To build up our first FreeBSD jail do this:

root@server# mkdir /usr/local/jail01
root@server# cd /usr/src
root@server# make world DESTDIR=/usr/local/jail01

Last point will take some time, so be patient and don’t panic. System is creating full copy of FreeBSD into the Jail. For another jails you don’t have to make world again, you just use the world already compiled. So, next jail you will create by this:

root@server# mkdir /usr/local/jail02
root@server# cd /usr/src
root@server# make installworld DESTDIR=/usr/local/jail02

This will be done much faster.

Configuring Jail

In following next steps we are going to make basic configuration of created jail:

root@server# cd /usr/src
root@server# make distribution DESTDIR=/usr/local/jail01 NO_MAKEDEV_RUN=yes
root@server# cd /usr/local/jail01
root@server# ln -sf dev/null kernel
root@server# touch /usr/local/jail01/etc/fstab
root@server# touch /usr/local/jail01/etc/rc.conf
root@server# cp /etc/resolv.conf /usr/local/jail01/etc

Official sources describe jail configuration from this point further but my experiences show that it is not necessary. I prefer to stop here and continue in different way in order to automate the rest of jail configuration on every boot strap.

For this reason now we open /etc/rc.conf of Host in your favorite text editor and add there following:

# —– global jail settings —–
jail_enable=”YES”
jail_list=”host01 host02″
jail_set_hostname_allow=”NO”

# —– individual jail settings —–
jail_host01_rootdir=”/usr/local/jail01″
jail_host01_hostname=”host01.example.com”
jail_host01_ip=”xx.xx.xx.x1″
jail_host01_interface=”bge0″
jail_host01_exec_start=”/bin/sh /etc/rc”
jail_host01_exec_stop=”/bin/sh /etc/rc.shutdown”
jail_host01_procfs_enable=”YES”
jail_host01_devfs_enable=”YES”
jail_host01_devfs_ruleset=”devfsrules_jail”
jail_host01_fdescfs_enable=”NO”
jail_host01_mount_enable=”NO”
jail_host01_fstab=”/usr/local/jail01/etc/fstab”
jail_host01_flags=”-l -U root”

jail_host02_rootdir=”/usr/local/jail02″
jail_host02_hostname=”host02.example.com”
jail_host02_ip=”xx.xx.xx.2″
jail_host02_interface=”bge0″
jail_host02_exec_start=”/bin/sh /etc/rc”
jail_host02_exec_stop=”/bin/sh /etc/rc.shutdown”
jail_host02_procfs_enable=”YES”
jail_host02_devfs_enable=”YES”
jail_host02_devfs_ruleset=”devfsrules_jail”
jail_host02_fdescfs_enable=”NO”
jail_host02_mount_enable=”NO”
jail_host02_fstab=”/usr/local/jail02/etc/fstab”
jail_host02_flags=”-l -U root”

The stated above entries ensure full configuration of all jails (in this example just 2 were used) at start up of Host. Last thing what we shouldn’t forget is make some entries to /etc/rc.conf of Jail:

network_interfaces=”"
syslogd_flags=”-ss”

and adjust /usr/local/jail01/etc/hosts, make entry:

127.0.0.1 host01 host01.example.com

Reboot Host.

Installation of services and final jail setup

Now you can check wheter your jails are running by typing

root@server# jls

If everything is OK, you should see

JID IP Address Hostname Path
2 xx.xx.xx.x2 host02.example.com /usr/local/jail02
1 xx.xx.xx.x1 host02.example.com /usr/local/jail01

and you can enter the Jail by typing

root@server# jail /usr/local/jail01 host01 xx.xx.xx.x1 /bin/sh

Once you’re in you can see

host01#

and start to install services as usually on common FreeBSD machine.

After installation services don’t forget adjust /etc/rc.conf of selected Jail. Then, the file will look like this:

apache22_enable=”YES”
mysql_enable=”YES”
network_interfaces=”"
syslogd_flags=”-ss”
vsftpd_enable=”YES”

Reboot Host.

Check whether installed services run correctly by typing

root@server# netstat -f inet -ant | grep ‘LISTEN’

or use

root@server# ps -aux | grep ‘J’

or

root@server# ps -aux -o jid,pid,args

or

root@server# pgrep -lfj JID // JID is jail number got from jls command

to see processes run in jails.

Now your jail runs as any other FreeBSD machine and you can make any changes, installations, experiments inside the Jail without any fear of damages of your Host – it will stay intact and safe. Such a good feeling!

Jail may be shutted down by

root@server# jail /usr/local/jail01 host01 xx.xx.xx.x1 /bin/sh /etc/rc.shutdown

or

root@server# killall -j JID // JID is jail number got from jls command

I realize that many of steps would require deeper explanation but as I wrote earlier, this article should be brief installation and setup guide written mainly by examples. If anybody would need more info don’t hesitate contact me and I can share experiences with you.

Finally, here are some usefull references: jail, jls, and jexec.

Tags: , ,

Leave a Reply

© 2007-2013 alphapatrol.com | AlphaPatrol Blog is proudly powered by WordPress | Entries (RSS) and Comments (RSS)