require "${General::swroot}/lang.pl";
require "/usr/lib/firewall/firewall-lib.pl";
require "${General::swroot}/location-functions.pl";
+require "${General::swroot}/ipblocklist-functions.pl";
# Set to one to enable debugging mode.
my $DEBUG = 0;
my %locationsettings = (
"LOCATIONBLOCK_ENABLED" => "off"
);
+my %blocklistsettings= (
+ "ENABLE" => "off",
+);
+
my %ipset_loaded_sets = ();
my @ipset_used_sets = ();
my $locationfile = "${General::swroot}/firewall/locationblock";
my $configgrp = "${General::swroot}/fwhosts/customgroups";
my $netsettings = "${General::swroot}/ethernet/settings";
+my $blocklistfile = "${General::swroot}/ipblocklist/settings";
&General::readhash("${General::swroot}/firewall/settings", \%fwdfwsettings);
&General::readhash("${General::swroot}/optionsfw/settings", \%fwoptions);
&General::readhash("$locationfile", \%locationsettings);
}
+# Check if the ipblocklist settings file exits.
+if (-e "$blocklistfile") {
+ # Read-in settings file.
+ &General::readhash("$blocklistfile", \%blocklistsettings);
+}
+
# Get all available locations.
my @locations = &Location::Functions::get_locations();
+# Get all supported blocklists.
+my @blocklists = &IPblocklist::get_blocklists();
+
# Name or the RED interface.
my $RED_DEV = &General::get_red_interface();
sub main {
# Get currently used ipset sets.
- &ipset_get_sets();
+ @ipset_used_sets = &ipset_get_sets();
# Flush all chains.
&flush();
# Load rules to block hostile networks.
&drop_hostile_networks();
+ # Handle ipblocklist.
+ &ipblocklist();
+
# Reload firewall policy.
run("/usr/sbin/firewall-policy");
$source = "";
}
+ # Make sure that $source is properly defined
+ next unless (defined $source);
+
my $source_intf = @$src[1];
foreach my $dst (@destinations) {
if ($source =~ /mac/) {
push(@source_options, $source);
} elsif ($source =~ /-m set/) {
- # Grab location code from hash.
- my $loc_src = $$hash{$key}[4];
+ # Split given arguments into single chunks to
+ # obtain the set name.
+ my ($a, $b, $c, $loc_src, $e) = split(/ /, $source);
# Call function to load the networks list for this country.
&ipset_restore($loc_src);
# Prepare destination options.
my @destination_options = ();
if ($destination =~ /-m set/) {
- # Grab location code from hash.
- my $loc_dst = $$hash{$key}[6];
+ # Split given arguments into single chunks to
+ # obtain the set name.
+ my ($a, $b, $c, $loc_dst, $e) = split(/ /, $destination);
# Call function to load the networks list for this country.
&ipset_restore($loc_dst);
run("$IPTABLES -A HOSTILE -o $RED_DEV -m set --match-set $HOSTILE_CCODE dst -j HOSTILE_DROP");
}
+sub ipblocklist () {
+ # Flush the ipblocklist chains.
+ run("$IPTABLES -F BLOCKLISTIN");
+ run("$IPTABLES -F BLOCKLISTOUT");
+
+ # 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) {
+ # 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");
+ }
+
+ # 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 Drop rule.
+ run("$IPTABLES -A ${blocklist}_DROP -j 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");
+
+ # 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");
+
+ # Drop the chain.
+ run("$IPTABLES -X ${blocklist}_DROP");
+ }
+ }
+ }
+}
+
sub get_protocols {
my $hash = shift;
my $key = shift;
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;
+
# Get all currently used ipset lists and store them in an array.
my @output = `$IPSET -n list`;
chomp($set);
# Add the set the array of used sets.
- push(@ipset_used_sets, $set);
+ push(@sets, $set);
}
# Display used sets in debug mode.
if($DEBUG) {
print "Used ipset sets:\n";
- print "@ipset_used_sets\n\n";
+ print "@sets\n\n";
}
+
+ # Return the array of sets.
+ return @sets;
}
sub ipset_restore ($) {
# If the set is not loaded, we have to rename it to proper use it.
run("$IPSET rename $loc_set $set");
}
+
+ # 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.
}
sub ipset_cleanup () {
+ # Reload the array of used sets.
+ @ipset_used_sets = &ipset_get_sets();
+
# Loop through the array of used sets.
foreach my $set (@ipset_used_sets) {
# Check if this set is still in use.