This document is an introduction to basic FreeBSD jails also called ‘fat jails’. We discuss an easy jail installation process. We will do some basic jail configuration and show you how to manage the jail environment. This document wil not cover building ‘chroot jails’ in a jail.
- Basic knowledge of FreeBSD
- Root access
- Read up on jails – see the references at the end of the document
Before we start: the machine which will run the jails is refered as ‘host’. The jails are built and configured from the host. Every individual jail runs the desired services. The host’s services are minimized, running a syslogd and sshd should be enough.
Determine where you want to install the jail(s). Throughout the document /usr/jails will be used. For example we will install a web server in the jail, so let us take /usr/jails/webserver1 as the location for the web server.
# cd /usr/ # mkdir jails # cd jails # mkdir webserver1 # sysinstall
- In the menu select ‘Custom’.
- Choose ‘2 Options’ and navigate to ‘Install Root /’. When selected, press spacebar and change ‘/’ to ‘/usr/jails/webserver1’. Press ‘q’ to quit the options menu.
- Go to ‘5 Distributions’ and select ‘A Minimal’.
- Then choose ‘6 Media’ from which you will install your base installation for the jail.
- When done, select ‘7 Commit’.
Don’t visit the general configuration menu. Every option you edit in the configuration menu will be executed on your host. Exit the installation menu and return to your host’s shell.
# cd /usr/jails/webserver1 # ls .cshrc boot libexec rescue tmp .profile dev media root usr COPYRIGHT etc mnt sbin var bin lib proc sys #
We have to edit and create some configuration files in order to make our jail(s) work.
Host – rc.conf
hostname="host" ifconfig_rl0="inet 10.0.0.10 netmask 255.255.255.0" ifconfig_rl0_alias0="inet 10.0.0.20 netmask 255.255.255.255" inetd_enable=”NO” # if you need inetd sevices on the host, uncomment the inetd lines #inetd_enable="YES" #inetd_flags="-wW -a 10.0.0.10" rpcbind_enable="NO" sendmail_enable="NO" sendmail_submit_enable="NO" sendmail_outbound_enable="NO" sendmail_msp_queue_enable="NO" syslogd_enable="YES" syslogd_flags="-ss" syslogd_flags="-a 10.0.0.10" syslogd_flags="-a 10.0.0.20" keymap="us.iso" sshd_enable="YES" # Jail general settings jail_set_hostname_allow=”NO” jail_enable="YES" jail_list="webserver1" jail_interface="rl0" jail_devfs_enable="YES" jail_procfs_enable="YES" # settings per jail listed in jail_list jail_webserver1_rootdir="/usr/jails/webserver1" jail_webserver1_hostname="webserver1" jail_webserver1_ip="10.0.0.20" jail_webserver1_devfs_ruleset="devfsrules_jail"
The host’s rc.conf consists of two blocks: the config for the host and the jail. The jail’s config consists of two subcategories: the general jail config and the per jail config.
Corresponding to the sections ‘Setting up the host environment’ and ‘Configuring the jail’ of the manual page of jail(8), we have to create IP-aliases, edit the super-server daemon (In this scenario, inetd is disabled.) , disable the portmapper and disable sendmail. Specifying the syslogd flags –ss disables remote logging and syslogd will not listen to any IP-address. Instead, we want syslogd to listen to specific socketaddresses through enabling the –a flag.
The next rc.conf block is about the jails. Read the manual page rc.conf(5) for all the jail options and jail(8) for their configuration and use. You have to know there are several sysctl management entries you can alter and configuration defaults aren’t listed in the provided rc.cconf. Check out ‘/usr/share/examples/etc/defaults/rc.conf’ for a complete survey. The first system control line you encounter is ‘jail_set_hostname_allow=”NO”’. This option affects all jails and has to be stated before any jail is started. It allows or disallows jail processes changing the jail’s hostname. This affects management tools relying on the jail information in /proc. The option should be disabled like this if you are giving out root access to untrusted users in the jail.
Through the ‘jail_list’ variable, the host knows and starts the known jails. For example ‘jail_list=”webserver1 database dns” ‘.
Webserver1 – rc.conf
hostname="webserver1" ifconfig_rl0="inet 10.0.0.20 netmask 255.255.255.255" defaultrouter="10.0.0.1" rpcbind_enable="NO" clear_tmp_enable="YES" sendmail_enable="YES" sshd_enable="YES"
When you enable sshd, specify the ListenAddress in /etc/ssh/sshd_conf. The ListenAddress will be 10.0.0.20 for ‘webserver1’.
Webserver1 – resolv.conf
If your host box has already an internet connection, you can copy the host’s DNS information to webserver1.
# cp /etc/resolv.conf /usr/jails/webserver1/etc/resolv.conf
This should be sufficient to start the jailed environment. There are more ways to execute a jail. The document’s information will keep it simple.
Reboot the host system or execute on the host:
# /bin/sh /etc/rc
Let us see if the jail and its network are up and running by using the commands ‘jls’ (jail list) and ‘ping’. Jail ID 0 equals the host.
# jls JID IP Address Hostname Path 1 10.0.0.20 webserver1 /usr/jails/webserver1 # ping -c 3 10.0.0.20 PING 10.0.0.20 (10.0.0.20): 56 data bytes 64 bytes from 10.0.0.20: icmp_seq=0 ttl=64 time=0.324 ms 64 bytes from 10.0.0.20: icmp_seq=1 ttl=64 time=0.222 ms 64 bytes from 10.0.0.20: icmp_seq=2 ttl=64 time=0.220 ms --- 10.0.0.20 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.220/0.255/0.324/0.049 ms #
We can ping the jail environment from the host or other machine, but when in a jail, only the tcp/ip (version 4) protocol is supported.
Some basic jail configuration: creating an empty fstab, setting a root password, adding a user and setting the timezone.
When adding the first user, invite him to the wheel group. Root can’t login in the jail when logging in from the host.
The command ‘jexec’ (jail execute) is used as follows:
# jexec 1 touch /etc/fstab # jexec 1 passwd # jexec 1 adduser # jexec 1 tzsetup
At this point we can login to the jail with a non-root account and look around.
# jexec 1 login $ su # exit $ exit #
If you didn’t added a user who can become root trough adduser, this is an alternative method. Spawn the root shell of the jail, open its group file and add the desired user to the wheel group. Exit the jail and re-login to the jail using ‘login’.
# jexec 1 /bin/sh # ee /etc/group # exit # jexec 1 login
To enable remote administration, edit the jail’s sshd_config to your needs and restart sshd. There will be at least one option in the sshd_config file you have to alter. The ‘ListenAddress’ has to be specified to the corresponding jail IP-address.
# /etc/rc.d/sshd stop # ee /etc/ssh/sshd_config # /etc/rc.d/sshd start # exit
Starting and stopping jails:
# /etc/rc.d/jail start # /etc/rc.d/jail stop
You can start and stop jails seperatly by specifying the jail’s name. For example:
# /etc/rc.d/jail start webserver1 # /etc/rc.d/jail stop webserver1
Installing a service
Let us continue and install a webserver trough the host’s ports collection. Installing the ports collection in a jail is unnessecary. Checkig installed ports for known vulnarabilities is of course necessary. We will mount the host’s ports against our jailed environments. Unmount the host’s /usr/ports and /usr/src them when done.
The ‘webserver1’ jail has no ports dirtectory at the moment; we have to create the directory.
# jexec 1 mkdir /usr/ports # mount_nullfs /usr/ports /usr/jails/webserver1/usr/ports # mount_nullfs /usr/src /usr/jails/webserver1/usr/src # jexec 1 login # su # cd /usr/ports/ports-mgmt/portaudit # make install distclean # /usr/local/sbin/portaudit -Fda # cd ../../www/apache22 # make install distclean # echo 'apache22_enable="YES"' >> /etc/rc.conf
For simplicity we add the IP-address as ServerName in the configuration file of httpd. Then we will try to fire it up.
ee /usr/local/etc/apache22/httpd.conf ServerName 10.0.0.20
# /usr/local/sbin/apachectl start
When you want to run the Apache web server, you can get following error:
[warn] (2)No such file or directory: Failed to enable the ‘httpready’ Accept Filter
You have to enable the accf_http module on the host, not the jailed environment. You can’t load kernel modules in your jail.
Add the line ‘accf_http_load=”YES”’ into the /boot/loader.conf of your host.
# echo ‘accf_http_load=”YES” ‘ >> /boot/loader.conf
When you check the hosts’ processes, look at the STAT column. Every process listed in that column with a ‘J’ attached to it, is a jailed process.
Now shutdown the jail and restart it and then check again if the web server is up and running.
The jail environment is just a virtual box with extra features for free.
- Jails: Confining the omnipotent root
- FreeBSD Handbook Chapter 15 ‘Jails’
- Mastering FreeBSD and OpenBSD Security
- Creating a FreeBSD Jail
The system’s manual pages: