Freebsd jails with iocage

This is small howto for star playing with jails in freeBSD.

All this assumes freeBSD 12.0, with zfs root and kernel with enabled VIMAGE option (on default kernel for 12.0 it already is.)

First install iocage from git repo:

pkg install python36 git-lite libgit2 py36-cython py36-pip
git clone --recursive https://github.com/iocage/iocage
make install

(make install needs root access!)

Next is modifying rc.conf file. Add following lines to the /etc/rc.conf:

cloned_interfaces="bridge0"

ifconfig_bridge0="addm vtnet0 up"  # (1)

pf_enable="YES"
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
gateway_enable="YES"

For line marked with (1) replace ‘vtnet0’ with your public facing interface!!

And following lines to /etc/sysctl.conf:

net.inet.ip.forwarding=1      # Enable IP forwarding between interfaces
net.link.bridge.pfil_onlyip=0 # Only pass IP packets when pfil is enabled
net.link.bridge.pfil_bridge=0 # Packet filter on the bridge interface
net.link.bridge.pfil_member=0 # Packet filter on the member interface

And to /etc/fstab add:

fdescfs /dev/fd  fdescfs  rw  0  0

All this can be found on iocage github page and/or their documentation, so visit that pages and read them! There is not much but it can help a lot!

iocage needs to be ‘activated’ before use, what it basically does is to find usable zpool for storing jails. Just run:

iocage activate

After that, freeBSD release that will be used for jails needs to be downloaded. Just run following command and follow it:

iocage fetch

This setup uses two public IP addresses, one for base system and one for jails. One jail will be router, and it needs something for proxy to be installed (nginx or HAproxy for ex.).

For first jail, VIMAGE/VNET is not used, instead IP alias is used. One is on public facing interface with second public IP address, and second is on bridge0 interface that VNET will use for jails.

All commands for iocage requre root access, so either run them as root or with sudo. Where you see <public_ip> set your public IP for jails (second IP address), and instead <vnet_ip> set jails internal IP address (for ex. 10.0.0.1/24).

Create first jail (replace ‘vtnet0’ with your public facing interface!!):

iocage create -r LATEST \
   -n router \
   ip4_addr="vtnet0|<public_ip>/32,bridge0|<vnet_ip>" \
   defaultrouter="<jails_router_ip>" \
   vnet="off"