From c599607c8e88955955680710b19a49fa917e5a97 Mon Sep 17 00:00:00 2001 From: Kajetan Staszkiewicz Date: Fri, 12 Aug 2022 18:09:45 +0200 Subject: [PATCH] Add support for pfctl ruleset with anchors --- igcollect/pf.py | 9 ++++----- igcollect/pf_labels.py | 31 ++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/igcollect/pf.py b/igcollect/pf.py index 68fdbf4..f4698a9 100755 --- a/igcollect/pf.py +++ b/igcollect/pf.py @@ -6,7 +6,7 @@ from __future__ import print_function from argparse import ArgumentParser -from subprocess import check_output +from subprocess import run from time import time import re @@ -58,11 +58,10 @@ def parse_args(): def parse_pf_info(): - pf_info_raw = check_output( + pf_info_raw = run( ['/sbin/pfctl', '-qvsi'], - universal_newlines=True, - close_fds=False, - ).splitlines() + capture_output=True, text=True, + ).stdout.splitlines() pf_info = {} for pf_info_graphite, (pf_info_section, pf_info_key) in PF_INFOS.items(): diff --git a/igcollect/pf_labels.py b/igcollect/pf_labels.py index d428820..b8d6481 100755 --- a/igcollect/pf_labels.py +++ b/igcollect/pf_labels.py @@ -7,12 +7,13 @@ from __future__ import print_function from argparse import ArgumentParser from socket import gethostname -from subprocess import check_output +from subprocess import run import json import re import time POOL_RE = re.compile('(pool_[0-9]+)_([46]).*') +ANCHOR_RE = re.compile('anchor "(pool_[0-9]+_(sg|acl)_IPv[46]_if_[a-z0-9]+)"') def parse_args(): parser = ArgumentParser() @@ -23,12 +24,28 @@ def parse_args(): def parse_pf_labels(): - # Get pfctl result of "show all labels" - pfctl_result = check_output( + pfctl_result = [] + + pfctl_result += run( ['/sbin/pfctl', '-q', '-sl'], - universal_newlines=True, - close_fds=False, - ) + capture_output=True, text=True, + ).stdout.splitlines() + + # To obtain labels from a ruleset with anchors it is necessary to dive + # into each anchor. + pfctl_rules = run( + ['/sbin/pfctl', '-q', '-sr'], + capture_output=True, text=True, + ).stdout.splitlines() + for line in pfctl_rules: + anchor_re = ANCHOR_RE.match(line) + if not anchor_re: + continue + else: + pfctl_result += run( + ['/sbin/pfctl', '-q', '-sl', '-a', anchor_re.group(1)], + capture_output=True, text=True, + ).stdout.splitlines() label_counters = {} @@ -43,7 +60,7 @@ def parse_pf_labels(): reverse_pools[kpv['pf_name']] = kpk # Read all lines - for line in pfctl_result.splitlines(): + for line in pfctl_result: # Split each line by ' ', this gives is the label name and values line_tab = line.split(' ')