From f035b94c216a8324e5b0d1637340c3736227781f Mon Sep 17 00:00:00 2001 From: batsumaru <> Date: Wed, 1 Jul 2026 18:01:39 +0900 Subject: Sort pf rules by interface, iconify from/to, drop redundant nat prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filter rules now sort by (interface, in-before-out) rather than pfctl's raw eval order, which just reflects pf.conf's authoring order and reads as arbitrarily interleaved (an "out" rule sandwiched between unrelated "in" rules for the same interface). Display-only reorder - pf's actual evaluation order and quick/first-match semantics on the box are untouched, only the informational listing is re-sorted. Generalized the "from X to Y" abbreviation beyond the from-any-to-any- port special case, and replaced pfctl's own "->" (nat rewrite target) with the unicode arrow for consistency with the in/out arrows already in use. Also dropped the "nat: " prefix, which was redundant with the rule text already starting with "nat". Applied the same "->" -> "→" consistency swap to jails.sh's http child-row label. Co-Authored-By: Claude Sonnet 5 --- statuspage/checks/pf.sh | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'statuspage/checks/pf.sh') diff --git a/statuspage/checks/pf.sh b/statuspage/checks/pf.sh index ef39268..08dc7d3 100755 --- a/statuspage/checks/pf.sh +++ b/statuspage/checks/pf.sh @@ -31,8 +31,11 @@ abbreviate_rule() { -e 's/ keep state/ [state]/' \ -e 's/ proto (tcp|udp|icmp)/ \1/' \ -e 's/ from any to any port = ([a-zA-Z0-9]+)/ :\1/' \ + -e 's/ from any to any/ /' \ + -e 's/ from ([^ ]+) to ([^ ]+)/ \1 → \2/' \ -e 's/ inet / /' \ -e 's/ round-robin//' \ + -e 's/ -> / → /' \ -e 's/ all$//' \ -e 's/ all / /' \ -e 's/ +/ /g' \ @@ -66,12 +69,30 @@ fi RULE_COUNT=$(pfctl -sr 2>/dev/null | grep -c .) || RULE_COUNT=0 json_line "pf" "filter rules loaded" "$RULE_COUNT" "ok" -pfctl -sr 2>/dev/null | while IFS= read -r rule; do +# Group rules by interface (then in before out) rather than pfctl's raw +# eval order, which is just how the ruleset happens to be authored and +# reads as arbitrarily interleaved (e.g. an "out" rule sandwiched between +# unrelated "in" rules for the same interface). This is a display-only +# reorder - pf's actual evaluation order (and quick/first-match +# semantics) is untouched, only pfctl -sr's raw output is re-sorted here. +TAB=$(printf '\t') +pfctl -sr 2>/dev/null | awk -v OFS="$TAB" ' +{ + iface = "" + n = split($0, w, " ") + for (i = 1; i <= n; i++) { + if (w[i] == "on" && i < n) { iface = w[i + 1]; break } + } + dir = "2" + if ($0 ~ / in /) dir = "0" + else if ($0 ~ / out /) dir = "1" + print iface, dir, $0 +}' | sort -t "$TAB" -k1,1 -k2,2 -k3 | cut -f3- | while IFS= read -r rule; do [ -n "$rule" ] || continue json_line "pf" " $(abbreviate_rule "$rule")" "" "info" done pfctl -sn 2>/dev/null | while IFS= read -r rule; do [ -n "$rule" ] || continue - json_line "pf" " nat: $(abbreviate_rule "$rule")" "" "info" + json_line "pf" " $(abbreviate_rule "$rule")" "" "info" done -- cgit v1.3