use `pf` to allow TCP traffic on specific port (from specific subnet)

So, I've read various posts about how to use both the Application Firewall (apf or socketfilterfw) and the Packet Filter (pf) at the same time. I thought this would be straightfoward since I'm not a pf newbie, but perhaps there is something to be learned about pf, or if not, about the combination under MacOS.

Essentially, I'm trying to add a pf rule that allows (TCP) traffic to a specific port (say 9999), from a specific subnet (say 192.168.5.0/24). Eventually on the Mac, the applciation in question will be a java process listening, hence my desire to limit the exposure over just allowing the Application Firewall to accept traffic from anywhere destined for java. In it's place, for experimentation, I'm using netcat (nc).

In System Preferences, I've of course enabled the application firewall, turned on ("Enable Stealth Mode"), and ensured that pf is enabled. I then loaded additional rules into pf, but I when the application is blocked (/usr/bin/nc in this case), it appears as if my pf rules are never used. A sample transcript to show my current state:

mac $ alias apf=/usr/libexec/ApplicationFirewall/socketfilterfw
mac $ apf --getglobalstate
Firewall is enabled. (State = 1)
mac $ apf --getstealthmode
Stealth mode enabled
mac $ apf --getappblocked /usr/bin/nc
Incoming connection to /usr/bin/nc is blocked
mac $ sudo pfctl -s info |& grep ^Status
Status: Enabled for 0 days 21:52:31           Debug: Urgent
mac $ sudo pfctl -s rules
pass in quick proto tcp from any to any port = 9999 flags S/SA keep state
scrub-anchor "com.apple/*" all fragment reassemble
anchor "com.apple/*" all
mac $

At this point it looks like I should be able to start nc listening and connect from another machine, as in:

mac $ nc -l 9999

linux $ nc -v -w 1 mac 9999
nc: connect to mac port 9999 (tcp) failed: Operation timed out

So, hypotheses and questions:

  • apf takes precedence over pf, in which case, (Q) how do I change or work around that?
  • I can't block the application in apf and allow some ports in via pf; see (Q) above.
  • pf rules are not really interpreted the same way on MacOS as, say, FreeBSD; then: (Q) why not?
  • I don't understand enough and I'm really just a newbie, hence, (Q) what don't I know?

Solution 1:

apf takes precedence over pf, in which case, (Q) how do I change or work around that?

It's not about precedence; it's logical AND — those firewalls are independent to each other and you're invoking both of them. Even if Pf won't block connections you have specifically verified that socketfilterfw won't pass it.