Project

General

Profile

Actions

Bug #14409

open

pfBlockerNG Cron Redundantly Updates pfSense Configuration When DNSBL is Disabled Due to Faulty Virtual IP Count

Added by LTC Tech over 2 years ago. Updated about 17 hours ago.

Status:
Feedback
Priority:
Normal
Assignee:
Category:
pfBlockerNG
Target version:
-
Start date:
Due date:
% Done:

100%

Estimated time:
Plus Target Version:
Affected Version:
Affected Plus Version:
23.01
Affected Architecture:

Description

pfBlockerNG: 3.2.0_4
pfSense Plus: 23.01

Related forum post:
https://forum.netgate.com/topic/174231/pfblockerng-fills-pfsense-config-history

Even though pfBlockerNG's DNSBL is disabled it checks for the presence of Virtual IPs matching DNSBL's description. It expects to find one (IPv4 only) or two (IPv4 and IPv6) Virtual IPs. When it does not find any VIPs (as DNSBL is disabled) it flips the $pfbupdate flag causing later code to write redundant changes to the pfSense config. This floods pfSense's Config History under Diagnostics -> Backup & Restore quickly overwriting legitimate history.

Relevant code:
https://github.com/pfsense/FreeBSD-ports/blob/1669285e76c1cbbdf0e08a74603537a955839139/net/pfSense-pkg-pfBlockerNG/files/usr/local/pkg/pfblockerng/pfblockerng.inc#L2016

        // Validate DNSBL VIP address(es)
        $pfb['dnsbl_v6'] == 'on' ? $vip_count = 2 : $vip_count = 1;
        $result = array();
        foreach (array("inet {$pfb['dnsbl_vip']}", "inet6 ::{$pfb['dnsbl_vip']}") as $g_vip) {
            $g_vip = escapeshellarg($g_vip);
            exec("/sbin/ifconfig {$iface} | {$pfb['grep']} {$g_vip} 2>&1", $result, $retval);
        }
        if (count($result) != $vip_count) {
            $pfbupdate = TRUE;
        }

        // Update config.xml, if changes required
        if ($pfbupdate) {
            init_config_arr(array('nat', 'rule'));
            config_set_path('nat/rule', $new_nat);

            init_config_arr(array('virtualip', 'vip'));
            config_set_path('virtualip/vip', $new_vip);
            write_config('pfBlockerNG: saving DNSBL changes');
        }

I've come up with a patch that sets $vip_count to 0 if DNSBL is disabled. This causes the Virtual IP counts to match and avoids the config update.

--- a/src/usr/local/pkg/pfblockerng/pfblockerng.inc
+++ b/src/usr/local/pkg/pfblockerng/pfblockerng.inc
@@ -2013,7 +2013,12 @@
                }

                // Validate DNSBL VIP address(es)
-               $pfb['dnsbl_v6'] == 'on' ? $vip_count = 2 : $vip_count = 1;
+               if($mode == 'enabled') {
+                       $pfb['dnsbl_v6'] == 'on' ? $vip_count = 2 : $vip_count = 1;
+               }
+               else {
+                       $vip_count = 0;
+               }
                $result = array();
                foreach (array("inet {$pfb['dnsbl_vip']}", "inet6 ::{$pfb['dnsbl_vip']}") as $g_vip) {
                        $g_vip = escapeshellarg($g_vip);

I am not sure if this actually breaks DNSBL functionality as we don't use it. It may potentially break Virtual IP addition or removal.

Can someone with more knowledge of the code take a look?


Files

clipboard-202509261403-h8t8u.png (65.2 KB) clipboard-202509261403-h8t8u.png Marcelo Cury, 09/26/2025 05:03 PM
pfblockerng.inc.patch (545 Bytes) pfblockerng.inc.patch Marcelo Cury, 10/01/2025 02:20 PM
pfblockerng.inc (361 KB) pfblockerng.inc Marcelo Cury, 10/01/2025 02:20 PM
pfblockerng_workaround.inc (361 KB) pfblockerng_workaround.inc Marcelo Cury, 10/01/2025 02:20 PM
update_logs_after_workaround.txt (10.1 KB) update_logs_after_workaround.txt Marcelo Cury, 10/01/2025 02:20 PM
Actions #1

Updated by LTC Tech over 2 years ago

Another quirk seems to be that there is some other bug that writes to config on cron until you toggle some DNSBL settings and save it. Setting the "Resolver Cache" checkbox off then saving and then setting it on again is sufficient.

Actions #2

Updated by Sima Xi over 1 year ago

I've come up with a patch that sets $vip_count to 0 if DNSBL is disabled. This causes the Virtual IP counts to match and avoids the config update.

[...]

I am not sure if this actually breaks DNSBL functionality as we don't use it. It may potentially break Virtual IP addition or removal.

Can someone with more knowledge of the code take a look?

That patch didn't stop the periodic updates for my system. So what I did instead was to skip that block of checks entirely when disabled:

--- pfblockerng.inc.orig        2024-02-14 16:42:24.057610000 +0800
+++ pfblockerng.inc     2024-02-14 16:43:10.935321000 +0800
@@ -2013,6 +2013,7 @@
                }

                // Validate DNSBL VIP address(es)
+       if ($mode == 'enabled') {
                $pfb['dnsbl_v6'] == 'on' ? $vip_count = 2 : $vip_count = 1;
                $result = array();
                foreach (array("inet {$pfb['dnsbl_vip']}", "inet6 ::{$pfb['dnsbl_vip']}") as $g_vip) {
@@ -2022,7 +2023,7 @@
                if (count($result) != $vip_count) {
                        $pfbupdate = TRUE;
                }
-
+       }
                // Update config.xml, if changes required
                if ($pfbupdate) {
                        init_config_arr(array('nat', 'rule'));

e.g:
        // Validate DNSBL VIP address(es)
    if ($mode == 'enabled') {
        $pfb['dnsbl_v6'] == 'on' ? $vip_count = 2 : $vip_count = 1;
        $result = array();
        foreach (array("inet {$pfb['dnsbl_vip']}", "inet6 ::{$pfb['dnsbl_vip']}") as $g_vip) {
            $g_vip = escapeshellarg($g_vip);
            exec("/sbin/ifconfig {$iface} | {$pfb['grep']} {$g_vip} 2>&1", $result, $retval);
        }
        if (count($result) != $vip_count) {
            $pfbupdate = TRUE;
        }
    }

Don't know whether this breaks anything. So do this at your own risk.

Actions #3

Updated by Steve Y 4 months ago

Noting this is still an issue, and also given the bug in Plus 24.03/24.11 where pfSense doesn't prune the configuration history, this can result in thousands of leftover backup files, particularly on the second router in an HA pair, since that has extra syncs from these "changes."

https://forum.netgate.com/topic/197685/config-history-not-pruning-on-ha-pair-has-3400-files/6
https://redmine.pfsense.org/issues/15994

Actions #4

Updated by Marcos M 4 months ago

  • Status changed from New to Feedback
  • Assignee set to Marcos M
  • % Done changed from 0 to 100
Actions #5

Updated by Marcelo Cury 8 days ago

Tested commit 6e558c8679c7cb9048a8c29101cb3158330d6dde, but it didn't resolve the issue: every time a cronjob runs, a new configuration is saved to the Configuration History.

pfSense 25.07.1
pfBlockerNG-devel 3.2.7
DNSBL is disabled; only using IP feeds.

(The commit includes the following patch to pfblockerng.inc—I've included it here for reference.)

Path Strip Count: 0

--- /usr/local/pkg/pfblockerng/pfblockerng.inc
+++ /usr/local/pkg/pfblockerng/pfblockerng.inc
@@ -1969,6 +1969,7 @@
             }
         }

+        $vip_count = 0;        
         $pfbfound = FALSE;
         // Collect existing pfSense VIPs
         foreach (config_get_path('virtualip/vip', []) as $ex_vip) {
@@ -1976,6 +1977,7 @@
                 // Collect DNSBL VIP
                 $dnsbl_ex_vip[] = $ex_vip;
                 $pfbfound = TRUE;
+                $vip_count++;
             } else {
                 // Collect all 'other' VIPs
                 $pfb_ex_vip[] = $ex_vip;
@@ -2017,7 +2019,6 @@
         }

         // Validate DNSBL VIP address(es)
-        $pfb['dnsbl_v6'] == 'on' ? $vip_count = 2 : $vip_count = 1;
         $result = array();
         foreach (array("inet {$pfb['dnsbl_vip']}", "inet6 ::{$pfb['dnsbl_vip']}") as $g_vip) {
             $g_vip = escapeshellarg($g_vip);

Reproduction steps after applying the patch:
  1. Uncheck both "Keep Settings" and "pfBlockerNG Enable," then save.
  2. Re-check/enable both options, save, and run an update.
  3. Trigger a cronjob (or wait for the next one)—a new configuration entry is still saved to the Configuration History each time.
Actions #6

Updated by Marcos M 6 days ago

The manual cron triggers are done by removing and re-adding the cron entry hence the configuration change. There is no configuration change during the scheduled events.

Actions #7

Updated by Marcelo Cury 6 days ago


Hello Marcos, this wasn't generated by a manual cron.

Actions #8

Updated by Marcos M 6 days ago

There are likely other other related patches/fixes which are needed. I am not able to reproduce the issue on the latest pfBlockerNG-devel version in 25.11 development snapshots; new public builds hopefully should be available soon.

Actions #9

Updated by Marcelo Cury 6 days ago

This is my primary system, so I cannot test development snapshots.
Unfortunately, I’m unable to test pfSense Plus in GNS3 either.

As a result, I’ve decided to completely remove pfBlockerNG from my system for now.
I believe maintaining configuration history is more critical, as I don’t want to risk losing track of recent changes if pfBlockerNG overwrites them.

Thanks, Marcos.

Actions #10

Updated by Marcelo Cury about 23 hours ago

Hi team,

Quick follow-up on #14409—still seeing this in pfBlockerNG-devel 3.2.10 on pfSense Plus 25.07.1.
The recent commit ( 6e558c867 ) helped with VIP counting but didn't stop the redundant config saves during DNSBL-disabled cron runs.

As a targeted workaround, I've patched `/usr/local/pkg/pfblockerng/pfblockerng.inc` to add a simple enable check before the update block.
This skips writes entirely when DNSBL is off, without affecting IP feeds or the root $pfbupdate flagging.

Caveats: Workaround only (doesn't fix upstream VIP logic). Tested solely with DNSBL disabled; no regressions noted on IP side.

--- /usr/local/pkg/pfblockerng/pfblockerng.inc
+++ /usr/local/pkg/pfblockerng/pfblockerng.inc
@@ -2023,10 +2023,10 @@
         }

         // Update config.xml, if changes required
-        if ($pfbupdate) {
+        if ($pfbupdate && $pfb['dnsbl'] == 'on') {
             config_set_path('nat/rule', $new_nat);
-            config_set_path('virtualip/vip', $new_vip);
-            write_config('pfBlockerNG: saving DNSBL changes');
+                config_set_path('virtualip/vip', $new_vip);
+                write_config('pfBlockerNG: saving DNSBL changes');
         }

         if ($mode == 'enabled' && $pfbupdate) {

Post-apply:
- No more "pfBlockerNG: saving DNSBL changes" in Diagnostics > Configuration History after cron/manual DNSBL runs.
- Logs clean, IP updates unaffected.

Attaching full original and patched files for reference:
original: pfblockerng.inc
file with workaround applied: pfblockerng_workaround.inc
patch diff: pfblockerng.inc.patch
logs during last cron: update_logs_after_workaround

Happy to test against newer commits or provide more logs.

Cheers,
Marcelo

Actions #11

Updated by BBcan177 . about 23 hours ago

Thanks for digging in. I think that resolved when you have DNSBL disabled. However, if DNSBL is enabled and the VIP is active, then you set DNSBL to disabled, your workaround might not allow the VIP to be removed.

I will look at it sometime this week.

Actions #12

Updated by BBcan177 . about 17 hours ago

Marcelo Cury I have a test file that I would like to see if you could test?

Would you mind shooting me an email (mine is in the pfB General tab (Contact us) ) and I can send you some instructions?

Actions #13

Updated by Marcelo Cury about 17 hours ago

BBcan177 . wrote in #note-12:

Marcelo Cury I have a test file that I would like to see if you could test?

Would you mind shooting me an email (mine is in the pfB General tab (Contact us) ) and I can send you some instructions?

Sure, I'm happy to test it. I've just sent you an email—please check your inbox.

Actions

Also available in: Atom PDF