PFSENSE - PFCTL Basic Usage

From IT-Arts.net


Return to Wiki Index


Packet Filter architecture

pfctl is the userland control utility for PF (Packet Filter), the stateful firewall subsystem originating from OpenBSD and integrated into pfSense (FreeBSD-based). pfSense dynamically generates PF rules from its configuration and loads them into the kernel via pfctl.

PF operates using:

  • Stateful inspection
  • Rule evaluation from top to bottom
  • First matching rule (with quick exceptions)
  • Separate rule sets for filtering, NAT, redirection, and normalization
  • Anchors for modular rule management (heavily used by pfSense)

Rule evaluation flow

  • Packet enters interface
  • Normalization rules (scrub) applied
  • NAT / RDR processed
  • Filtering rules evaluated
  • State table checked/updated
  • Packet passed or blocked

Anchors and pfSense integration

pfSense uses anchors extensively to isolate automatically generated rules:

  • pfSense
  • pfSense/*
  • relayd

Anchors allow dynamic insertion and removal of rules without reloading the entire ruleset.

Example:

pfctl -a pfSense -sr

State table management

PF is a stateful firewall; every allowed connection is tracked.

Display states:

pfctl -s state

Kill a specific state:

pfctl -k 192.0.2.10 -k 198.51.100.20

Clear all states:

pfctl -Fs

Tables and dynamic address management

PF tables provide high-performance lookups for large address lists.

List tables:

pfctl -s Tables

Show table content:

pfctl -t bogons -T show

Add an IP to a table:

pfctl -t blocked_hosts -T add 203.0.113.45

Remove an IP:

pfctl -t blocked_hosts -T delete 203.0.113.45

NAT and redirection inspection

Display NAT rules:

pfctl -s nat

Display redirection rules:

pfctl -s rdr

Show all translation rules:

pfctl -s rules | grep nat

Rule counters and performance metrics

PF tracks packets and bytes per rule.

Show rules with counters:

pfctl -vvsr

Reset counters:

pfctl -z

This is critical for traffic analysis and policy validation.

Normalization and packet scrubbing

Scrub rules normalize packets to prevent evasion techniques:

  • MSS clamping
  • Fragment reassembly
  • Invalid flag dropping

Display scrub rules:

pfctl -s all | grep scrub

Security concepts

Stateful filtering

Only packets belonging to a valid state are allowed to pass, reducing attack surface.

Default deny policy

pfSense enforces an implicit block at the end of rule sets.

Verify block rules:

pfctl -sr | grep block

Antispoofing

PF can prevent IP spoofing on interfaces.

Example:

antispoof quick for em0

SYN flood protection

PF supports SYN proxies and connection rate limiting.

Example rule:

pass in proto tcp from any to any flags S/SA keep state (max-src-conn 100, max-src-conn-rate 50/10)

Table-based threat mitigation

Dynamic tables allow automatic blocking via IDS/IPS or scripts.

Example integration:

  • Snort / Suricata populating PF tables
  • Fail2ban-style blocking

Logging and diagnostics

PF logs packets to pflog interfaces.

Enable logging on a rule:

pass in log proto tcp from any to any port 22

View logs:

tcpdump -n -e -ttt -i pflog0

Troubleshooting

Rules not matching

  • Verify rule order
  • Check for quick rules
  • Inspect active rules instead of GUI configuration
pfctl -sr

NAT not working

  • Confirm NAT rules are loaded
  • Ensure outbound NAT mode is correct
  • Check rule auto-generation
pfctl -s nat

Traffic blocked unexpectedly

  • Inspect states
  • Check floating rules
  • Analyze logs in pflog
pfctl -s state

Performance degradation

  • Check state table size
  • Inspect table sizes
  • Reset counters and monitor
pfctl -si

Rules disappear after reload

pfSense regenerates rules automatically. Manual pfctl changes are ephemeral and overwritten on reload or reboot.