8

I am looking for a pretty elegant way to launch the pf - a.k.a. Packet Filtering - process at startup. Using the launchctl or the pfctl commands, root privileges are required and so it is useless to add them into .bash_profile. Are there alternative solutions to this issue?

  • Can you explain what you're actually trying to accomplish? Pf might not even be the best way. – Harv Dec 08 '17 at 08:56
  • 1
    @Harv I’d like to block the outgoing connections that some applications establish on launch. – rudicangiotti Dec 09 '17 at 02:05
  • Check this out: http://www.hanynet.com/pflists/index.html, I'm guessing you ruled out Radio Silence, Little Snitch etc? – Harv Dec 09 '17 at 04:33
  • @Harv yes, because they are not free applications. pflist, on its side, is an open source project but seems to be not fully compatible with macOS Sierra - which I’m currently using - and next versions. Furthermore, it is nothing but an user-friendly interface of pf. – rudicangiotti Dec 10 '17 at 14:10

5 Answers5

7

By default pf is silenced at startup, a launch daemon com.apple.pfctl.plist exists though in /System/Library/LaunchDaemons/. To enable pf while booting you would have to add an -e switch in the plist.

Since all files in /System/Library/LaunchDaemons/ are protected by SIP in macOS 10.11 and later you have to disable it first.

Then, after booting to the main system, edit the launch daemon plist:

sudo nano /System/Library/LaunchDaemons/com.apple.pfctl.plist

and replace

  ...
  <key>ProgramArguments</key>
  <array>
    <string>/sbin/pfctl</string>
    <string>-f</string>
    <string>/etc/pf.conf</string>
  </array>
  ...

with

  ...
  <key>ProgramArguments</key>
  <array>
    <string>/sbin/pfctl</string>
    <string>-e</string>
    <string>-f</string>
    <string>/etc/pf.conf</string>
  </array>
  ...

Reboot to Recovery Mode and enable SIP again.

klanomath
  • 66,391
  • 9
  • 130
  • 201
4

It is possible to launch processes at startup using daemons. You can create a daemon - or even edit an already existing one - respectively adding or modifying a .plist file inside /System/Library/LaunchDaemons or /Library/LaunchDaemons.
In my case, running macOS Sierra, a daemon for pfctl was already located inside one of those folders but it was set up without the -e option; consequently, at startup the daemon was launched without any effect.
The issue has been solved adding that mentioned option, plus something more despite it is not properly necessary:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Disabled</key>
  <false/>
  <key>Label</key>
  <string>com.apple.pfctl</string>
  <key>WorkingDirectory</key>
  <string>/var/run</string>
  <key>Program</key>
  <string>/sbin/pfctl</string>
  <key>ProgramArguments</key>
  <array>
    <string>/sbin/pfctl</string>
    <string>-e</string>
    <string>-f</string>
    <string>/etc/pf.conf</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>StandardErrorPath</key>
  <string>/var/log/pfctl.err</string>
  <key>StandardOutPath</key>
  <string>/var/log/pfctl.out</string>
</dict>
</plist>
4

Are there alternative solutions to this issue?

Yes*, in System Preferences / Security & Privacy / Firewall Options..., check "Enable stealth mode" and turn on Firewall.

Somehow this enables PF. You can check by running sudo pfctl -s info.

*Tested on High Sierra and Mojave

  • This is the MVP answer right here, thank you – Kaan Jun 19 '20 at 08:02
  • This is the simplest way to manage the PF startup which will survive to an OS upgrade and will avoid damage on /System/Library/LaunchDaemons/.... – dan Jul 25 '21 at 11:32
2

If you don't want to mess about disabling System Integrity Protection (SIP), you can simply copy the existing file /System/Library/LaunchDaemons/com.apple.pfctl.plist to the unprotected user area /Library/LaunchDaemons giving it a slightly different name eg. /Library/LaunchDaemons/my.netfilter.pfctl.plist.

Then make your edits, I changed the Label name to match the filename and added the -e option as described in the other answers.

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key> <string>my.netfilter.pfctl</string>
    <key>Disabled</key> <false/>
    <key>RunAtLoad</key> <true/>
    <key>WorkingDirectory</key> <string>/var/run</string>
    <key>Program</key> <string>/sbin/pfctl</string>
    <key>ProgramArguments</key>
    <array>
        <string>pfctl</string>
        <string>-e</string>
        <string>-f</string>
        <string>/etc/pf.conf</string>
    </array>
</dict>
</plist>

After reboot check it's running with pfctl -s all. Tested on Mojave.

2

Enable PF via Console

Here is how to enable your Mac Packet Filter (PF), and have it turn on automatically after each reboot. Other methods did not work for me.

Run the following from Terminal or via SSH:

sudo -i    
defaults write /Library/Preferences/com.apple.alf globalstate -int 1
defaults write /Library/Preferences/com.apple.alf stealthenabled "1"
/usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on

Handy when working from home in a lockdown and have no access to GUI :-). As sunknudsen has pointed out: stealth mode will enable PF to start automatically and stay on after reboots.

Testing PF

Reboot the computer (shutdown -r now) and after boot run the following command:

pfctl -s info

Look for a line that starts with "Status: Enabled". If it says that then the Mac Packet Filter is running.

Bastion
  • 201
  • 1
    Before running this command you need to ensure your firewall is turned on with sudo defaults write /Library/Preferences/com.apple.alf globalstate -int 1 – bobbyg603 Jul 27 '21 at 20:36