###############################################################################
# #
# IPFire.org - A linux based firewall #
-# Copyright (C) 2007-2020 IPFire Team <info@ipfire.org> #
+# Copyright (C) 2007-2024 IPFire Team <info@ipfire.org> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
"172.16.0.0/12",
"192.168.0.0/16",
"100.64.0.0/10",
+ "224.0.0.0/4",
);
# MARK masks
$source = "";
}
+ # Make sure that $source is properly defined
+ next unless (defined $source);
+
my $source_intf = @$src[1];
foreach my $dst (@destinations) {
&ipset_restore($HOSTILE_CCODE);
# Check traffic in incoming/outgoing direction and drop if it matches
- run("$IPTABLES -A HOSTILE -i $RED_DEV -m set --match-set $HOSTILE_CCODE src -j HOSTILE_DROP");
- run("$IPTABLES -A HOSTILE -o $RED_DEV -m set --match-set $HOSTILE_CCODE dst -j HOSTILE_DROP");
+ run("$IPTABLES -A HOSTILE -i $RED_DEV -m set --match-set $HOSTILE_CCODE src -j HOSTILE_DROP_IN");
+ run("$IPTABLES -A HOSTILE -o $RED_DEV -m set --match-set $HOSTILE_CCODE dst -j HOSTILE_DROP_OUT");
}
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;
+ # Check if the blocklist feature is enabled.
+ if($blocklistsettings{'ENABLE'} eq "on") {
+ # Loop through the array of private networks.
+ foreach my $private_network (@PRIVATE_NETWORKS) {
+ # Create firewall rules to never block private networks.
+ run("$IPTABLES -A BLOCKLISTIN -p ALL -i $RED_DEV -s $private_network -j RETURN");
+ run("$IPTABLES -A BLOCKLISTOUT -p ALL -o $RED_DEV -d $private_network -j RETURN");
+ }
}
# Loop through the array of blocklists.
foreach my $blocklist (@blocklists) {
- # Skip disabled blocklists.
- next unless($blocklistsettings{$blocklist}) && ($blocklistsettings{$blocklist} eq "on"));
+ # 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");
+ } else {
+ # Flush the chain.
+ run("$IPTABLES -F ${blocklist}_DROP");
+ }
- # Call function to load the blocklist.
- &ipset_restore($blocklist);
+ # Check if logging is enabled.
+ if(($blocklistsettings{'LOGGING'}) && ($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");
+ }
+ }
}
}
return 0;
}
+sub firewall_chain_exists ($) {
+ my ($chain) = @_;
+
+ my $ret = &General::system("iptables", "--wait", "-n", "-L", "$chain");
+
+ return $ret;
+}
+
sub ipset_get_sets () {
my @sets;
# Check if the given set name is a blocklist.
} elsif ($set ~~ @blocklists) {
+ # IPblocklist sets contains v4 as setname extension.
+ my $set_name = "$set" . "v4";
+
# Get the database file for the given blocklist.
my $db_file = &IPblocklist::get_ipset_db_file($set);
# Call function to restore/load the set.
&ipset_call_restore($db_file);
+
+ # Check if the set is already loaded (has been used before).
+ if ($set ~~ @ipset_used_sets) {
+ # Swap the sets.
+ run("$IPSET swap $set_name $set");
+ } else {
+ # Rename the set to proper use it.
+ run("$IPSET rename $set_name $set");
+ }
}
# Store the restored set to the hash to prevent from loading it again.