LightAtom

pfctl: The Mac's Built-in Packet Filter

Beneath the app firewall, macOS ships pf, a powerful packet filter. pfctl controls it: block addresses and ports, redirect traffic, and test rules.

sudo pfctl -s info

Show whether pf is enabled, with counters.

advanced20 minNeeds: Administrator password, Comfort with the command line

When to use it

Use pf when the app firewall isn't enough: blocking specific IP addresses or ports for all apps, limiting a service to the local network, or port redirection. Mistakes can cut your Mac off the network, so test carefully and keep a way back.

Steps

  1. Check the status

    pf is usually disabled unless something (the app firewall, Internet Sharing, a VPN) enabled it.
    sudo pfctl -s info
  2. Look at Apple's configuration

    The default /etc/pf.conf only loads Apple's anchors. Don't edit it; system updates may replace it.
    cat /etc/pf.conf
  3. Write rules in your own anchor

    Create /etc/pf.anchors/blockexample with a rule, for example: block drop out quick to 203.0.113.0/24
    sudo nano /etc/pf.anchors/blockexample
  4. Test and load

    -n parses without loading; then load into the anchor and enable pf.
    sudo pfctl -n -f /etc/pf.anchors/blockexample && sudo pfctl -a blockexample -f /etc/pf.anchors/blockexample && sudo pfctl -E
  5. Remove the rules

    Flush the anchor's rules to undo.
    sudo pfctl -a blockexample -F rules

Output explained

The default /etc/pf.conf on macOS 15 (comments removed):

scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

Only Apple's anchors are loaded. Your rules in a separate anchor stay independent and are easy to remove.

pfctl -E prints a Token; pf stays enabled while any token is held. pfctl -X TOKEN releases yours.

Options and variations

FlagMeaningExample
-s info|rules|statesShow status, rules or the state tablesudo pfctl -s rules
-a ANCHORWork inside an anchorsudo pfctl -a blockexample -s rules
-f FILELoad rules from a filesudo pfctl -a blockexample -f rules.conf
-nParse only, don't loadsudo pfctl -n -f rules.conf
-E / -X TOKENEnable pf with a reference / release itsudo pfctl -E
-F rules|states|allFlush rules or statessudo pfctl -a blockexample -F rules

Common errors

ErrorCauseFix
pfctl: Use of -f option, could result in flushing of rules present in the main ruleset added by the system at startup.Loading into the main rulesetAlways load your rules into an anchor with -a.
Rules don't applypf isn't enabledRun sudo pfctl -E.
Rules gone after restartAnchors aren't loaded at bootAdd a launchd job to load them, or a load line in a custom config.

Do it in the app

Before blocking anything, LightAtom's connections view shows which addresses your apps actually use, so you block exactly what you mean to.

Frequently asked questions

Does macOS have pf?

Yes. macOS includes the pf packet filter from OpenBSD, controlled with pfctl. The app firewall in System Settings is a separate, simpler layer.

Is pf enabled by default on Mac?

pf is usually disabled until a feature such as Internet Sharing or certain VPNs enables it. Check with sudo pfctl -s info.

How do I block an IP address on a Mac?

Put a rule like block drop out quick to 203.0.113.10 in your own anchor file, load it with sudo pfctl -a NAME -f FILE, and enable pf with sudo pfctl -E.

LightAtom team

The people who build LightAtom, a network monitor for macOS.