Purpose of tracker on pfsense config rules

  • Hi,

    I sometimes manually edit pfsense xml config files directly as it is much quicker than doing so via GUI. I noticed that new config file rules have something called tracker, which is essentially a unix time stamp. Where is this used, does it have to be unique, does it determine rule order?

    The nat rules have something called associated-rule-id which is just a php uniqid and it has to match the associated the rules, so it's obvious what that does.


  • It's put into the ruleset for log identification purposes. Only the rule number as configured in the running ruleset was logged by pf previously, and that isn't a static number. So if you made significant enough changes to your rules and/or NAT, then go to the firewall log, it'd tell you the wrong rule or be unable to find a matching rule.

    Check the code in /etc/inc/filter.inc to ensure you're properly generating that for rules. There's a function there you could use or adapt.

  • according to https://docs.netgate.com/pfsense/en/latest/monitoring/raw-filter-log-format.html#bnf-grammar

    the purpose of the tracker id is

    <tracker> ::= <integer> -- Unique ID per rule, tracker ID is stored with the rule in config.xml for user added rules, or check /tmp/rules.debug

    I've written this script to fix my rules and make the tracker id numbers unique

    import xml.etree.ElementTree as ET
    ONE_SECOND = 1
    def main():
        start_epoch = 1585650686
        root_element = ET.fromstring(XML_DATA)
        rule_elements = root_element.findall('rule')
        for rule_index, rule_element in enumerate(rule_elements):
            rule_id = str(start_epoch + (rule_index * ONE_SECOND))
            tracker_element = rule_element.find('tracker')
            tracker_element.text = rule_id
            created_time_element = rule_element.find('created').find('time')
            created_time_element.text = rule_id
            updated_time_element = rule_element.find('updated').find('time')
            updated_time_element.text = rule_id
        fixed_xml = ET.tostring(root_element, encoding='unicode')
        with open('fixed-firewall-rules.xml', 'w+') as f:
    XML_DATA = '''
         ... // copy and paste the exported rules here
    if __name__ == '__main__':

Log in to reply