Date: Fri, 04 Jun 2021 09:53:17 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 256410] pf: Add pf_default_rules option Message-ID: <bug-256410-227@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D256410 Bug ID: 256410 Summary: pf: Add pf_default_rules option Product: Base System Version: Unspecified Hardware: amd64 OS: Any Status: New Severity: Affects Some People Priority: --- Component: misc Assignee: bugs@FreeBSD.org Reporter: thomas@gibfest.dk Created attachment 225540 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D225540&action= =3Dedit The patch for /etc/rc.d/pf and /etc/defaults/rc.conf Out of the three firewalls in FreeBSD pf is the only one without a way to m= ake it default to deny everything: - IPFW has "65535 deny ip from any to any" unless IPFIREWALL_DEFAULT_TO_ACC= EPT is set. - ipfilter has something called IPFILTER_DEFAULT_BLOCK, I think. I don't re= ally know anything about ipfilter. With pf, if no rules are loaded all traffic is permitted. This can be considered a feature or a problem, recently it was a very big problem in my end. I propose the attached patch for /etc/rc.d/pf and a couple of new rc.conf variables pf_default_rules_enable and pf_default_rules to improve this situation. The patch simply checks the exit code of the pfctl command which loads the pf.conf ruleset, and if the exit code is 1 and pf_default_rules_enable is s= et to YES, then it loads the rules in pf_default_rules, which defaults to a si= ngle rule: "block drop log all". BACKGROUND: A little backstory might help clear up why I think this is a valuable and neccesary change. We (our company) had ended up with a pf.conf with a typo in it. The typo was that the leading "$" sign of a macro was missing. This makes pf treat it as= a hostname instead of a macro, so it does a DNS lookup to process the firewall rule. The typo could have been a missing quote or something else too, the central point is the pf.conf was invalid, and it had been missed (humans be= ing human and all that). The server in question was then rebooted, and suddently no firewall rules w= ere loaded, permitting all traffic to the networks behind it, leading to some b= ad times at the office before it was discovered. In the postmortem clean-up it was determined that since /etc/rc.d/pf had fa= iled to load the ruleset during bootup, and there being no "default block functionality", there was 0 rules loaded so it of course permitted everythi= ng. On these particular firewall machines it would have been MUCH better to hav= e a non-functional firewall than a fully open one. YMMV, and the default in my patch is to keep the status quo, of course. With this patch and pf_default_rules_enable set to YES I would have discove= red the issue much sooner and with no security incidents, which is vastly preferable in this situation. THE PATCH: Mostly it is just a new "if" block around the pfctl -f call inside pf_start= (). I included some warnings (for both cases) while here. The only files touched are /etc/rc.d/pf and /etc/defaults/rc.conf. EXAMPLE: Note: All of these examples are with the attached patch applied. I made two simple pf.conf files where one has small but significant typo: [tykling@nuc2 ~]$ cat /etc/pf.conf=20 foo=3D"192.0.2.42" pass in quick on em0 from any to $foo [tykling@nuc2 ~]$ cat /etc/pf-typo.conf=20 foo=3D"192.0.2.42" pass in quick on em0 from any to foo [tykling@nuc2 ~]$=20 Note how "foo" is missing the leading $ sign meaning pf interprets it as a hostname, which can't be resolved in this case. First the default behaviour with no changes in rc.conf and a valid ruleset: [tykling@nuc2 ~]$ sudo sysrc pf_default_rules_enable pf_default_rules_enable: NO [tykling@nuc2 ~]$ sudo sysrc pf_default_rules=20=20=20=20=20=20=20 pf_default_rules: block drop log all [tykling@nuc2 ~]$ sysrc pf_rules pf_rules: /etc/pf.conf [tykling@nuc2 ~]$ sudo service pf restart Password: Enabling pf. [tykling@nuc2 ~]$ sudo pfctl -s rules | wc -l 1 [tykling@nuc2 ~]$ sudo pfctl -s rules=20=20=20=20=20=20=20=20 pass in quick on em0 inet from any to 192.0.2.42 flags S/SA keep state [tykling@nuc2 ~]$=20 All is well, it loaded the one rule in the ruleset. Now an example with an invalid ruleset, still with the above defaults in place: [tykling@nuc2 ~]$ sudo service pf restart=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20 Disabling pf. Enabling pfno IP address found for foo /etc/pf-typo.conf:2: could not parse host specification pfctl: Syntax error in config file: pf rules not loaded /etc/rc.d/pf: WARNING: Unable to load pf.conf, and pf_default_rules_enable = is NO. /etc/rc.d/pf: WARNING: No pf rules are loaded, this means all traffic is permitted. . [tykling@nuc2 ~]$ sudo pfctl -s rules [tykling@nuc2 ~]$=20=20=20=20 The behaviour is the same as always, but a couple of new warn() calls infor= ms the admin about what happened so they might spot it in /var/log/messages. Now the same setup but with the new feature enabled: [tykling@nuc2 ~]$ sudo sysrc pf_default_rules_enable=3D"YES" pf_default_rules_enable: NO -> YES [tykling@nuc2 ~]$=20 The valid ruleset behaves as always: [tykling@nuc2 ~]$ sudo sysrc pf_rules=3D"/etc/pf.conf"=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 pf_rules: /etc/pf.conf -> /etc/pf.conf [tykling@nuc2 ~]$ sudo service pf restart=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20 Disabling pf. Enabling pf. [tykling@nuc2 ~]$ sudo pfctl -s rules | wc -l=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 1 [tykling@nuc2 ~]$=20 With the invalid ruleset the pf_default_rules are loaded: [tykling@nuc2 ~]$ sudo sysrc pf_default_rules_enable=3D"YES"=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 pf_default_rules_enable: NO -> YES [tykling@nuc2 ~]$ sudo service pf restart=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20 Disabling pf. Enabling pfno IP address found for foo /etc/pf-typo.conf:2: could not parse host specification pfctl: Syntax error in config file: pf rules not loaded /etc/rc.d/pf: WARNING: Unable to load pf.conf, and pf_default_rules_enable = is set to YES. /etc/rc.d/pf: WARNING: Loading pf_default_rules: block drop log all . [tykling@nuc2 ~]$ sudo pfctl -s rules block drop log all [tykling@nuc2 ~]$ Say I wanted a way in, a management backdoor in case this happens, I could = for example choose to pass traffic on a management interface only: [tykling@nuc2 ~]$ sudo sysrc pf_default_rules=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 pf_default_rules: block drop log all\npass quick on em0 [tykling@nuc2 ~]$ sudo service pf restart=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20 Enabling pfno IP address found for foo /etc/pf-typo.conf:2: could not parse host specification pfctl: Syntax error in config file: pf rules not loaded /etc/rc.d/pf: WARNING: Unable to load pf.conf, and pf_default_rules_enable = is set to YES. /etc/rc.d/pf: WARNING: Loading pf_default_rules: block drop log all\npass q= uick on em0 . [tykling@nuc2 ~]$ sudo pfctl -s rules block drop log all pass quick on em0 all flags S/SA keep state [tykling@nuc2 ~]$=20 I guess that is all. I hope it made sense and that the feature will find its way into FreeBSD. I know I will be running with it locally until such a tim= e. Apologies in advance if I messed up the patch, I don't do this often, and I don't have a phabricator account (yet). Have a lovely weekend :) ps. I know about it being FreeBSDs job to ensure a reliable delivery of bul= let from gun to foot. But I feel like an exception is warranted here, especially given that the two other firewalls have similar functionality. --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-256410-227>