Bastille is a container management system for FreeBSD, similar to Docker or Podman on Linux. The historical name of containers on FreeBSD is jail, and they appeared a lot earlier than containers on Linux. Managing jails was not always easy. When I started to use this technology in production in 2001, nothing was automated. Using Bastille, you can easily create, configure, or update jails at scale. It has a template system to install applications in containers and there is a template also for syslog-ng.
From this blog, you can learn how to get started with Bastille and how to create and run a syslog-ng jail using the freshly released 0.8 version of Bastille.
Before you begin
First of all, to use Bastille, you need FreeBSD installed. I used FreeBSD 12.2 on AMD64, but it also works on CURRENT and on any platform supported by FreeBSD, including the Raspberry Pi. Bastille 0.8, the release I’m describing in my blog, was released after the latest quarterly package release. It means, that by the time of writing this blog article, you can install it only using an up-to-date ports snapshot or following the latest PKG builds, instead of the quarterly PKG release.
The easiest way to install Bastille is to use the pkg command:
pkg install bastille
And depending on your Internet connection, it will be installed within a few seconds. You can also install it from ports:
cd /usr/ports/sysutils/bastille/ make install clean
There are no extra dependencies when you install Bastille. There is one exception, even if it is not hardcoded into the Makefile in ports: you need to install Git to be able to use the template system.
pkg install git
Bastille supports many different FreeBSD features, like ZFS or VNET. However, these need extra planning, stronger hardware, and more control over the network. So, in this blog, I go with the easiest configuration possible, which works anywhere: on your local network or somewhere in a public cloud as well. For more choices and advanced functionality, check the Bastille documentation at https://bastille.readthedocs.io/en/latest/
The commands below enable Bastille, create and start an internal network interface for jails and also enable the PF firewall. Run each of these commands from a terminal.
sysrc bastille_enable="YES" sysrc cloned_interfaces+=lo1 sysrc ifconfig_lo1_name="bastille0" service netif cloneup sysrc pf_enable="YES"
The next step is to set up the PF firewall. The configuration below should go into /etc/pf.conf and you should replace “em0” on the first line with your actual network interface name. This configuration makes sure that jails can reach the Internet through NAT and Bastille can create rules to access services in jails without editing the firewall configuration manually.
ext_if="em0" set block-policy return scrub in on $ext_if all fragment reassemble set skip on lo table <jails> persist nat on $ext_if from <jails> to any -> ($ext_if) rdr-anchor "rdr/*" block in all pass out quick modulate state antispoof for $ext_if inet pass in inet proto tcp from any to any port ssh flags S/SA modulate state
You can now restart the pf service for these rules to take effect. Note, that if you work over an SSH connection, you might be kicked off from the system when you hit Enter. In this case, reconnect and continue your work:
service pf restart
Finally, bootstrap the release of your choice (not more recent than what the host is running):
bastille bootstrap 12.2-RELEASE
It downloads and extracts the given release. You are now ready to create your first jail!
Creating your first jail
The first step is to create a jail. “bastille create” expects a few parameters from you. One is a name for the jail. In the example below, we use “alcatraz”, but in real life, you will most likely use names that remind you of the function of the jail, for example: centralsyslog. You also need a FreeBSD release name and finally an IP address. Use a different IP address if your host is on a 10.0.0.0/8 network.
bastille create alcatraz 12.2-RELEASE 10.17.89.50
Unlike previous releases, version 0.8 of Bastille starts the freshly created jail automatically. I prefer this way, but not everyone is happy with this change, so it might change in future releases.
Now, bootstrap the syslog-ng template. It uses Git to download the template from a repository on GitLab.
bastille bootstrap https://gitlab.com/BastilleBSD-Templates/syslog-ng
Apply the template to the jail. As you can see, we refer to the jail by its name, so choose jail names wisely!
bastille template alcatraz BastilleBSD-Templates/syslog-ng
Finally configure the PF firewall with a bastille command, and redirect the external 514 port to the 514 port of the freshly created jail on the internal network:
bastille rdr alcatraz tcp 514 514
And your second jail
The commands below create a second jail with a slightly different name and IP address. You do not have to bootstrap the syslog-ng template again, just apply it to the jail. And as port 514 on the host is already redirected to the first jail, here we redirect the external 515 port to the 514 port of the jail.
bastille create alcatray 12.2-RELEASE 10.17.89.51 bastille template alcatray BastilleBSD-Templates/syslog-ng bastille rdr alcatray tcp 515 514
You can check the logs from both jails with the following command:
tail -f /usr/local/bastille/jails/alcatraz/root/var/log/messages /usr/local/bastille/jails/alcatray/root/var/log/messages
You should see two sets of log messages from the two jails. The -f option means that you do not get back the command prompt, but tail follows the files.
Now open another terminal and from another system use telnet to connect to port 514 and 515 of your FreeBSD host. In both cases, enter some test messages.
czanik@czplaptop:~> telnet 172.16.167.138 515 Trying 172.16.167.138... Connected to 172.16.167.138. Escape character is '^]'. this is a test ^] telnet> quit Connection closed. czanik@czplaptop:~> telnet 172.16.167.138 514 Trying 172.16.167.138... Connected to 172.16.167.138. Escape character is '^]'. this is another test ^] telnet> quit Connection closed.
On the other terminal, you should see log messages about the connection and the test messages as well:
Jan 22 10:03:13 alcatraz syslog-ng: syslog-ng starting up; version='3.30.1' Jan 22 11:52:52 alcatraz syslog-ng: Syslog connection accepted; fd='23', client='AF_INET(172.16.167.1:50212)', local='AF_INET(0.0.0.0:514)' Jan 22 11:52:56 172.16.167.1 this is another test Jan 22 11:53:01 alcatraz syslog-ng: Syslog connection closed; fd='23', client='AF_INET(172.16.167.1:50212)', local='AF_INET(0.0.0.0:514)'
If you have questions or comments related to syslog-ng, do not hesitate to contact us. You can reach us by email or even chat with us. For a list of possibilities, check our GitHub page under the “Community” section at https://github.com/syslog-ng/syslog-ng. On Twitter, I am available as @Pczanik.