December 12, 2018

How to Install and Use the PF Firewall on FreeBSD

FreeBSD Logo

PF or Packet Filter is the in-build firewall software of FreeBSD.
This firewall was originally developed for OpenBSD and has been ported to other operating systems like FreeBSD, NetBSD, Mac and Debian.
In this tutorial we will show you the PF installation and configuration steps on FreeBSD to keep your network secure.

Root access is required to edit the following files and to execute commands. Log in as root (su) or simply prepend sudo to all commands that require root privileges.

Install the PF Firewall

It is recommended to include PF into the kernel. For this you need to rebuild your kernel. Make sure you have the full src collection from sysinstall. The next steps will cover the process of building and installing a new FreeBSD kernel.

cd /usr/src/sys/amd64/conf
mkdir /root/kernels
cp GENERIC /root/kernels/NEWKERNEL
ln -s /root/kernels/NEWKERNEL

Open the kernel configuration file.

vi /root/kernels/NEWKERNEL

Edit this as follows:

device pf
device pflog
device pfsync
options         ALTQ
options         ALTQ_CBQ        # Class Bases 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 Queuing (PRIQ)
options         ALTQ_NOPCC      # Required for SMP build

Read more about the kernel configuration in the FreeBSD handbook.
Navigate to the /usr/src directory and bulid the new kernel with:

cd /usr/src
make buildkernel KERNCONF=NEWKERNEL
make installkernel KERNCONF=NEWKERNEL

Last check that there is UseDNS No and PermitRootLogin yes in the /etc/ssh/sshd_config.

Configure the PF firewall

First we will create the file /etc/blocked_ips.conf to manual maintain a list of IPs we do not trust. Create the new configuration file.

vi /etc/blocked_ips.conf

Add new IP addresses as follows:

Now we can start modifying the main configuration file /etc/pf.conf but first we need some information about our network, like the IP addresses and interface names. You can check this with the ifconfig command.


Open the PF configuration file.

vi /etc/pf.conf

Here is an example /etc/pf.conf for your convenience.

udp_services = "{ ntp }"
tcp_services = "{ smtp, ssh, http }"
table <blockedips> persist file "/etc/blocked_ips.conf"
set block-policy return
set skip on lo0
scrub in all
block all
block drop in log quick on $interface from <blockedips> to any
pass out on $interface inet from $local_host to any
pass in on $interface inet proto tcp from any to $local_host port $tcp_services
pass in on $interface inet proto udp from any to $local_host port $udp_services
pass in on $interface inet proto icmp from any to $local_host icmp-type echoreq

Include PF into the /etc/rc.conf to start the firewall on system start.

vi /etc/rc.conf

Read more about the PF configuration in the FreeBSD handbook.

Start the PF firewall

Please check your PF configuration in detail before enabling the firewall so that you do not block your own IP address. Check the syntax of the PF configuration file with:

pfctl -vnf /etc/pf.conf

Enable the PF firewall with:

pfctl -e

Disable the PF firewall with:

pfctl -d

Optionally as a final test you can reboot your system.


Speak Your Mind