Tyler's Site

What are Jails

FreeBSD’s jails are an expansion of the chroot command that many will be familiar with. Jails were introduced in FreeBSD 4.0 and have served many FreeBSD users very well since. While this may or may not be technically correct, FreeBSD’s jails are effectively FreeBSD’s container system similar to what LXC is for Linux.

Getting Started

Like many other great features in FreeBSD, jails are built into the base system. The FreeBSD handbook’s section on Jails is a great resource to get started with jails and is mostly what I referenced to get them set up. There are a few ways to get a jail installation, but I chose to do use the method from the Internet. Running the following command as root will download all of the files needed for a jail to a directory located at /usr/jails/example:

bsdinstall jail /usr/jails/example

The script will download all of the files needed and also ask for some configuration from the user for things like root password and users for the system. After the script runs the system is downloaded and ready to be configured in the /etc/jail.conf file.

It is also possible to install a jail from a FreeBSD ISO or from FreeBSD’s source, however, it is also worth noting that jails cannot run a newer version of FreeBSD than the host. For example, a FreeBSD 12.4 host can run a FreeBSD 11.4 jail, but not a FreeBSD 13.2 jail.

Configuration

Basic configurations for the jails are not difficult to read or write. The example included here is for a jail named “example” located at /usr/jails/example.

# Configuration for exaple jail
# Name of jail on top line. This is how the jail will be referenced
# from rc scripts
example {
# Hostname of jail, can be anything
host.hostname = example.home;
# loopback address of jail if desired
ip4.addr += "lo0|127.0.1.1";
# Network address
ip4.addr += "vtnet0|192.168.122.22";
# Path to jail directory
path = "/usr/jails/example";
# Mount devfs so things like SSH works inside of the jail
mount.devfs
# Startup scripts
exec.start = "/bin/sh /etc/rc";
# Shutdown scripts
exec.stop = "/bin/sh /etc/rc.shutdown";
}

Getting the networking for the jails to be able to access the Internet took a little research, however, the issue was that I did not assign a network Interface to the jails network address. I found that information from this article that goes into more depth about networking within jails.

Using the jails

From here we are ready to start the jail by running the following command as root:

# to start the jail
service jail onestart example
# to stop the jail
service jail onestop example

If you are wanting the jails to start automatically upon system boot, simply add jail_enable="YES" to /etc/rc.conf. From there the above command can be changed to:

# to start the jail
service jail start example
# to stop the jail
service jail stop example

The jls command will show the current running jails and their associated Jail ID (JID). Running a command within a jail is as easy as running jexec ${JID} ${PATH_TO_COMMAND} as root. For example, getting a shell on a jail with a JID of 3 would look like:

# Make sure to run as root
jexec 3 /bin/sh

You are then greeted to a very standard FreeBSD userland that can be used for testing or running services.

More resources

As alluded to in an earlier section of this article, FreeBSD jails are a widely covered topic within the FreeBSD community because of how useful they are. One person that has a lot of information about FreeBSD’s jails, and many other BSD related topics, is Michael W Lucas. He has written a very good book called FreeBSD Mastery: Jails He also gave a talk at BSDCan in 2019 about jails: Michael W Lucas: Twenty Years in Jail. Both of those resources would be really good places to start if you need more information than what I have provided here concerning FreeBSD’s jail system.