Ezjail is a utility that will help us manage jails on FreeBSD more easily. An interesting feature is that it uses a base template that is shared between jails through nullfs, so the base will be reused without using additional disk space. Updates made to the base will be automatically applied to the rest of the jails, and the ports system will behave analogously.
To use jails, we must create a secondary loopback interface, which will give us a completely isolated 127.0.0.0/8 network:
cloned_interfaces="lo1"
With this interface, all jails can see each other. The first jail will be 127.0.0.1, the next one will be .2, and so on.
We install ezjail:
We enable it at startup:
Now we start it manually:
We install the base template for all jails:
We create the first jail:
If we want ping to work, the jail must use raw sockets. We edit the config to allow it. We only need to enable the options strictly necessary for the jail to provide service, and ping is not one of them, but in this example, we will enable it for easier debugging since it is our first jail:
export jail_kr0mjail_parameters="allow.raw_sockets=1"
We start the jail:
We check that it has started and that the network configuration is correct:
STA JID IP Hostname Root Directory
--- ---- --------------- ------------------------------ ------------------------
DR 2 127.0.0.1 kr0mjail /usr/jails/kr0mjail
2 em0|192.168.69.24
We enter the jail and assign a password to the root user:
We enable ssh at startup:
We start it manually:
We add a secondary user:
We configure the timezone:
adjkerntz will try to adjust the system time but the jail will not be able to do so, so we comment it out in the crontab:
We configure the DNS servers:
echo “nameserver 8.8.4.4” » /etc/resolv.conf
We configure the /etc/hosts:
::1 localhost kr0mjail
127.0.0.1 localhost kr0mjail
We should now have ssh access:
Base updates will be performed on the parent host using:
If it is not a routine update but a version update, we must first find out which version we are starting from:
/usr/jails/basejail/bin/sh: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 12.0 (1200086), FreeBSD-style, stripped
Then we would execute:
Now we have to finish the update from within each jail, depending on whether the jail’s users/services are trustworthy or not, we will proceed differently.
Unreliable:
We mount the /usr/src directory inside the jail:
mkdir /usr/jails/kr0mjail/usr/src
mount -t nullfs -o ro /usr/src /usr/jails/kr0mjail/usr/src
We access the jail and run mergemaster:
cd /usr/src
mergemaster -U
exit
Unmount /usr/src:
Reliable:
The ports are shared between jails, so we proceed to update them in all jails simultaneously:
NOTE: Some ports need to be compiled with the JAIL option to work correctly.
NOTE: Deleting a jail is buggy, it leaves residual files.
We delete the jail:
If we try to create it again:
Error: A file or a non empty directory already exists at the specified jail root /usr/jails/kr0mjail.
We remove the immutable flag from the directory and delete it:
rm -rf /usr/jails/kr0mjail
Ezjail allows us to archive a jail and restore it on the same host or any other, thus we can duplicate jails quickly:
chflags noschg /usr/jails/kr0mjail//var/empty/
ezjail-admin archive kr0mjail
ls -la /usr/jails/ezjail_archives/
total 10
drwxr-xr-x 2 root wheel 3 Apr 25 20:46 .
drwxr-xr-x 7 root wheel 7 Apr 25 15:51 ..
-rw-r--r-- 1 root wheel 1033845 Apr 25 20:46 kr0mjail-201904251646.31.tar.gz
We can restore the archive with another name:
ezjail-admin list
ezjail-admin list
STA JID IP Hostname Root Directory
--- ---- --------------- ------------------------------ ------------------------
DS N/A 127.0.0.2 kr0mjail-clone /usr/jails/kr0mjail-clone
N/A em0|192.168.69.25
DS N/A 127.0.0.1 kr0mjail /usr/jails/kr0mjail
N/A em0|192.168.69.24
We start the copy and the original jail:
ezjail-admin start kr0mjail
As a summary, I leave the basic operations performed in ezjail.
Start jail:
Stop jail:
Disable auto-start:
Enable auto-start: