A few weeks ago, a user on the Bro IDS mailing list was looking for a way to run Bro in a FreeBSD jail. FreeBSD jails provide the foundation of operating system-level virtualization, later utilized and enhanced by Solaris zones, and those containers that everyone thinks are something new. To avoid going on a complete rant, I recommend the following write-up as an overview of FreeBSD jails:
https://www.freebsd.org/doc/handbook/jails.html
The purpose of this howto is to document that basic steps necessary to use Bro within a FreeBSD jail. For jail management, ezjail is normally the recommended way to setup jails. With a recent copy of FreeBSD (FreeBSD 11), run the following commands to install the ezjail package and setup your Bro jail (Note: vtnet0 is my network interface on the host, which could also be em0, or re0 in your case):
# pkg install -y ezjail
# ezjail-admin install -p
# ezjail-admin create bro 'vtnet0|192.168.1.20'
# cat << EOF > /usr/jail/bro/etc/rc.conf
rpcbind_enable="NO"
cron_flags="$cron_flags -J 15"
syslogd_flags="-ss"
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
sshd_enable="NO"
EOF
# echo 'nameserver 192.168.1.1' > /usr/jails/bro/etc/resolv.conf
# sysrc ezjail_enable=yes
# ezjail-admin start bro
The settings for rc.conf are recommended for jails, but they can be adjusted as needed, since Bro can be configured to send out email alerts. Now with the jail running, the Bro package can be installed within the jail using pkg with the following command:
# pkg -j bro install -y bro
Before Bro can be used, the jail configuration needs to be updated to allow the bro jail access to bpf, the berkley packet filter used for reading packets from a network device. By design, the jail does not allow access to listen on a network interface. Modifying the devfs rules loaded by the jail will allow for reading of packets from the interface used to create the jail (which matches the host interface). Run the following commands to create a special devfs rule that will allow the jail access to bpf device:
# cat << EOF >> /etc/devfs.conf
[devfsrules_jail_bro=7]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add include $devfsrules_unhide_bpf
EOF
# sed -i '' -e 's/devfsrules_jail/7/' /usr/local/etc/ezjail/bro
The jail is now setup to work with Bro, and the necessary Bro configuration updates can be made. The following commands are the bare minimum to get Bro running, please see the Bro documentation for additional configuration settings (Note: replace vtnet0 with the same interface used to create the jail):
# sed -i '' -e 's/^127.0.0.1.*/127.0.0.1 bro localhost/' /usr/jails/bro/etc/hosts
# sed -i '' -e 's/^interface=.*/interface=vtnet0/' /usr/jails/bro/usr/local/etc/node.cfg
# sed -i '' -e 's/^host=.*/host=192.168.1.20/' /usr/jails/bro/usr/local/etc/node.cfg
Now after restarting the jail, you can start Bro using the ‘broctl’ script:
# ezjail-admin restart bro
# jexec bro /usr/local/bin/broctl deploy
Bro will now be running within the jail, and from the host you can analyze the logs in /usr/jails/bro/usr/local/spool/bro.
There are additional configurations that can be made to this Bro jail, including the usage of a non-root user for Bro. With this configuration, if there was a vulnerability within Bro that could be exploited, the attacker could only break out into the jail file tree structure. Another caveat is that the jail is setup to start when the FreeBSD host starts, but in order to make Bro start automatically, you can add the following to rc.local within the jail
echo '/usr/local/bin/broctl deploy' >> /usr/jails/bro/etc/rc.local