/etc insider

since 1999 (and still editing)

OpenBSD’s PF for Mac OS X is mostly outdated, broken, rotten

| Comments

Being a Mac OS X user (too, not solely) for a while I know of Apple developers’ attempts to bring in some packet firewall (I guess they already had “Socket (level) firewall) into OS X. They’ve tried FreeBSD’s ipfw and threw it out later, although you can see its reamins are still in system, even El Capitan:

sysctl net.inet.ip.fw

and they’re trying with PF now. PF itself has rather harsh way of evolving. First of all, term “forking” would be very much appropriate here. PF for FreeBSD and OpenBSD’s PF are pretty much forks. FreeBSD 10.2 uses PF from OpenBSD 4.5. Their ways are greatly diverged. If being asked which one I’d prefer I’d rather go with OpenBSD’s, buuut, I admit it became more complex than anybody would expect in the beginning. NAT/routing syntax, for e. g., is pretty much different between them.

Well, back again to Mac OS X. I don’t know which OpenBSD version they have choosen (this is very interesting question), but I can assure you that both in Yosemite and El Capitan it’s rather “outdated, broken, rotten”.

You should realize that it contains bugs that were fixed long time ago in upstream and it lacks of some features too, even not that modern. A few things to mention:

  • TCP modulate state isn’t working, don’t waste your time with trying:
 % cat -n pf-modulate.conf 
     1    pass all
     2    pass out on lo0 proto tcp from any to any port 22 modulate state
 % sudo pfctl -ef pf-modulate.conf
 % nc -w 1 22        
 % nc -w 1 22
 % head -n1 pf-modulate.conf | sudo pfctl -f -
 % sudo pfctl -s r 2>/dev/null
pass all flags S/SA keep state
 % nc -w 1 22                       
 % nc -w 1 22
  • Logging worked really strange. I’d say that it worked rather sticky, w/o ability to unset logging for specific rules sometimes (circumstances are unclear), although I don’t have any confirmation on hands now. I’ll update it if I find again eventually.

  • route-to and nat (together) won’t give you the result you expect. It works as expected in FreeBSD 10.2 (and may be 10.1), although it takes you to a quiz way. ;) It works in OpenBSD although as I said earlier syntax there’s changed significantly.

  • (self) and co. – the manual page says: “Surrounding the interface name (and optional modifiers) in parentheses changes this behaviour.” It simply doesn’t work. You’d have to pfctl -f your ruleset file.

So, what’s in the rest? – Don’t expect much from PF on Mac OS X. It works generally. Buuuut…

Ough, and I was able to crash El Capitan at least 2 or 3 times when experimenting with “nat route-to”.