I am answering this with what i’ve done so far, cuz it took some digging and could be useful to someone. You could make something more complicated based on this, it’s just kind of a start. If someone posts something better i will accept that, i guess.
A more complicated solution would save tokens and use ‘-E’ and ‘-X’ to retain and release references to the packet filtering system, or allow unloading the service, but i don’t do that here. Note that launchd does not really support running a command when unloading a service. You could write a script to keep a process alive and handle the shutdown, or in most cases you would probably just handle flushing rules for the anchor when shutting down your process for your application.
Save all of the below files to their locations and do the following:
sudo launchctl load -w /Library/LaunchDaemons/org.myorg.mypf.plist # Note: the next step turns on ip forwarding for your system. # You only need to do this if you are doing actual NAT # and not just referencing this answer for something else like packet # filtering sudo sysctl -w net.inet.ip.forwarding=1
If you would like ip forwarding to persist across boots, create (if needed)
/etc/sysctl.conf and set contents:
... net.inet.ip.forwarding=1 ...
Again, this is only necessary to make NAT work, as we are in this specific example. If you are doing something else, you don’t need it.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE plist PUBLIC "-//Apple Computer/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>org.myorg.pfsettings</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/myorg-install-pf</string> </array> <key>LaunchOnlyOnce</key> <true/> </dict> </plist>
#!/usr/bin/env zsh /sbin/pfctl -f - <<EOF scrub-anchor "org.myorg/*" nat-anchor "org.myorg/*" rdr-anchor "org.myorg/*" dummynet-anchor "org.myorg/*" anchor "org.myorg/*" EOF # Flush existing rules. # Not that useful for our one-shot, but could be useful in more complicated setups /sbin/pfctl -a org.myorg -F all /sbin/pfctl -a org.myorg/system -F all /sbin/pfctl -a org.myorg/system -f /usr/local/etc/pf.anchors/org.myorg/system
# Set 192.168.142.0/24 to your "inside" network, or see `man pf.conf` and # use something else (you could use someif0:network, for example) nat on en0 inet from 192.168.142.0/24 to any -> (en0)