]> git.ipfire.org Git - ipfire-2.x.git/commitdiff
rules.pl: Refactor logic to handle the IP blocklist feature.
authorStefan Schantl <stefan.schantl@ipfire.org>
Mon, 4 Apr 2022 19:43:49 +0000 (21:43 +0200)
committerStefan Schantl <stefan.schantl@ipfire.org>
Thu, 7 Jul 2022 15:26:14 +0000 (17:26 +0200)
* Fixes that the same chain would be created each time a firewall
reload is performed.

* Also fixes multiple log and drop rules inside the the BLOCKLIST_DROP
  chains after doing a firewall reload.

* Orphaned BLOCKLIST_DROP chains now will be flushed and removed in case
  the blocklist gets disabled or the entire feature will be swithed off.

Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
config/firewall/rules.pl

index 1bd2920591baa0cca7cb71f1bc78c9d9ecb5597e..9198fec1d50d61b3b10e9dc6bde91ed58417947f 100644 (file)
@@ -731,35 +731,43 @@ sub ipblocklist () {
        run("$IPTABLES -F BLOCKLISTIN");
        run("$IPTABLES -F BLOCKLISTOUT");
 
-       # If the blocklist feature is disabled we are finished here.
-       if($blocklistsettings{'ENABLE'} ne "on") {
-               # Bye.
-               return;
-       }
-
        # Loop through the array of blocklists.
        foreach my $blocklist (@blocklists) {
-               # Skip disabled blocklists.
-               next unless($blocklistsettings{$blocklist}) && ($blocklistsettings{$blocklist} eq "on"));
-
-               # Call function to load the blocklist.
-               &ipset_restore($blocklist);
+               # Check if the blocklist feature and the current processed blocklist is enabled.
+               if(($blocklistsettings{'ENABLE'} eq "on") && ($blocklistsettings{$blocklist}) && ($blocklistsettings{$blocklist} eq "on")) {
+                       # Call function to load the blocklist.
+                       &ipset_restore($blocklist);
+
+                       # Call function to check if the corresponding iptables drop chain already has been created.
+                       if(&firewall_chain_exists("${blocklist}_DROP")) {
+                               # Create iptables chain.
+                               run("$IPTABLES -N ${blocklist}_DROP");
+
+                               # Check if logging is enabled.
+                               if($blocklistsettings{'LOGGING'} eq "on") {
+                                       # Create logging rule.
+                                       run("$IPTABLES -A ${blocklist}_DROP -j LOG -m limit --limit 10/second --log-prefix \"BLKLST_$blocklist\" ");
+                               }
 
-               # Create iptables chain.
-               run("$IPTABLES -N ${blocklist}_DROP");
+                               # Create Drop rule.
+                               run("$IPTABLES -A ${blocklist}_DROP -j DROP");
+                       }
 
-               # Check if logging is enables.
-               if($blocklistsettings{'LOGGING'} eq "on") {
-                       # Create logging rule.
-                       run("$IPTABLES -A ${blocklist}_DROP -j LOG -m limit --limit 10/second --log-prefix \"BLKLST_$blocklist\" ");
-               }
+                       # Add the rules to check against the set
+                       run("$IPTABLES -A BLOCKLISTIN -p ALL -i $RED_DEV -m set --match-set $blocklist src -j ${blocklist}_DROP");
+                       run("$IPTABLES -A BLOCKLISTOUT -p ALL -o $RED_DEV -m set --match-set $blocklist dst -j ${blocklist}_DROP");
 
-               # Create Drop rule.
-               run("$IPTABLES -A ${blocklist}_DROP -j DROP");
+               # IP blocklist or the blocklist is disabled.
+               } else {
+                       # Check if the blocklist related iptables drop chain exits.
+                       unless(&firewall_chain_exists("${blocklist}_DROP")) {
+                               # Flush the chain.
+                               run("$IPTABLES -F ${blocklist}_DROP");
 
-               # Add the rules to check against the set
-               run("$IPTABLES -A BLOCKLISTIN -p ALL -i $RED_DEV -m set --match-set $blocklist src -j ${blocklist}_DROP");
-               run("$IPTABLES -A BLOCKLISTOUT -p ALL -o $RED_DEV -m set --match-set $blocklist dst -j ${blocklist}_DROP");
+                               # Drop the chain.
+                               run("$IPTABLES -X ${blocklist}_DROP");
+                       }
+               }
        }
 }