Learn how to build DynFi Firewall from scratch

Building DynFi Firewall

DynFi Firewall is a modern firewall based on FreeBSD. The software is fully open sourced, but having a fully open sourced system isn’t enough these days. Almost 40 years ago Ken Thompson in his article “Reflections on trusting trust” showed us that software that can’t be built and verified by the community shouldn’t be trusted. Following his idea we would like to show how to build DynFi Firewall step-by-step. This is exactly the same process used in the release process of the software.

Overview

The DynFi Firewall uses standard FreeBSD build mechanisms. What is innovative however is that it also uses a package base which isn’t so popular yet. In case of the ports the firewall uses poudriere with an overlay for building. Overlays are also a new technique which allows to merge multiple ports trees into a single one.
Thanks to these techniques we are able to keep all our changes in separate repositories and easily merge them with next quarterly ports branches.

##Prerequisite

Before we start the prerequisite is to install a couple tools required by the build system.
First one is poudriere. At the time of writing the article, the overlays are not yet in the release of poudriere available in FreeBSD. Because of that the easiest way is to fetch the main poudriere branch and install it from the official repo - https://github.com/freebsd/poudriere.

As well we also have to install a jq(1) which is a command-line JSON processor. # pkg install jq

The build scripts are prepared to build everything in the user directory. However there are some tools, like poudriere, which require root privileges.
Because of that we also require that the user has root access through sudo(8).

##Cloning repos

The firewall is built from couples of repositories. All source code is hosted publicly on GitHub.

The project is splitted into following repositories:

  • FreeBSD-base - its a FreeBSD repository with the custom changes used by the firewall
  • dynfi-overlay - it’s a ports overlay, this repository contains all additional or modified ports required by the Firewall
  • dynfi-build - it’s a set of building scripts used to build a DynFi Firewall

We will start by fetching the dynfi-builder. $ git clone https://github.com/DynFi/dynfi-build

The FBSD_TREE variable in common.subr allows us to point where the FreeBSD-base repo is located. By default the location is in the dynfi-build directory. Let’s pull it to that directory.

$ cd dynfi-build
$ git clone https://github.com/DynFi/FreeBSD-base freebsd

Poudriere

The build system is prepared to work in multiuser environments, or multi-poudriere instances.
Because of that all poudriere files are kept in a private user directories. To set up all necessary environment variables required by poudriere we prepared a poudriere.sh script. This script is a wrapper to a default poudriere instance with all settings required to build a project in the home directory.

First we have to choose a FreeBSD ports branch we want to use. Currently DynFi Firewall is built based on the 2021Q2 branch. We simply use poudriere.sh to fetch this branch.

$ sh poudriere.sh ports -c -p 2021Q2 -B 2021Q2
[00:00:00] Creating 2021Q2 fs at /usr/home/buildtest/dynfi-build/poudriere-base/ports/2021Q2... done
[00:00:00] Cloning the ports tree... done
$

The command above will fetch the 2021Q2 ports branch to poudriere under the ports name 2021Q2.

Next step is to create a port with the dynfi-overlay. We can use the same technique as in the previous exemple. In this case we will just tell poudriere not to use the official repository but the one hosted on GitHub.
The ports name used by the build system is dynfi-overlay, this can be changed in common.subr file under OVERLAY_PORTS variable.

$ sh poudriere.sh ports -c -p dynfi-overlay -m git+https -U ‘https://github.com/DynFi/dynfi-overlay‘
[00:00:00] Creating dynfi-overlay fs at https://github.com/DynFi/dynfi-overlay... done
[00:00:00] Cloning the ports tree... done
$ 

Signing

The DynFi Firewall uses signed packages. For this reason when building a system you have to also create signatures. Unfortunately this breaks a reproducible mechanism as the packages will have different signatures than the one you will see in official repositories - in feature we will work on providing a more robust way of verifying that.

The signing keys should be placed in the keys directory.
To create a singing key you can follow a method described in pkg-repo(8) man page which is:

$ openssl genrsa -out pkg-dff.key 2048
$ chmod 0400 pkg-dff.key
$ openssl rsa -in pkg-dff.key -out pkg-dff.pub -pubout

This step is always required however if you want to use the official DynFi repository you don’t have to modify anything more.
If you would like to configure our own pkg repository you have to modify the usr.sbin/pkg/DynFi-base.conf to point to our ports server and upload the signature to the share/DynFi/keys/pkg/trusted directory.
The file and the directory are in freebsd repo.

Building

When we pull all of the repositories and we have signing keys we can start building the Firewall. First we can start by building a DynFi World and Kernel. We can simply use a build_base.sh script.

$ sh build_base.sh 
Building world and kernel
[...]

After this first step, we are ready to build the required ports.
This can be done by build_packages.sh. This will build both the packages required for the install image as well as the packages required for the installer.

In upcoming features we can also try to separate those two. We provide -c option to the script to indicate that this is a clean build and everything should be rebuilded.

For the next build we can skip this option to speed up the process.

$ sh build_packages.sh -c
Building the poudriere jail

[00:00:00] Error: No such jail: dynfi-13-stable
[00:00:00] Creating dynfi-13-stable fs at /usr/home/buildtest/dynfi-build/poudriere-base/jails/dynfi-13-stable... done
[00:00:00] Checking out the sources with git+http...
[...]

Finally we can build an installer with a simple script build_installer.sh. New installers with vga and serial support will be built in the image directory.

$ sh build_installer.sh
[.../usr/home/buildtest/dynfi-build/image/dynfi_installer_serial_0.99.021-20211031-222857.iso:  1.519:1,  5.265 bits/byte, 34.19% saved, 672233472 in, 442410256 out.]
[...]  /usr/home/buildtest/dynfi-build/image/dynfi_installer_vga_0.99.021-20211031-222857.iso:  1.519:1,  5.265 bits/byte, 34.19% saved, 672233472 in, 442410256 out.

When this step is done we can use new iso images to install the DynFi firewall.

If we have setup the ports server we can upload them using the build_sync.sh script. This script will upload everything to the ports server.
Just remember to adjust the IP server in the common.subr file under the PUBLIC_SRV variable.

Conclusion

DynFi Firewall is a modern firewall with a simple building mechanism. Mechanism uses unique methods like overlays or package bases.
Besides using those uniqueness mechanisms the whole process is wrapped up in a couple of simple to understand scripts.

If you like this article, please try to buy your devices from our e-shop ;-) This will allow the project to smoothly grow and provide you with more cutting edge features.

Deploying DynFi Managers on Docker
 
DynFi Manager upgrade 22.0.0
Need experts to secure your networks?

Discover our managed services

Related Articles