Compiling a custom FreeBSD kernel with Packet Filtering (PF) and Alternate Queuing (ALTQ)

Phil PhillipsPrincipal Engineer
Execution-focused Full Stack Developer and DevOps Engineer with over 10 years experience in all facets of the software development lifecycle

FreeBSD on EC2

FreeBSD is a robust Unix-like operating system that has been around for many years. FreeBSD is available on Amazon EC2 through Amazon Machine Images (AMIs) provided by FreeBSD developer and security officer Colin Percival. Percival’s list of AMIs for multiple versions of FreeBSD and Amazon regions can be found here. The AMIs come installed with the GENERIC kernel, plus options to enable XEN support (XEN support allows FreeBSD to run on EC2).

However, the GENERIC kernel does not include support for PF (Packet Filter) with Alternative Queuing (ALTQ).  PF is the packet filtering system ported from OpenBSD.  It provides a system for filtering, normalizing, and conditioning TCP/IP traffic.  PF is also capable of doing Network Address Translation (NAT).  It’s an alternative to using IPFW or IPFILTER in FreeBSD.  ALTQ provides Quality of Service (QoS) mechanisms, such as the capability for bandwidth control and packet prioritization.  This article will explain how to configure, build, and install a custom kernel with PF+ALTQ built-in.  

Note that this article focuses on FreeBSD on EC2. While you should be able to follow these steps for other architectures, keep in mind that you may have to tweak a few things. For example, if you see references to ‘amd64’, you may have to alter commands to fit your own architecture. 

Update FreeBSD Source

The FreeBSD EC2 AMIs come with the FreeBSD source already installed under /usr/src. You will want to make sure that you’re up to date with security patches. We will be updating the system against FreeBSD's RELEASE branch. The RELEASE branch is a stable branch of FreeBSD that recieves crictical security updates.

To update your system, run the following as root: 

freebsd-update fetch install

Open in new window


This will bring your system up-to-date with the current RELEASE branch for your FreeBSD OS version. 

Create Configuration File

cd to /usr/src/sys/amd64/conf.  Create a new file called "CUSTOM" using your favorite command line editor with the following contents: 

include GENERIC
                      ident CUSTOM
                      # PF
                      device pf
                      device pflog
                      device pfsync
                      # ALTQ for PF
                      options         ALTQ
                      options         ALTQ_CBQ        # Class-Based Queuing (CBQ)
                      options         ALTQ_RED        # Random Early Detection (RED)
                      options         ALTQ_RIO        # RED In/Out
                      options         ALTQ_HFSC       # Hierarchical Packet Scheduler (HFSC)
                      options         ALTQ_PRIQ       # Priority Queueing (PRIQ)

Open in new window

This configuration basically includes everything from the GENERIC kernel, plus all of the devices and options needed for adding in PF and ALTQ. The "ident" tag allows us to give our kernel a custom name. If you want to name your kernel something else, you can replace CUSTOM with whatever you want -- just make sure to change the filename as well.

Build and Install Kernel

We’re now ready to build and install our custom kernel.  Under your /usr/src directory, run the following:


Open in new window


If you named your kernel something other than "CUSTOM", you will need to modify the command accordingly. It will take a while to build and install the kernel. The amount of time it takes depends on the horsepower of your instance. For reference, on an m3.large EC2 instance (2 virtual CPUs - Intel Xeon E5-2670 v2 Processors) with SSD-backed storage, the whole process took about 25 minutes.  Once the process is done, reboot your system:

shutdown -r now

Open in new window


Your system should now come up with your custom kernel.  You can verify this by running the following:  uname -i

The output should be something like:

[you@ec2 ~]$ uname -i

Open in new window


Use PF!

Your FreeBSD instance now has the full feature-set of PF and ALTQ available to you. The FreeBSD PF Documention page provides everything you need to get going with PF.  Some basics for getting it going:
1. Add the following to /etc/rc.conf:

Open in new window

2. Create /etc/pf.conf with your desired firewall rules.

3. Start the PF Services:
service pf start
                      service pflog start

Open in new window

Phil PhillipsPrincipal Engineer
Execution-focused Full Stack Developer and DevOps Engineer with over 10 years experience in all facets of the software development lifecycle

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.