Starting `pf` Firewall at System Startup I have a particular machine that I keep buttoned down very tight. Only a few specific ports/protocols are allowed. I have a pretty basic set of rules that work very well.
While working on a different problem, I realized I could add a few more rules and button things down even tighter by specifying specific ports on specific network interfaces. So for example, on one network interface, only access to 80 &amp; 443 are allowed, no mail or vpn access to that interface.
So here is what one of the old rules looked like:
pass in quick proto tcp from any to any port { 80 443 } keep state

And this is what one of the new rules looks like:
pass in quick proto tcp from any to en1 port { 80 443 } keep state

The difference is subtle but I'm specifying a specific network interface, not just in to 'any'. This particular server has three connections to the internet.
The problem is... pf will no longer start up right at boot with these new rules. When I specify the interface, my pf startup script fails to start pf. And I have to do it manually through the terminal.
At first glance, the problem seems like my script is probably just trying to use network interfaces that aren't up yet. But I'm already waiting for them to come up. Here is my pf startup script, it has been working perfectly for years, until this rule change.
#!/bin/bash
ipconfig waitall
/sbin/pfctl -e -f /etc/pf.conf

With the new rules, nothing gets loaded at system startup when this runs. But if I run the same pfctl command once the system is up, it loads the rules and starts the firewall just fine.
I modified my script to save multiple copies of ifconfig so I could see how the status of the two interfaces en0 and en1 progress. Before the ipconfig waitall command, they are there with no IPs. After the command, they still have no ips and they show up as 'inactive'. Over the next few seconds, the various IPs start to load up. But the two interfaces show up the whole time.
So the easy patch solution would be to just run ipconfig waitall followed by sleep 6 and call it a day. But I'd rather learn exactly what is causing the hangup so I can wait for that exact 'thing' to be ready, instead of leaving the firewall completely open for 6 seconds. It is a high traffic server and gets lots of hack/ddos attempts so every second may count.
You shouldn't have to create your own plist to enable the pf firewall on boot especially since you're using the default rule set.  You just need to enable it.  This will launch at the &quot;correct time&quot; when all of your interfaces are configured and up.
Step 1:  Edit the Apple supplied plist
The file you're looking for is  /System/Library/LaunchDaemons/com.apple.pfctl.plist.
Change the Disabled key from &quot;true&quot; to &quot;false&quot;.  Here's what it should look like:
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;dict&gt;
    &lt;key&gt;Disabled&lt;/key&gt;
    &lt;false/&gt;
    &lt;key&gt;Label&lt;/key&gt;
    &lt;string&gt;com.apple.pfctl&lt;/string&gt;
    &lt;key&gt;WorkingDirectory&lt;/key&gt;
    &lt;string&gt;/var/run&lt;/string&gt;
    &lt;key&gt;Program&lt;/key&gt;
    &lt;string&gt;/sbin/pfctl&lt;/string&gt;
    &lt;key&gt;ProgramArguments&lt;/key&gt;
    &lt;array&gt;
        &lt;string&gt;pfctl&lt;/string&gt;
        &lt;string&gt;-f&lt;/string&gt;
        &lt;string&gt;/etc/pf.conf&lt;/string&gt;
    &lt;/array&gt;
    &lt;key&gt;RunAtLoad&lt;/key&gt;
    &lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;

Step 2:  Load (or reload) the plist with launchctl
% sudo launchctl load /System/Library/LaunchDaemons/com.apple.pfctl.plist

Step 3:  Firewall should be enabled upon boot.

My recommendation...
You should not expose the Mac (or any server) directly to the Internet but instead, it should be behind a firewall box/appliance!
Don't get me wrong - I am a huge fan of pf.  You should still enable the pf firewall on the Mac.   However, if what you're saying is correct that even for a couple seconds you get slammed with DDoS attacks, the (Mac) server shouldn't be dealing with them; your firewall should.  In fact, you should have a proper pfSense firewall in front of this server.  By having a separate firewall, the Mac will always be protected regardless of its status (i.e. an inadvertent rule change mistakenly opens it up).
You also gain the advantage of being able to run packages like pfBlocker-NG on the appliance (will drop connections from known bad actors based on black/white lists) giving you a higher level of protection.  Having it on the appliance frees up your Mac from having to handle those processes.