FreeBSD's jails are pretty powerful tools, in this post I will go over how they can be used.
Types of Jails
there are 3 main types of jails:
- Thick jails
- Thin Jails
- Linux Jails
Thick jails are the "traditional" form of jails in FreeBSD, they contain a complete copy of the FreeBSD base system. This means that each jail has its own libraries, executables and configuration files. This can be thought of like it's own standalone installation. This isolation ensures that processes within the jail are kept entirely separate from the host or other jails.
Thin jails share the base system using OpenZFS snapshots or a NullFS mounts from a template, so only a minimal set of the base system is copied for each thin jail. This means less resources but also less isolation, and changes in shared components could affect multiple thin jails at once.
Linux jails are a feature of the FreeBSD OS that allows running Linux binaries and applications within a FreeBSD jail. This is done with a compatibility layer of the host system that translates Linux system calls to FreeBSD system calls.
In this post I'll go over Thick jails, but you can read more about the other types in the freebsd documentation
Enabeling Jails
To enable jails, we need to run the following commands:
sysrc jail_enable="YES"
sysrc jail_parallel_start="YES"
next we need to set up the directory tree for the jails:
zfs create -o mountpoint=/usr/local/jails zroot/jails
zfs create zroot/jails/media
zfs create zroot/jails/templates
zfs create zroot/jails/containers
Thick (classic) jails
First we need to download and extract the userland files. thickjail
is the name of the jail I'm creating
fetch https://download.freebsd.org/ftp/releases/amd64/amd64/13.2-RELEASE/base.txz -o /usr/local/jails/media/13.2-RELEASE-base.txz
mkdir -p /usr/local/jails/containers/thickjail
tar -xf /usr/local/jails/media/13.2-RELEASE-base.txz -C /usr/local/jails/containers/thickjail --unlink
cp /etc/resolv.conf /usr/local/jails/containers/thickjail/etc/resolv.conf
cp /etc/localtime /usr/local/jails/containers/thickjail/etc/localtime
now we have the jail configured, we can update the jail to the latest patch level:
freebsd-update -b /usr/local/jails/containers/thickjail/ fetch install
Next, add the following to /etc/jail.conf
(or; to a new file in /etc/jail.conf.d
)
thickjail {
# STARTUP/LOGGING
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.consolelog = "/var/log/jail_console_${name}.log";
# PERMISSIONS
allow.raw_sockets;
exec.clean;
mount.devfs;
# HOSTNAME/PATH
host.hostname = "${name}";
path = "/usr/local/jails/containers/${name}";
# NETWORK
ip4.addr = 172.16.0.201;
interface = em0;
}
(tip: if you want to share the IP of the host, you can use ip4 = inherit
instead)
and start it with
service jail start thickjail
Jail management
Now we have a jail running, we need to manage it. With jls
we can list the running jails
root@testbsd:/etc/jail.conf.d # jls
JID IP Address Hostname Path
1 172.16.0.201 thickjail /usr/local/jails/containers/thickjail
to control power, we can use service jail <start|stop|restart> <jailname>
for example
service jail stop thickjail
If needed, we can enter a jail with jexec
.
jexec -u root thickjail
Starting jails at boot time
To start jails at boot time, you can add the following to /etc/rc.conf
(you can add multiple jails, seperated with a space, like jail_list="jail-1 jail-2"
)
jail_list="thickjail"
Deleting a jail
service jail stop jailname
chflags -R 0 /usr/local/jails/containers/jailname
rm -rf /usr/local/jails/containers/jailname