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
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-pf
To unsubscribe, send any mail to "[email protected]"

Reply via email to