MacOS – Launch daemon not processing program arguments

launchdmacosplistterminal

I have been trying to make a change (for port forwarding/redirecting) to the pfctl.conf file and have it ( the /etc/pfctl.conf file) loaded at startup. The pfctl.conf has been been confirmed to be working as expected because issuing sudo pfctl -ef /etc/pfctl.conf leads to the desired behavior (requests to one port get forwarded to the other).

That pfctl itself is actually loaded at startup is also confirmed because doing launchctl list | grep pf shows com.apple.pfctl in the output. However, the desired forwarding behavior is not achieved directly after startup. It happens only on doing pfctl -f /etc/pfctl.conf after startup. Oddly enough, the output of pfctl -ef /etc/pfctl.conf still says pf already enabled.

Therefore, I concluded that while pf is loaded at startup, the daemon seems to not load from the conf file. The body of the launch daemon com.apple.pfctl.plist now looks like:

<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/>
</dict>
</plist>

Having checked the discussion at
Getting launchd to read program arguments correctly it was informative but not practically helpful in this instance – I have already tried editing the program arguments of the plist file to include the full path to the pfctl executable (as can be seen in the code above – first line of the arguments array) but to no avail. I have also added an argument (second line of arguments array) to actually launch pfctl based on the discussion at this gist. The daemon also seems to be configured correctly according to the instructions at Apple developer docs. In accordance to the developer docs (which state that the program tag is required when the program arguments are not supplied and vice versa), I also tried removing the program tag while leaving the program arguments array in place (with the path to the executable as the first argument) – but this had no effect either.

Puzzlingly, the shipped version of the pfctl.plist file (which can be assumed to be most likely correct) had both the program tag and the program arguments tag, apparently in contradiction to the dev docs (or maybe I misunderstood the docs).

So now I am completely at a loss. Any help would be most appreciated!

Additional info:
Not sure this is relevant, but just in case it is: the anchor file (created by me) which is referenced by pf.conf looks like:

rdr pass on lo0 inet proto tcp from any to 127.0.0.1 port =80 -> 127.0.0.1 port 8888  

So is there a possibility that the network interface is not yet active and addresses have not been assigned at the time the daemon runs? If so, how can it be fixed?

Best Answer

Try removing the Program argument:

<key>Program</key>
<string>/sbin/pfctl</string>

A deep explanation is found here: https://akikoskinen.info/launch-daemon-agent-program-programarguments/