Virtual FreeBSD jail based server environments can not easily trigger actions in the host system, most prominently restarting themselves (if they
kill -1 everything, they usually stay shut down) and trigger actions like routing table updates, triggering zfs snapshots or rollbacks and configuring
tun/tap-Devices (as an openvpnd would).
There are several less-than-optimal solutions for that problem: granting forced-command ssh access to jails, polling some Jail-state from within the host system or dig some proprietary socket holes through the Jail's barrier, exposing a root-shell attack vector to the outside world.
jaildaemon aims to solve the problem in a simple and straight forward way while trying to minimize the attack surface for adversaries from the Jail and the network. It is a tiny daemon running in the host system that forks a probe process with a single associated command on demand, attaches it to a single jail and (optionally) assigns it a verbose proctitle. When the Jail's root user sends a SIGHUP to this probe process, it dies with a magic exit code, signalling the daemon to execute the associated command (in host context). You can chose to have the daemon restart the probe process after the command is executed (e.g. when it triggers updating routing tables) or just wait for it to be restarted by the Jail management tool (e.g. when using
/usr/local/etc/rc.d/ezjail restart shell.foo.com as a reboot helper).
You can always get the latest version of jaildaemon, use
git clone git://erdgeist.org/jaildaemon or the legacy view
cvs -d :pserver:firstname.lastname@example.org:/home/cvsroot co jaildaemon with an empty password to check it out. There is a jaildaemon tarball, but no versioning yet. You can scroll through the source at jaildaemon gitweb or jaildaemon cvsweb (deprecated). Typing
make install installs the binary in your
/usr/local, if none is set) and the rc-script to
A tight integration with ezjail is, of course, following soon.
Start the daemon as root with
jaildaemon -D, with optional parameters
f to request the pidfile being written or to specify a different controlling command unix domain socket location (that is used by jaildaemon when run in client mode to communicate with the server, and defaults to
If you installed the package, you can just enable jaildaemon in your
/etc/rc.conf, by adding
jaildaemon_enable=YES. It should then start at reboot, or when you run
Start a new probe process in a Jail (in this example jid 23) to trigger the execution of the script:
/usr/local/bin/parse_route_config -s /usr/jails/shell.foo.com/
while identifying as 'route config update' in the jail and respawn:
jaildaemon -j 23 -c '/usr/local/bin/parse_route_config -s /usr/jails/shell.foo.com/' -t 'route config update' -r
From within the jail (
ezjail-admin console shell.foo.com) trigger the command by
pkill -HUP -f 'route config update'.
Start a (non-spawning) Jail reboot trigger:
jaildaemon -j 23 -c '/usr/local/etc/rc.d/ezjail restart shell.foo.com' -t REBOOT
Now, from within that Jail, reboot via
pkill -HUP -f REBOOT.
Fix the IPC packet size to match with system's net.local.dgram.maxdgram, which defaults to 2048
Fix a bug where proctitle length was not parsed from the correct field
Add a -g switch to allow jaildaemon to be passed a gid.
Fixed a bug where jaildaemon when run from /etc/rc would ignore SIGHUP by default.
You can now make the probe drop into another uid, so that non-root-processes can trigger actions, as well.
Allow jaildaemon to accept the jailname for the -j parameter, as well.