]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/commitdiff
ipblocklist-update: Introduce script to automatically update blacklists.
authorStefan Schantl <stefan.schantl@ipfire.org>
Sun, 6 Mar 2022 14:11:48 +0000 (15:11 +0100)
committerStefan Schantl <stefan.schantl@ipfire.org>
Thu, 7 Jul 2022 15:26:13 +0000 (17:26 +0200)
Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
src/scripts/update-ipblocklists [new file with mode: 0644]

diff --git a/src/scripts/update-ipblocklists b/src/scripts/update-ipblocklists
new file mode 100644 (file)
index 0000000..16ed3da
--- /dev/null
@@ -0,0 +1,145 @@
+#!/usr/bin/perl
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2007-2022  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        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+use strict;
+use POSIX;
+
+# Load perl module to talk to the kernel syslog.
+use Sys::Syslog qw(:DEFAULT setlogsock);
+
+require '/var/ipfire/general-functions.pl';
+require "${General::swroot}/ipblocklist-functions.pl";
+require "${General::swroot}/lang.pl";
+
+# Hash to store the settings.
+my %settings = ();
+
+# The user and group name as which this script should be run.
+my $run_as = 'nobody';
+
+# Get user and group id of the user.
+my ( $uid, $gid ) = ( getpwnam $run_as )[ 2, 3 ];
+
+# Check if the script currently runs as root.
+if ( $> == 0 ) {
+       # Drop privileges and switch to the specified user and group.
+       POSIX::setgid( $gid );
+       POSIX::setuid( $uid );
+}
+
+# Establish the connection to the syslog service.
+openlog('ipblocklist', 'cons,pid', 'user');
+
+# Grab the configured providers.
+&General::readhash("${General::swroot}/ipblocklist/settings", \%settings);
+
+# Check if the blocklist feature is enabled.
+unless ($settings{'ENABLE'} eq "on") {
+       # Exit.
+       exit 0;
+}
+
+# Check if the red device is active.
+unless (-e "${General::swroot}/red/active") {
+       # Log to syslog.
+       &_log_to_syslog("<ERROR> Could not update any blocklist - The system is offline!");
+
+       # Exit.
+       exit 1;
+}
+
+# Get all available blocklists.
+my @blocklists = &IPblocklist::get_blocklists();
+
+# Gather the details, when a list got modified last time.
+my %modified = ();
+
+# Read-in data if the file exists.
+&General::readhash($IPblocklist::modified_file, \%modified ) if (-e $IPblocklist::modified_file);
+
+# Loop through the array of blocklists.
+foreach my $blocklist (@blocklists) {
+       # Skip if the blocklist is not enabled.
+       next if($settings{$blocklist} ne "on");
+
+       # Get current time.
+       my $time = time();
+
+       # Get time, when the blocklist has been downloaded last.
+       my $last_download_time = $modified{$blocklist};
+
+       # Get the holdoff rate in seconds for the current processed blocklist.
+       my $rate_time = &IPblocklist::get_holdoff_rate($blocklist);
+
+       # Calculate holdoff time.
+       my $holdoff_time = $last_download_time + $rate_time;
+
+       # Check if enough time has passed since the last download of the list.
+       if ($time <= $holdoff_time) {
+               # To frequent updates, log to syslog.
+               &_log_to_syslog("<INFO> Skipping $blocklist blocklist - Too frequent update attempts!");
+
+               # Skip this provider.
+               next;
+       }
+       
+       # Try to download and update the blocklist.
+       my $return = &IPblocklist::download_and_create_blocklist($blocklist);
+
+       # Check if we got a return code.
+       if ($return) {
+               # Handle different return codes.
+               if ($return eq "not_modified") {
+                       # Log notice to syslog.
+                       &_log_to_syslog("<INFO> Skipping $blocklist blocklist - It has not been modified!");
+               } elsif ($return eq "dl_error") {
+                       # Log error to the syslog.
+                       &_log_to_syslog("<ERROR> Could not update $blocklist blocklist - Download error\!");
+               } else {
+                       # Log error to syslog.
+                       &_log_to_syslog("<ERROR> Could not update $blocklist blocklist - Unexpected error\!");
+               }
+       } else {
+               # Log successfull update.
+               &_log_to_syslog("<INFO> Successfully updated $blocklist blocklist.");
+       }
+}
+
+END {
+       # Close connection to syslog.
+       closelog();
+}
+
+#
+# Tiny function to sent the error message to the syslog.
+#
+sub _log_to_syslog($) {
+       my ($message) = @_;
+
+       # The syslog function works best with an array based input,
+       # so generate one before passing the message details to syslog.
+       my @syslog = ("ERR", "$message");
+
+       # Send the log message.
+       syslog(@syslog);
+}
+
+1;