pfSense Firewall Config: My Settings with Screenshots – Part 2
Let’s pick up right where Part 1 left off: pfSense Firewall Appliance Unboxing. This isn’t a quick-start guide. It’s my logbook from weeks of fine-tuning pfSense. Weeks, not years, so follow along and let’s learn and improve our pfSense configs together. In this article, I share my pfSense setup: network interfaces, firewall rules, pfBlockerNG, Suricata, the works. Basically, this is a dump of my journey in finding the best pfSense settings that work for me.
It’s my first time using pfSense, but I’ve managed various firewalls on Linux servers over the years. By sharing my config, I hope to welcome corrections, suggestions, and to help readers who are just getting started with pfSense.
The main goal here that we configure a secure pfSense firewall setup that survives ISP hiccups while providing added visibility into what’s going in and out of our home lab, home office, or small business networks. You know, peace of mind, all while being interesting!
pfSense Hardware & Prep
Photo of my current home lab. A work in progress.
If you haven’t settled on a firewall appliance yet, check out my unboxing write-up first (Part 1): Intel N100 CPU, 82599ES 10G SFP+ NIC, and i226-V 2.5G ports give you plenty of headroom while keeping power under 15W at idle. Note that some links below point to Amazon, where I earn a small amount on qualifying purchases, while other links direct you to manufacturer or product pages and other related resources that I’ve found useful during my pfSense firewall setup.
Choosing pfSense hardware
There are a host of hardware options available. I’ve filtered some of the best pfSense hardware options, that you can currently find on Amazon, as well as eBay.
RAM is cheap, around $15 to $20; start with at least 4 GB if you intend to run Suricata and pfBlockerNG concurrently. Then drop in a 128 GB NVMe for $20 for fast storage.
In my case, I’m using a 256 GB TEAMGROUP MP33 that I purchased back in 2022. Full parts list and thermals are in the unboxing post: My $300 pfSense Firewall Appliance – Part 1: Unboxing.
10G Uplink Options: Cat6, Fiber or DAC?
For connecting the 10G SFP+ port from my pfSense box to my TP-Link SG2210XMP-M2 switch, I went with a pair of 10GTEK 10GBase-SR SFP+ LC Transceivers and a 7 inch OM4 Fiber LC to LC cable. My main ISP uses not one, but two devices for internet connection: their Fiber ONT device and a modem-router device. I managed to delete the router, and I’m now waiting on an ONT stick in order to direct-connect the fiber to my pfSense box.
Here’s a comparison of your options for connecting via SFP+:
- Plain CAT 6a, plug and play 10GBase-T modules convenient, but dissipate up to 5 watts, so they run pretty hot. Keep the hop under 15 meters, or you’ll pay in heat as you get closer to 30 meters.
- Passive DAC (Direct Attach Copper) twin-ax is the cheapest way to connect a 10 Gb link inside the rack (up to ~7 m). It’s essentially two SFP+ ends bonded by copper; no optics, <0.5 W, not much heat generated.
- Fiber (LC multimode, 10 G SR optics) breezes past 30 m connections, laughs at EMI (Electromagnetic Interference) and lowest power at ~ 1 W. Two SR modules plus a short OM4 patch cable usually cost less than a pair of RJ-45 10GBase-T transceivers.
Type | 10GBASE-T SFP+ (RJ-45) | Passive DAC SFP+ | Fiber SFP+ (SR) |
---|---|---|---|
Max Distance | ≤ 30 m (Short RJ-45 runs) | ≤ 7 m (Intra-rack) | 300 m (Long or EMI-prone runs) |
Power Draw | 2 to 5 W | < 0.5 W | ~ 1 W |
Heat | Moderate (needs airflow) | Minimal | Low |
Cost (pair) | Moderate | Lowest | Moderate |
EMI Immune? | No | No | Yes |
Recommended Model | H!Fiber 10Gb Transceiver | 10Gtek SFP+ DAC Twinax | 10GTEK 10GBase-SR |
Removing my ISP’s ONT (Optical Network Terminal)
Rest in peace, ISP router. An electricity leach @ ~20 watts.
As mentioned above, I was able to get rid of the ISP’s modem/router box and plug the RJ-45 cable from the ONT directly into my second SFP+ port on the pfSense firewall. I did this by spoofing the mac address of the ISP device and then cloning the PPPoE connection. The PPPoE config was not visible in the UI of the device, so I had to download the config using the UI’s backup feature and found everything needed in the exported text config file.
Hopefully, the GPON stick works so I can unplug this ONT and save ~10 watts.
The ONT is already set to pass-through mode, so it’s solely there to terminate the fiber. PfSense is already handling connecting to my ISP. Mainly, now, it’s just a waste of electricity and an additional failure point. But first, I’ll need a GPON stick. I just ordered one on eBay for $20 (while writing this they cancelled my order and said due to shipping and taxes I have to pay $35).
Please check your specific ISP requirements, but here’s an comparison of GPON SFP modules specific to my setup for ONT delete (sometimes called an “ONT-stick”, “mini-ONT” or “PON-stick”):
Model | Chipset | Connector | Notes |
---|---|---|---|
Sercomm FGS202 | Lantiq PEB98036 | SC/APC inside SFP shell | Same vendor as my FG1000R; already built to talk GPON OLTs with Sercomm profile. |
FS GPON-ONU-34-20BI | Broadcom B+ class | LC/UPC | Lets you spoof/clone LOID/SN via CLI; widely documented. |
Nokia G-010S-A / G-010S-P | Broadcom | SC/APC | Works on many Huawei/Calix OLTs after the ISP whitelists the module’s serial number. |
Ubiquiti UF-Instant | Realtek | LC/UPC | User-friendly web UI, but some OLTs reject non-Broadcom sticks. |
pfSense Installation
I’m not going into great detail. Because the installation process is pretty simple. However, I will include a few tips and comments.
BIOS and booting checklist
These were my settings for my n100 (fan disabled) pfSense install. The N100 is overkill for most setups. But it’s cheap, runs cool and very well proven with lots of online documentation, and discussions specific to pfSense:
- Secure Boot: disable it because it blocks the booting pfSense.
- Restore power on AC Power Loss: Set to ‘Power On’ so that pfSense will automatically boot when power is restored after a power loss.
- Fan profile: choose “Balanced” or “Off” for CPUs like the N100 which run really cool. Also see: N100 Fans Don’t Turn Off. If all else fails, you can unplug the fan.
- Boot delay: Still in system BIOS, don’t remove the default 3-second pause! Keeping this allows the hardware a little extra breathing room to fully initialize before pfSense begins probing interfaces. If you remove the BIOS boot 3-second delay, NICs sometimes aren’t 100% ready, kernel sees up/down flapping events, pfSense triggers package/service restarts, and it results in slower problematic startups. I experienced this first hand, so sharing.
- Reduce or remove pfSense boot delay: On the other hand, this IS safe! Use either the System → Advanced → System Tunables or manually create
/conf/loader.conf.local
with:autoboot_delay="-1"
to remove completely orautoboot_delay="1"
to reduce delay to 1 second. - With these settings, rebooting takes ~ 60 seconds, even with IDS/IPS packages installed.
Grab a clean image
- Head to Downloads ▸ pfSense CE and pull the latest amd64 ISO.
- Verify it before you touch a USB key:
sha256sum pfSense-CE-*.iso
Compare against the SHA-256 string on the download page; mismatches mean re-download.
Write the installer to a USB
I used balenaEtcher.
You can also use Linux CLI:
sudo dd if=pfSense-CE-*.iso of=/dev/sdX bs=1M status=progress && sync
Replace /dev/sdX
with your flash-drive path.
On macOS use balenaEtcher or sudo diskutil unmountDisk /dev/diskN
then dd
.
Windows users: balenaEtcher or Rufus.
Boot and run the pfSense installer
- Insert the USB, hit your board’s boot menu, choose the USB device. (Walkthrough)
- At the pfSense splash, accept defaults → Install → keymap (your language)→ filesystem *ZFS**.
- Reboot when prompted; remove the stick.
Complete the first-boot wizard
I like to use Cloudflare or Quad9.
I use time.cloudflare.com
and time.google.com
.
Use defaults for DHCP. Keep everything else default for now.
Set LAN IP address to your preference. Click next, then set password.
Finally, click reload and then continue from there.
Now open https://192.168.1.1
(or the IP you assigned), accept the self-signed cert warning, then sign in. That’s it, let’s go!
Ten Things to Change Right After pfSense Install
1 — Secure the WebGUI straight away
Straight after the installation, head to System → Advanced → Admin Access. Switch the webConfigurator to HTTPS and, in the TCP port box, use a non-standard port anything high and random works.
That single change does two things: it encrypts every login session and keeps casual scanners from spotting your firewall on the popular default 443 port.
2 — Leave SSH turned off (or harden it if you really must switch on)
Still on System → Advanced → Admin Access, scroll down to Secure Shell.
If you have a good reason to check Enable Secure Shell, set SSHD Key Only to Require both Password and Public Key, and choose a non-standard port instead of the default port 22. That gives you an encrypted back-door for maintenance while sheltering the daemon from the endless credential-stuffing noise that targets port 22. Ideally, keep SSH disabled!
3 — Tighten Login Protection
Yet aagain,on the System → Advanced → Admin Access page, scroll to Login Protection and harden the values. Shown in the screenshot above are my recommended settings: threshold 10, block-time 3600 seconds, detection window 86400 seconds, with at least your internal subnets in the pass-list. These settings lock out an IP for an hour after a bad login attempt, while letting trusted LAN ranges bypass the check.
Of course, like my setup, your pfSense won’t be available via any public ports by default. However, it’s still a best practice to have these settings in place, in the event that pfSense gets unknowingly exposed.
4 — Disable the built-in “admin” user and create your own
Under System → User Manager → Users, click Add to create a new account with a non-obvious username, a strong password, membership in the admins group, and no shell access.
Next, edit the default admin user, tick This user cannot login, and save. From now on, you’ll manage the firewall through that new user only. If you ever need console work, briefly re-enable the original admin account, finish your task, and disable it again.
5 — Switch the DHCP backend to Kea early on
In System → Advanced → Networking, make sure Kea DHCP is selected (screenshot above). It’s the new default and will eventually replace ISC entirely—so it’s better to make the switch now while your setup is still fresh. Kea handles things differently under the hood, so making the change early avoids conversion headaches down the road.
Note: since upgrading to pfSense 2.8.0 while writing this article, it looks like Kea is the new default on fresh installs.
6 — Turn on hardware crypto and choose the right thermal sensor
In System → Advanced → Miscellaneous set Cryptographic Hardware to AES-NI CPU-based Acceleration. Modern Intel and AMD CPUs include AES instructions that pfSense can tap for IPsec, OpenVPN, WireGuard and even GUI HTTPS—handing off the heavy math, cutting VPN latency and freeing the cores for everything else. Check if your CPU supports this first.
Just below that, pick the thermal-sensor driver that matches your processor (for example Intel Core on-die, AMD Zen, etc.). With the correct module loaded, the dashboard will now show real chip temperatures.
7 — Move /tmp and /var into RAM for speed on beefy boxes
If your pfSense box has 4 GB of RAM or more, tick Use RAM Disks on the System → Advanced → Miscellaneous page and size the /tmp and /var directories to match your usage (128 MiB is a safe starting point). PfBlockerNG and Suricata spin up large temporary files when pulling or reloading feeds. Keeping those in RAM rather than on a slower SSD or disk slashes I/O latency and makes rule-reloads and other pfSense related processing faster.
8 — Bump the local backup count well past the default
Right after install go to Diagnostics → Backup & Restore → Config History and change Backup Count from the default 30 to something much larger, like 300, 500, even 1 000! During the first days you’ll add interfaces, aliases, firewall rules, packages, tweak settings, delete and redo things, dozens of saves per hour.
With only 30 backups kept, those rapid-fire edits can push earlier restore points off the list in just minutes. A setting of 1000 kept me from losing work twice. Sometimes it can take days or more before you realize your config changes created issues. As such, more history means that you can roll back to a previous working backup instead of guessing which tweak(s) introduced problems. Thank me later!
9 — Turn on encrypted Auto Config Backup for cloud backups
Follow that up in Services → Auto Configuration Backup (ACB): tick Enable automatic configuration backups, set a long Encryption Password, and keep the generated Device Key somewhere safe. Every saved change is now shipped, encrypted, to Netgate’s cloud. If the firewall’s storage dies or some other issue preventing local restore, you can reinstall, enter the key, and your exact config comes back!
Together, an expanded local history and an off-site ACB for disaster recovery gives you added protection and peace of mind.
10. Install Service Watchdog to auto-restart key daemons
System → Package Manager → Available Packages → service_watchdog
Suricata, pfBlockerNG, Wireguard, and OpenVPN are all great, until one of them crashes at 3 a.m. Unbound stopped on my pfSense yesterday after I restarted Suricata and pfBlockerNG. The Watchdog package polls selected services every minute and restarts any that aren’t running. A tiny safety net that costs almost no resources but saves a midnight drive home (or office) to the rack.
With that, you’re now ready to dive into pfSense configuration! Let’s move on to the pfSense configuration settings.
pfSense System settings walkthrough
Let’s begin from left-to-right in the navigation bar at the top of the pfSense UI. Starting with the ‘system‘ menu. The first drop-down on the pfSense navigation bar. This is where you tell the firewall who it is, how it keeps time, which DNS servers it trusts, and how you, and only you, get through the admin door.
A couple of minutes in General Setup and Advanced locks the GUI behind HTTPS on a quiet port, routes all look-ups through a filtered resolver, and enables the CPU’s AES instructions so every future VPN or TLS handshake runs at full speed. Many of these essential settings we already covered in the previous section.
Moving on, the same menu also houses the day-to-day plumbing: extra packages, user accounts, and the gateway group that lets the box fail over ISPs without dropping a beat. Configure these early and every setting that follows—DHCP scopes, IDS/IPS, even the dashboard graphs, inherits a clean, trusted baseline. Below is an overview of my settings.
General Setup
- Hostname / domain:
hostname.hydn.dev
ties local services and to my personal namespace. - Timezone:
America/St_Kitts
keeps log time-stamps square with your location. - DNS servers: Quad9 primary/secondary
9.9.9.9 / 149.112.112.112
. Quad9 DNS blocks malware, phishing, spyware, and botnets. You can also use Cloudflare’s DNS. - NTP pool:
time.cloudflare.com
followed bytime.google.com
.
Advanced (System → Advanced)
- WebGUI hardening: GUI is HTTPS-only on non-standard port, autocomplete disabled and an alternate host list (
myaccountname.cloudflareaccess.com
) for Cloudflare Zero-Trust can front-end it while keeping WAN ports closed. - GUI certificate: Presented cert is GUI default a self-signed RSA created at install.
- SSH access: Disabled but when enabled is also on non-standard Port, key-only auth. SSHGuard blocks a source after x bad logins for x hours (tweak to your preference).
- Hardware tweaks: AES-NI crypto enabled, thermal set to Intel, and NAT reflection is pure-NAT.
SMTP notifications
System > Advanced > Notifications: The system is set up to send mail (notifications) using my Postmarkapp account on TLS with my unique token.
User Manager
- admin (uid 0) is the built-in root with shell access, login disabled.
- myusrname is the day-to-day admin account, member of admins but without a shell for extra safety.
Package Manager
My installed packages:
- pfBlockerNG-devel: IP blocking and DNS geo and content filtering with DNSBL.
- Suricata: IDS in IPS-inline mode on WANs, alert logs pruned after 14 days.
- Cron: A package to apply and maintain custom and recommended system patches.
- System_Patches: A package to apply and maintain custom and recommended system patches.
- Watchdog: Monitors for stopped services and restarts them.
Routing
- Gateways: Three dynamic gateways: WAN1_ISP_CW (fiber), WAN2_ISP_Cable (coax), and NORDVPN_VPNV4 (client).
- Gateway group “Multi_ISP”: sets WAN1 Tier-1, WAN2 Tier-2 with trigger down/packet-loss/latency, giving automatic fail-over while avoiding flaps during brief jitter.
- Default Gateway IPv4: points to the group; IPv6 disabled everywhere.
Network Interfaces config — Assignments, VLANs, and WAN links
Before any firewall rules or packages can do their job, the box needs a solid interface blueprint. Mine carves the network into clear-cut zones, each with its own Layer-3 IP space: an admin LAN on 192.168.11.0/24, a Windows LAN on 192.168.4.0/24, a Homelab LAN on 192.168.2.0/24, and an IoT/guest VLAN on 192.168.3.0/24. That separation lets stateful rules decide, down to the byte, who can talk to whom.
Physical layout follows function
Read more about this box: My $300 pfSense Firewall Appliance – Part 1: Unboxing
The 10G port ix1 carries both management (tag 1) and guest (tag 3) traffic to the 10G SFP+ port on my multigig switch, where eight 2.5 Gb ports fan out to my IoT hardware (with some unused for future expansion).
For internet, ix0 tags VLAN 20 for the fiber ISP’s PPPoE hand-off, while igc3 (ETH3) keeps a DHCP cable link as fail-over; pfSense lumps them into a Multi_ISP gateway group so latency or packet-loss flips routes automatically. A NordVPN tunnel shows up as ovpnc1, giving policy-based routing the same knobs as any WAN. This is handy for pushing only the IoT VLAN through a privacy exit without floating-rules.
From here, firewall policies, DHCP scopes, and IDS sensors slot into place:
Interface Assignments | Physical port | Type | IPv4 / Mask | Role |
---|---|---|---|---|
WAN1_FIBER (ix0 fiber) | pppoe0 → ix0.20 | PPPoE on VLAN 20 | Dynamic | Primary ISP (fiber) |
WAN2_Coax | igc3 | DHCP | Dynamic | Backup ISP (cable) |
VPN_NORD | ovpnc1 | OpenVPN client | — | NordVPN for VLAN3 |
L0_ADM | igc0 | Static IPv4 | 192.168.11.1/24 | Admin-only LAN |
L1_WIN | igc1 | Static IPv4 | 192.168.4.1/24 | Windows devices |
L2_LAB | igc2 | Static IPv4 | 192.168.2.1/24 | Home-lab devices |
VLAN1 (ix1 fiber sw uplink) | ix1.1 (tag 1) | Static IPv4 | 192.168.1.1/24 | Wired & Wi-Fi LAN |
VLAN3 (ix1 fiber sw uplink) | ix1.3 (tag 3) | Static IPv4 | 192.168.3.1/24 | Guest Wi-Fi / IoT devices |
Why this layout works for me
- Clear separation – each security zone (admin, lab, IoT/guest) has its own Layer-3 interface, so stateful rules can isolate or allow traffic precisely where I need.
- 10 Gb trunk –
ix1
carries both management VLAN 1 and guest VLAN 3 to my 10 GB switch, which has eight 2.5 GB LAN ports. - Dual-WAN resilience – fiber ISP (Tier 1) and cable ISP (Tier 2) are fed into a gateway group Multi_ISP that fails over on loss/latency; pfSense sets that group as the IPv4 default route.
- Clean PPPoE – the FTTH provider requires VLAN 20 in order to replace their modem device; tagging happens on
ix0.20
, then PPPoE createspppoe0
. - VPN as an interface – having NordVPN on
ovpnc1
lets me make policy-routing and NAT rules just like any other WAN, instead of having to use floating rules.
Firewall — Aliases, NAT, pfBlockerNG, Rules
The Firewall menu is where the design you mapped out in Interfaces turns into concrete, enforceable policies. I started by building a list of aliases—IP, network and port groups. With names such as Ring_Cams
or Web_TCP
, a single edit later can ripple through dozens of rules without hunting for scattered addresses.
Because a Cloudflare Tunnel fronts the primary WAN for the hydn.dev website, Checkmk, the Unifi controller, the network switch, remote printing and other services, inbound NAT is almost nonexistent; the box handles only a pair of port-forwards on the backup WAN2, restricted to specific allowed ports and IPs.
Let’s go over some of the config.
Aliases – the Lego-bricks for firewall rules
PfSense lets you build reusable address/port groups (“aliases”) so rules stay readable and easier to manage. My config holds several aliases spanning IPs, Ports, URLs, and networks:
Type | Examples | Purpose |
---|---|---|
Port/IPs | Windows , Web browsing , Security/IoT bundles such as Ring , Unifi doorbell, cams, APs, controller. |
Bundle many TCP/UDP service ports. |
Network / Host | RFC1918 networks , DoT IPs/ports , Checkmk |
Reference entire subnets or key hosts without hard-coding individual IPs. |
URL Table | Pingdom Probes IPs , Cloudflare IPv4 ranges , pfBlockerNG auto-generated lists |
Pull external TXT/IP lists on a schedule (e.g. Pingdom probe list, threat feeds). |
Adding and organizing Aliases pays dividends later when you need to make changes.
NAT (Network Address Translation)
As mentioned I’m making use of Cloudflare Tunnels via Zero trust. So my front facing ISP WAN1 has all incoming ports closed and firewall rules set to drop all unsolicited incoming traffic. Check/test your with routersecurity.org.
Port-forward snapshot
On WAN2, Two port forwarding rules expose Checkmk server which runs on a VM on Win 11 ThinkCentre-M75 box (192.168.4.109) to the alias cmk_hosts
(access restricted to this IP list):
pfBlockerNG – layered threat-feed defense
pfBlockerNG is used to pull CINS Army, DShield, and Emerging-Threats intopfB_PRI1_v4
and AbuseIPDB feeds into pfB_AbuseIPdb_v4
on a 12-hour refresh.
Note: The default pfBlockerNG selected lists include a couple of deprecated and broken links, so feel free to use and improve on my list below:
Feed/URL | Description | Approx. unique IPs |
---|---|---|
CINS Army “CI Bad Guys” | High-confidence attacker list built from a global network of honeypots; refreshed ~12-hourly. | ≈ 15000 |
DShield Top Attackers (7-day aggregate) |
Rolling set of the most aggressive /24 subnets seen scanning the Internet in the last three days; FireHOL keeps seven days of history. | ≈ 10000 (37 /24 nets) |
Emerging Threats “Block IPs” | Composite feed (Spamhaus DROP + DShield + Abuse.ch); updated twice daily for broad, catch-all blocking. | ≈ 15 million |
There is about 65% overlap between DShield and ET. Still, I kept both feeds because pfBlockerNG deduplicates IPs before they ever reach the firewall table, so the overlap costs no extra states, no extra memory, and no extra processing time. Whereas, what I’d lose by dropping one list is the 35% that doesn’t overlap. I’ll continue to compare the two and may replace if I find better. Recommendations are welcome.
pfBlockerNG is set to automatically inject drop rules on WAN2, Windows LAN and the Guest/IoT VLAN interfaces, so that any packets matching the above feeds are dropped even before the default pfSense firewall rules run. I tried my best to focus on feeds that are well-respected, actively updated, and have low false-positives.
For DNSBL, I’m not using GeoIP. I did briefly, but I think it’s overkill and prone to false positives depending on the countries blocked. If you do use it, I wouldn’t recommend mass country blocking. It’s easy to get carried away! I’ve seen admins just block Russia and China. Even then, maybe just block inbound or outbound, not both. It really varies depending on each network. For me, I decided to roll back GeoIP blocks.
In any case, for pfBlockerNG’s “DNSBL groups”, I’m using PhishingArmy which is a compilation of PhishTank, OpenPhish, Cert.pl, PhishFindR, Urlscan.io and Phishunt.io reports:
Firewall Rules
IPv6 traffic is globally blocked on all interfaces silently to reduce logs/noise. pfBlockerNG rules sit at the top and my custom rules follow. As an example, here are a few screenshots of my rules. Suggestions welcomed:
Services — DNS Resolver, DHCP and NTP
The Services menu is where the box acts like the nervous system of the network: handing out IP leases, resolving names, and keeping everything in sync. It’s here that we lean on three core daemons:
-
DNS Resolver (Unbound): for encrypted, policy-aware name look-ups.
-
DHCP Server (kea-dhcp4): to parcel out addresses and gateways.
-
NTP (ntpd): so logs and certificates all agree on the same timeline.
The goal is to keep each one as simple as possible while still gaining the speed of local caching, the convenience of per-VLAN pools, and the reliability of good time.
DNS Resolver (Unbound)
Unbound is running and bound to all interfaces for both listening and outgoing queries. You only need two DNS server entries (a pair), add a third DNS provider if worried about DNS outages, which are extremely rare for both Cloudflare and Quad9. Cloudflare offers lower latency than Quad9, while Quad9 offers better malware blocking and privacy.
Also, I enabled forward TLS upstream, to my preferred DoT endpoints so that all queries are TLS encrypted beyond pfSense in Services > DNS Resolver > General Settings:
Added dedicated “DoT” (DNS over TLS) allow rule (drop all other DNS traffic):
The result of these changes seen in the below screenshot when visiting the Cloudflare DNS debug/test page — https://one.one.one.one/help/:
Note, you must also set your DNS IPs AND hostnames in System > General Setup:
Find the hostname you need you use for Cloudflare or Quad9.
DHCP Server (kea-dhcp4)
Kea DHCP4 manages DHCP for the following pfSense interfaces:
Interface | DHCP Pool | Notes |
---|---|---|
Admin (LAN 0) | 192.168.11.100 – 192.168.11.150 | Management devices |
Windows (LAN 1) | 192.168.4.100 – 192.168.4.150 | Desktops / VMs |
Home Lab (LAN 2) | 192.168.2.150 – 192.168.2.200 | Home-lab VLAN-aware (ex. Unifi Controller) |
VLAN 1 (Trusted LAN + Wi-Fi) | 192.168.1.100 – 192.168.1.200 | 10 Gb back-bone (ix1) |
VLAN 3 (Guest Wi-FI SSID/IoT devices) | 192.168.3.20 – 192.168.3.200 | Guest Wi-Fi & cameras (ix1) |
My NTP settings
To ensure consistent timekeeping across, I’ve enabled pfSense’s built-in NTP server. It syncs against two trusted public time sources: time.cloudflare.com and time.google.com. Both known for their reliability and low jitter. Cloudflare is set as preferred.
Services — Suricata
With the core firewall rules and PFBlockerNG in place, it’s time to add Suricata as a second firewall security layer IDS/IPS. Another option is to SKIP adding PGBlockerNG if you prefer the IDS analytics of Suricata. Suricata also has IP reputation blocking as well as additional feeds that you can enable.
For Suricate, I skipped WAN1_FIBER where firewall rules blocks all incoming traffic because all ports are set to closed, and instead focused inline IPS on WAN2_Coax where a few ports are open.
I have Suricata also enabled on VLAN3 (Guest/IoT) and L1_WIN (for Windows devices) so I can monitor (IDS) traffic. Traffic now flows through three security layers—pfBlockerNG first, Suricata next, and finally, my pfSense firewall rules:
• IP & GeoIP feeds/tables
• DNSBL filters (DNS query level, not packet level)
• Signature matching (ETOpen, Snort GPLv2 rules)
• Automatic SID management (drops, disabled rules)
• Drop all IPv6 traffic
• Interface Pass / Drop / Reject rules
• Drop all remaining IPv4 packets.
Suricata — Global Settings & Rule Downloads
In the Suricata Global Settings page, you’ll see a handful of rule categories ready to download. I’ve opted to enable the ETOpen Emerging Threats rules. This gives a solid, community-maintained baseline without the complexity or cost of ETPro or paid Snort feeds.
Just below it, I’ve also enabled the Snort GPLv2 Community ruleset (the Talos-certified subset), which rounds out coverage for the most common threat signatures. To keep the interface clean, the Hide deprecated rules categories option is checked, so you’re not distracted by legacy rule groups you’ll never use.
Finally, the update interval is set to “1 DAY” with a randomized start minute. This ensures you get fresh rules every 24 hours without hammering the download servers.
Suricata Enabled Interfaces
In the Suricata Interfaces overview you can see three Suricata instances that use IDS on: WAN2_Coax (igc3), VLAN3 (ix1.3) and L1_WIN (igc1). All configured for HS (High-speed) pattern matching (more efficient CPU performance). WAN2 is also running IPS (intrusion prevention system) Inline IPS mode, so threats are automatically blocked, while VLAN3 and L1_WIN remain in alert-only mode with blocking disabled until I’ve had more time to understand their traffic profiles better in the coming weeks. I’ve been learning so much, patience is key!
Suricate Per-Interface Settings (WAN2_COAX)
In the WAN2_COAX Suricata interface settings, I’ve enabled Suricata inspection but otherwise left most extras turned off to keep resource use and log noise to a minimum. HTTP logging remains on using the regular file format, in append mode with extended HTTP info. This is so that I can see requests without generating massive dumps.
Down in Alert & Block Settings, the “Block Offenders” box is checked. Any host that trips a signature will be dropped immediately.
When running Suricata in inline IPS mode, it’s recommended to set the Run Mode to Workers as it allows Suricata to run with multiple dedicated worker threads that process packets in parallel and efficiently. This mode uses zero-copy packet handling, which reduces CPU overhead and latency by not copying packets between kernel and user space.
It also allows for proper CPU affinity, where each worker thread can be pinned to a separate CPU core, for maximum performance and throughput for inline packet inspection and dropping. This is critical for inline IPS as it must process and potentially drop packets in real time without introducing bottlenecks or packet loss. So, setting the Run Mode to Workers ensures Suricata can perform well and be reliable when blocking traffic inline. Source: docs.suricata.io, /r/pfSense/ and forums I’ve been reading.
Suricata Rule Categories
In the Categories tab, Resolve Flowbits is enabled (I believe this is default). Enabled are Talos-certified Snort GPLv2 Community Rules up top (checked for insight into common exploits). Below that, you see three columns of rule sets: the Default Rules, ET Open Emerging-Threats rules and Snort rules. The latter, I didn’t enable.
Suricata SID Management
In the SID Management section, allows the system to enable, disable, or drop signatures based on predefined lists, avoiding the need to manually adjust rules after every update.
My configuration includes a list called WAN-Disabled that filters out noisy or redundant signatures on the WAN2 interface. Another list is Drops, this contains high-confidence signatures that should immediately trigger packet drops. WAN-Enabled is blank, have not had the need to use that yet. For internal networks like VLAN3 and L1_WIN, I’m using a separate LAN-Disabled list to hide the flood of low-risk alerts from logs during this learning phase as I observe traffic behavior.
Drop and reject actions are not configured on these LAN interfaces, since they are still in alert-only mode while I monitor traffic. I will continue to update this blog post as I keep making changes, learn more and have more to share.
Why Suricata (or Snort) Matters!
Running Suricata inline on my fail-over WAN2 catches common bad traffic in the act by actively inspecting and blocking malicious packets before they hit my internal network. This inline IPS deployment allows Suricata to inspect network traffic in real time, using its multithreaded architecture to handle high volumes without becoming a bottleneck.
On my VLAN3 (IoT devices and guest Wi-Fi) I run Suricata in alert-only IDS mode, which gives me visibility into network activity and potential threats without disrupting devices that may be sensitive to blocking actions. This staged approach allows me to tune and manage Suricata’s Signature IDs (SIDs) to filter out false positives and make sure legitimate traffic isn’t blocked. Of course, VLAN3 as mentioned earlier, is isolated—blocked from accessing any of the other LANs (private networks).
Once I’m confident the ruleset is properly filtered, I can enable full blocking in inline IPS mode and Suricata will automatically drop or reject malicious traffic without blocking valid traffic.
Suricata AND Snort, both being open source, having extensive protocol parsing and an active community, are flexible and powerful tools for network security, providing visibility and control over evolving threats.
VPN settings — OpenVPN
OpenVPN client (NordVPN)
My only VPN entry is a site-to-Internet client that dials NordVPN. It connects to the Multi_ISP gateway, meaning when even WAN1 is down or experiencing packet loss, it will automatically reconnect to NordVPN using WAN2.
- Interface & transport It rides the Multi_ISP gateway group over UDP in a TUN device, so pfSense can fail over from fiber to cable without dropping the tunnel.
- TLS profile The client runs in p2p-tls mode with its CA/cert pair and full TLS-key-based server verification (
remote-cert-tls server
). - Keep-alive
keepalive 10 60
means pfSense sends a ping every ten seconds and restarts the session if nothing returns within a minute. - Route handling
route-no-exec yes
blocks OpenVPN from touching the system routing table; instead, it steers traffic with policy-routing firewall rules, keeping default WAN traffic on your faster ISP.
Status menu
Having finished every menu that actually stores settings, the Status menu is where you simply view and monitor the firewall. Aside from a handful of log-rotation options and graph layouts, these pages contain mostly read-only information that lets you confirm if the tweaks you just made are working or identify any trouble.
Status menu cheat sheet
pfSense Status menu | What you’ll look for | Typical use-case |
---|---|---|
Dashboard | Widgets: gateways, services, traffic, alerts | Quick “all-green?” morning glance |
Gateways | dpinger latency / loss icons | Confirm or debug WAN fail-over |
Interfaces | Link speed, errors, IP/MAC | Spot a NIC that dropped to 100 Mb/s |
Monitoring | RRD graphs: bandwidth, RTT, states | Compare week-long trends to an outage |
Traffic Graph | 1-second live bps per interface | Verify a backup saturates WAN2 |
Services | Daemon up/down toggles | Restart Unbound without SSH |
System Logs | Tail by tab: firewall, DHCP, etc. | Watch drops while testing a rule |
DNS Resolver | Cache hits, forwarder status | Verify DoT is healthy |
NTP | Peer offset & jitter | Ensure time sync for VPN/IPsec |
OpenVPN | Client/server byte counters | Confirm NordVPN tunnel is up |
IPsec | Phase-1/2 health | Check site-to-site tunnels (if used) |
Queues | Traffic-shaper stats | See which class is hitting its cap |
Captive Portal | Active sessions | Audit guest logins (if portal used) |
CARP (failover) | VIP state: master/backup | Verify HA pair roles |
DHCP Leases | IP ↔ MAC ↔ hostname list | Find what IP a device pulled |
DHCPv6 Leases | IPv6 lease table | Same idea for v6 (if enabled) |
UPnP & NAT-PMP | Current port mappings | Review or clear auto-opened ports |
Status > Traffic Graph
A one-minute, per-interface chart. Play around with it. Great to monitor real-time traffic on your interfaces.
Status > System Logs > Firewall > Summary View
pfSense crunches the last 10,000 log entries into pie charts. The first shows the split between blocks, passes and rejects; the second breaks those actions down by interface. If I suddenly find 90% of blocks coming from WAN2 COAX, it’s a quick hint that the cable link is under scanning fire or a rule is mis-matching. Below this screenshot, it also breaks down events by protocols, IPs, and ports.
Status > Monitoring
RRD-backed line, bar, or area graphs for bandwidth, gateway quality, CPU load, and more. Tabs across the top (“WAN1-RxTx”, “VLAN-Guest”, “NordVPN-Uptime”) let you save custom views for instant access when you return. Pick Quality on the left axis to graph packet-loss and latency, or choose Traffic to watch seven-day throughput trends. Great for correlating a user’s “it was slow Tuesday night” report with an actual spike.
pfSense Diagnostics menu
The Diagnostics menu is your on-demand toolbox for low-level troubleshooting: everything from ARP tables to live pf state viewers, inline shell and file editors, packet captures, and quick network probes. Most entries simply scan the running system, while some more advanced options you can interact with the system as root, so use them carefully!
A couple of settings do persist, like forcing Syslog into reverse order, or grabbing backups preferences under Backup & Restore, but otherwise these pages let you verify runtime health, debug issues without SSH, and perform emergency tasks without rebooting.
Diagnostics menu cheat sheet
Below is a reference to the Diagnostics menu options, what each one does, and a few notes to keep in mind while using them:
pfSense Diagnostics menu | What it’s for / does | Notes / gotchas |
---|---|---|
ARP Table | Show MAC ↔ IP neighbours on IPv4 networks | Clears on reboot; useful for spotting rogue hosts |
Authentication | Test LDAP, RADIUS or local-user login | Great sanity-check before enabling GUI SSO |
Backup & Restore | Download / upload config.xml and RRD data | Safest place to grab a manual backup |
Command Prompt | Run shell or PHP commands in browser | Executes using root user |
DNS Lookup | GUI wrapper for dig |
Perfect for verifying DoT / forwarder changes |
Edit File | Inline editor for any file on disk | Put custom scripts in /conf to survive upgrades |
Factory Defaults | Erase config and reboot to stock state | Nuke button—always back up first |
Halt System | Graceful shutdown | Unmounts ZFS cleanly |
Limiter Info | Display ALTQ/HFSC limiters | Empty when no traffic-shaper is configured |
NDP Table | IPv6 neighbour cache (ARP for IPv6) | Often empty if IPv6 is disabled or blocked |
Packet Capture | Browser front-end for tcpdump |
Stores capture in RAM until you download |
pfInfo | Quick summary of loaded pf rules & counters | Great “is this rule matching?” sanity check |
pfTop | Real-time state viewer (top-like) | Filter by interface, rule number, address, etc. |
Ping | ICMP reachability test | Choose source-interface to test Multi-WAN paths |
Reboot | Warm restart of firewall | Graceful—waits for services |
Routes | Show routing table | Validate policy-routing or static routes |
S.M.A.R.T. Status | Drive health (smartctl ) |
Visible only if smartmontools is installed |
Sockets | List open TCP/UDP sockets (sockstat ) |
Filter by PID when hunting suspicious listeners |
States | Live list of all pf states | Search by IP to debug NAT / asymmetric flows |
States Summary | Counts of states per rule / interface | Quick view of which rule is hottest |
System Activity | CPU / RAM viewer (top -SHaz ) |
Toggle threads to spot runaway PHP workers |
Tables | View / flush individual pf tables | Essential for pfBlockerNG testing |
Test Port | TCP connect test to remote host:port | Great for quick “is this service reachable?” checks |
Traceroute | Hop-by-hop path discovery | Source-interface option mirrors Ping/Test Port |
Bringing it all together with the Dashboard!
Now that everything has been configured, the last step is to arrange the Dashboard so a single glance answers the daily “is it healthy?” question. The screenshot above shows my layout, stacked left-to-right, top-to-bottom:
- Gateways sits at the very top-left, so WAN latency or a fail-over event jumps out immediately.
- Just below, Services Status turns red the moment Unbound, Suricata, pfBlockerNG, or OpenVPN stumbles.
- System Information I unchecked some options and kept version, uptime, DNS servers, temperature, system load average, CPU, and memory usage.
- Below that is Disks. It’s a lot more space than needed, but it was an NVMe I had sitting around since 2022. You can easily run pfSense for years on just 8 GB — 16 GB USB stick! These 128 GB NVMe’s, however, are cheap and fast!
- The center column starts with the rolling Firewall Logs, followed by Suricata Alerts and the pfBlockerNG widget—three panes that surface security events without diving into log files.
- Under those are Interfaces status, Interface Statistics and OpenVPN Client Interface Statistics (have to scroll).
- Lastly, the right column is all traffic: four live Traffic Graph widgets (Guest VLAN, VPN tunnel, Fiber WAN, Cable WAN) refresh every second, so bandwidth spikes are obvious.
- Oh, there’s also the Dynamic DNS Status confirm link errors are zero and DDNS has the correct IP. But since making use of Cloudflare Zero Trust Tunnels, I can remove that.
That order matches how I triage problems: WAN up? → services up? → any blocks or alerts? → bandwidth normal? With the dashboard tuned this way, you land on pfSense, skim, and move on—no extra clicks needed.
Conclusion
With that, your pfSense box is no longer a blank slate but a finely tuned gateway: hardened at the edges, segmented into clear security zones, armed with curated threat feeds, and topped off with real-time visibility and off-site backups.
What we’ve built here is a platform we can use to learn our network traffic and, over time, improve performance, reliability, and security. A network you can continue to refine as your needs change or new packages emerge.
Sorry about the fingerprints. I’ve resorted the entire rack but have not gotten to tidy up yet.
In this article, I tried to share tweaks, tips, and pitfalls from my own first few weeks with pfSense in the hope it accelerates your journey and my learning as you point out any ways I—or the guide—can get even better! In the photo above of my homelab 12u rack, I also wrote a guide to building out your own home lab. In this familiar format. If interested, take a read here: Home Lab Beginners guide (Hardware). I’m updating that article with the latest changes to hardware.
So for now, here’s to stable ISPs, encrypted tunnels, and many trouble-free hours behind a pfSense firewall that we will continue to understand increasingly with time.