pfSense is a very popular free and open source firewall solution. It does not only provide classic firewall services but has plenty of features like VPN server or can offer DNS, DHCP, proxy services… and many more. pfSense is also proposed by some companies as a commercial service with support. That’s why it is used in many organisations.
About the firewall configuration, pfSense offers a way to backup/restore the running configuration but also proposed a tool to test what changed between changes, a little bit like a ‘diff’:
This works perfectly but, from my point of view, there are two problems: If you maintain a big firewall policy and perform many changes, you’ll probably hit the maximum number of previous configurations and you must have access to the firewall to use the feature. One of my customers was looking for a solution to automate this and store changes outside of the firewall for auditing reasons (some of their customers require firewalls to be audited at regular intervals).
To achieve this, I wrote a Python scripts, called “pfaudit”, that takes care of everything for you:
- Connect to the firewall and download the running configuration
- Compare the previous version to the new one
- Output differences
- Optionally generate JSON events based on detected changes
- Saves the configuration locally
This job is performed at regular interval from a cron job.
The generated JSON events contain a lot of fields but you’ve ALL the details to detect any change in the firewall configuration (not only the firewall policy). The syntax is easy to understand:
# /pfaudit.py -h Usage: pfaudit.py [options] Options: --version show program's version number and exit -h, --help show this help message and exit -u SSH_USER, --user=SSH_USER SSH user -H SSH_HOST, --host=SSH_HOST Firewall FQDN or IP address -k KEY_FILE, --key=KEY_FILE SSH RSA private key -p KEY_PASSPHRASE, --passphrase=KEY_PASSPHRASE SSH key passphrase -j, --json Generate JSON logfile -l LOG_FILE, --log=LOG_FILE Local log file (default: stdout) -v, --verbose Verbose output
Example of script output. The detected changes are located in the DHCP server configuration block:
Connecting to ssh://firstname.lastname@example.org Dumping configuration to /tmp/tmpgud0m1mz Processing /tmp/tmpgud0m1mz Firewall hostname: pf0 Writing encrypted configuration to pf0.network.conf Comparing configurations: Old SHA256: c171e090d58c0ebbe50ef71b9140d6f93eecdf94996cc8ff24361e21e95ac100, New SHA256: 890a5dd4fca8cbb80e0e302580f8a8f338ba4f174c7fcf0a669486d4c3f81acd Changes in / Changes in /pfsense/ Changes in /pfsense/dhcpd/ Changes in /pfsense/dhcpd/lan/ Changes in /pfsense/dhcpd/lan/staticmap/ Key '43' removed from config<br>Changes in /pfsense/dhcpd/lan/staticmap/39/ Key 'mac' changed to 'xx:xx:xx:xx:xx:xx' Key 'cid' added to config Key 'ipaddr' changed to '192.168.254.225' Key 'hostname' changed to 'xxxxxxxx' Key 'descr' changed to 'xxxxxxxx' Dumping JSON events to firewall.json
Here is another example, dumped in JSON:
Based on the JSON events, you’ll have a complete overview of changes performed on your pfSense firewalls.
To improve the process of “firewall change request”, you could ask people responsible for implementing the firewall changes to add the related change requests in the comment fields (pfSense allows to comment on all changes, not only rules). Based on JSON events, you correlate them with a list of approved change requests… More visibility!
The script is available on Github. Feel free to use it, improve it. I’m open to suggestions!