automatic tables / self statement in pf.conf
Miroslav Lachman
000.fbsd at quip.cz
Wed Jan 22 10:13:30 UTC 2020
mike tancsa wrote on 2020/01/20 15:37:
> I have a process that runs every few min looking to see if the pf rules
> changed on some of our firewalls. On one customer unit, we have a
> "self" statement and the script detected a change this morning. The
> rule reads
>
> block log quick from <rejects> to self
> block log quick from self to <rejects>
>
> but when shown it looks like
>
> block drop log quick inet from <rejects> to <__automatic_32a5c00f_0>
> block drop log quick inet from <__automatic_32a5c00f_1> to <rejects>
>
> I guess 'self' is treated like a table ? The diff that got flagged
> looked like
>
> -block drop log quick inet from <rejects> to <__automatic_786310c4_0>
> -block drop log quick inet from <__automatic_786310c4_1> to <rejects>
> +block drop log quick inet from <rejects> to <__automatic_32a5c00f_0>
> +block drop log quick inet from <__automatic_32a5c00f_1> to <rejects>
>
> What would trigger the table name to change like that ?
>
> Also, is there a better way to monitor pf rule changes ? I dont see any mention in FreeBSD audit ?
Monitoring of PF rules is kind of hard and not just because of automatic
tables. (automatic tables are created by optimizer not only for self
rules, optimizer can be disabled by -o none)
We are monitoring changes between production rules in pf.conf, testing
temporary rules in pf.conf.tmp and live running rules.
pfctl -s all prints scrub / NAT / rules in different order than for
pfctl -nvf /etc/pf.conf
I chosen to replace random automatic tables names with sequence numbers
so they are still the same.
This is the part of our script solving this issue.
==========snippet===========
## this ugly awk hack is needed because PF rules optimizer creates
__automatic_
## tables when machine has many IPs and similar rules for them
## but tables are named randomly / different for live rules and pfct -nvf
## live:
## block drop in quick inet from <__automatic_fc1015f3_0> to any
## file parser
## block drop in quick inet from <__automatic_0> to any
##
## awk will replace automatic table name with own incremental sequence
pfctl -nvf /etc/pf.conf | egrep '^(nat|rdr|scrub|block|pass)' |
awk '{ if ( $0 ~ /<__automatic_[^>]*>/ ) { ac=ac+1; c=ac-1;
gsub(/__automatic_[^>]*/, "__automatic_"c); } { print $0 } }' > $tmp_prod
pfctl -nvf /etc/pf.conf.tmp | egrep '^(nat|rdr|scrub|block|pass)' |
awk '{ if ( $0 ~ /<__automatic_[^>]*>/ ) { ac=ac+1; c=ac-1;
gsub(/__automatic_[^>]*/, "__automatic_"c); } { print $0 } }' > $tmp_temp
## live rules must be re-ordered because pfctl prints scrub with filter
rules
## together for live rules, but scrub / NAT / filter rules for check
from file
_pf_live=$(pfctl -s all | egrep '^(nat|rdr|scrub|block|pass)' |
awk '{ if ( $0 ~ /<__automatic_[^>]*>/ ) { ac=ac+1; c=ac-1;
gsub(/__automatic_[^>]*/, "__automatic_"c); } { print $0 } }')
_live_scrub=$(echo "$_pf_live" | grep '^scrub')
_live_nat=$(echo "$_pf_live" | egrep '^(nat|rdr)')
_live_rules=$(echo "$_pf_live" | egrep '^(block|pass)')
## create empty file
: > $tmp_live
if [ -n "$_live_scrub" ]; then
echo "$_live_scrub" >> $tmp_live
fi
if [ -n "$_live_nat" ]; then
echo "$_live_nat" >> $tmp_live
fi
if [ -n "$_live_rules" ]; then
echo "$_live_rules" >> $tmp_live
fi
==========snippet===========
Then we can check for differences between all created files + last known
live ruleset from previous run.
Kind regards
Miroslav Lachman
More information about the freebsd-pf
mailing list