News from the Machineroom


Rebuilding my Jails

Published:

The service jails on my server were built a long time ago using iocage. I do not like many aspects of iocage, so I decided to ditch it and replace it with something simpler and more bare bones.

  1. Run my mkjail script to create a new template jail. I most probably need to update the FreeBSD version in the script, because that is not configurable yet:

    % mkjail template
    
  2. Send the snapshot to the server:

    % zfs send -R zroot/jails/template@template | mbuffer -s 128k -m 1G | \
        ssh myhost 'mbuffer -s 128K -m 1G | zfs receive zroot/jails/template'
    
  3. On the server, create a new jail from the template. This requires several steps, beginning with the filesystem:

    # zfs clone zroot/jails/template@template/root zroot/jails/myjail/root
    # zfs create zroot/jails/myjail/cfg
    # zfs create zroot/jails/myjail/log
    
  4. Create the fstab for the new jail. Mine looks like this:

    /var/cache/pkg  /jails/myjail/root/var/cache/pkg  nullfs  rw      0       0
    /data/ssl	/jails/myjail/root/data/ssl	nullfs	ro	0	0
    /data/svc	/jails/myjail/root/data/svc	nullfs	rw	0	0
    

    The first entry makes the pkg cache from the host available to the jails. The second entry makes the ssl certificates available. There is no need to write to the data, so it is mounted read-only. The third entry makes service-specific data available. Since this data is used by the jailed service, it needs to be mounted read-write.

    Don’t forget to create the mountpoints you want to use!

    mkdir -p /jails/myjail/root/var/cache/pkg
    mkdir -p /jails/myjail/root/data/ssl /jails/myjail/root/data/svc
    
  5. Add the new jail to /etc/jail.conf. Mine looks like this:

    $j="/jails/$name";
    
    path="$j/root";
    host.hostname="$name.purplekraken.com";
    allow.noset_hostname;
    mount.devfs;
    mount.fstab="$j/cfg/fstab";
    exec.clean;
    exec.start="/bin/sh /etc/rc";
    exec.stop="/bin/sh /etc/rc.shutdown";
    exec.timeout=90;
    stop.timeout=90;
    exec.consolelog="$j/log/console.log";
    securelevel=2;
    ip6=disable;
    
    myjail {
            ip4.addr="192.168.13.37";
    }
    
  6. Setup DNS and timezone

    # cp /etc/resolv.conf /jails/myjail/root/etc/resolv.conf
    # cp /etc/localtime /jails/myjail/root/etc/localtime
    
  7. Start the new jail

    # jail -c myjail
    
  8. Install services into the jail

    # pkg -j myjail update
    Updating FreeBSD repository catalogue...
    [myjail.purplekraken.com] Fetching packagesite.pkg: 100%    7 MiB   3.4MB/s    00:02    
    Processing entries: 100%
    FreeBSD repository update completed. 32882 packages processed.
    All repositories are up to date.
    # pkg -j myjail install svc
    

    Don’t forget to add the appropriate firewall rules! (Don’t ask me why I stress this point…)

The procedure still contains a lot of manual steps, but the result should be reasonably lightweight so it can run for a while.