From ec1878771a278faaa4922955a3d1a1db7c0039f8 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Sun, 6 Mar 2022 15:11:48 +0100 Subject: [PATCH] ipblocklist-update: Introduce script to automatically update blacklists. Signed-off-by: Stefan Schantl --- src/scripts/update-ipblocklists | 145 ++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src/scripts/update-ipblocklists diff --git a/src/scripts/update-ipblocklists b/src/scripts/update-ipblocklists new file mode 100644 index 0000000000..16ed3da383 --- /dev/null +++ b/src/scripts/update-ipblocklists @@ -0,0 +1,145 @@ +#!/usr/bin/perl +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007-2022 IPFire Team # +# # +# 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 . # +# # +############################################################################### + +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(" 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(" 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(" Skipping $blocklist blocklist - It has not been modified!"); + } elsif ($return eq "dl_error") { + # Log error to the syslog. + &_log_to_syslog(" Could not update $blocklist blocklist - Download error\!"); + } else { + # Log error to syslog. + &_log_to_syslog(" Could not update $blocklist blocklist - Unexpected error\!"); + } + } else { + # Log successfull update. + &_log_to_syslog(" 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; -- 2.39.2