Community Tutorials FreeBSD / OpenBSD How to Configure pf Firewall on FreeBSD and OpenBSD
How to Configure pf Firewall on FreeBSD and OpenBSD
FREEBSD / OPENBSD

How to Configure pf Firewall on FreeBSD and OpenBSD

SKYLINE Knowledge Base
Photo by Gabriel Heinzer on Unsplash

A field-tested, step-by-step guide. How to Configure pf Firewall on FreeBSD and OpenBSD — prerequisites, the actual commands, verification, and links to related FreeBSD / OpenBSD topics.

pf is the BSD-family packet filter — same name on FreeBSD and OpenBSD, same syntax (mostly), the cleanest firewall language on any OS. This guide writes a default-deny ruleset, allows SSH and HTTPS, drops scanner noise, and reloads safely.

Prerequisites

  • FreeBSD 13/14 or OpenBSD 7.x with root access.
  • A second SSH session held open while editing rules.

Step 1: Enable pf

FreeBSD — add to /etc/rc.conf:

pf_enable="YES"
pflog_enable="YES"
pf_rules="/etc/pf.conf"

OpenBSD already enables pf by default; just make sure pf=YES in /etc/rc.conf.local.

Step 2: Write /etc/pf.conf

The minimal sane production ruleset:

# /etc/pf.conf
ext_if = "vtnet0"          # change to your interface

# Tables for source-restricted access
table <admin>      const { 203.0.113.0/24 }    # office subnet
table <bruteforce> persist

# Defaults
set skip on lo
set block-policy drop
set loginterface $ext_if

# Antispoof, scrub
antispoof quick for $ext_if
scrub in all

# Default-deny inbound
block in  log all
pass  out all keep state

# Allow ICMP echo (ping)
pass in inet proto icmp icmp-type echoreq

# SSH — admin only, rate-limited
pass in on $ext_if proto tcp from <admin> to ($ext_if) port 22 \
  flags S/SA keep state \
  (max-src-conn 5, max-src-conn-rate 5/30, overload <bruteforce> flush global)

# Public HTTP / HTTPS
pass in on $ext_if proto tcp to ($ext_if) port { 80 443 } \
  flags S/SA keep state

# Drop anything else from the bruteforce table for an hour
block quick from <bruteforce>

Two patterns to learn here:

  • overload <table> — auto-add an offender to a table when they exceed a rate.
  • quick — short-circuit the rule list (pf is normally "last match wins").

Step 3: Test syntax and load

sudo pfctl -nf /etc/pf.conf       # parse-only — never skip
sudo pfctl -f  /etc/pf.conf       # load
sudo service pf reload            # FreeBSD

On OpenBSD use doas instead of sudo.

Step 4: Inspect state and logs

sudo pfctl -s rules            # active rules
sudo pfctl -s states           # connection state table
sudo pfctl -s info             # counters
sudo pfctl -t bruteforce -T show  # who's been banned

# pflog — pcap-format ring buffer
sudo tcpdump -n -i pflog0

Step 5: Add a port forward / NAT

For a host doing NAT for a private network:

int_if = "vtnet1"
nat on $ext_if inet from ($int_if:network) to any -> ($ext_if)

Port-forward to an internal host:

rdr pass on $ext_if proto tcp from any to ($ext_if) port 8443 \
  -> 10.0.10.50 port 443

Step 6: Clear bans and watch live

sudo pfctl -t bruteforce -T expire 3600     # expire entries older than 1h
sudo pfctl -t bruteforce -T flush           # nuke the table

# Live state addition
watch -n 2 'sudo pfctl -s info | head -20'

Verify

From outside the server:

nmap -Pn -p 22,80,443 your.host.sa
# Expect: 22 filtered (unless from <admin>), 80 + 443 open

Conclusion

pf's grammar is the most readable of any firewall — once you internalise block/pass, quick, tables, and overload, you can write a production ruleset on one page. Keep it in git, deploy via Ansible, never edit on a running box without pfctl -nf first.

Next steps

SKYLINE Engineering

@skyline

The engineering team at SKYLINE Industrial Solutions. We publish field-tested guides drawn from real KSA and GCC deployments.

See author profile
SKYLINE engineering services

Need this implemented for you?

Reading is free — building it right takes a team. SKYLINE engineers ship FreeBSD / OpenBSD for Aramco vendors, banks, hospitals and government agencies across Saudi Arabia. Talk to us before you start.

Aramco Approved Contractor ISO 9001 · ISO 27001 SAMA CSF aligned NCA ECC ready 247+ KSA clients

Comments

0 total · 0 threads
Be the first to leave a comment.