From patchwork Mon Apr 27 14:31:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim FitzGeorge X-Patchwork-Id: 3004 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 499nKl6jDWz3xQy for ; Mon, 27 Apr 2020 14:32:11 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKl1rjMz1nk; Mon, 27 Apr 2020 14:32:11 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 499nKl0NKZz2yVn; Mon, 27 Apr 2020 14:32:11 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 499nKj3XsNz2xnp for ; Mon, 27 Apr 2020 14:32:09 +0000 (UTC) Received: from smtp.hosts.co.uk (smtp.hosts.co.uk [85.233.160.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKj0dhhz32M for ; Mon, 27 Apr 2020 14:32:09 +0000 (UTC) Received: from [95.149.142.196] (helo=aragorn.hosts.co.uk.tfitzgeorge.me.uk) by smtp.hosts.co.uk with esmtpa (Exim) (envelope-from ) id 1jT4nm-0003Z9-6u; Mon, 27 Apr 2020 15:32:08 +0100 From: Tim FitzGeorge To: development@lists.ipfire.org Subject: [PATCH v2 1/8] ipblacklist: Main script Date: Mon, 27 Apr 2020 15:31:16 +0100 Message-Id: <20200427143123.6378-2-ipfr@tfitzgeorge.me.uk> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> References: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1587997929; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:in-reply-to:in-reply-to:references:references; bh=UymzgFsNLPCzCiWzflOtN5j0qd3gVGIPzJsdkkn2IUg=; b=BLvURApageYndKcymXj3astjToS/BKEu4pFciu/Yep6A/+7azFckBQiNkyaXoD7mHzs55H lTDJPUhY7EFxQxyG+rp3HP6uNUlXtbc6rJ0GR06Cfl7wahnsS8Er1ECdI9hlJIk25uz0Ox 01Dch7+vIBKQ0x16mddy+Ex72+HTGDVcIm7TUYg879UMsWCRLuMEXw6ze6GTMW8c/2VynP PIefiJOZzpfBYtU4bpZd2g/Z3DDFPdn03eN11KdZxK4ghAiMpVaM2LafxDAt/bY+zeEfyE De361VvYhROnzg+EVDkwqkL20KhBvMMOuD59buAAVOr+OJcYcA085FiX8lcb8A== ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1587997929; a=rsa-sha256; cv=none; b=hj1M/sYTRDFzf1D2GKbcB1ZFJuFAZ/jnpjKhpL/AI44cztcg/sf41/KYyPpcF9vSfKE5r+ xlGG/M5rX6E0Reb/gySbXz7SGwEbRFUxQSvq/mT5pLE4ZJZosyKrVmB7bgnAKAw3IYgox8 pgiGNItbWWIdlF3SG//8VU2KSZ90vUz8ia2U01i6102E8ihUGXwf95ERrexbA78Wte+QL5 nflV2cJy/yTAH+Mz/6CfzQ9RD7mSgoMnMaHOzGKxm6gNffVHAdcANT+3n2u0rdDUgzDup5 e2B+EYDUWhzGBvBJFW5y190AUHUbRpODfKABqst6bn3F+4B0BAXu4/VGvBpd7A== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk X-Rspamd-Queue-Id: 499nKj0dhhz32M X-Spamd-Result: default: False [-3.37 / 11.00]; RCVD_TLS_LAST(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[95.149.142.196:received]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; RWL_MAILSPIKE_GOOD(0.00)[85.233.160.19:from]; R_SPF_ALLOW(-0.20)[+ip4:85.233.160.0/27]; MIME_GOOD(-0.10)[text/plain]; ARC_SIGNED(0.00)[i=1]; ARC_NA(0.00)[]; DMARC_NA(0.00)[tfitzgeorge.me.uk]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[]; RCPT_COUNT_TWO(0.00)[2]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-0.96)[-0.964]; IP_REPUTATION_SPAM(0.01)[asn: 8622(0.00), country: GB(0.01), ip: 85.233.160.19(0.00)]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:8622, ipnet:85.233.160.0/19, country:GB]; RCVD_COUNT_TWO(0.00)[2]; BAYES_HAM(-3.00)[99.99%]; RCVD_IN_DNSWL_LOW(-0.10)[85.233.160.19:from] X-Rspamd-Server: mail01.haj.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Responsible for downloading blacklists and creating/modifying IPSets Does all work involving creating, deleting and changing IPTables and IPSets. Signed-off-by: Tim FitzGeorge --- src/scripts/ipblacklist | 1382 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1382 insertions(+) create mode 100755 src/scripts/ipblacklist diff --git a/src/scripts/ipblacklist b/src/scripts/ipblacklist new file mode 100755 index 000000000..6f950214c --- /dev/null +++ b/src/scripts/ipblacklist @@ -0,0 +1,1382 @@ +#! /usr/bin/perl + +############################################################################ +# # +# IP Address blocklists for IPFire # +# # +# This 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 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 IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2018 - 2020 The IPFire team # +# # +############################################################################ +# # +# This script uses a file containing blacklist details in # +# /var/ipfire/ipblacklist/sources as well as # +# /var/ipfire/ipblacklistsettings containing an enable/disable flag for # +# each source. # +# # +# Two IPTables chains are used: BLACKLISTIN and BLACKLISTOUT are inserted # +# inserted into the main INPUT, OUTPUT and FORWARD chains; they capture # +# packets other than for the ICMP protocol. # +# # +# For each blacklist that is loaded, a chain is created to optionally log # +# and then to drop matching packets. An IPSet is created containing the # +# addresses or networks blocked by the blacklist, and then rules are added # +# to the BLACKLISTIN and BLACKLISTOUT chains to jump to this chain if a # +# packet list matches the set. # +# # +# When checking for updates, the modification time is used for each source # +# and if necessary the list is downloaded. The downloaded list is # +# compared to the existing IPSet contents and entries created or deleted # +# as necessary. # +# # +############################################################################ + +use strict; +#use warnings; + +use Carp; +use Sys::Syslog qw(:standard :macros); +use HTTP::Request; +use LWP::UserAgent; + +require "/var/ipfire/general-functions.pl"; + +############################################################################ +# Configuration variables +# +# These variables give the locations of various files used by this script +############################################################################ + +my $settingsdir = "/var/ipfire/ipblacklist"; +my $savedir = "/var/lib/ipblacklist"; +my $tmpdir = "/var/tmp"; + +my $settings = "$settingsdir/settings"; +my $sources = "$settingsdir/sources"; +my $checked = "$settingsdir/checked"; +my $modified = "$settingsdir/modified"; +my $iptables_list = "/var/tmp/iptables.txt"; +my $getipstat = "/usr/local/bin/getipstat"; +my $iptables = "/sbin/iptables"; +my $ipset = "/usr/sbin/ipset"; +my $fcrontab = "/usr/bin/fcrontab"; +my $lockfile = "/var/run/ipblacklist.pid"; +my $proxy_settings = "${General::swroot}/proxy/settings"; +my $red_setting = "/var/ipfire/red/iface"; +my $detailed_log = "$tmpdir/ipblacklist_log.txt"; +my $active = "/var/ipfire/red/active"; + +# Other configuration items + +my $margin = 30; # Scheduling allowance for run time etc in seconds +my $count = 30; # Maximum time to wait for another instance (300s) +my $max_dl_fails = 3; # Ignore check rate limit for this number of failures +my $max_size_fraction = 0.7; # Maximum fill fraction of IPSet before enlarging. +my $min_ipset_entries = 1024; # The minimum size of an IPSet. +my $max_dl_bytes = 10_485_760; # Maximum number of bytes to download. +my %parsers = ( 'ip-or-net-list' => \&parse_ip_or_net_list, + 'dshield' => \&parse_dshield ); + +############################################################################ +# Default settings +# Should be overwritten by reading settings files +############################################################################ + +my %sources = ( ); + +my %settings = ( 'DEBUG' => 0, + 'LOGGING' => 'on', + 'ENABLE' => 'off' ); + +my %proxy_settings = ( 'UPSTREAM_PROXY' => '' ); # No Proxy in use + +############################################################################ +# Function prototypes +############################################################################ + +sub abort( $ ); +sub create_list( $ ); +sub create_ipset( $$$ ); +sub debug( $$ ); +sub delete_list( $ ); +sub disable_logging(); +sub disable_updates(); +sub do_delete(); +sub do_start(); +sub do_stop(); +sub do_update(); +sub download_list( $$$ ); +sub download_check_header_time( $$$ ); +sub download_wget( $$$ ); +sub enable_logging(); +sub enable_updates(); +sub get_ipsets(); +sub get_rate_seconds( $ ); +sub iptables( $ ); +sub ipset( $ ); +sub stop_ipset(); +sub is_connected(); +sub log_message( $$ ); +sub parse_dshield( $ ); +sub parse_ip_or_net_list( $ ); +sub read_ipset( $$$$ ); +sub update_list( $$$ ); + +############################################################################ +# Variables +############################################################################ + +my %chains; # The Blacklist IPSets already loaded +my %old_blacklist; # Already blocked IP Addresses and/or networks + # downloaded for current blacklist +my $update_status = 0; # Set to 1 to update status file +my $ipset_running = 0; # Set to 1 if IPSet process is running +my %status; # Status information +my %checked; # Time blacklists last changed +my %modified; # Time blacklists last modified +my $red_iface; # The name of the red interface + +############################################################################ +# Synchronise runs +############################################################################ + +# This script can be triggered either by cron or the WUI. If another +# instance is running, wait for it to finish or timeout. + +while (-r $lockfile and $count > 0) +{ + open LOCKFILE, '<', $lockfile or (abort "Can't open lockfile", last); + my $pid = ; + close LOCKFILE; + + chomp $pid; + + last unless (-e "/proc/$pid"); + + sleep 10; + $count--; +} + +# Create pid file before starting main processing + +open LOCKFILE, '>', '/var/run/ipblacklist.pid' or abort "Can't open PID file: $!"; +print LOCKFILE "$$\n"; +close LOCKFILE; + +############################################################################ +# Set up for update +############################################################################ + +mkdir $settingsdir unless (-d $settingsdir); + +# Connect to the system log + +openlog( "ipblacklist", "nofatal", LOG_USER); +log_message LOG_INFO, "Starting IP Blacklist processing"; + +# Read settings + +General::readhash( $settings, \%settings ) if (-e $settings); +General::readhash( $checked, \%checked ) if (-e $checked); +General::readhash( $modified, \%modified ) if (-e $modified); +General::readhash( $proxy_settings, \%proxy_settings ) if (-e $proxy_settings); + +if (-r $sources) +{ + debug 1, "Reading sources file"; + + eval qx|/bin/cat $sources|; +} + +if (-r $red_setting) +{ + open REDIF, '<', $red_setting or (abort "Can't open red interface file", exit); + $red_iface = ; + chomp $red_iface; + close REDIF; +} + +if (@ARGV) +{ + foreach my $cmd (@ARGV) + { + if ('update' =~ m/^$cmd/i) + { + # Called hourly when enabled and on setting changes. + # Update the blacklists. + + if ($settings{'ENABLE'} eq 'on') + { + do_update(); + } + } + elsif ('start' =~ m/^$cmd/i) + { + # Called during system startup. + # Restore saved blacklists. + # Don't do an update since can take too long. + + do_start() if ($settings{'ENABLE'} eq 'on'); + } + elsif ('stop' =~ m/^$cmd/i) + { + # Called when shutting down. + # Delete IPSets and IPTables chains + + do_stop(); + } + elsif ('restore' =~ m/^$cmd/i) + { + # Called after restoring backup. + # Delete IPSets and IPTables chains, then re-create them with the new + # (restored) settings and make sure updates are enabled. + + do_stop(); + + if ($settings{'ENABLE'} eq 'on') + { + do_start(); + enable_updates(); + } + else + { + disable_updates(); + } + } + elsif ('log-on' =~ m/^$cmd/i) + { + # Called from WUI. + # Create entries in IPTables chains to log dropped packets. + + if ($settings{'ENABLE'} eq 'on') + { + enable_logging(); + } + } + elsif ('log-off' =~ m/^$cmd/i) + { + # Called from WUI + # Delete entries in IPTables chains to log dropped packets. + + disable_logging(); + } + elsif ('enable' =~ m/^$cmd/i) + { + # Called from WUI to enable blacklists + # Do an update and then enable automatic updates + + if ($settings{'ENABLE'} eq 'on') + { + do_update(); + enable_updates(); + } + } + elsif ('disable' =~ m/^$cmd/i) + { + # Called from WUI to disable blacklists. + # Disable updates, delete IPSets, IPTables chains and save files. + + disable_updates(); + do_delete(); + } + else + { + print "Usage: $0 [update|start|stop|restart|log-on|log-off|enable|disable]\n"; + } + } +} +elsif ($settings{'ENABLE'} eq 'on') # Default action if none specified +{ + do_update(); +} + +stop_ipset(); + +if ($update_status) +{ + debug 1, "Writing updated status file"; + + General::writehash( $checked, \%checked ); + General::writehash( $modified, \%modified ); +} + +# Remove the pid file + +unlink $lockfile; + +log_message LOG_INFO, "Finished IP Blacklist processing"; +closelog(); + + +#------------------------------------------------------------------------------ +# sub do_stop +# +# Deletes all the IPTables chains and the IPSets +#------------------------------------------------------------------------------ + +sub do_stop() +{ + get_ipsets(); + + log_message LOG_NOTICE, "Stopping IP Blacklists"; + + foreach my $list ( sort keys %sources ) + { + delete_list( $list ) if (exists $chains{$list}); + } +} + + +#------------------------------------------------------------------------------ +# sub do_start +# +# Recreates the IPTables chains and the IPSets from the saved values +#------------------------------------------------------------------------------ + +sub do_start() +{ + log_message LOG_NOTICE, "Starting IP Blacklists"; + + foreach my $list ( sort keys %sources ) + { + delete_list( $list ) if (exists $chains{$list}); # Make sure OK to start + + if ((-e "$savedir/$list.conf") and ($red_iface)) + { + log_message LOG_INFO, "Restoring blacklist $list"; + system( "$ipset restore -f $savedir/$list.conf" ); # Can't use the ipset + # function to do this + + create_list( $list ); + } + } +} + + +#------------------------------------------------------------------------------ +# sub do_delete +# +# Deletes the IPTables chains, the IPSets and the saved values. +#------------------------------------------------------------------------------ + +sub do_delete() +{ + # Get the list of current ipsets + + get_ipsets(); + + log_message LOG_NOTICE, "Deleting IP Blacklists"; + + foreach my $source ( sort keys %sources ) + { + if (exists $chains{$source}) + { + delete_list( $source ); + } + + if (-e "$savedir/$source.conf") + { + unlink "$savedir/$source.conf"; + } + } + + %modified = (); + $update_status = 1; +} + + +#------------------------------------------------------------------------------ +# sub do_update +# +# Updates all the blacklists. +# Creates or deletes the blacklist firewall rules as necessary and checks for +# updates to the blacklists. Each blacklist has its own minimum elapsed time +# between updates, which is specified in the sources file, so the time of each +# check is stored. +#------------------------------------------------------------------------------ + +sub do_update() +{ + return unless ($red_iface); + + # Get the list of current ipsets + + get_ipsets(); + + # Check sources + + debug 1, "Checking blacklist sources"; + + LIST: + foreach my $list ( sort keys %sources ) + { + my @new_blacklist = (); + my $name = $sources{$list}{'name'}; + my $last_checked = $checked{$list} || 0; + my $failures = $checked{"${list}_failures"} || 0; + my $enabled = 0; + + if (exists $settings{$list}) + { + $enabled = $settings{$list} eq 'on'; + } + + if ($enabled and is_connected()) + { + debug 1, "Checking blacklist source: $name"; + + # Calculate the per list rate + + my $rate = get_rate_seconds( $sources{$list}{'rate'} ); + + # Has enough time passed since the last time we checked the list? + # Ignore the limit if the last download failed + + if (($last_checked + $rate) < (time() + $margin) or + ($failures > 0 and $failures < $max_dl_fails)) + { + my $type = 'hash:ip'; + + download_list( $list, \@new_blacklist, \$type ); + + next LIST unless (@new_blacklist); + + if (not exists $chains{$list}) + { + # Doesn't currently exist: Create it. + + create_ipset( $list, $type, scalar @new_blacklist ); + create_list( $list ); + } + + update_list( $list, \@new_blacklist, $type ); + } + } + elsif (exists $chains{$list}) + { + # Exists, but not enabled: Delete it. + + delete_list( $list ); + + # Delete the save file + # Don't delete the checked time from the status, in case the list is + # re-enabled quickly - don't want to exceed maximum allowed download + # rate. + + unlink "$savedir/$list.conf" if (-e "$savedir/$list.conf"); + + delete $modified{$list} if (exists $modified{$list}); + delete $checked{"${list}_failures"} if (exists $checked{"${list}_failures"}); + $update_status = 1; + } + } + + # Check for any lists that don't exist any more + + foreach my $list (keys %modified) + { + next if (exists $sources{$list}); + + delete_list( $list ); + + # Delete the save file + + unlink "$savedir/$list.conf" if (-e "$savedir/$list.conf"); + + # Delete from the status + + delete $modified{$list} if (exists $modified{$list}); + $update_status = 1; + } + + foreach my $list (keys %checked) + { + next if ($list =~ m/_failures/); + next if (exists $sources{$list}); + + delete $checked{$list}; + delete $checked{"${list}_failures"}; + delete $settings{$list} if (exists $settings{$list}); + $update_status = 1; + } +} + + +#------------------------------------------------------------------------------ +# sub get_rate_seconds( text ) +# +# Converts a check rate into seconds. A sanity check is made on the coverted +# value. +# +# Parameters: +# text The value to convert in the form nnnu, where nnn is a number and u +# is either m (minutes), h (hours) or d (days). Hours is assumed if +# not specified and everything after the first letter is ignored. +#------------------------------------------------------------------------------ + +sub get_rate_seconds( $ ) +{ + my ($text) = @_; + + my ($value, $unit) = (uc $text) =~ m/(\d+)([DHM]?)/; + + if ($unit eq 'D') # Days + { + $value *= 60 * 60 * 24; + } + elsif ($unit eq 'M') # Minutes + { + $value *= 60; + } + else # Everything else - assume hours + { + $value *= 60 * 60; + } + + # Sanity check - limit to range 5 min .. 1 week + + # d h m s + $value = 5 * 60 if ($value < 5 * 60); + $value = 7 * 24 * 60 * 60 if ($value > 7 * 24 * 60 * 60); + + return $value; +} + + +#------------------------------------------------------------------------------ +# sub is_connected() +# +# Checks that the system is connected to the internet. +# +# This looks for a file created by IPFire when connected to the internet +#------------------------------------------------------------------------------ + +sub is_connected() +{ + return (-e $active); +} + + +#------------------------------------------------------------------------------ +# sub create_list( list ) +# +# Creates a new IPTables chain for a blacklist source. +# The set must be created before calling this function. Two rules are added to +# the chain: +# (optional) 1 Log the packet +# 2 Drop the packet +# +# The log rule is only added when logging is enabled by the WUI. +# +# Rules are then added to the BLACKLISTIN and BLACKLISTOUT chains that check +# the packet's IP address against the IPSet and then jump to the newly created +# chain. +# +# Parameters: +# list The name of the blacklist +#------------------------------------------------------------------------------ + +sub create_list( $ ) +{ + my ($list) = @_; + + log_message LOG_INFO, "Create IPTables chains for blacklist $list"; + + # Create new chain in filter table + + iptables( "-N ${list}_DROP" ) == 0 or + ( abort "Could not create IPTables chain ${list}_DROP", return ); + + # Add the logging and drop rules + + if ($settings{'LOGGING'} eq 'on') + { + iptables( "-A ${list}_DROP -j LOG -m limit --limit 10/second --log-prefix 'BLKLST_$list'" ) == 0 or + ( abort "Could not create IPTables chain $list LOG rule", return ); + } + + iptables( "-A ${list}_DROP -j DROP" ) == 0 or + ( abort "Could not create IPTables chain $list drop rule", return ); + + # Add the rules to check against the set + + iptables( "-A BLACKLISTIN -p ALL -i $red_iface -m set --match-set $list src -j ${list}_DROP" ); + iptables( "-A BLACKLISTOUT -p ALL -o $red_iface -m set --match-set $list dst -j ${list}_DROP" ); +} + + +#------------------------------------------------------------------------------ +# sub delete_list( $list ) +# +# Deletes an IPTables chain when a blacklist source is disabled. Also flushes +# and destroys the IPSet. +# +# Parameters: +# list The name of the blacklist +#------------------------------------------------------------------------------ + +sub delete_list( $ ) +{ + my ($list) = @_; + + log_message LOG_INFO, "Delete IPTables chains for blacklist $list"; + + # Remove the blacklist chains from the main INPUT and OUTPUT chains + + iptables( "-D BLACKLISTIN -p ALL -i $red_iface -m set --match-set $list src -j ${list}_DROP" ); + iptables( "-D BLACKLISTOUT -p ALL -o $red_iface -m set --match-set $list dst -j ${list}_DROP" ); + + # Flush and delete the chain + + iptables( "-F ${list}_DROP" ); + iptables( "-X ${list}_DROP" ); + + # Flush and delete the set + + ipset( "flush $list" ); + ipset( "destroy $list" ); +} + + +#------------------------------------------------------------------------------ +# sub download_list( list, ref_list, ref_type ) +# +# Downloads the IP Addresses for a blacklist. +# +# Once downloaded the list is parsed to get the IP addresses and/or networks. +# +# Parameters: +# list The name of the blacklist +# ref_list A reference to an array to store the downloaded blacklist +# ref_type A reference to store the type of the blacklist +#------------------------------------------------------------------------------ + +sub download_list( $$$ ) +{ + my ($list, $new_blacklist, $type) = @_; + + $checked{$list} = time(); # Record that the list has been checked + $update_status = 1; + + # Check the parser for the blacklist + + if (not exists $parsers{ $sources{$list}{'parser'} }) + { + log_message LOG_ERR, "Can't find parser $sources{$list}{'parser'} for $list blacklist"; + return; + } + + # Add alternative download mechanisms here + + download_check_header_time( $list, $new_blacklist, $type ); +} + + +#------------------------------------------------------------------------------ +# sub download_check_header_time( list, ref_list, ref_type ) +# +# Updates the IP Addresses for a blacklist. The If-Modified-Since header is +# specified in the request so that only updated lists are downloaded (providing +# that the server supports this functionality). +# +# Once downloaded the list is parsed to get the IP addresses and/or networks. +# +# Parameters: +# list The name of the blacklist +# ref_list A reference to an array to store the downloaded blacklist +# ref_type A reference to store the type of the blacklist +# +# Returns: +# The list type: 'hash:ip' or 'hash:net' +#------------------------------------------------------------------------------ + +sub download_check_header_time( $$$ ) +{ + my ($list, $new_blacklist, $type) = @_; + my $found_ip = 0; + my $found_net = 0; + + # Get the parser for the blacklist + + my $parser = $parsers{ $sources{$list}{'parser'} }; + + debug 1, "Checking for blacklist $list updates with LWP"; + + # Create a user agent for downloading the blacklist + # Limit the download size for safety + + my $ua = LWP::UserAgent->new( max_size => $max_dl_bytes ); + + # Get the Proxy settings + + if ($proxy_settings{'UPSTREAM_PROXY'}) + { + if ($proxy_settings{'UPSTREAM_USER'}) + { + $ua->proxy( [["http", "https"] => "http://$proxy_settings{'UPSTREAM_USER'}:$proxy_settings{'UPSTREAM_PASSWORD'}\@$proxy_settings{'UPSTREAM_PROXY'}/"] ); + } + else + { + $ua->proxy( [["http", "https"] => "http://$proxy_settings{'UPSTREAM_PROXY'}/"] ); + } + } + + # Get the last modified time + + my $modified = gmtime( $modified{$list} || 0 ); + + # Download the blacklist + + my $response = $ua->get( $sources{$list}{'url'}, 'If-Modified-Since' => $modified ); + + if (not $response->is_success) + { + if ($response->code == 304) + { + # Not an error - list has not been modified + debug 1, "Blacklist $list not modified"; + + return; + } + + log_message LOG_WARNING, "Failed to download $list blacklist $sources{$list}{'url'}: ". $response->status_line; + $checked{"${list}_failures"}++; + + return; + } + + $modified{$list} = $response->last_modified; + $checked{"${list}_failures"} = 0; + + # Parse the downloaded list, checking if it's a list of addresses or nets + + foreach my $line (split /[\r\n]+/, $response->content) + { + chomp $line; + + my $address = &$parser( $line ); + + next unless ($address and $address =~ m/\d+\.\d+\.\d+\.\d+/); + + if ($address =~ m|/32|) + { + $address =~ s|/32||; + $found_ip = 1; + } + elsif ($address =~ m|/\d+|) + { + $found_net = 1; + } + else + { + $found_ip = 1; + } + + push @{ $new_blacklist }, $address; + } + + if ($found_net and $found_ip) + { + # Convert mixed addresses and networks to all networks + + foreach my $address (@{ $new_blacklist }) + { + $address .= '/32' unless ($address =~ m|/\d+|); + } + + $found_ip = 0; + } + + $$type = $found_net ? 'hash:net' : 'hash:ip'; +} + + +#------------------------------------------------------------------------------ +# sub read_ipset( list, old, type, maxelem ) +# +# Reads the existing contents and type of the set. +# +# Parameters: +# list The name of the blacklist +# old Reference to array to contain blacklist +# type Reference to type +# maxelem Reference to maximum number of elements +#------------------------------------------------------------------------------ + +sub read_ipset( $$$$ ) +{ + my ($list, $old, $type, $maxelem) = @_; + my $found_net = 0; + my $found_ip = 0; + + debug 2, "Reading existing ipset for blacklist $list"; + + foreach my $line (qx/$ipset list $list/) + { + if ($line =~ m|Header:.*maxelem (\d+)|) + { + $$maxelem = $1; + next; + } + + next unless ($line =~ m|(\d+\.\d+\.\d+\.\d+(?:/\d+)?)|); + + my $address = $1; + + if ($address =~ m|/32|) + { + $found_ip = 1; + $address =~ s|/32$||; + } + elsif ($address =~ m|/\d+$|) + { + $found_net = 1; + } + else + { + $found_ip = 1; + } + + $$old{$address} = 1; + } + + if ($found_ip and $found_net) + { + # Convert mixed addresses and networks to all networks + + my @ads_list = keys %{ $old }; + + foreach my $address (@ads_list) + { + unless ($address =~ m|/\d+|) + { + delete $$old{$address}; + $$old{"$address/32"} = 1; + } + } + + $found_ip = 0; + } + + $$type = $found_net ? 'hash:net' : 'hash:ip'; +} + + +#------------------------------------------------------------------------------ +# sub update_list( list, new, new_type ) +# +# Updates the IP Addresses for a blacklist +# +# The new list is compared to the existing list and new entries added or old +# entries deleted as necessary. If the list type ('hash:ip' or 'hash:net') has +# changed then the IPSet is deleted and re-created with the new type. +# +# Parameters: +# list The name of the blacklist +# new Reference to array of new blacklist entries +# new_type The type of the updated list (hash:ip or hash:net) +#------------------------------------------------------------------------------ + +sub update_list( $$$ ) +{ + my ($list, $new, $new_type) = @_; + my %old; + my $old_type; + my $changes = 0; + my $maxelem = 0; + + debug 1, "Checking for $list blacklist update from $sources{$list}{'url'}"; + + if (exists $chains{$list} ) + { + my $recreate_ipset = 0; + + read_ipset( $list, \%old, \$old_type, \$maxelem ); + + # Check the IPSet type hasn't changed + + if ($new_type ne $old_type) + { + log_message LOG_NOTICE, "Blacklist $list changed type from $old_type to $new_type"; + $recreate_ipset = 1; + } + + if ($max_size_fraction * $maxelem < scalar @{ $new } ) + { + log_message LOG_NOTICE, "Blacklist $list changed size from $maxelem"; + $recreate_ipset = 1; + } + + if ($recreate_ipset) + { + # Change the IPSet type and/or size. This requires removing references + # to it first. We could delete and then create the chain, but doing it + # like this keeps the statistics. + + # Remove the IPSet from the IPTables chains + + iptables( "-D 'BLACKLISTIN' -p ALL -i $red_iface -m set --match-set $list src -j ${list}_DROP" ) == 0 or + log_message LOG_ERR, "Could not remove ${list} from BLACKLISTIN chain"; + + iptables( "-D 'BLACKLISTOUT' -p ALL -o $red_iface -m set --match-set $list dst -j ${list}_DROP" ) == 0 or + log_message LOG_ERR, "Could not remove ${list} from BLACKLISTOUT chain"; + + # Flush and delete the old set + + ipset( "flush $list" ); + ipset( "destroy $list" ); + + %old = (); # Since we've deleted the old set it can't have any entries. + + # Create the new ipset + + create_ipset( $list, $new_type, scalar @{ $new } ); + + # Add the rules to check against the set + + iptables( "-A 'BLACKLISTIN' -p ALL -i $red_iface -m set --match-set $list src -j ${list}_DROP" ) == 0 or + log_message LOG_ERR, "Could not add IPSet $list to BLACKLISTIN chain"; + + iptables( "-A 'BLACKLISTOUT' -p ALL -o $red_iface -m set --match-set $list dst -j ${list}_DROP" ) == 0 or + log_message LOG_ERR, "Could not add IPSet $list to BLACKLISTOUT chain"; + } + } + + # Process the blacklist + + foreach my $address ( @{ $new } ) + { + # We've got an address. Add to IPSet if it's new + + if (exists $old{$address}) + { + delete $old{$address}; # Not new - don't delete from chain later + } + else + { + ipset( "add $list $address -exist" ); # New - add it + + $changes++; + } + + debug 3, "Add net $address to blacklist $list"; + } + + # Delete old entries that aren't needed any more + + debug 2, "Removing deleted rules from IPTables chain for blacklist $list"; + + foreach my $address ( keys %old ) + { + ipset( "del $list $address" ); + + $changes++; + + debug 3, "Delete old net $address from blacklist $list"; + } + + log_message LOG_INFO, "Updated $list blacklist with $changes changes"; + + # Save the blacklist for the next reboot + + mkdir "$savedir" unless (-d "$savedir" ); + + ipset( "save $list -file $savedir/$list.conf" ) if ($changes > 0); + + stop_ipset(); +} + + +#------------------------------------------------------------------------------ +# sub get_ipsets( ) +# +# Gets a list of the current IPSets +#------------------------------------------------------------------------------ + +sub get_ipsets( ) +{ + debug 1, "Reading list of existing ipsets"; + + my @sets = qx($ipset -n list); + + # Parse the tables + + foreach my $line (@sets) + { + chomp $line; + + next unless ($line); + + $chains{$line} = 1; + } +} + + +#------------------------------------------------------------------------------ +# sub create_ipset( list, type, size ) +# +# Creates a new IPSet. The current size of the set is determined by taking the +# next power of two greater than the number of entries; the maximum size is set +# to double this, subject to a minimum size. This allows for future expansion. +# +# Parameters: +# list The name of the blacklist +# type The type of the blacklist (hash:ip or hash:net) +# size The number of entries in the lsit +#------------------------------------------------------------------------------ + +sub create_ipset( $$$ ) +{ + my ($list, $type, $size) = @_; + + my $hashsize = 1; + $hashsize <<= 1 while ($hashsize < $size); + my $maxsize = $hashsize * 2; + $maxsize = $min_ipset_entries if ($maxsize < $min_ipset_entries); + + # Create the new ipset + ipset( "create $list $type hashsize $hashsize maxelem $maxsize" ); + stop_ipset(); # Need to do this to action the IPSet commands +} + + +#------------------------------------------------------------------------------ +# sub enable_logging() +# +# Enable logging of packets dropped by IP Blacklist rules. +# This adds a rule to log the packet to each lists' IPTables chain. +#------------------------------------------------------------------------------ + +sub enable_logging() +{ + get_ipsets(); + + log_message LOG_NOTICE, "Enabling IP Blacklist logging"; + + foreach my $list ( sort keys %sources ) + { + if (exists $chains{$list}) + { + iptables( "-I ${list}_DROP 1 -j LOG -m limit --limit 10/second --log-prefix 'BLKLST_$list'" ); + } + } +} + + +#------------------------------------------------------------------------------ +# sub disable_logging() +# +# Disable logging of packets dropped by IP Blacklist rules. +# This deletes a rule to log the packet from each lists' IPTables chain. +#------------------------------------------------------------------------------ + +sub disable_logging() +{ + get_ipsets(); + + log_message LOG_NOTICE, "Disabling IP Blacklist logging"; + + foreach my $list ( sort keys %sources ) + { + if (exists $chains{$list}) + { + iptables( "-D ${list}_DROP -j LOG -m limit --limit 10/second --log-prefix 'BLKLST_$list'" ); + } + } +} + + +#------------------------------------------------------------------------------ +# sub enable_updates() +# +# Adds a command to the fcrontab to run the update hourly. +# If there is a command already in the fcrontab to do this it will be +# uncommented, otherwise a new line is added. +# +# The update is executed at an offset from the hour so that all the users don't +# try to download the updates at exactly the same time - the blacklists are +# provided free, so it's good manners to spread the load on the servers. The +# offset is initialised to a random number that avoids running on the hour +# (when a lot of other things happen), and every fifteen minutes thereafter. +#------------------------------------------------------------------------------ + +sub enable_updates() +{ + my @lines = qx/$fcrontab -l/; + my $found = 0; + + # Check for an existing fcrontab entry. + + foreach my $line (@lines) + { + if ($line =~ m|/usr/local/bin/ipblacklist|) + { + return if ($line !~ m/^#/); # Already enabled - do nothing + + # Already in fcrontab - uncomment the line + + $line =~ s/^#+//; + $found = 1; + log_message LOG_INFO, "Enable IP Address Blacklist update in crontab"; + last; + } + } + + if (not $found) + { + # Add a new entry to fcrontab + + my $start = int( rand(13) ) + 1; + + my $times = $start; + + for (my $offset = $times+15 ; $offset < 60 ; $offset += 15) + { + $times .= ",$offset"; + } + + push @lines, "\n"; + push @lines, "# IP Blacklist update\n"; + push @lines, "\%nice(1) $times * * * * /usr/local/bin/ipblacklist\n"; + log_message LOG_INFO, "Add IP Address Blacklist update to crontab"; + } + + open FCRONTAB, "| $fcrontab -" or (abort "Can't open pipe to write fcrontab: $!", return); + print FCRONTAB @lines; + close FCRONTAB; +} + + +#------------------------------------------------------------------------------ +# sub disable_updates() +# +# Comments out the entry in the fcrontab that runs the updates. +#------------------------------------------------------------------------------ + +sub disable_updates() +{ + my @lines = qx/$fcrontab -l/; + my $found = 0; + + foreach my $line (@lines) + { + if ($line =~ m|/usr/local/bin/ipblacklist|) + { + return if ($line =~ m/^#/); # Already disabled - do nothing + + # In fcrontab - comment the line + + $line =~ s/^#*/#/; + $found = 1; + log_message LOG_INFO, "Disable IP Address Blacklist updates"; + last; + } + } + + return unless ($found); # Don't update crontab unnecessarily + + open FCRONTAB, "| $fcrontab -" or (abort "Can't open pipe to write fcrontab: $!", return); + print FCRONTAB @lines; + close FCRONTAB; +} + + +#------------------------------------------------------------------------------ +# sub parse_ip_or_net_list( line ) +# +# Parses an input line, looking for lines starting with an IP Address or +# Network specification. +# +# Parameters: +# line The line to parse +# +# Returns: +# Either an IP Address or a null string +#------------------------------------------------------------------------------ + +sub parse_ip_or_net_list( $ ) +{ + my ($line) = @_; + + $line =~ m|^(\d+\.\d+\.\d+\.\d+(?:/\d+)?)|; + + return $1; +} + + +#------------------------------------------------------------------------------ +# sub parse_dshield( line ) +# +# Parses an input line removing comments. +# +# The format is: +# Start Addrs End Addrs Netmask Nb Attacks Network Name Country email +# We're only interested in the start address and netmask. +# +# Parameters: +# line The line to parse +# +# Returns: +# Either and IP Address or a null string +#------------------------------------------------------------------------------ + +sub parse_dshield( $ ) +{ + my ($line) = @_; + + return "" if ($line =~ m/^\s*#/); + + $line =~ s/#.*$//; + + # |Start addrs | |End Addrs | |Mask + $line =~ m|(\d+\.\d+\.\d+\.\d+(?:/\d+)?)\s+\d+\.\d+\.\d+\.\d+(?:/\d+)?\s+(\d+)|; + + return unless ($1); + return "$1/32" unless ($2); + + return "$1/$2"; +} + + +#------------------------------------------------------------------------------ +# sub iptables( cmd ) +# +# Executes an IPTables command, waiting for the internal lock to ensure only +# one change is made at a time. +# +# Parameters: +# cmd The command to execute +# +# Returns: +# Status of command +#------------------------------------------------------------------------------ + +sub iptables( $ ) +{ + my ($cmd) = @_; + + return system( "$iptables $cmd" ); +} + + +#------------------------------------------------------------------------------ +# sub ipset( cmd ) +# +# Executes an IPSet command. The command is piped to a sub-process running +# ipset, rather than exected separately. This saves the overhead of starting a +# new process for each command. The sub-process is started if it's not already +# running. +# +# Note that the pipe is buffered so commands are not necessarily executed +# immediately. Use ipset_stop() to force commands to be executed. This should +# be done before relying on anything that the ipset commands do, for example +# before referencing the IPSet in an IPTables command. +# +# Parameters: +# cmd The command to execute +#------------------------------------------------------------------------------ + +sub ipset( $ ) +{ + my ($cmd) = @_; + + if (not $ipset_running) + { + local $SIG{PIPE} = 'IGNORE'; + open IPSET, "|-", $ipset, "restore" or die "Can't start ipset: $!"; + $ipset_running = 1; + } + + print IPSET "$cmd\n"; +} + + +#------------------------------------------------------------------------------ +# sub stop_ipset( ) +# +# Stops the ipset sub-process. +# This causes any pending ipset commands to be executed. +#------------------------------------------------------------------------------ + +sub stop_ipset( ) +{ + if ($ipset_running) + { + close IPSET or abort "ipset process died: $! $?"; + $ipset_running = 0; + } +} + + +#------------------------------------------------------------------------------ +# sub abort( message, parameters... ) +# +# Used when aborting the current activity, printing out an error message. +# +# Parameters: +# message Message to be printed +#------------------------------------------------------------------------------ + +sub abort( $ ) +{ + my ($message) = @_; + + log_message( LOG_ERR, $message ); + carp $message; +} + + +#------------------------------------------------------------------------------ +# sub log_message( level, message ) +# +# Logs a message. If the script is run from a terminal messages are also +# output on STDOUT. +# +# Parameters: +# level Severity of message +# message Message to be logged +#------------------------------------------------------------------------------ + +sub log_message( $$ ) +{ + my ($level, $message) = @_; + + print "($level) $message\n" if (-t STDIN); + syslog( $level, $message ); +} + + +#------------------------------------------------------------------------------ +# sub debug( level, message ) +# +# Optionally logs a debug message. If the script is run from a terminal, level +# 1 debug messages are output regardless of the debug setting. +# +# Parameters: +# level Debug level +# message Message to be logged +#------------------------------------------------------------------------------ + +sub debug( $$ ) +{ + my ($level, $message) = @_; + + if (($level <= $settings{'DEBUG'}) or + ($level == 1 and -t STDIN)) + { + log_message LOG_DEBUG, $message; + } +} From patchwork Mon Apr 27 14:31:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim FitzGeorge X-Patchwork-Id: 3006 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 499nKr21qzz3xQy for ; Mon, 27 Apr 2020 14:32:16 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKp12Wkz3B5; Mon, 27 Apr 2020 14:32:14 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 499nKp04zWz2yxh; Mon, 27 Apr 2020 14:32:14 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 499nKl5Jxzz2xnp for ; Mon, 27 Apr 2020 14:32:11 +0000 (UTC) Received: from smtp.hosts.co.uk (smtp.hosts.co.uk [85.233.160.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKk1sNLz32M for ; Mon, 27 Apr 2020 14:32:10 +0000 (UTC) Received: from [95.149.142.196] (helo=aragorn.hosts.co.uk.tfitzgeorge.me.uk) by smtp.hosts.co.uk with esmtpa (Exim) (envelope-from ) id 1jT4no-0003Z9-9Y; Mon, 27 Apr 2020 15:32:10 +0100 From: Tim FitzGeorge To: development@lists.ipfire.org Subject: [PATCH v2 2/8] ipblacklist: WUI Settings page Date: Mon, 27 Apr 2020 15:31:17 +0100 Message-Id: <20200427143123.6378-3-ipfr@tfitzgeorge.me.uk> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> References: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1587997930; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:in-reply-to:in-reply-to:references:references; bh=SvuIDqAMYikC5T3E6p2/sw5JzJitivid2BgzjiNzuzc=; b=lQOuFEjqVnwdCLPWP5Nj2+FGpK/P++hV+S6TO03aV5W1eBAdaXm4NjTBMjwgrofm9HGHjj bxPvoMs3dFo8AJX6ZUxNq2SP4fTDxd/0ttXPK9jkQZdgdvl7rtI2Na3G8+gkBOVQSqTRew CuBVyQdcnlWOi+YGDC+cPHg94ti2tww/PDCXRIJleKPWrYo8VrKif4tp+1+QCyNciKD7RB FZ0TExFAEUb90s0GjqySRuLQ93dGIp8AMLXEQv6wfB8BFhpcZ5VBo0+smQtWxqoN+4IlDi 6c9MFsOtmI8yr6+T5iaDyag+wQ7alkYR5KnJT9n4WYz+ePoibC2DfTm/dULUXg== ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1587997930; a=rsa-sha256; cv=none; b=FMOtnukAh5i1+Mv5ni+IvrybGBTryrOI+dtQhBHquBmaZh7ooaV0xQT57yhKjfTiuYpPpC 8NBRSRfrtVrYKqH1uN3UM7kR2Xjn4SNPKahXfb0SUJ4Y0kd1Q3FXs5npNdp9wIzNZXGAoB 8wbZntPsWSC/G1dmTSJ5NF2pNTEzLLSEI11x4X74VDAJ9cVh9wB0KHyHYDjPHdS3ImmqC6 R1hS8Ze9KaijX5eHWWKy2UPDGqRrb4Y3FvAlbnxj4FLMVVujIaoEwF3f+KvBnbZiNT/g4U a8a1hPRwD3Ee3mWrZRD4cNUa2KJWglNojP/XPtt1/KjhjRhBqjCtBbA8yG4Xbw== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk X-Rspamd-Queue-Id: 499nKk1sNLz32M X-Spamd-Result: default: False [1.68 / 11.00]; RCVD_TLS_LAST(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[95.149.142.196:received]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; HTML_META_REFRESH_URL(5.00)[]; R_SPF_ALLOW(-0.20)[+ip4:85.233.160.0/27]; MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[tfitzgeorge.me.uk]; ARC_NA(0.00)[]; RWL_MAILSPIKE_GOOD(0.00)[85.233.160.19:from]; ARC_SIGNED(0.00)[i=1]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[]; RCPT_COUNT_TWO(0.00)[2]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-0.93)[-0.928]; IP_REPUTATION_SPAM(0.01)[asn: 8622(0.00), country: GB(0.01), ip: 85.233.160.19(0.00)]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:8622, ipnet:85.233.160.0/19, country:GB]; RCVD_COUNT_TWO(0.00)[2]; BAYES_HAM(-2.99)[99.97%]; RCVD_IN_DNSWL_LOW(-0.10)[85.233.160.19:from] X-Rspamd-Server: mail01.haj.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Signed-off-by: Tim FitzGeorge --- html/cgi-bin/ipblacklist.cgi | 463 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 463 insertions(+) create mode 100644 html/cgi-bin/ipblacklist.cgi diff --git a/html/cgi-bin/ipblacklist.cgi b/html/cgi-bin/ipblacklist.cgi new file mode 100644 index 000000000..28b42edf2 --- /dev/null +++ b/html/cgi-bin/ipblacklist.cgi @@ -0,0 +1,463 @@ +#!/usr/bin/perl + +############################################################################### +# # +# IPFire.org - A linux based firewall # +# # +# 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 . # +# # +# Copyright (C) 2018 - 2020 The IPFire Team # +# # +############################################################################### + +use strict; +use CGI qw/:standard/; +# enable the following only for debugging purposes +#use warnings; +#use CGI::Carp 'fatalsToBrowser'; +use Sort::Naturally; +use Socket; + +require '/var/ipfire/general-functions.pl'; +require "${General::swroot}/lang.pl"; +require "${General::swroot}/header.pl"; + +############################################################################### +# Configuration variables +############################################################################### + +my $settings = "${General::swroot}/ipblacklist/settings"; +my $sources = "${General::swroot}/ipblacklist/sources"; +my $getipstat = '/usr/local/bin/getipstat'; +my $getipsetstat = '/usr/local/bin/getipsetstat'; +my $control = '/usr/local/bin/ipblacklistctrl'; +my $lockfile = '/var/run/ipblacklist.pid'; +my %cgiparams = ('ACTION' => ''); + +############################################################################### +# Variables +############################################################################### + +my $errormessage = ''; +my $updating = 0; +my %mainsettings; +my %color; +my %sources; +my %stats; + +# Default settings - normally overwritten by settings file + +my %settings = ( 'DEBUG' => 0, + 'LOGGING' => 'on', + 'ENABLE' => 'off' ); + +# Read all parameters + +Header::getcgihash( \%cgiparams); +General::readhash( "${General::swroot}/main/settings", \%mainsettings ); +General::readhash( "/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color ); +General::readhash( $settings, \%settings ) if (-r $settings); +eval qx|/bin/cat $sources| if (-r $sources); + +# Show Headers + +Header::showhttpheaders(); + +# Process actions + +if ($cgiparams{'ACTION'} eq "$Lang::tr{'save'}") +{ + # Save Button + + my %new_settings = ( 'ENABLE' => 'off', + 'LOGGING' => 'off', + 'DEBUG' => 0 ); + + foreach my $item ('LOGGING', 'ENABLE', keys %sources) + { + $new_settings{$item} = (exists $cgiparams{$item}) ? 'on' : 'off'; + + $updating = 1 if (not exists $settings{$item} or $new_settings{$item} ne $settings{$item}); + } + + # Check for redundant blacklists being enabled + + foreach my $list (keys %sources) + { + if (exists $new_settings{$list} and + $new_settings{$list} eq 'on' and + exists $sources{$list}{'disable'}) + { + my @disable; + + if ('ARRAY' eq ref $sources{$list}{'disable'}) + { + @disable = @{ $sources{$list}{'disable'} }; + } + else + { + @disable = ( $sources{$list}{'disable'} ); + } + + foreach my $disable (@disable) + { + if ($new_settings{$disable} eq 'on') + { + $new_settings{$disable} = 'off'; + + $updating = 1; + $errormessage .= "$Lang::tr{'ipblacklist disable pre'} $disable " . + "$Lang::tr{'ipblacklist disable mid'} $list $Lang::tr{'ipblacklist disable post'}
\n"; + } + } + } + } + + if ($settings{'LOGGING'} ne $new_settings{'LOGGING'}) + { + if ($new_settings{'LOGGING'} eq 'on') + { + system( "$control log-on" ); + } + else + { + system( "$control log-off" ); + } + } + + if ($settings{'ENABLE'} ne $new_settings{'ENABLE'}) + { + if ($new_settings{'ENABLE'} eq 'on') + { + system( "$control enable" ); + } + else + { + system( "$control disable" ); + } + + $updating = 1; + } + + %settings = %new_settings; + + if ($errormessage) + { + $updating = 0; + } + else + { + General::writehash($settings, \%new_settings); + + if ($updating) + { + system( "$control update &" ); + show_running(); + exit 0; + } + } +} + +if (is_running()) +{ + show_running(); + exit 0; +} + +# Show site + +Header::openpage($Lang::tr{'ipblacklist'}, 1, ''); +Header::openbigbox('100%', 'left'); + +error() if ($errormessage); + +configsite(); + +# End of page + +Header::closebigbox(); +Header::closepage(); + +exit 0; + + +#------------------------------------------------------------------------------ +# sub configsite() +# +# Displays configuration +#------------------------------------------------------------------------------ + +sub configsite +{ + # Find preselections + + my $enable = 'checked'; + Header::openbox('100%', 'left', $Lang::tr{'settings'}); + + #### JAVA SCRIPT #### + + print< + \$(document).ready(function() + { + // Show/Hide elements when ENABLE checkbox is checked. + if (\$("#ENABLE").attr("checked")) + { + \$(".sources").show(); + } + else + { + \$(".sources").hide(); + } + + // Toggle Source list elements when "ENABLE" checkbox is clicked + \$("#ENABLE").change(function() + { + \$(".sources").toggle(); + }); + }); + +END + + ##### JAVA SCRIPT END #### + + # Enable checkbox + + $enable = ($settings{'ENABLE'} eq 'on') ? ' checked' : ''; + + print< + + + + + +
$Lang::tr{'ipblacklist use ipblacklists'}

+ +END + + # The following are only displayed if the blacklists are enabled + + $enable = ($settings{'LOGGING'} eq 'on') ? ' checked' : ''; + + print < + + + + + +
$Lang::tr{'ipblacklist log'}
+

+

$Lang::tr{'ipblacklist blacklist settings'}

+ + + + + + + +END + + # Iterate through the list of sources + + my $lines = 0; + + foreach my $list (sort keys %sources) + { + my $name = escapeHTML( $sources{$list}{'name'} ); + my $category = $Lang::tr{"ipblacklist category $sources{$list}{'category'}"}; + $enable = ''; + my $col = ($lines++ % 2) ? "bgcolor='$color{'color20'}'" : "bgcolor='$color{'color22'}'"; + + $enable = ' checked' if (exists $settings{$list} and $settings{$list} eq 'on'); + + print < + + + + \n +END + } + + # The save button at the bottom of the table + + print < + +
$Lang::tr{'ipblacklist id'}$Lang::tr{'ipblacklist name'}$Lang::tr{'ipblacklist category'}$Lang::tr{'ipblacklist enable'}
+END + + if ($sources{$list}{info}) + { + print "$list\n"; + } + else + { + print "$list\n"; + } + + print < + $name$category
+ + + +
+END + + Header::closebox(); +} + + +#------------------------------------------------------------------------------ +# sub get_ipset_stats() +# +# Gets the number of entries in each IPSet. +#------------------------------------------------------------------------------ + +sub get_ipset_stats +{ + my $name; + + system( $getipsetstat ); + + if (-r '/var/tmp/ipsets.txt') + { + open STATS, '<', '/var/tmp/ipsets.txt' or die "Can't open IP Sets stats file: $!"; + + foreach my $line () + { + if ($line =~ m/Name: (\w+)/) + { + $name = $1; + next; + } + + if ($line =~ m/Number of entries: (\d+)/) + { + $stats{$name}{'size'} = $1; + } + } + + close STATS; + + unlink( '/var/tmp/ipsets.txt' ); + } +} + + +#------------------------------------------------------------------------------ +# sub is_running() +# +# Checks to see if the main script is running +#------------------------------------------------------------------------------ + +sub is_running +{ + return 0 unless (-r $lockfile); + + open LOCKFILE, '<', $lockfile or die "Can't open lockfile"; + my $pid = ; + close LOCKFILE; + + chomp $pid; + + return (-e "/proc/$pid"); +} + + +#------------------------------------------------------------------------------ +# sub show_running +# +# Displayed when update is running. +# Shows a 'working' message plus some information about the IPSets. +#------------------------------------------------------------------------------ + +sub show_running +{ + # Open site + + Header::openpage( $Lang::tr{'ipblacklist'}, 1, '' ); + Header::openbigbox( '100%', 'center' ); + error(); + Header::openbox( 'Working', 'center', "$Lang::tr{'ipblacklist working'}" ); + + print < + + + $Lang::tr{  + + + +
+ + +END + + get_ipset_stats(); + + foreach my $name (sort keys %stats) + { + print "\n" if (exists $stats{$name}{'size'}); + } + + print < +END + + Header::closebox(); + + Header::closebigbox(); + Header::closepage(); +} + + +#------------------------------------------------------------------------------ +# sub error() +# +# Shows error messages +#------------------------------------------------------------------------------ + +sub error +{ + Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage\n"; + print " \n"; + Header::closebox(); +} + + +#------------------------------------------------------------------------------ +# sub format_time( seconds ) +# +# Converts time in seconds to HH:MM:SS +#------------------------------------------------------------------------------ + +sub format_time($) { + my $time = shift; + + my $seconds = $time % 60; + my $minutes = $time / 60; + + my $hours = 0; + if ($minutes >= 60) { + $hours = $minutes / 60; + $minutes %= 60; + } + + return sprintf("%3d:%02d:%02d", $hours, $minutes, $seconds); +} From patchwork Mon Apr 27 14:31:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim FitzGeorge X-Patchwork-Id: 3005 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 499nKp4DYKz3xQy for ; Mon, 27 Apr 2020 14:32:14 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKn6LRkz32M; Mon, 27 Apr 2020 14:32:13 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 499nKn5SD5z30GQ; Mon, 27 Apr 2020 14:32:13 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 499nKl3vgvz30GQ for ; Mon, 27 Apr 2020 14:32:11 +0000 (UTC) Received: from smtp.hosts.co.uk (smtp.hosts.co.uk [85.233.160.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKl2HMZz33L for ; Mon, 27 Apr 2020 14:32:11 +0000 (UTC) Received: from [95.149.142.196] (helo=aragorn.hosts.co.uk.tfitzgeorge.me.uk) by smtp.hosts.co.uk with esmtpa (Exim) (envelope-from ) id 1jT4nq-0003Z9-6t; Mon, 27 Apr 2020 15:32:11 +0100 From: Tim FitzGeorge To: development@lists.ipfire.org Subject: [PATCH v2 3/8] ipblacklist: WUI Log page Date: Mon, 27 Apr 2020 15:31:18 +0100 Message-Id: <20200427143123.6378-4-ipfr@tfitzgeorge.me.uk> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> References: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1587997931; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:in-reply-to:in-reply-to:references:references; bh=wzQ1lkU2y5TWlOlfyRMgpRFBFvLg4xqgU1rCRWL5ux0=; b=CkUesP1nsahMK9id0qPp7X3LqhBxsRAcIML0L8CLyYqDwg4bVoKZng3PfE0O1adRpQD65o K6tIJxwyI51snwKYXqYii4U56KoFaeASZgtP5V7wIHF9tLIxIoNyeEDn5VFkNQJvWz5jUT TlXoXepAIzwESqODE3IVQ5qNtVFiRzM66zds1vt/D4+aJSg6Y+0szBPHDPz/opnA9UbSSi MAhYd5Uq4E580Z9Bgiw1D8UvRi0myWhnVnB0lpXHNUvzl1ecFFfEdRbGHB9gNeM4Q/MM6B LY1H6AP/8SuBBp06LotVUlJTlpLrzaKOFNJciFJibEzJgx4oXQGQLqizKRTu4A== ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1587997931; a=rsa-sha256; cv=none; b=SfdoiSyTdr3aTwHT6FfSW2E0kWifZqF77jS3SNZ9Xl30dNTftgcGRuHGt0d+pjRN9zrJQL g5Rv+KBn6sfJwscVqBiFmGhJikEqKYkNW3tmkJfjKthQjl1RdD4V3apIzebn+GIbP/5VoI E8GkQkXQ5jcONqlqbF7XGsjoMzlnDp81RqJ4Pf/dbM/xCJD69StBF52+dRT6pRVBTmlvgd zhmmkvJmFs8XrM2ODK6O1RcaxAsaoeCUOD42BfRDxeqKm6md7+cxvJCpyH/9aES8c9TC19 BxD0RxX5JakHIDP7VTq5ab5KBi7ej3ac2QurVS6egscm5re0hjD7R2zxSkQvLQ== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk X-Rspamd-Queue-Id: 499nKl2HMZz33L X-Spamd-Result: default: False [-3.27 / 11.00]; RCVD_TLS_LAST(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[95.149.142.196:received]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; RWL_MAILSPIKE_GOOD(0.00)[85.233.160.19:from]; R_SPF_ALLOW(-0.20)[+ip4:85.233.160.0/27]; MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[tfitzgeorge.me.uk]; ARC_NA(0.00)[]; ARC_SIGNED(0.00)[i=1]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[]; RCPT_COUNT_TWO(0.00)[2]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-0.94)[-0.942]; IP_REPUTATION_SPAM(0.01)[asn: 8622(0.00), country: GB(0.01), ip: 85.233.160.19(0.00)]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:8622, ipnet:85.233.160.0/19, country:GB]; RCVD_COUNT_TWO(0.00)[2]; BAYES_HAM(-2.93)[99.68%]; RCVD_IN_DNSWL_LOW(-0.10)[85.233.160.19:from] X-Rspamd-Server: mail01.haj.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Signed-off-by: Tim FitzGeorge --- html/cgi-bin/logs.cgi/ipblacklists.dat | 363 +++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100755 html/cgi-bin/logs.cgi/ipblacklists.dat diff --git a/html/cgi-bin/logs.cgi/ipblacklists.dat b/html/cgi-bin/logs.cgi/ipblacklists.dat new file mode 100755 index 000000000..9b8db7062 --- /dev/null +++ b/html/cgi-bin/logs.cgi/ipblacklists.dat @@ -0,0 +1,363 @@ +#!/usr/bin/perl +# +# SmoothWall CGIs +# +# This code is distributed under the terms of the GPL +# +# JC HERITIER +# page inspired from the initial firewalllog.dat +# +# Modified for IPFire by Christian Schmidt +# and Michael Tremer (www.ipfire.org) + +use strict; +use Getopt::Std; + +# enable only the following on debugging purpose +#use warnings; +#use CGI::Carp 'fatalsToBrowser'; + +require '/var/ipfire/general-functions.pl'; +require "${General::swroot}/geoip-functions.pl"; +require "${General::swroot}/lang.pl"; +require "${General::swroot}/header.pl"; + +use POSIX(); + +my %cgiparams=(); +my $errormessage = ''; + +my @shortmonths = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', + 'Sep', 'Oct', 'Nov', 'Dec' ); +my @longmonths = ( $Lang::tr{'january'}, $Lang::tr{'february'}, $Lang::tr{'march'}, + $Lang::tr{'april'}, $Lang::tr{'may'}, $Lang::tr{'june'}, $Lang::tr{'july'}, $Lang::tr{'august'}, + $Lang::tr{'september'}, $Lang::tr{'october'}, $Lang::tr{'november'}, + $Lang::tr{'december'} ); + +my @now = localtime(); +my $dow = $now[6]; +my $doy = $now[7]; +my $tdoy = $now[7]; +my $year = $now[5]+1900; + +$cgiparams{'DAY'} = $now[3]; +$cgiparams{'MONTH'} = $now[4]; +$cgiparams{'ACTION'} = ''; + +&Header::getcgihash(\%cgiparams); + +my $start = -1; +if ($ENV{'QUERY_STRING'} && $cgiparams{'ACTION'} ne $Lang::tr{'update'}) +{ + my @temp = split(',',$ENV{'QUERY_STRING'}); + $start = $temp[0]; + $cgiparams{'MONTH'} = $temp[1]; + $cgiparams{'DAY'} = $temp[2]; +} + +if (!($cgiparams{'MONTH'} =~ /^(0|1|2|3|4|5|6|7|8|9|10|11)$/) || + !($cgiparams{'DAY'} =~ /^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31)$/)) +{ + $cgiparams{'DAY'} = $now[3]; + $cgiparams{'MONTH'} = $now[4]; +} +elsif($cgiparams{'ACTION'} eq '>>') +{ + my @temp_then=(); + my @temp_now = localtime(time); + $temp_now[4] = $cgiparams{'MONTH'}; + $temp_now[3] = $cgiparams{'DAY'}; + @temp_then = localtime(POSIX::mktime(@temp_now) + 86400); + ## Retrieve the same time on the next day - + ## 86400 seconds in a day + $cgiparams{'MONTH'} = $temp_then[4]; + $cgiparams{'DAY'} = $temp_then[3]; +} +elsif($cgiparams{'ACTION'} eq '<<') +{ + my @temp_then=(); + my @temp_now = localtime(time); + $temp_now[4] = $cgiparams{'MONTH'}; + $temp_now[3] = $cgiparams{'DAY'}; + @temp_then = localtime(POSIX::mktime(@temp_now) - 86400); + ## Retrieve the same time on the previous day - + ## 86400 seconds in a day + $cgiparams{'MONTH'} = $temp_then[4]; + $cgiparams{'DAY'} = $temp_then[3]; +} + +if (($cgiparams{'DAY'} ne $now[3]) || ($cgiparams{'MONTH'} ne $now[4])) +{ + my @then = (); + if ( ( $cgiparams{'MONTH'} eq $now[4]) && ($cgiparams{'DAY'} > $now[3]) || + ( $cgiparams{'MONTH'} > $now[4] ) ) { + @then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1901 )); + } else { + @then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1900 )); + } + $tdoy = $then[7]; + my $lastleap=($year-1)%4; + if ($tdoy>$doy) { + if ($lastleap == 0 && $tdoy < 60) { + $doy=$tdoy+366; + } else { + $doy=$doy+365; + } + } +} + +my $datediff=0; +my $dowd=0; +my $multifile=0; +if ($tdoy ne $doy) { + $datediff=int(($doy-$tdoy)/7); + $dowd=($doy-$tdoy)%7; + if (($dow-$dowd)<1) { + $datediff=$datediff+1; + } + if (($dow-$dowd)==0) { + $multifile=1; + } +} + +my $monthstr = $shortmonths[$cgiparams{'MONTH'}]; +my $longmonthstr = $longmonths[$cgiparams{'MONTH'}]; +my $day = $cgiparams{'DAY'}; +my $daystr=''; +if ($day <= 9) { + $daystr = " $day"; } +else { + $daystr = $day; +} + +my %lists; +my %directions; +my %sources = (); +my %settings = (); +&General::readhash("${General::swroot}/ipblacklist/settings", \%settings); +eval qx|/bin/cat /var/ipfire/ipblacklist/sources|; + +foreach my $blacklist (keys %sources) +{ + $lists{$blacklist} = {} if ($settings{$blacklist} eq 'on'); +} + +my $skip=0; +my $filestr=''; +if ($datediff==0) { + $filestr="/var/log/messages"; +} else { + $filestr="/var/log/messages.$datediff"; + $filestr = "$filestr.gz" if -f "$filestr.gz"; +} + +if (!(open (FILE,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr)))) { + $errormessage = "$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}"; + $skip=1; + # Note: This is in case the log does not exist for that date +} + +my $lines = 0; +my $directions = 0; + +if (!$skip) +{ + while () + { + if (/^${monthstr} ${daystr} ..:..:.. [\w\-]+ kernel:.*BLKLST_(\w+)\s*IN=(\w*)/) + { + my $list = $1; + + if ($2 =~ m/ppp|red/) + { + $lists{$list}{in}++; + $directions{in}++; + } + else + { + $lists{$list}{out}++; + $directions{out}++; + } + + $lines++; + } + + } + close (FILE); +} + +if ($multifile) { + $datediff=$datediff-1; + if ($datediff==0) { + $filestr="/var/log/messages"; + } else { + $filestr="/var/log/messages.$datediff"; + $filestr = "$filestr.gz" if -f "$filestr.gz"; + } + if (!(open (FILE,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr)))) { + $errormessage="$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}"; + $skip=1; + } + if (!$skip) { + while () { + if (/^${monthstr} ${daystr} ..:..:.. [\w\-]+ kernel:.*BLKLST_(\w+)\s*IN=(\w+)/) + { + my $list = $1; + + if ($2 =~ m/ppp|red/) + { + $lists{$list}{in}++; + $directions{in}++; + } + else + { + $lists{$list}{out}++; + $directions{out}++; + } + + $lines++; + } + } + close (FILE); + } +} + +my $MODNAME="fwlogs"; + +&Header::showhttpheaders(); +&Header::openpage($Lang::tr{'ipblacklist logs'}, 1, ''); +&Header::openbigbox('100%', 'left', '', $errormessage); + + +if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage \n"; + &Header::closebox(); +} + +&Header::openbox('100%', 'left', "$Lang::tr{'settings'}"); + +print < +
$Lang::tr{'ipblacklist id'}$Lang::tr{'ipblacklist entries'}
$name$stats{$name}{'size'}
+ + + + + + + + + +
$Lang::tr{'month'}:  +  $Lang::tr{'day'}:  +
+ +END +; + +&Header::closebox(); + +&Header::openbox('100%', 'left', $Lang::tr{'firewall log'}); +print "

$Lang::tr{'ipblacklist hits'} $longmonthstr $daystr: $lines

"; + +my %color = (); +my %mainsettings = (); +&General::readhash("${General::swroot}/main/settings", \%mainsettings); +&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); + +my @lists = sort keys (%lists); + +print < + + +$Lang::tr{'ipblacklist id'} +$Lang::tr{'ipblacklist category'} +$Lang::tr{'ipblacklist input'} +$Lang::tr{'ipblacklist output'} + + +$Lang::tr{'count'} +$Lang::tr{'percentage'} +$Lang::tr{'count'} +$Lang::tr{'percentage'} + +END +; + +$lines = 0; +my $lists = join ',', @lists; + +foreach my $list (@lists) +{ + my $col = ($lines++ % 2) ? "bgcolor='$color{'color20'}'" : "bgcolor='$color{'color22'}'"; + my $category = exists( $sources{$list}) ? $Lang::tr{"ipblacklist category $sources{$list}{'category'}"} : ' '; + + print ""; + + print "
"; + + if (exists($sources{$list}) and $sources{$list}{'info'}) + { + print "$list"; + } + else + { + print "$list"; + } + + print "$category"; + + foreach my $direction ('in', 'out') + { + my $count = $lists{$list}{$direction} || 0; + my $percent = $directions{$direction} > 0 ? $count * 100 / $directions{$direction} : 0; + $percent = sprintf("%.f", $percent); + print "$count"; + print "$percent%"; + } + + print ""; +} +print < +END +; + +&Header::closebox(); +&Header::closebigbox(); +&Header::closepage(); + +sub checkversion { + #Automatic Updates is disabled + return "0","0"; +} From patchwork Mon Apr 27 14:31:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim FitzGeorge X-Patchwork-Id: 3007 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 499nKw03MHz3xQy for ; Mon, 27 Apr 2020 14:32:20 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKp4CCWz3Bn; Mon, 27 Apr 2020 14:32:14 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 499nKp2KF9z30Fs; Mon, 27 Apr 2020 14:32:14 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 499nKm4SLkz2xmB for ; Mon, 27 Apr 2020 14:32:12 +0000 (UTC) Received: from smtp.hosts.co.uk (smtp.hosts.co.uk [85.233.160.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKm36xPz2kw for ; Mon, 27 Apr 2020 14:32:12 +0000 (UTC) Received: from [95.149.142.196] (helo=aragorn.hosts.co.uk.tfitzgeorge.me.uk) by smtp.hosts.co.uk with esmtpa (Exim) (envelope-from ) id 1jT4nr-0003Z9-6t; Mon, 27 Apr 2020 15:32:12 +0100 From: Tim FitzGeorge To: development@lists.ipfire.org Subject: [PATCH v2 4/8] ipblacklist: WUI Log details page Date: Mon, 27 Apr 2020 15:31:19 +0100 Message-Id: <20200427143123.6378-5-ipfr@tfitzgeorge.me.uk> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> References: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1587997932; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:in-reply-to:in-reply-to:references:references; bh=EdE/F7o+teKWnHaRWsmqmw6WU39JeYb29e7T7dxKjEs=; b=ibLrvc7BJiHTK5IpENeV0CfEIrvTajcC8qtZu6NLfRrWsNi4E6kWj6lNrf8jMOzefHTOJJ zGWfjR5XMnakfc+A8FhbDn2/v8bgOzGg8nPLpUrAFZeIeUP60w10ThAcotvitEpsYJ83LT LuhFE3msTtrzGSuCwYZmplKHt5A+W1n2UhjLa8kppTLklUML6MmPCQug0VUuAzM/RsTYY4 VRvddWAOtAZbOscvexXB64ZIWf50S5cVF7UZNe60+jZqtbVqutHD4IrQLXHxw8nLM/7QS1 v/b9xyjyd2ju5LlN5MhPiUpGfrCxAd5vGMelbIeDXag7CNR5FFpLudKfb8rBGw== ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1587997932; a=rsa-sha256; cv=none; b=tVC62vivW/zDAVr5OVwMLvaGu6WAL9/YxwObx4L4uxe8MwudMW3Xu4ueXn/W6Z81njQFco 5eLSP9oAg1hIaTE3jwqZkUBzr4U9suLZudXpMWrMyj+cZ2+pQ4rSPPtIBtpD7yJLPgOzrv 7tr0PtQsAeKRl6tV3hf6x7+Nkcrgnve8lcgDUog7sDKArsj8m/rxzdnezhK/GMPvFbWY6K 0bLrpsb8r4RtI6HdfosjP6anbzREB3ZKJHstiWLZmRw2wQ+ku3FTJ1wnd02xVy6AAVYemJ MkshMejIW2wYa+UY0DgXk+YM+9aU7pcBjui7Fh6dG+uuzOiEV5V5W/xIyAdOVA== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk X-Rspamd-Queue-Id: 499nKm36xPz2kw X-Spamd-Result: default: False [-3.34 / 11.00]; RCVD_TLS_LAST(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[95.149.142.196:received]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; RWL_MAILSPIKE_GOOD(0.00)[85.233.160.19:from]; R_SPF_ALLOW(-0.20)[+ip4:85.233.160.0/27]; MIME_GOOD(-0.10)[text/plain]; ARC_SIGNED(0.00)[i=1]; ARC_NA(0.00)[]; DMARC_NA(0.00)[tfitzgeorge.me.uk]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[]; RCPT_COUNT_TWO(0.00)[2]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-0.94)[-0.942]; IP_REPUTATION_SPAM(0.01)[asn: 8622(0.00), country: GB(0.01), ip: 85.233.160.19(0.00)]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:8622, ipnet:85.233.160.0/19, country:GB]; RCVD_COUNT_TWO(0.00)[2]; BAYES_HAM(-3.00)[99.98%]; RCVD_IN_DNSWL_LOW(-0.10)[85.233.160.19:from] X-Rspamd-Server: mail01.haj.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Signed-off-by: Tim FitzGeorge --- html/cgi-bin/logs.cgi/showrequestfromblacklist.dat | 415 +++++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100755 html/cgi-bin/logs.cgi/showrequestfromblacklist.dat diff --git a/html/cgi-bin/logs.cgi/showrequestfromblacklist.dat b/html/cgi-bin/logs.cgi/showrequestfromblacklist.dat new file mode 100755 index 000000000..0de381a2d --- /dev/null +++ b/html/cgi-bin/logs.cgi/showrequestfromblacklist.dat @@ -0,0 +1,415 @@ +#!/usr/bin/perl +# SmoothWall CGIs +# +# This code is distributed under the terms of the GPL +# +# JC HERITIER +# page inspired from the initial firewalllog.dat +# +# Modified for IPFire by Christian Schmidt (www.ipfire.org) + +# enable only the following on debugging purpose +#use warnings; +#use CGI::Carp 'fatalsToBrowser'; + +require '/var/ipfire/general-functions.pl'; +require "${General::swroot}/lang.pl"; +require "${General::swroot}/header.pl"; + +use POSIX(); + +#workaround to suppress a warning when a variable is used only once +my @dummy = ( ${Header::table2colour} ); +undef (@dummy); + +my %cgiparams=(); +my %logsettings=(); +my $errormessage = ''; + +my @shortmonths = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', + 'Sep', 'Oct', 'Nov', 'Dec' ); +my @longmonths = ( $Lang::tr{'january'}, $Lang::tr{'february'}, $Lang::tr{'march'}, + $Lang::tr{'april'}, $Lang::tr{'may'}, $Lang::tr{'june'}, $Lang::tr{'july'}, $Lang::tr{'august'}, + $Lang::tr{'september'}, $Lang::tr{'october'}, $Lang::tr{'november'}, + $Lang::tr{'december'} ); + +my @now = localtime(); +my $dow = $now[6]; +my $doy = $now[7]; +my $tdoy = $now[7]; +my $year = $now[5]+1900; + +$cgiparams{'DAY'} = $now[3]; +$cgiparams{'MONTH'} = $now[4]; +$cgiparams{'ACTION'} = ''; + +&Header::getcgihash(\%cgiparams); + +$logsettings{'LOGVIEW_REVERSE'} = 'off'; +&General::readhash("${General::swroot}/logging/settings", \%logsettings); + +my $start = -1; +my @blacklists; +if ($ENV{'QUERY_STRING'} && $cgiparams{'ACTION'} ne $Lang::tr{'update'}) +{ + my @temp = split(',',$ENV{'QUERY_STRING'}, 5); + $start = shift @temp; + $cgiparams{'MONTH'} = shift @temp; + $cgiparams{'DAY'} = shift @temp; + $cgiparams{'blacklist'} = shift @temp; + $cgiparams{'blacklists'} = shift @temp; +} + +if (!($cgiparams{'MONTH'} =~ /^(0|1|2|3|4|5|6|7|8|9|10|11)$/) || + !($cgiparams{'DAY'} =~ /^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31)$/)) +{ + $cgiparams{'DAY'} = $now[3]; + $cgiparams{'MONTH'} = $now[4]; +} +elsif($cgiparams{'ACTION'} eq '>>') +{ + my @temp_then=(); + my @temp_now = localtime(time); + $temp_now[4] = $cgiparams{'MONTH'}; + $temp_now[3] = $cgiparams{'DAY'}; + @temp_then = localtime(POSIX::mktime(@temp_now) + 86400); + ## Retrieve the same time on the next day - + ## 86400 seconds in a day + $cgiparams{'MONTH'} = $temp_then[4]; + $cgiparams{'DAY'} = $temp_then[3]; +} +elsif($cgiparams{'ACTION'} eq '<<') +{ + my @temp_then=(); + my @temp_now = localtime(time); + $temp_now[4] = $cgiparams{'MONTH'}; + $temp_now[3] = $cgiparams{'DAY'}; + @temp_then = localtime(POSIX::mktime(@temp_now) - 86400); + ## Retrieve the same time on the previous day - + ## 86400 seconds in a day + $cgiparams{'MONTH'} = $temp_then[4]; + $cgiparams{'DAY'} = $temp_then[3]; +} + +if (($cgiparams{'DAY'} ne $now[3]) || ($cgiparams{'MONTH'} ne $now[4])) +{ + my @then = (); + if ( ( $cgiparams{'MONTH'} eq $now[4]) && ($cgiparams{'DAY'} > $now[3]) || + ( $cgiparams{'MONTH'} > $now[4] ) ) { + @then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1901 )); + } else { + @then = localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1900 )); + } + $tdoy = $then[7]; + my $lastleap=($year-1)%4; + if ($tdoy>$doy) { + if ($lastleap == 0 && $tdoy < 60) { + $doy=$tdoy+366; + } else { + $doy=$doy+365; + } + } +} + +if ($cgiparams{'blacklists'}) +{ + @blacklists = split ',', $cgiparams{'blacklists'}; +} + +my $datediff=0; +my $dowd=0; +my $multifile=0; +if ($tdoy ne $doy) { + $datediff=int(($doy-$tdoy)/7); + $dowd=($doy-$tdoy)%7; + if (($dow-$dowd)<1) { + $datediff=$datediff+1; + } + if (($dow-$dowd)==0) { + $multifile=1; + } +} + +my $monthstr = $shortmonths[$cgiparams{'MONTH'}]; +my $longmonthstr = $longmonths[$cgiparams{'MONTH'}]; +my $day = $cgiparams{'DAY'}; +my $daystr=''; +if ($day <= 9) { + $daystr = " $day"; } +else { + $daystr = $day; +} + +my $skip=0; +my $filestr=''; +if ($datediff==0) { + $filestr="/var/log/messages"; +} else { + $filestr="/var/log/messages.$datediff"; + $filestr = "$filestr.gz" if -f "$filestr.gz"; +} + +if (!(open (FILE,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr)))) { + $errormessage = "$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}"; + $skip=1; + # Note: This is in case the log does not exist for that date +} +my $lines = 0; +my @log=(); +my $blacklist = $cgiparams{blacklist}; + +if (!$skip) +{ + while () { + if (/^${monthstr} ${daystr} ..:..:.. [\w\-]+ kernel:.*BLKLST_(\w+)IN=.*/) { + if($1 eq $blacklist){ + $log[$lines] = $_; + $lines++; + } + } + } + close (FILE); +} + +$skip=0; +if ($multifile) { + $datediff=$datediff-1; + if ($datediff==0) { + $filestr="/var/log/messages"; + } else { + $filestr="/var/log/messages.$datediff"; + $filestr = "$filestr.gz" if -f "$filestr.gz"; + } + if (!(open (FILE,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr)))) { + $errormessage="$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}"; + $skip=1; + } + if (!$skip) { + while () { + if (/^${monthstr} ${daystr} ..:..:.. [\w\-]+ kernel:.*BLKLST_(\w+)IN=.*/) { + if($1 eq $blacklist){ + $log[$lines] = $_; + $lines++; + } + } + } + close (FILE); + } +} + +&Header::showhttpheaders(); +&Header::openpage($Lang::tr{'ipblacklist log list'}, 1, ''); +&Header::openbigbox('100%', 'left', '', $errormessage); + +if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage \n"; + &Header::closebox(); +} + +&Header::openbox('100%', 'left', "$Lang::tr{'settings'}:"); + +print < + + + + + + + + + + + + +
$Lang::tr{'month'}:  +  $Lang::tr{'day'}:  +
$Lang::tr{'ipblacklist id'}
+ +END +; + +&Header::closebox(); + +&Header::openbox('100%', 'left', $Lang::tr{'ipblacklist log list'}); +print "

$Lang::tr{'firewall hits'} $longmonthstr $daystr: $lines

"; + +if ($start == -1) { + $start = $lines - ${Header::viewsize}; +} +if ($start >= $lines - ${Header::viewsize}) { $start = $lines - ${Header::viewsize}; }; +if ($start < 0) { $start = 0; } + +my $prev = $start - ${Header::viewsize}; +my $next = $start + ${Header::viewsize}; + +if ($prev < 0) { $prev = 0; } +if ($next >= $lines) { $next = -1 } +if ($start == 0) { $prev = -1; } + +if ($lines != 0) { &oldernewer(); } + +print < + +$Lang::tr{'time'} +$Lang::tr{'iface'} +$Lang::tr{'proto'} +$Lang::tr{'source'} +$Lang::tr{'src port'} +$Lang::tr{'destination'} +$Lang::tr{'dst port'} + +END +; + +my @slice = splice(@log, $start, ${Header::viewsize}); + +if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @slice = reverse @slice; } + +$lines = 0; +foreach $_ (@slice) { + $a = $_; + # Check whether valid ipv4 or ipv6 address + if (($_ =~ /BLKLST_(\w+)IN=/)) { + if($1 eq $blacklist) { + + my $in = '-'; my $out = '-'; + my $srcaddr = ''; my $dstaddr = ''; + my $protostr = ''; + my $srcport = ''; my $dstport = ''; + + # If ipv6 uses bridge, the use PHYSIN, otherwise use IN + if ($_ =~ /(^.* ..:..:..) [\w\-]+ kernel:.*(IN=.*)(PHYSIN=.*)$/) {} + elsif ($_ =~ /(^.* ..:..:..) [\w\-]+ kernel:.*(IN=.*)$/) {} + my $timestamp = $1; my $packet = $2; + $timestamp =~ /(...) (..) (..:..:..)/; + my $month = $1; my $day = $2; my $time = $3; + + # If ipv6 uses bridge, the use PHYSIN and PHYSOUT, otherwise use IN and OUT + if ($a =~ /PHYSIN=(\w+)/) { $iface = $1; } elsif ($a =~ /IN=(\w+)/) { $iface = $1; } + if ($a =~ /PHYSOUT=(\w+)/) { $out = $1; } elsif ($a =~ /OUT=(\w+)/) { $out = $1; } + # Detect ipv4 and ipv6 addresses + if (($a =~ /SRC\=(([\d]{1,3})(\.([\d]{1,3})){3})/) or ($a =~ /SRC\=(([0-9a-fA-F]{0,4})(\:([0-9a-fA-F]{0,4})){2,7})/)) { $srcaddr = $1; } + if (($a =~ /DST\=(([\d]{1,3})(\.([\d]{1,3})){3})/) or ($a =~ /DST\=(([0-9a-fA-F]{0,4})(\:([0-9a-fA-F]{0,4})){2,7})/)) { $dstaddr = $1; } + if ($a =~ /PROTO\=(\w+)/) { $protostr = $1; } + my $protostrlc = lc($protostr); + if ($a =~ /SPT\=([\d\.]+)/){ $srcport = $1; } + if ($a =~ /DPT\=([\d\.]+)/){ $dstport = $1; } + + if ($lines % 2) { + print "\n"; + } + else { + print "\n"; + } + print <$time + $iface + $protostr + + + +
$srcaddr
+ + $srcport + + + +
$dstaddr
+ + $dstport + +END + ; + $lines++; + } + } +} + +print < +END +; + +&oldernewer(); + + print"
$Lang::tr{
"; + +&Header::closebox(); + +&Header::closebigbox(); + +&Header::closepage(); + +sub oldernewer +{ + print < + +END + ; + + my $blacklists = join ',', @blacklists; + + print ""; + if ($prev != -1) { + print "$Lang::tr{'older'}"; + } + else { + print "$Lang::tr{'older'}"; + } + print "\n"; + + print ""; + if ($next != -1) { + print "$Lang::tr{'newer'}"; + } + else { + print "$Lang::tr{'newer'}"; + } + print "\n"; + + print < + +END + ; +} From patchwork Mon Apr 27 14:31:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim FitzGeorge X-Patchwork-Id: 3008 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 499nL14FXRz3xQy for ; Mon, 27 Apr 2020 14:32:25 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 499nL11gfWz329; Mon, 27 Apr 2020 14:32:25 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 499nL10rjHz2yty; Mon, 27 Apr 2020 14:32:25 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 499nKz36cvz2xmB for ; Mon, 27 Apr 2020 14:32:23 +0000 (UTC) Received: from smtp.hosts.co.uk (smtp.hosts.co.uk [85.233.160.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 499nKz1jWXz32y for ; Mon, 27 Apr 2020 14:32:23 +0000 (UTC) Received: from [95.149.142.196] (helo=aragorn.hosts.co.uk.tfitzgeorge.me.uk) by smtp.hosts.co.uk with esmtpa (Exim) (envelope-from ) id 1jT4o2-0003o8-8G; Mon, 27 Apr 2020 15:32:22 +0100 From: Tim FitzGeorge To: development@lists.ipfire.org Subject: [PATCH v2 5/8] ipblacklist: WUI menus, language file etc Date: Mon, 27 Apr 2020 15:31:20 +0100 Message-Id: <20200427143123.6378-6-ipfr@tfitzgeorge.me.uk> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> References: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1587997943; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:in-reply-to:in-reply-to:references:references; bh=H03Py5mJFVIo/TV0O8grmONowHgJlCZvI8IAcBLauTE=; b=doXQ3H6wOA9xB3NoZycu2u060jX7RC1mzrG63Zd/hrG4c/UL4M6iHUJoMb85uZsejQ8xx4 0gS8X17savLkwZhTaZ3m4JO63FN+iw+GZ2qSWj716BuSb1INuEu5Qe+AJVN7lSFuzlVkNs O/3TiRPrdlVuUXGnVoRtdLnjiRdtOEYtGQvOzcLA0YA0FKvIdWuUL2yAWq+oxJs7Im9kvn XcKG0WwDMGv8m8x0Rnea3pt/Ou5njbc0V53HwZCCYV/8GfUWhONi1jpWfU31eFx4Hfyg/x WqM1GxNVqZ9ZUP8o7fS8eZZ1blSv+6lhXPXdR3eEXqGTyQFIgqSFfeoxw7OlRA== ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1587997943; a=rsa-sha256; cv=none; b=qNW4Klagr6emOUbhkkhjYL5v/rxu/WQWJN7j0k+URP+01FruSLQ7SmvDDxV2n3QT4L7aYw lnblhUlA0NiiYbL1I2qIsoxnjMxfoGSLaYhZsh/GUinF9TgH+00MG29csk2Yk7SyPLNpBZ P3PeA8JcJwh6WHOuodVs30DPXVNlgvdPp40eMdsctdiHNPsLUE9ZexmYjS+pap9Yr3O+xA rnABwUeETON9dNMrIa13OccQ15oSBZJ6ihPP4gI5Fij6d11HAiFz9L/QXUvdiOw4PbPyDk u2ctIDaxYaW4zR2vWD3fIIIPQUJx8ELpK2Lv+JVQQHXSahjm2dKco6AwbIkNIw== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk X-Rspamd-Queue-Id: 499nKz1jWXz32y X-Spamd-Result: default: False [-3.36 / 11.00]; RCVD_TLS_LAST(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[95.149.142.196:received]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; RWL_MAILSPIKE_GOOD(0.00)[85.233.160.19:from]; R_SPF_ALLOW(-0.20)[+ip4:85.233.160.0/27]; MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[tfitzgeorge.me.uk]; ARC_NA(0.00)[]; ARC_SIGNED(0.00)[i=1]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[]; RCPT_COUNT_TWO(0.00)[2]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-0.96)[-0.960]; IP_REPUTATION_SPAM(0.01)[asn: 8622(0.00), country: GB(0.01), ip: 85.233.160.19(0.00)]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:8622, ipnet:85.233.160.0/19, country:GB]; RCVD_COUNT_TWO(0.00)[2]; BAYES_HAM(-3.00)[99.98%]; RCVD_IN_DNSWL_LOW(-0.10)[85.233.160.19:from] X-Rspamd-Server: mail01.haj.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Signed-off-by: Tim FitzGeorge --- config/menu/50-firewall.menu | 5 +++++ config/menu/70-log.menu | 5 +++++ html/cgi-bin/logs.cgi/log.dat | 2 ++ langs/en/cgi-bin/en.pl | 27 ++++++++++++++++++++++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/config/menu/50-firewall.menu b/config/menu/50-firewall.menu index 5ec1f67fc..3cfcde835 100644 --- a/config/menu/50-firewall.menu +++ b/config/menu/50-firewall.menu @@ -21,6 +21,11 @@ 'title' => "$Lang::tr{'intrusion detection system'}", 'enabled' => 1, }; + $subfirewall->{'45.ipblacklist'} = {'caption' => $Lang::tr{'ipblacklist'}, + 'uri' => '/cgi-bin/ipblacklist.cgi', + 'title' => "$Lang::tr{'ipblacklist'}", + 'enabled' => 1, + }; $subfirewall->{'50.p2p'} = { 'caption' => $Lang::tr{'p2p block'}, 'uri' => '/cgi-bin/p2p-block.cgi', diff --git a/config/menu/70-log.menu b/config/menu/70-log.menu index 08973de5a..67bbecc1a 100644 --- a/config/menu/70-log.menu +++ b/config/menu/70-log.menu @@ -43,6 +43,11 @@ 'title' => "$Lang::tr{'ids logs'}", 'enabled' => 1 }; + $sublogs->{'55.ipblacklist'} = {'caption' => $Lang::tr{'ipblacklist logs'}, + 'uri' => '/cgi-bin/logs.cgi/ipblacklists.dat', + 'title' => "$Lang::tr{'ipblacklist logs'}", + 'enabled' => 1 + }; $sublogs->{'60.urlfilter'} = { 'caption' => $Lang::tr{'urlfilter logs'}, 'uri' => '/cgi-bin/logs.cgi/urlfilter.dat', diff --git a/html/cgi-bin/logs.cgi/log.dat b/html/cgi-bin/logs.cgi/log.dat index 8ca32d675..ba1a482c8 100644 --- a/html/cgi-bin/logs.cgi/log.dat +++ b/html/cgi-bin/logs.cgi/log.dat @@ -59,6 +59,7 @@ my %sections = ( 'dhcp' => '(dhcpd: )', 'dma' => '(dma: |dma\[.*\]: |postfix/\w*\[\d*\]: )', 'guardian' => '(guardian\[.*\]: )', + 'ipblacklist' => '(ipblacklist: )', 'ipfire' => '(ipfire: )', 'ipsec' => '(ipsec_[\w_]+: |pluto\[.*\]: |charon: |vpnwatch: )', 'kernel' => '(kernel: (?!DROP_))', @@ -87,6 +88,7 @@ my %trsections = ( 'dhcp' => "$Lang::tr{'dhcp server'}", 'dma' => 'Mail', 'guardian' => "$Lang::tr{'guardian'}", + 'ipblacklist' => "$Lang::tr{'ipblacklist'}", 'ipfire' => 'IPFire', 'ipsec' => 'IPSec', 'kernel' => "$Lang::tr{'kernel'}", diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 3f3e46641..57f52fa48 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -1,4 +1,4 @@ -%tr = ( +%tr = ( %tr, '24 hours' => '24 Hours', @@ -1534,6 +1534,31 @@ 'ip alias changed' => 'External IP alias changed', 'ip alias removed' => 'External IP alias removed', 'ip info' => 'IP Information', +'ipblacklist' => 'IP Address Blacklists', +'ipblacklist blacklist settings' => 'Blacklist settings', +'ipblacklist category' => 'Category', +'ipblacklist category application' => 'Application', +'ipblacklist category attacker' => 'Attacker', +'ipblacklist category c and c' => 'Malware C&C', +'ipblacklist category composite' => 'Composite', +'ipblacklist category invalid' => 'Invalid Address', +'ipblacklist category reputation' => 'Reputation', +'ipblacklist category scanner' => 'Scanner', +'ipblacklist disable mid' => 'because it is included in', +'ipblacklist disable post' => '', +'ipblacklist disable pre' => 'Disabling', +'ipblacklist enable' => 'Enable', +'ipblacklist entries' => 'Entries', +'ipblacklist hits' => 'Total number of blacklist hits for', +'ipblacklist id' => 'Blacklist', +'ipblacklist input' => 'Packets Dropped In', +'ipblacklist log list' => 'Firewall log (blacklist)', +'ipblacklist log' => 'Log dropped packets', +'ipblacklist logs' => 'IP Address Blacklist Logs', +'ipblacklist name' => 'Name', +'ipblacklist output' => 'Packets Dropped Out', +'ipblacklist use ipblacklists' => 'Enable IP Blacklists', +'ipblacklist working' => 'Updating IP address blacklists...', 'ipfire has now rebooted' => 'IPFire is rebooting now.', 'ipfire has now shutdown' => 'IPFire is shutting down now.', 'ipfire side' => 'IPFire side:', From patchwork Mon Apr 27 14:31:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim FitzGeorge X-Patchwork-Id: 3010 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 499nLC3lKtz3xQy for ; Mon, 27 Apr 2020 14:32:35 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 499nLC16gQz3Ch; Mon, 27 Apr 2020 14:32:35 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 499nLC093hz2yty; Mon, 27 Apr 2020 14:32:35 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 499nL93lFXz2xmB for ; Mon, 27 Apr 2020 14:32:33 +0000 (UTC) Received: from mail-out-auth2.hosts.co.uk (mail-out-auth2.hosts.co.uk [212.84.127.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 499nL72G3hz3Ch for ; Mon, 27 Apr 2020 14:32:31 +0000 (UTC) Received: from [95.149.142.196] (helo=aragorn.hosts.co.uk.tfitzgeorge.me.uk) by smtp.hosts.co.uk with esmtpa (Exim) (envelope-from ) id 1jT4o3-0003o8-6n; Mon, 27 Apr 2020 15:32:24 +0100 From: Tim FitzGeorge To: development@lists.ipfire.org Subject: [PATCH v2 6/8] ipblacklist: Ancillary files Date: Mon, 27 Apr 2020 15:31:21 +0100 Message-Id: <20200427143123.6378-7-ipfr@tfitzgeorge.me.uk> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> References: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1587997951; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:in-reply-to:in-reply-to:references:references; bh=cCllcvNyFVji10On9xyxajKGIukAltSzm1Iwdmgdsf8=; b=tnPbamHuapE0zAYTMQT6a1erG8nFGSk9jhu+ybD1pA8T5FWFi3piHVlp5Q5NpQUSZ6AwDh 0au01xs0Ivg0iDvQZtdLnfDcNqdVXHfk+RGN5C2k3CQqZ6aonSJ8tn0pHO3QnThs0Sk1JC QeCB+ESs04S/+X8JSCYRsGjKJUDxZMjPdizl6XeFrzlAFszgOuJf6XQqirrcbnFdrMdbCr TUNfX7yi9bDVoo4/teGP0rybAh+1Ky/HUjFtrQZUS0QtFyeCE3MvLIl0iqzJvND7U00oRO nls/cnlnLPpMTL79+tu2NBmaNb61nnypCjr0gkr3S2OOBYyqn9dhorDJzow3Eg== ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1587997951; a=rsa-sha256; cv=none; b=uiXDgnBM7S++juzl/svq1nB9YgoVtH08Xer+kEMQcM1Cu/gRPe8iITCxJ9GcUBw06sTfV8 bDlXG0UNVZNk/iTlqWweU6vY0N2ozk/taK6KJfePCTjWaurYwfUnVVkUjn5g6rltJ96S3J 5NkwGes0ePVIxEYys6TbYQLsdZNtbOxwrnCM1AFme1eEZ7X1mo9krBRgpUKZLb/zA3gMcB A/PLMNky0a5rZJk3sPQOzJtugWow0LyVsaLcDLWFk6XoLcujk7sqBnG6nemKgXeTB8SYOR DSF6rY2Tv+Ixu/enSwyHblVYlS/gIZqthlVhJTLqweM4jBYXVR7v/j3SwErl+A== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 212.84.127.1 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 212.84.127.1 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk X-Rspamd-Queue-Id: 499nL72G3hz3Ch X-Spamd-Result: default: False [-3.33 / 11.00]; RCVD_TLS_LAST(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; ARC_NA(0.00)[]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; R_SPF_ALLOW(-0.20)[+ip4:212.84.127.0/25]; MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[tfitzgeorge.me.uk]; ARC_SIGNED(0.00)[i=1]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[]; RCPT_COUNT_TWO(0.00)[2]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-0.94)[-0.941]; IP_REPUTATION_SPAM(0.01)[asn: 8622(0.00), country: GB(0.01), ip: 212.84.127.1(0.00)]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:8622, ipnet:212.84.96.0/19, country:GB]; RCVD_COUNT_TWO(0.00)[2]; BAYES_HAM(-2.99)[99.94%]; RCVD_IN_DNSWL_LOW(-0.10)[212.84.127.1:from] X-Rspamd-Server: mail01.haj.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" getipsetstat Gets information on IPSETs for WUI ipblacklistctrl Allows WUI to call main script as root sources List of blacklists used by main script and WUI Signed-off-by: Tim FitzGeorge --- config/ipblacklist/sources | 138 +++++++++++++++++++++++++++++++++++++++ src/misc-progs/getipsetstat.c | 25 +++++++ src/misc-progs/ipblacklistctrl.c | 48 ++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 config/ipblacklist/sources create mode 100644 src/misc-progs/getipsetstat.c create mode 100644 src/misc-progs/ipblacklistctrl.c diff --git a/config/ipblacklist/sources b/config/ipblacklist/sources new file mode 100644 index 000000000..3cfa7f7d4 --- /dev/null +++ b/config/ipblacklist/sources @@ -0,0 +1,138 @@ +############################################################################ +# # +# IP Address blacklists for IPFire # +# # +# This file contains a list of blacklist sources that will replace the one # +# internal to the updated if it is found at /var/ipfire/blacklist/sources. # +# The intention is to provide a common source of information for both the # +# updater and WUI. # +# # +# The chains created in the packet filter will be named by the top level # +# key and this will also be used in the log message to identify the reason # +# for the dropped packet. # +# # +# The fields are: # +# # +# name The blacklist's full name # +# url URL of the file containing the list # +# info URL giving information about the source # +# parser The parser function used to extract IP addresses from the # +# downloaded list # +# rate Minimum period between checks for updates. Can be specified in # +# days (d), hours (h) or minutes (m) # +# category Used for documentation on the WUI. Can be one of the following # +# 'application' Potentially unwanted applications # +# 'attacker' Generic source of malicious packets # +# 'c and c' Malware Command and Control source # +# 'composite' Composite of other lists # +# 'invalid' Invalid addresses on the public internet # +# 'scanner' Port scanner that is not initself malicious # +# disable Name of another list to disable if this one is enabled. Used # +# when the other list is a subset of this one. # +# # +# The info and category fields are purely for documentation. # +# # +############################################################################ + +%sources = ( 'EMERGING_FWRULE' => { 'name' => 'Emerging Threats Blocklist', + 'url' => 'https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt', + 'info' => 'https://doc.emergingthreats.net/bin/view/Main/EmergingFirewallRules', + 'parser' => 'ip-or-net-list', + 'rate' => '1h', + 'category' => 'composite', + 'disable' => ['FEODO_RECOMMENDED', 'FEODO_IP', 'FEODO_AGGRESIVE', 'SPAMHAUS_DROP', 'DSHIELD'] }, + 'EMERGING_COMPROMISED' => { 'name' => 'Emerging Threats Compromised IPs', + 'url' => 'https://rules.emergingthreats.net/blockrules/compromised-ips.txt', + 'info' => 'https://doc.emergingthreats.net/bin/view/Main/CompromisedHost', + 'parser' => 'ip-or-net-list', + 'rate' => '1h', + 'category' => 'attacker' }, + 'SPAMHAUS_DROP' => { 'name' => "Spamhaus Don't Route or Peer List", + 'url' => 'https://www.spamhaus.org/drop/drop.txt', + 'info' => 'https://www.spamhaus.org/drop/', + 'parser' => 'ip-or-net-list', + 'rate' => '12h', + 'category' => 'reputation' }, + 'SPAMHAUS_EDROP' => { 'name' => "Spamhaus Extended Don't Route or Peer List", + 'url' => 'https://www.spamhaus.org/drop/edrop.txt', + 'info' => 'https://www.spamhaus.org/drop/', + 'parser' => 'ip-or-net-list', + 'rate' => '1h', + 'category' => 'reputation' }, + 'DSHIELD' => { 'name' => 'Dshield.org Recommended Block List', + 'url' => 'https://www.dshield.org/block.txt', + 'info' => 'https://dshield.org/', + 'parser' => 'dshield', + 'rate' => '1h', + 'category' => 'attacker' }, + 'FEODO_RECOMMENDED'=> {'name' => 'Feodo Trojan IP Blocklist (Recommended)', + 'url' => 'https://feodotracker.abuse.ch/downloads/ipblocklist_recommended.txt', + 'info' => 'https://feodotracker.abuse.ch/blocklist', + 'parser' => 'ip-or-net-list', + 'rate' => '5m', + 'category' => 'c and c' }, + 'FEODO_IP' => { 'name' => 'Feodo Trojan IP Blocklist', + 'url' => 'https://feodotracker.abuse.ch/downloads/ipblocklist.txt', + 'info' => 'https://feodotracker.abuse.ch/blocklist', + 'parser' => 'ip-or-net-list', + 'rate' => '5m', + 'category' => 'c and c', + 'disable' => 'FEODO_RECOMMENDED' }, + 'FEODO_AGGRESIVE' => { 'name' => 'Feodo Trojan IP Blocklist (Aggresive)', + 'url' => 'https://feodotracker.abuse.ch/downloads/ipblocklist_aggressive.txt', + 'info' => 'https://feodotracker.abuse.ch/blocklist', + 'parser' => 'ip-or-net-list', + 'rate' => '5m', + 'category' => 'c and c', + 'disable' => ['FEODO_IP', 'FEODO_RECOMMENDED'] }, + 'CIARMY' => { 'name' => 'The CINS Army List', + 'url' => 'https://cinsscore.com/list/ci-badguys.txt', + 'info' => 'https://cinsscore.com/#list', + 'parser' => 'ip-or-net-list', + 'rate' => '15m', + 'category' => 'reputation' }, + 'TOR_ALL' => { 'name' => 'Known TOR Nodes', + 'url' => 'https://www.dan.me.uk/torlist', + 'info' => 'https://www.dan.me.uk/tornodes', + 'parser' => 'ip-or-net-list', + 'rate' => '1h', + 'category' => 'application', + 'disable' => 'TOR_EXIT' }, + 'TOR_EXIT' => { 'name' => 'Known TOR Exit Nodes', + 'url' => 'https://www.dan.me.uk/torlist/?exit', + 'info' => 'https://www.dan.me.uk/tornodes', + 'parser' => 'ip-or-net-list',, + 'rate' => '1h', + 'category' => 'application' }, + 'ALIENVAULT' => { 'name' => 'AlienVault IP Reputation database', + 'url' => 'https://reputation.alienvault.com/reputation.generic', + 'info' => 'https://www.alienvault.com/resource-center/videos/what-is-ip-domain-reputation', + 'parser' => 'ip-or-net-list', + 'rate' => '1h', + 'category' => 'reputation' }, + 'BOGON' => { 'name' => 'Bogus address list (Martian)', + 'url' => 'https://www.team-cymru.org/Services/Bogons/bogon-bn-agg.txt', + 'info' => 'https://www.team-cymru.com/bogon-reference.html', + 'parser' => 'ip-or-net-list', + 'rate' => '1d', + 'category' => 'invalid' }, + 'BOGON_FULL' => { 'name' => 'Full Bogus Address List', + 'url' => 'https://www.team-cymru.org/Services/Bogons/fullbogons-ipv4.txt', + 'info' => 'https://www.team-cymru.com/bogon-reference.html', + 'parser' => 'ip-or-net-list', + 'rate' => '4h', + 'category' => 'invalid', + 'disable' => 'BOGON' }, + 'SHODAN' => { 'name' => 'ISC Shodan scanner blacklist', + 'url' => 'https://isc.sans.edu/api/threatlist/shodan?tab', + 'info' => 'https://isc.sans.edu', + 'parser' => 'ip-or-net-list', + 'rate' => '1d', + 'category' => 'scanner' }, + 'BLOCKLIST_DE' => { 'name' => 'Blocklist.de all attacks list', + 'url' => 'https://lists.blocklist.de/lists/all.txt', + 'info' => 'https://www.blocklist.de', + 'parser' => 'ip-or-net-list', + 'rate' => '30m', + 'category' => 'attacker' } + ); diff --git a/src/misc-progs/getipsetstat.c b/src/misc-progs/getipsetstat.c new file mode 100644 index 000000000..781bfc55b --- /dev/null +++ b/src/misc-progs/getipsetstat.c @@ -0,0 +1,25 @@ +/* IPFire helper program - GetIPSetStat + * + * Get the list from IPSET LIST + * + */ + +#include +#include +#include +#include +#include +#include +#include "setuid.h" + + +int main(void) +{ + if (!(initsetuid())) + exit(1); + + safe_system("/usr/sbin/ipset list -t -f /var/tmp/ipsets.txt"); + safe_system("chown nobody:nobody /var/tmp/ipsets.txt"); + + return 0; +} diff --git a/src/misc-progs/ipblacklistctrl.c b/src/misc-progs/ipblacklistctrl.c new file mode 100644 index 000000000..7536b1e97 --- /dev/null +++ b/src/misc-progs/ipblacklistctrl.c @@ -0,0 +1,48 @@ +/* This file is part of the IPFire Firewall. + * + * This program is distributed under the terms of the GNU General Public + * Licence. See the file COPYING for details. + * + */ + +#include +#include +#include +#include +#include +#include +#include "setuid.h" + +int main(int argc, char *argv[]) { + + if (!(initsetuid())) + exit(1); + + if (argc < 2) { + fprintf(stderr, "\nNo argument given.\n" + "ipblacklistctrl (update|restore|log-on|log-off|" + "enable|disable)\n\n"); + exit(1); + } + + if (strcmp(argv[1], "update") == 0) { + safe_system("/usr/local/bin/ipblacklist update >/dev/null 2>&1 &"); + } else if (strcmp(argv[1], "restore") == 0) { + safe_system("/usr/local/bin/ipblacklist restore >/dev/null 2>&1 &"); + } else if (strcmp(argv[1], "log-on") == 0) { + safe_system("/usr/local/bin/ipblacklist log-on >/dev/null 2>&1 &"); + } else if (strcmp(argv[1], "log-off") == 0) { + safe_system("/usr/local/bin/ipblacklist log-off >/dev/null 2>&1 &"); + } else if (strcmp(argv[1], "enable") == 0) { + safe_system("/usr/local/bin/ipblacklist enable >/dev/null 2>&1 &"); + } else if (strcmp(argv[1], "disable") == 0) { + safe_system("/usr/local/bin/ipblacklist disable >/dev/null 2>&1 &"); + } else { + fprintf(stderr, "\nBad argument given.\n" + "ipblacklistctrl (update|restore|log-on|log-off|" + "enable|disable)\n\n"); + exit(1); + } + + return 0; +} From patchwork Mon Apr 27 14:31:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim FitzGeorge X-Patchwork-Id: 3009 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 499nL42lbrz3xQy for ; Mon, 27 Apr 2020 14:32:28 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 499nL406jrz2Pf; Mon, 27 Apr 2020 14:32:28 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 499nL36QHLz2yxh; Mon, 27 Apr 2020 14:32:27 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 499nL26cjLz2xmB for ; Mon, 27 Apr 2020 14:32:26 +0000 (UTC) Received: from smtp.hosts.co.uk (smtp.hosts.co.uk [85.233.160.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 499nL242BCz1JK for ; Mon, 27 Apr 2020 14:32:26 +0000 (UTC) Received: from [95.149.142.196] (helo=aragorn.hosts.co.uk.tfitzgeorge.me.uk) by smtp.hosts.co.uk with esmtpa (Exim) (envelope-from ) id 1jT4o5-0003o8-7T; Mon, 27 Apr 2020 15:32:26 +0100 From: Tim FitzGeorge To: development@lists.ipfire.org Subject: [PATCH v2 8/8] ipblacklist: Build infrastructure Date: Mon, 27 Apr 2020 15:31:23 +0100 Message-Id: <20200427143123.6378-9-ipfr@tfitzgeorge.me.uk> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> References: <20200427143123.6378-1-ipfr@tfitzgeorge.me.uk> ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1587997946; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:in-reply-to:in-reply-to:references:references; bh=7GfimWsHErpnQJb+bx1h2jpdLBc9bbx3eobC0e5rZqU=; b=JZDHwqvH+3NbAzM/mcxwen5CFncz+D/Cm+1RjweyGduLojJzBZSfsOsse+X/diwRE40eUP 3IW3hwgk7V49FkmPs9v98RBu/s+Ht7qy31dltjfNoTdnzbOeyPxHTRPMJ84gqSoV4+9eCS di+cU5HAQH9gJ2jimFmqvb36G5OMA/FJ0BDgRp+KqQ9wqfiu4Ppz2+DpYSVvwt+uQ/tc/j /kbNTZqV0WpCOFx7GvHZ5LZhwi9zzAKDILRTvWgQcA92HgxUKh72anPL9f86D0F+xWEGIK lIkSrrX3NRVvfdZaVIO0mbZPMw4joEMTWNP0YyZlxQO6Ij/jpu88wSKVRCBfzw== ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1587997946; a=rsa-sha256; cv=none; b=SK+L7ho1YExvJdNLAQA8ZmC1dLXIVtvMQrg/n2MHX/HNP3nzHWRpzI4kYHlMdACkAPzTrB T8+SC1ioN6rVUpheftv41q9tzjUCEAm5bOCda18wGgAFF2rzb5FN4DKayGzAF4SRCCRrXk 9V2kuSk2cn0RbyDxdtJS79e9ReA6y9pL0KAOrErtOk+J4x07JTdZKCMXdYOsXpWQNTozlz O8MkIrukdR/j4aymc4bDiEtgj4s1x5V6Ul1/Z1qvQPAUBITuHGgsS94uLxFEbhpbobsERh zeucsdVRD4Aqr5FmRxypsGSHPFjjHVLN3F+3kr1/vSNIOwIVgWzdf90abXyAoQ== ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk X-Rspamd-Queue-Id: 499nL242BCz1JK X-Spamd-Result: default: False [-3.33 / 11.00]; RCVD_TLS_LAST(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; ARC_NA(0.00)[]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; RWL_MAILSPIKE_GOOD(0.00)[85.233.160.19:from]; R_SPF_ALLOW(-0.20)[+ip4:85.233.160.0/27]; MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[tfitzgeorge.me.uk]; ARC_SIGNED(0.00)[i=1]; RECEIVED_SPAMHAUS_PBL(0.00)[95.149.142.196:received]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[]; RCPT_COUNT_TWO(0.00)[2]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-0.93)[-0.932]; IP_REPUTATION_SPAM(0.01)[asn: 8622(0.00), country: GB(0.01), ip: 85.233.160.19(0.00)]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:8622, ipnet:85.233.160.0/19, country:GB]; RCVD_COUNT_TWO(0.00)[2]; BAYES_HAM(-3.00)[99.99%]; RCVD_IN_DNSWL_LOW(-0.10)[85.233.160.19:from] X-Rspamd-Server: mail01.haj.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Signed-off-by: Tim FitzGeorge --- config/rootfiles/common/aarch64/stage2 | 1 + config/rootfiles/common/configroot | 2 ++ config/rootfiles/common/ipblacklist-sources | 1 + config/rootfiles/common/logwatch | 2 ++ config/rootfiles/common/misc-progs | 2 ++ config/rootfiles/common/stage2 | 1 + config/rootfiles/common/web-user-interface | 3 ++ config/rootfiles/common/x86_64/stage2 | 1 + lfs/configroot | 4 +-- lfs/ipblacklist-sources | 53 +++++++++++++++++++++++++++++ lfs/logwatch | 2 ++ make.sh | 1 + src/misc-progs/Makefile | 2 +- 13 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 config/rootfiles/common/ipblacklist-sources create mode 100644 lfs/ipblacklist-sources diff --git a/config/rootfiles/common/aarch64/stage2 b/config/rootfiles/common/aarch64/stage2 index 82e2c20d0..e78137d08 100644 --- a/config/rootfiles/common/aarch64/stage2 +++ b/config/rootfiles/common/aarch64/stage2 @@ -96,6 +96,7 @@ usr/local/bin/convert-dns-settings usr/local/bin/convert-ovpn usr/local/bin/filesystem-cleanup usr/local/bin/hddshutdown +usr/local/bin/ipblacklist usr/local/bin/ipsec-interfaces usr/local/bin/makegraphs usr/local/bin/qosd diff --git a/config/rootfiles/common/configroot b/config/rootfiles/common/configroot index 67c4abc75..e2ebf2c84 100644 --- a/config/rootfiles/common/configroot +++ b/config/rootfiles/common/configroot @@ -82,6 +82,8 @@ var/ipfire/geoip-functions.pl var/ipfire/graphs.pl var/ipfire/header.pl var/ipfire/ids-functions.pl +var/ipfire/ipblacklist +#var/ipfire/ipblacklist/settings var/ipfire/isdn #var/ipfire/isdn/settings var/ipfire/key diff --git a/config/rootfiles/common/ipblacklist-sources b/config/rootfiles/common/ipblacklist-sources new file mode 100644 index 000000000..7f54b1bbf --- /dev/null +++ b/config/rootfiles/common/ipblacklist-sources @@ -0,0 +1 @@ +var/ipfire/ipblacklist/sources diff --git a/config/rootfiles/common/logwatch b/config/rootfiles/common/logwatch index c47fb4199..8b4810d97 100644 --- a/config/rootfiles/common/logwatch +++ b/config/rootfiles/common/logwatch @@ -192,6 +192,7 @@ usr/share/logwatch/default.conf/services/zz-sys.conf usr/share/logwatch/dist.conf/logfiles usr/share/logwatch/dist.conf/services usr/share/logwatch/dist.conf/services/dialup.conf +usr/share/logwatch/dist.conf/services/ipblacklist.conf #usr/share/logwatch/lib usr/share/logwatch/lib/Logwatch.pm #usr/share/logwatch/scripts @@ -256,6 +257,7 @@ usr/share/logwatch/scripts/services/http usr/share/logwatch/scripts/services/imapd #usr/share/logwatch/scripts/services/in.qpopper usr/share/logwatch/scripts/services/init +usr/share/logwatch/scripts/services/ipblacklist usr/share/logwatch/scripts/services/ipop3d usr/share/logwatch/scripts/services/iptables usr/share/logwatch/scripts/services/kernel diff --git a/config/rootfiles/common/misc-progs b/config/rootfiles/common/misc-progs index c48a474b2..d17f3dd80 100644 --- a/config/rootfiles/common/misc-progs +++ b/config/rootfiles/common/misc-progs @@ -10,8 +10,10 @@ usr/local/bin/extrahdctrl usr/local/bin/fireinfoctrl usr/local/bin/firewallctrl usr/local/bin/getconntracktable +usr/local/bin/getipsetstat usr/local/bin/getipstat #usr/local/bin/iowrap +usr/local/bin/ipblacklistctrl usr/local/bin/ipfirereboot usr/local/bin/ipsecctrl usr/local/bin/launch-ether-wake diff --git a/config/rootfiles/common/stage2 b/config/rootfiles/common/stage2 index 8067df39b..78c55338d 100644 --- a/config/rootfiles/common/stage2 +++ b/config/rootfiles/common/stage2 @@ -95,6 +95,7 @@ usr/local/bin/convert-dns-settings usr/local/bin/convert-ovpn usr/local/bin/filesystem-cleanup usr/local/bin/hddshutdown +usr/local/bin/ipblacklist usr/local/bin/ipsec-interfaces usr/local/bin/makegraphs usr/local/bin/qosd diff --git a/config/rootfiles/common/web-user-interface b/config/rootfiles/common/web-user-interface index a3636002e..a3434128d 100644 --- a/config/rootfiles/common/web-user-interface +++ b/config/rootfiles/common/web-user-interface @@ -34,6 +34,7 @@ srv/web/ipfire/cgi-bin/hardwaregraphs.cgi srv/web/ipfire/cgi-bin/hosts.cgi srv/web/ipfire/cgi-bin/ids.cgi srv/web/ipfire/cgi-bin/index.cgi +srv/web/ipfire/cgi-bin/ipblacklist.cgi srv/web/ipfire/cgi-bin/ipinfo.cgi srv/web/ipfire/cgi-bin/iptables.cgi srv/web/ipfire/cgi-bin/logs.cgi @@ -44,8 +45,10 @@ srv/web/ipfire/cgi-bin/logs.cgi/firewalllogcountry.dat srv/web/ipfire/cgi-bin/logs.cgi/firewalllogip.dat srv/web/ipfire/cgi-bin/logs.cgi/firewalllogport.dat srv/web/ipfire/cgi-bin/logs.cgi/ids.dat +srv/web/ipfire/cgi-bin/logs.cgi/ipblacklists.dat srv/web/ipfire/cgi-bin/logs.cgi/log.dat srv/web/ipfire/cgi-bin/logs.cgi/proxylog.dat +srv/web/ipfire/cgi-bin/logs.cgi/showrequestfromblacklist.dat srv/web/ipfire/cgi-bin/logs.cgi/showrequestfromcountry.dat srv/web/ipfire/cgi-bin/logs.cgi/showrequestfromip.dat srv/web/ipfire/cgi-bin/logs.cgi/showrequestfromport.dat diff --git a/config/rootfiles/common/x86_64/stage2 b/config/rootfiles/common/x86_64/stage2 index 026532b8f..5aa177008 100644 --- a/config/rootfiles/common/x86_64/stage2 +++ b/config/rootfiles/common/x86_64/stage2 @@ -97,6 +97,7 @@ usr/local/bin/convert-dns-settings usr/local/bin/convert-ovpn usr/local/bin/filesystem-cleanup usr/local/bin/hddshutdown +usr/local/bin/ipblacklist usr/local/bin/ipsec-interfaces usr/local/bin/makegraphs usr/local/bin/qosd diff --git a/lfs/configroot b/lfs/configroot index 2c9dbe0e3..90b90eb3c 100644 --- a/lfs/configroot +++ b/lfs/configroot @@ -51,7 +51,7 @@ $(TARGET) : # Create all directories for i in addon-lang auth backup ca captive certs connscheduler crls ddns dhcp dhcpc dns dnsforward \ - ethernet extrahd/bin fwlogs fwhosts firewall isdn key langs logging mac main \ + ethernet extrahd/bin fwlogs fwhosts firewall ipblacklist isdn key langs logging mac main \ menu.d modem optionsfw \ ovpn patches pakfire portfw ppp private proxy/advanced/cre \ proxy/calamaris/bin qos/bin red remote sensors suricata time \ @@ -65,7 +65,7 @@ $(TARGET) : captive/settings captive/agb.txt captive/clients captive/voucher_out certs/index.txt certs/index.txt.attr ddns/config ddns/settings ddns/ipcache dhcp/settings \ dhcp/fixleases dhcp/advoptions dhcp/dhcpd.conf.local dns/settings dns/servers dnsforward/config ethernet/aliases ethernet/settings ethernet/known_nics ethernet/scanned_nics \ ethernet/wireless extrahd/scan extrahd/devices extrahd/partitions extrahd/settings firewall/settings firewall/config firewall/geoipblock firewall/input firewall/outgoing \ - fwhosts/customnetworks fwhosts/customhosts fwhosts/customgroups fwhosts/customservicegrp fwhosts/customgeoipgrp fwlogs/ipsettings fwlogs/portsettings \ + fwhosts/customnetworks fwhosts/customhosts fwhosts/customgroups fwhosts/customservicegrp fwhosts/customgeoipgrp fwlogs/ipsettings fwlogs/portsettings ipblacklist/settings \ isdn/settings mac/settings main/hosts main/routing main/security main/settings optionsfw/settings \ ovpn/ccd.conf ovpn/ccdroute ovpn/ccdroute2 pakfire/settings portfw/config ppp/settings-1 ppp/settings-2 ppp/settings-3 ppp/settings-4 \ ppp/settings-5 ppp/settings proxy/settings proxy/squid.conf proxy/advanced/settings proxy/advanced/cre/enable remote/settings qos/settings qos/classes qos/subclasses qos/level7config qos/portconfig \ diff --git a/lfs/ipblacklist-sources b/lfs/ipblacklist-sources new file mode 100644 index 000000000..c9431285d --- /dev/null +++ b/lfs/ipblacklist-sources @@ -0,0 +1,53 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007 Michael Tremer & Christian Schmidt # +# # +# 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 . # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include Config + +VER = ipfire + +THISAPP = ipblacklist-sources +TARGET = $(DIR_INFO)/$(THISAPP) + +############################################################################### +# Top-level Rules +############################################################################### + +install : $(TARGET) + +check : + +download : + +md5 : + +############################################################################### +# Installation Details +############################################################################### + +$(TARGET) : + @$(PREBUILD) + mkdir -p /var/ipfire/ipblacklist + install -v -m 0644 $(DIR_SRC)/config/ipblacklist/sources /var/ipfire/ipblacklist + + @$(POSTBUILD) diff --git a/lfs/logwatch b/lfs/logwatch index a980b1b40..a1b02f9d7 100644 --- a/lfs/logwatch +++ b/lfs/logwatch @@ -93,6 +93,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) # done cp -f $(DIR_SRC)/config/logwatch/dialup /usr/share/logwatch/scripts/services/dialup cp -f $(DIR_SRC)/config/logwatch/dialup.conf /usr/share/logwatch/dist.conf/services/dialup.conf + cp -f $(DIR_SRC)/config/logwatch/ipblacklist /usr/share/logwatch/scripts/services/ipblacklist + cp -f $(DIR_SRC)/config/logwatch/ipblacklist.conf /usr/share/logwatch/dist.conf/services/ipblacklist.conf -mkdir -p /var/cache/logwatch chmod -v 777 /var/cache/logwatch diff --git a/make.sh b/make.sh index f507c5584..8e062140b 100755 --- a/make.sh +++ b/make.sh @@ -1645,6 +1645,7 @@ buildipfire() { lfsmake2 speedtest-cli lfsmake2 rfkill lfsmake2 amazon-ssm-agent + lfsmake2 ipblacklist-sources } buildinstaller() { diff --git a/src/misc-progs/Makefile b/src/misc-progs/Makefile index bea54e773..60b3965e0 100644 --- a/src/misc-progs/Makefile +++ b/src/misc-progs/Makefile @@ -32,7 +32,7 @@ SUID_PROGS = squidctrl sshctrl ipfirereboot \ smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \ setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes \ getconntracktable wirelessclient torctrl ddnsctrl unboundctrl \ - captivectrl + captivectrl ipblacklistctrl getipsetstat SUID_UPDX = updxsetperms OBJS = $(patsubst %,%.o,$(PROGS) $(SUID_PROGS))