mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-09 10:35:53 +02:00
Merge branch 'temp-stevee-ipblocklist-final' into next
This commit is contained in:
@@ -41,6 +41,7 @@ var/ipfire/ethernet/aliases
|
||||
var/ipfire/ethernet/wireless
|
||||
var/ipfire/firewall
|
||||
var/ipfire/fwhosts
|
||||
var/ipfire/ipblocklist/modified
|
||||
var/ipfire/main/*
|
||||
var/ipfire/ovpn
|
||||
var/ipfire/ovpn/collectd.vpn
|
||||
@@ -54,6 +55,7 @@ var/ipfire/*/settings
|
||||
var/ipfire/time/
|
||||
var/ipfire/urlfilter
|
||||
var/ipfire/vpn
|
||||
var/lib/ipblocklist
|
||||
var/lib/suricata
|
||||
var/log/ip-acct/*
|
||||
var/log/rrd/*
|
||||
|
||||
386
config/cfgroot/ipblocklist-functions.pl
Normal file
386
config/cfgroot/ipblocklist-functions.pl
Normal file
@@ -0,0 +1,386 @@
|
||||
#!/usr/bin/perl -w
|
||||
###############################################################################
|
||||
# #
|
||||
# IPFire.org - A linux based firewall #
|
||||
# Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 2 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
package IPblocklist;
|
||||
|
||||
require '/var/ipfire/general-functions.pl';
|
||||
require "${General::swroot}/ipblocklist/sources";
|
||||
|
||||
# The directory where all ipblocklist related files and settings are stored.
|
||||
our $settings_dir = "/var/ipfire/ipblocklist";
|
||||
|
||||
# Main settings file.
|
||||
our $settings_file = "$settings_dir/settings";
|
||||
|
||||
# The file which keeps the time, when a blocklist last has been modified.
|
||||
our $modified_file = "$settings_dir/modified";
|
||||
|
||||
# Location where the blocklists in ipset compatible format are stored.
|
||||
our $blocklist_dir = "/var/lib/ipblocklist";
|
||||
|
||||
# File extension of the blocklist files.
|
||||
my $blocklist_file_extension = ".conf";
|
||||
|
||||
# Hash which calls the correct parser functions.
|
||||
my %parsers = (
|
||||
'ip-or-net-list' => \&parse_ip_or_net_list,
|
||||
'dshield' => \&parse_dshield
|
||||
);
|
||||
|
||||
#
|
||||
## Function to get all available blocklists.
|
||||
#
|
||||
sub get_blocklists () {
|
||||
my @blocklists;
|
||||
|
||||
# Loop through the hash of blocklists.
|
||||
foreach my $blocklist ( keys %IPblocklist::List::sources ) {
|
||||
# Add the list to the array.
|
||||
push(@blocklists, $blocklist);
|
||||
}
|
||||
|
||||
# Sort and return the array.
|
||||
return sort(@blocklists);
|
||||
}
|
||||
|
||||
#
|
||||
## Tiny function to get the full path and name of a given blocklist.
|
||||
#
|
||||
sub get_ipset_db_file($) {
|
||||
my ($set) = @_;
|
||||
|
||||
# Generate the
|
||||
my $file = "$blocklist_dir/$set$blocklist_file_extension";
|
||||
|
||||
# Return the file name.
|
||||
return $file;
|
||||
}
|
||||
|
||||
#
|
||||
## The main download_and_create blocklist function.
|
||||
##
|
||||
## Uses LWP to download a given blocklist. 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 gets parsed, converted and stored in an ipset compatible
|
||||
## format.
|
||||
##
|
||||
## Parameters:
|
||||
## list The name of the blocklist
|
||||
##
|
||||
## Returns:
|
||||
## nothing - On success
|
||||
## not_modified - In case the servers responds with "Not modified" (304)
|
||||
## dl_error - If the requested blocklist could not be downloaded.
|
||||
## empty_list - The downloaded blocklist is empty, or the parser was not able to parse
|
||||
## it correctly.
|
||||
#
|
||||
sub download_and_create_blocklist($) {
|
||||
my ($list) = @_;
|
||||
|
||||
# Check if the given blockist is known and data available.
|
||||
unless($IPblocklist::List::sources{$list}) {
|
||||
# No valid data for this blocklist - exit and return "1".
|
||||
return 1;
|
||||
}
|
||||
|
||||
# The allowed maximum download size in bytes.
|
||||
my $max_dl_bytes = 10_485_760;
|
||||
|
||||
# The amount of download attempts before giving up and
|
||||
# logging an error.
|
||||
my $max_dl_attempts = 5;
|
||||
|
||||
# Read proxysettings.
|
||||
my %proxysettings=();
|
||||
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
|
||||
|
||||
# Load required perl module to handle the download.
|
||||
use LWP::UserAgent;
|
||||
|
||||
# Create a user agent for downloading the blacklist
|
||||
# Limit the download size for safety
|
||||
my $ua = LWP::UserAgent->new (
|
||||
ssl_opts => {
|
||||
SSL_ca_file => '/etc/ssl/cert.pem',
|
||||
verify_hostname => 1,
|
||||
},
|
||||
|
||||
max_size => $max_dl_bytes,
|
||||
);
|
||||
|
||||
# Set timeout to 10 seconds.
|
||||
$ua->timeout(10);
|
||||
|
||||
# Check if an upstream proxy is configured.
|
||||
if ($proxysettings{'UPSTREAM_PROXY'}) {
|
||||
my $proxy_url;
|
||||
|
||||
$proxy_url = "http://";
|
||||
|
||||
# Check if the proxy requires authentication.
|
||||
if (($proxysettings{'UPSTREAM_USER'}) && ($proxysettings{'UPSTREAM_PASSWORD'})) {
|
||||
$proxy_url .= "$proxysettings{'UPSTREAM_USER'}\:$proxysettings{'UPSTREAM_PASSWORD'}\@";
|
||||
}
|
||||
|
||||
# Add proxy server address and port.
|
||||
$proxy_url .= $proxysettings{'UPSTREAM_PROXY'};
|
||||
|
||||
# Setup proxy settings.
|
||||
$ua->proxy(['http', 'https'], $proxy_url);
|
||||
}
|
||||
|
||||
# Gather the details, when a list got modified last time.
|
||||
my %modified = ();
|
||||
|
||||
# Read-in data if the file exists.
|
||||
&General::readhash($modified_file, \%modified ) if (-e $modified_file);
|
||||
|
||||
# Get the last modified time for this list.
|
||||
my $last_modified = gmtime($modified{$list} || 0);
|
||||
|
||||
my $dl_attempt = 1;
|
||||
my $response;
|
||||
|
||||
# Download and rety on failure loop.
|
||||
while ($dl_attempt <= $max_dl_attempts) {
|
||||
# Try to determine if there is a newer blocklist since last time and grab it.
|
||||
$response = $ua->get($IPblocklist::List::sources{$list}{'url'}, 'If-Modified-Since' => $last_modified );
|
||||
|
||||
# Check if the download attempt was successfull.
|
||||
if ($response->is_success) {
|
||||
# We successfully grabbed the list - no more retries needed, break the loop.
|
||||
# Further process the script code.
|
||||
last;
|
||||
|
||||
# Exit, if the server responds with "Not modified (304).
|
||||
} elsif ($response->code == 304) {
|
||||
# Exit and return "not modified".
|
||||
return "not_modified";
|
||||
|
||||
# Exit and log an erro
|
||||
} elsif ($dl_attempt eq $max_dl_attempts) {
|
||||
# Exit and return "dl_error".
|
||||
return "dl_error";
|
||||
}
|
||||
|
||||
# Increase download attempt counter.
|
||||
$dl_attempt++;
|
||||
}
|
||||
|
||||
# Update the timestamp for the new or modified list.
|
||||
if($response->last_modified) {
|
||||
$modified{$list} = $response->last_modified;
|
||||
} else {
|
||||
$modified{$list} = time();
|
||||
}
|
||||
|
||||
# Write-back the modified timestamps.
|
||||
&General::writehash($modified_file, \%modified);
|
||||
|
||||
# Parse and loop through the downloaded list.
|
||||
my @blocklist = ();
|
||||
|
||||
# Get the responsible parser for the current list.
|
||||
my $parser = $parsers{$IPblocklist::List::sources{$list}{'parser'}};
|
||||
|
||||
# Loop through the grabbed raw list.
|
||||
foreach my $line (split /[\r\n]+/, $response->content) {
|
||||
# Remove newlines.
|
||||
chomp $line;
|
||||
|
||||
# Call the parser and obtain the addess or network.
|
||||
my $address = &$parser($line);
|
||||
|
||||
# Skip the line if it does not contain an address.
|
||||
next unless ($address and $address =~ m/\d+\.\d+\.\d+\.\d+/);
|
||||
|
||||
# Check if we got a single address.
|
||||
if ($address =~ m|/32|) {
|
||||
# Add /32 as prefix.
|
||||
$address =~ s|/32||;
|
||||
}
|
||||
|
||||
# Push the address/network to the blocklist array.
|
||||
push(@blocklist, $address);
|
||||
}
|
||||
|
||||
# Check if the content could be parsed correctly and the blocklist
|
||||
# contains at least one item.
|
||||
unless(@blocklist) {
|
||||
# No entries - exit and return "empty_list".
|
||||
return "empty_list";
|
||||
}
|
||||
|
||||
# Get amount of entries in the blocklist array.
|
||||
my $list_entries = scalar(@blocklist);
|
||||
|
||||
# Optain the filename for this blocklist to save.
|
||||
my $file = &get_ipset_db_file($list);
|
||||
|
||||
# Open the file for writing.
|
||||
open(FILE, ">", "$file") or die "Could not write to $file. $!\n";
|
||||
|
||||
# Write file header.
|
||||
print FILE "#Autogenerated file. Any custom changes will be overwritten!\n\n";
|
||||
|
||||
# Calculate the hashsize for better list performance.
|
||||
my $hashsize = &_calculate_hashsize($list_entries);
|
||||
|
||||
# Simply set the limit of list elements to the double of current list elements.
|
||||
my $maxelem = $list_entries *2;
|
||||
|
||||
# Add "v4" suffix to the list name.
|
||||
$list = "$list" . "v4";
|
||||
|
||||
# Write line to create the set.
|
||||
#
|
||||
# We safely can use hash:net as type because it supports single addresses and networks.
|
||||
print FILE "create $list hash:net family inet hashsize $hashsize maxelem $maxelem -exist\n";
|
||||
|
||||
# Write line to flush the set itself during loading.
|
||||
print FILE "flush $list\n";
|
||||
|
||||
# Loop through the array which contains the blocklist.
|
||||
foreach my $entry (@blocklist) {
|
||||
# Add the entry to the list.
|
||||
print FILE "add $list $entry\n";
|
||||
}
|
||||
|
||||
# Close the file handle.
|
||||
close(FILE);
|
||||
|
||||
# Finished.
|
||||
return;
|
||||
}
|
||||
|
||||
#
|
||||
## 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) = @_;
|
||||
|
||||
# Grab the IP address or network.
|
||||
$line =~ m|^(\d+\.\d+\.\d+\.\d+(?:/\d+)?)|;
|
||||
|
||||
# Return the grabbed address.
|
||||
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) = @_;
|
||||
|
||||
# Skip coments.
|
||||
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 nothing if no start address could be grabbed.
|
||||
return unless ($1);
|
||||
|
||||
# Add /32 as prefix for single addresses and return it.
|
||||
return "$1/32" unless ($2);
|
||||
|
||||
# Return the obtained network.
|
||||
return "$1/$2";
|
||||
}
|
||||
|
||||
#
|
||||
## Helper function to proper calculate the hashsize.
|
||||
#
|
||||
sub _calculate_hashsize($) {
|
||||
my ($list_entries) = @_;
|
||||
|
||||
my $hashsize = 1;
|
||||
$hashsize <<= 1 while ($hashsize < $list_entries);
|
||||
|
||||
# Return the calculated hashsize.
|
||||
return $hashsize;
|
||||
}
|
||||
|
||||
#
|
||||
## sub get_holdoff_rate(list)
|
||||
##
|
||||
## This function is used to get the holdoff rate in seconds for a desired provider,
|
||||
## based on the configured rate limit in minutes (m), hours (h) or days (d) in the
|
||||
## blacklist sources settings file.
|
||||
##
|
||||
#
|
||||
sub get_holdoff_rate($) {
|
||||
my ($list) = @_;
|
||||
|
||||
# Grab the configured lookup rate for the given list.
|
||||
my $rate = $IPblocklist::List::sources{$list}{'rate'};
|
||||
|
||||
# Split the grabbed rate into value and unit.
|
||||
my ($value, $unit) = (uc $rate) =~ m/(\d+)([DHM]?)/;
|
||||
|
||||
# Days
|
||||
if ($unit eq 'D') {
|
||||
$value *= 60 * 60 * 24;
|
||||
|
||||
# Minutes
|
||||
} elsif ($unit eq 'M') {
|
||||
$value *= 60;
|
||||
|
||||
# Everything else - assume hours.
|
||||
} else {
|
||||
$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;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -65,6 +65,9 @@ HOME=/
|
||||
# Perform a surciata rules update every 12 hours.
|
||||
@ 12h [ -f "/var/ipfire/red/active" ] && /usr/local/bin/update-ids-ruleset >/dev/null 2>&1
|
||||
|
||||
# Update Lists for IP-based blocking every 15 minutes.
|
||||
@ 15 [ -f "/var/ipfire/red/active" ] && /usr/local/bin/update-ipblocklists >/dev/null 2>&1
|
||||
|
||||
# Retry sending spooled mails regularly
|
||||
%hourly * /usr/sbin/dma -q
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ require '/var/ipfire/general-functions.pl';
|
||||
require "${General::swroot}/lang.pl";
|
||||
require "/usr/lib/firewall/firewall-lib.pl";
|
||||
require "${General::swroot}/location-functions.pl";
|
||||
require "${General::swroot}/ipblocklist-functions.pl";
|
||||
|
||||
# Set to one to enable debugging mode.
|
||||
my $DEBUG = 0;
|
||||
@@ -73,6 +74,10 @@ my %confignatfw=();
|
||||
my %locationsettings = (
|
||||
"LOCATIONBLOCK_ENABLED" => "off"
|
||||
);
|
||||
my %blocklistsettings= (
|
||||
"ENABLE" => "off",
|
||||
);
|
||||
|
||||
my %ipset_loaded_sets = ();
|
||||
my @ipset_used_sets = ();
|
||||
|
||||
@@ -82,6 +87,7 @@ my $configoutgoing = "${General::swroot}/firewall/outgoing";
|
||||
my $locationfile = "${General::swroot}/firewall/locationblock";
|
||||
my $configgrp = "${General::swroot}/fwhosts/customgroups";
|
||||
my $netsettings = "${General::swroot}/ethernet/settings";
|
||||
my $blocklistfile = "${General::swroot}/ipblocklist/settings";
|
||||
|
||||
&General::readhash("${General::swroot}/firewall/settings", \%fwdfwsettings);
|
||||
&General::readhash("${General::swroot}/optionsfw/settings", \%fwoptions);
|
||||
@@ -97,9 +103,18 @@ if (-e "$locationfile") {
|
||||
&General::readhash("$locationfile", \%locationsettings);
|
||||
}
|
||||
|
||||
# Check if the ipblocklist settings file exits.
|
||||
if (-e "$blocklistfile") {
|
||||
# Read-in settings file.
|
||||
&General::readhash("$blocklistfile", \%blocklistsettings);
|
||||
}
|
||||
|
||||
# Get all available locations.
|
||||
my @locations = &Location::Functions::get_locations();
|
||||
|
||||
# Get all supported blocklists.
|
||||
my @blocklists = &IPblocklist::get_blocklists();
|
||||
|
||||
# Name or the RED interface.
|
||||
my $RED_DEV = &General::get_red_interface();
|
||||
|
||||
@@ -144,6 +159,9 @@ sub main {
|
||||
# Load rules to block hostile networks.
|
||||
&drop_hostile_networks();
|
||||
|
||||
# Handle ipblocklist.
|
||||
&ipblocklist();
|
||||
|
||||
# Reload firewall policy.
|
||||
run("/usr/sbin/firewall-policy");
|
||||
|
||||
@@ -708,6 +726,64 @@ sub drop_hostile_networks () {
|
||||
run("$IPTABLES -A HOSTILE -o $RED_DEV -m set --match-set $HOSTILE_CCODE dst -j HOSTILE_DROP");
|
||||
}
|
||||
|
||||
sub ipblocklist () {
|
||||
# Flush the ipblocklist chains.
|
||||
run("$IPTABLES -F BLOCKLISTIN");
|
||||
run("$IPTABLES -F BLOCKLISTOUT");
|
||||
|
||||
# Check if the blocklist feature is enabled.
|
||||
if($blocklistsettings{'ENABLE'} eq "on") {
|
||||
# Loop through the array of private networks.
|
||||
foreach my $private_network (@PRIVATE_NETWORKS) {
|
||||
# Create firewall rules to never block private networks.
|
||||
run("$IPTABLES -A BLOCKLISTIN -p ALL -i $RED_DEV -s $private_network -j RETURN");
|
||||
run("$IPTABLES -A BLOCKLISTOUT -p ALL -o $RED_DEV -d $private_network -j RETURN");
|
||||
}
|
||||
}
|
||||
|
||||
# Loop through the array of blocklists.
|
||||
foreach my $blocklist (@blocklists) {
|
||||
# Check if the blocklist feature and the current processed blocklist is enabled.
|
||||
if(($blocklistsettings{'ENABLE'} eq "on") && ($blocklistsettings{$blocklist}) && ($blocklistsettings{$blocklist} eq "on")) {
|
||||
# Call function to load the blocklist.
|
||||
&ipset_restore($blocklist);
|
||||
|
||||
# Call function to check if the corresponding iptables drop chain already has been created.
|
||||
if(&firewall_chain_exists("${blocklist}_DROP")) {
|
||||
# Create iptables chain.
|
||||
run("$IPTABLES -N ${blocklist}_DROP");
|
||||
} else {
|
||||
# Flush the chain.
|
||||
run("$IPTABLES -F ${blocklist}_DROP");
|
||||
}
|
||||
|
||||
# Check if logging is enabled.
|
||||
if($blocklistsettings{'LOGGING'} eq "on") {
|
||||
# Create logging rule.
|
||||
run("$IPTABLES -A ${blocklist}_DROP -j LOG -m limit --limit 10/second --log-prefix \"BLKLST_$blocklist\" ");
|
||||
}
|
||||
|
||||
# Create Drop rule.
|
||||
run("$IPTABLES -A ${blocklist}_DROP -j DROP");
|
||||
|
||||
# Add the rules to check against the set
|
||||
run("$IPTABLES -A BLOCKLISTIN -p ALL -i $RED_DEV -m set --match-set $blocklist src -j ${blocklist}_DROP");
|
||||
run("$IPTABLES -A BLOCKLISTOUT -p ALL -o $RED_DEV -m set --match-set $blocklist dst -j ${blocklist}_DROP");
|
||||
|
||||
# IP blocklist or the blocklist is disabled.
|
||||
} else {
|
||||
# Check if the blocklist related iptables drop chain exits.
|
||||
unless(&firewall_chain_exists("${blocklist}_DROP")) {
|
||||
# Flush the chain.
|
||||
run("$IPTABLES -F ${blocklist}_DROP");
|
||||
|
||||
# Drop the chain.
|
||||
run("$IPTABLES -X ${blocklist}_DROP");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_protocols {
|
||||
my $hash = shift;
|
||||
my $key = shift;
|
||||
@@ -921,6 +997,14 @@ sub firewall_is_in_subnet {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub firewall_chain_exists ($) {
|
||||
my ($chain) = @_;
|
||||
|
||||
my $ret = &General::system("iptables", "--wait", "-n", "-L", "$chain");
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub ipset_get_sets () {
|
||||
my @sets;
|
||||
|
||||
@@ -986,6 +1070,26 @@ sub ipset_restore ($) {
|
||||
# If the set is not loaded, we have to rename it to proper use it.
|
||||
run("$IPSET rename $loc_set $set");
|
||||
}
|
||||
|
||||
# Check if the given set name is a blocklist.
|
||||
} elsif ($set ~~ @blocklists) {
|
||||
# IPblocklist sets contains v4 as setname extension.
|
||||
my $set_name = "$set" . "v4";
|
||||
|
||||
# Get the database file for the given blocklist.
|
||||
my $db_file = &IPblocklist::get_ipset_db_file($set);
|
||||
|
||||
# Call function to restore/load the set.
|
||||
&ipset_call_restore($db_file);
|
||||
|
||||
# Check if the set is already loaded (has been used before).
|
||||
if ($set ~~ @ipset_used_sets) {
|
||||
# Swap the sets.
|
||||
run("$IPSET swap $set_name $set");
|
||||
} else {
|
||||
# Rename the set to proper use it.
|
||||
run("$IPSET rename $set_name $set");
|
||||
}
|
||||
}
|
||||
|
||||
# Store the restored set to the hash to prevent from loading it again.
|
||||
|
||||
140
config/ipblocklist/sources
Normal file
140
config/ipblocklist/sources
Normal file
@@ -0,0 +1,140 @@
|
||||
############################################################################
|
||||
# #
|
||||
# IP Address blocklists for IPFire #
|
||||
# #
|
||||
# This file contains a list of blocklist sources that will replace the one #
|
||||
# internal to the updated if it is found at /var/ipfire/blocklist/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 blocklist'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. #
|
||||
# #
|
||||
############################################################################
|
||||
|
||||
package IPblocklist::List;
|
||||
|
||||
our %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 blocklist',
|
||||
'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' }
|
||||
);
|
||||
91
config/logwatch/ipblocklist
Executable file
91
config/logwatch/ipblocklist
Executable file
@@ -0,0 +1,91 @@
|
||||
###########################################################################
|
||||
# ipblocklist script for Logwatch
|
||||
# Analyzes the IPFire IP Blocklist log
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
########################################################
|
||||
## Copyright (c) 2008 Lars Skjærlund
|
||||
## Covered under the included MIT/X-Consortium License:
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
## All modifications and contributions by other persons to
|
||||
## this script are assumed to have been donated to the
|
||||
## Logwatch project and thus assume the above copyright
|
||||
## and licensing terms. If you want to make contributions
|
||||
## under your own copyright or a different license this
|
||||
## must be explicitly stated in the contribution and the
|
||||
## Logwatch project reserves the right to not accept such
|
||||
## contributions. If you have made significant
|
||||
## contributions to this script and want to claim
|
||||
## copyright please contact logwatch-devel@lists.sourceforge.net.
|
||||
#########################################################
|
||||
|
||||
#########################################################################
|
||||
# Files - all shown with default paths:
|
||||
#
|
||||
# /usr/share/logwatch/default.conf/logfiles/messages.conf
|
||||
# /usr/share/logwatch/dist.conf/services/blocklist.conf
|
||||
# /usr/share/logwatch/scripts/services/ipblocklist (this file)
|
||||
#
|
||||
# ... and of course
|
||||
#
|
||||
# /var/log/messages
|
||||
#########################################################################
|
||||
|
||||
use Logwatch ':dates';
|
||||
|
||||
my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'};
|
||||
|
||||
my $SearchDate;
|
||||
|
||||
my %Updates;
|
||||
my %Errors;
|
||||
|
||||
$SearchDate = TimeFilter("%b %e");
|
||||
|
||||
while (defined(my $ThisLine = <STDIN>))
|
||||
{
|
||||
next unless ($ThisLine =~ m/^\s*\w+\s+\w+\s+(..:..:..) .* ipblocklist: (.*)/);
|
||||
|
||||
my $text = $2;
|
||||
|
||||
if ($text =~ m/Successfully updated (\w+) blocklist/)
|
||||
{
|
||||
$Updates{$1}{updates}++;
|
||||
}
|
||||
elsif ($text !~ m/Skipping (\w+) blocklist - Too frequent update attempts!/ and
|
||||
$text !~ m/Skipping (\w+) blocklist - It has not been modified!/ )
|
||||
{
|
||||
$Errors{$text}++;
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
|
||||
if (keys %Updates)
|
||||
{
|
||||
print "\nThe following block lists were updated:\n";
|
||||
foreach my $Lists (sort keys %Updates)
|
||||
{
|
||||
print " $Lists: $Updates{$Lists}{updates} Time(s)\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (keys %Errors)
|
||||
{
|
||||
print "\nThe following errors were detected:\n";
|
||||
|
||||
foreach my $Text (keys %Errors)
|
||||
{
|
||||
print " $Text: $Errors{$Text} Time(s)\n";
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
||||
# vi: shiftwidth=3 tabstop=3 syntax=perl et
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 3
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
34
config/logwatch/ipblocklist.conf
Normal file
34
config/logwatch/ipblocklist.conf
Normal file
@@ -0,0 +1,34 @@
|
||||
#########################################################################
|
||||
# ids-update script for Logwatch
|
||||
# Analyzes the IPFire IP Blocklist update log
|
||||
#
|
||||
# Version: 1.0.0
|
||||
# Initial release
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
#########################################################################
|
||||
# This script is subject to the same copyright as Logwatch itself
|
||||
#########################################################################
|
||||
|
||||
#########################################################################
|
||||
# Files - all shown with default paths:
|
||||
#
|
||||
# /usr/share/logwatch/default.conf/logfiles/messages.conf
|
||||
# /usr/share/logwatch/dist.conf/services/blocklist.conf (this file)
|
||||
# /usr/share/logwatch/scripts/services/blocklist
|
||||
#
|
||||
# ... and of course
|
||||
#
|
||||
# /var/log/messages
|
||||
#########################################################################
|
||||
|
||||
|
||||
Title = "IP Blocklist"
|
||||
|
||||
# Which logfile group...
|
||||
LogFile = messages
|
||||
|
||||
*applystddate
|
||||
|
||||
# vi: shiftwidth=3 tabstop=3 et
|
||||
@@ -21,6 +21,11 @@
|
||||
'title' => "$Lang::tr{'intrusion detection system'}",
|
||||
'enabled' => 1,
|
||||
};
|
||||
$subfirewall->{'50.ipblocklist'} = {'caption' => $Lang::tr{'ipblocklist'},
|
||||
'uri' => '/cgi-bin/ipblocklist.cgi',
|
||||
'title' => "$Lang::tr{'ipblocklist'}",
|
||||
'enabled' => 1,
|
||||
};
|
||||
$subfirewall->{'60.locationblock'} = {
|
||||
'caption' => $Lang::tr{'locationblock'},
|
||||
'uri' => '/cgi-bin/location-block.cgi',
|
||||
|
||||
@@ -43,6 +43,11 @@
|
||||
'title' => "$Lang::tr{'ids logs'}",
|
||||
'enabled' => 1
|
||||
};
|
||||
$sublogs->{'53.ipblocklist'} = {'caption' => $Lang::tr{'ipblocklist logs'},
|
||||
'uri' => '/cgi-bin/logs.cgi/ipblocklists.dat',
|
||||
'title' => "$Lang::tr{'ipblocklist logs'}",
|
||||
'enabled' => 1
|
||||
};
|
||||
$sublogs->{'55.ovpnclients'} = {
|
||||
'caption' => $Lang::tr{'ovpn rw connection log'},
|
||||
'uri' => '/cgi-bin/logs.cgi/ovpnclients.dat',
|
||||
|
||||
@@ -106,6 +106,7 @@ usr/local/bin/settime
|
||||
usr/local/bin/timecheck
|
||||
usr/local/bin/timezone-transition
|
||||
usr/local/bin/update-ids-ruleset
|
||||
usr/local/bin/update-ipblocklists
|
||||
usr/local/bin/update-lang-cache
|
||||
usr/local/bin/update-location-database
|
||||
#usr/local/include
|
||||
@@ -154,6 +155,7 @@ var/cache/ldconfig
|
||||
var/cache/ldconfig/aux-cache
|
||||
var/empty
|
||||
#var/lib
|
||||
var/lib/ipblocklist
|
||||
#var/lib/misc
|
||||
#var/local
|
||||
var/lock
|
||||
|
||||
@@ -104,6 +104,7 @@ usr/local/bin/settime
|
||||
usr/local/bin/timecheck
|
||||
usr/local/bin/timezone-transition
|
||||
usr/local/bin/update-ids-ruleset
|
||||
usr/local/bin/update-ipblocklists
|
||||
usr/local/bin/update-lang-cache
|
||||
usr/local/bin/update-location-database
|
||||
#usr/local/include
|
||||
@@ -152,6 +153,7 @@ var/cache/ldconfig
|
||||
var/cache/ldconfig/aux-cache
|
||||
var/empty
|
||||
#var/lib
|
||||
var/lib/ipblocklist
|
||||
#var/lib/misc
|
||||
#var/local
|
||||
var/lock
|
||||
|
||||
@@ -81,6 +81,9 @@ var/ipfire/graphs.pl
|
||||
var/ipfire/header.pl
|
||||
var/ipfire/location-functions.pl
|
||||
var/ipfire/ids-functions.pl
|
||||
var/ipfire/ipblocklist-functions.pl
|
||||
var/ipfire/ipblocklist
|
||||
#var/ipfire/ipblocklist/settings
|
||||
var/ipfire/isdn
|
||||
#var/ipfire/isdn/settings
|
||||
var/ipfire/key
|
||||
|
||||
1
config/rootfiles/common/ipblocklist-sources
Normal file
1
config/rootfiles/common/ipblocklist-sources
Normal file
@@ -0,0 +1 @@
|
||||
var/ipfire/ipblocklist/sources
|
||||
@@ -195,6 +195,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/ipblocklist.conf
|
||||
#usr/share/logwatch/lib
|
||||
usr/share/logwatch/lib/Logwatch.pm
|
||||
#usr/share/logwatch/scripts
|
||||
@@ -260,6 +261,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/ipblocklist
|
||||
usr/share/logwatch/scripts/services/ipop3d
|
||||
usr/share/logwatch/scripts/services/iptables
|
||||
usr/share/logwatch/scripts/services/kernel
|
||||
|
||||
@@ -27,6 +27,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/ipblocklist.cgi
|
||||
srv/web/ipfire/cgi-bin/ipinfo.cgi
|
||||
srv/web/ipfire/cgi-bin/iptables.cgi
|
||||
srv/web/ipfire/cgi-bin/location-block.cgi
|
||||
@@ -38,9 +39,11 @@ 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/ipblocklists.dat
|
||||
srv/web/ipfire/cgi-bin/logs.cgi/log.dat
|
||||
srv/web/ipfire/cgi-bin/logs.cgi/ovpnclients.dat
|
||||
srv/web/ipfire/cgi-bin/logs.cgi/proxylog.dat
|
||||
srv/web/ipfire/cgi-bin/logs.cgi/showrequestfromblocklist.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
|
||||
|
||||
@@ -106,6 +106,7 @@ usr/local/bin/settime
|
||||
usr/local/bin/timecheck
|
||||
usr/local/bin/timezone-transition
|
||||
usr/local/bin/update-ids-ruleset
|
||||
usr/local/bin/update-ipblocklists
|
||||
usr/local/bin/update-lang-cache
|
||||
usr/local/bin/update-location-database
|
||||
#usr/local/include
|
||||
@@ -154,6 +155,7 @@ var/cache/ldconfig
|
||||
var/cache/ldconfig/aux-cache
|
||||
var/empty
|
||||
#var/lib
|
||||
var/lib/ipblocklist
|
||||
#var/lib/misc
|
||||
#var/local
|
||||
var/lock
|
||||
|
||||
@@ -143,6 +143,22 @@ if grep -q "ENABLED=on" /var/ipfire/vpn/settings; then
|
||||
/etc/init.d/ipsec start
|
||||
fi
|
||||
|
||||
# krb5 is now part of the core system, remove Pakfire metadata for it
|
||||
if [ -e "/opt/pakfire/db/installed/meta-krb5" ] && [ -e "/opt/pakfire/db/meta/meta-krb5" ]; then
|
||||
rm -vf \
|
||||
/opt/pakfire/db/installed/meta-krb5 \
|
||||
/opt/pakfire/db/meta/meta-krb5 \
|
||||
/opt/pakfire/db/rootfiles/krb5
|
||||
fi
|
||||
|
||||
# libtiff is now part of the core system, remove Pakfire metadata for it
|
||||
if [ -e "/opt/pakfire/db/installed/meta-libtiff" ] && [ -e "/opt/pakfire/db/meta/meta-libtiff" ]; then
|
||||
rm -vf \
|
||||
/opt/pakfire/db/installed/meta-libtiff \
|
||||
/opt/pakfire/db/meta/meta-libtiff \
|
||||
/opt/pakfire/db/rootfiles/libtiff
|
||||
fi
|
||||
|
||||
# This update needs a reboot...
|
||||
touch /var/run/need_reboot
|
||||
|
||||
|
||||
260
html/cgi-bin/ipblocklist.cgi
Normal file
260
html/cgi-bin/ipblocklist.cgi
Normal file
@@ -0,0 +1,260 @@
|
||||
#!/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 <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# Copyright (C) 2018 - 2020 The IPFire Team #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
use strict;
|
||||
|
||||
# enable the following only for debugging purposes
|
||||
#use warnings;
|
||||
#use CGI::Carp 'fatalsToBrowser';
|
||||
|
||||
require '/var/ipfire/general-functions.pl';
|
||||
require "${General::swroot}/lang.pl";
|
||||
require "${General::swroot}/header.pl";
|
||||
require "${General::swroot}/ipblocklist-functions.pl";
|
||||
|
||||
# Import blockist sources and settings file.
|
||||
require "${General::swroot}/ipblocklist/sources";
|
||||
|
||||
###############################################################################
|
||||
# Configuration variables
|
||||
###############################################################################
|
||||
|
||||
my $settings = "${General::swroot}/ipblocklist/settings";
|
||||
my %cgiparams = ('ACTION' => '');
|
||||
|
||||
###############################################################################
|
||||
# Variables
|
||||
###############################################################################
|
||||
|
||||
my $errormessage = '';
|
||||
my $headline = "$Lang::tr{'error message'}";
|
||||
my $updating = 0;
|
||||
my %mainsettings;
|
||||
my %color;
|
||||
|
||||
# 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 );
|
||||
|
||||
# Get list of supported blocklists.
|
||||
my @blocklists = &IPblocklist::get_blocklists();
|
||||
|
||||
# Show Headers
|
||||
&Header::showhttpheaders();
|
||||
|
||||
# Process actions
|
||||
if ($cgiparams{'ACTION'} eq "$Lang::tr{'save'}") {
|
||||
# Array to store if blocklists are missing on the system
|
||||
# and needs to be downloaded first.
|
||||
my @missing_blocklists = ();
|
||||
|
||||
# Loop through the array of supported blocklists.
|
||||
foreach my $blocklist (@blocklists) {
|
||||
# Skip the blocklist if it is not enabled.
|
||||
next if($cgiparams{$blocklist} ne "on");
|
||||
|
||||
# Get the file name which keeps the converted blocklist.
|
||||
my $ipset_db_file = &IPblocklist::get_ipset_db_file($blocklist);
|
||||
|
||||
# Check if the blocklist already has been downloaded.
|
||||
if(-f "$ipset_db_file") {
|
||||
# Blocklist already exits, we can skip it.
|
||||
next;
|
||||
} else {
|
||||
# Blocklist not present, store in array to download it.
|
||||
push(@missing_blocklists, $blocklist);
|
||||
}
|
||||
}
|
||||
|
||||
# Check if the red device is not active and blocklists are missing.
|
||||
if ((not -e "${General::swroot}/red/active") && (@missing_blocklists)) {
|
||||
# The system is offline, cannot download the missing blocklists.
|
||||
# Store an error message.
|
||||
$errormessage = "$Lang::tr{'system is offline'}";
|
||||
} else {
|
||||
# Loop over the array of missing blocklists.
|
||||
foreach my $missing_blocklist (@missing_blocklists) {
|
||||
# Call the download and convert function to get the missing blocklist.
|
||||
my $status = &IPblocklist::download_and_create_blocklist($missing_blocklist);
|
||||
|
||||
# Check if there was an error during download.
|
||||
if ($status eq "dl_error") {
|
||||
$errormessage = "$Lang::tr{'ipblocklist could not download blocklist'} - $Lang::tr{'ipblocklist download error'}";
|
||||
} elsif ($status eq "empty_list") {
|
||||
$errormessage = "$Lang::tr{'ipblocklist could not download blocklist'} - $Lang::tr{'ipblocklist empty blocklist received'}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Check if there was an error.
|
||||
unless($errormessage) {
|
||||
# Write configuration hash.
|
||||
&General::writehash($settings, \%cgiparams);
|
||||
|
||||
# Call function to mark a required reload of the firewall.
|
||||
&General::firewall_config_changed();
|
||||
|
||||
# Display notice about a required reload of the firewall.
|
||||
$headline = "$Lang::tr{'notice'}";
|
||||
$errormessage = "$Lang::tr{'fw rules reload notice'}";
|
||||
}
|
||||
}
|
||||
|
||||
# Show site
|
||||
&Header::openpage($Lang::tr{'ipblocklist'}, 1, '');
|
||||
&Header::openbigbox('100%', 'left');
|
||||
|
||||
# Display error message if there was one.
|
||||
&error() if ($errormessage);
|
||||
|
||||
# Read-in ipblocklist settings.
|
||||
&General::readhash( $settings, \%settings ) if (-r $settings);
|
||||
|
||||
# Display configuration section.
|
||||
&configsite();
|
||||
|
||||
# End of page
|
||||
&Header::closebigbox();
|
||||
&Header::closepage();
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# sub configsite()
|
||||
#
|
||||
# Displays configuration
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
sub configsite {
|
||||
# Find preselections
|
||||
my $enable = 'checked';
|
||||
|
||||
&Header::openbox('100%', 'left', $Lang::tr{'settings'});
|
||||
|
||||
# Enable checkbox
|
||||
$enable = ($settings{'ENABLE'} eq 'on') ? ' checked' : '';
|
||||
|
||||
print<<END;
|
||||
<form method='post' action='$ENV{'SCRIPT_NAME'}'>
|
||||
<table style='width:100%' border='0'>
|
||||
<tr>
|
||||
<td style='width:24em'>$Lang::tr{'ipblocklist use ipblocklists'}</td>
|
||||
<td><input type='checkbox' name='ENABLE' id='ENABLE'$enable></td>
|
||||
</tr>
|
||||
</table><br>
|
||||
END
|
||||
|
||||
# The following are only displayed if the blacklists are enabled
|
||||
$enable = ($settings{'LOGGING'} eq 'on') ? ' checked' : '';
|
||||
|
||||
print <<END;
|
||||
<div class='sources'>
|
||||
<table style='width:100%' border='0'>
|
||||
<tr>
|
||||
<td style='width:24em'>$Lang::tr{'ipblocklist log'}</td>
|
||||
<td><input type='checkbox' name="LOGGING" id="LOGGING"$enable></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
<h2>$Lang::tr{'ipblocklist blocklist settings'}</h2>
|
||||
|
||||
<table width='100%' cellspacing='1' class='tbl'>
|
||||
<tr>
|
||||
<th align='left'>$Lang::tr{'ipblocklist id'}</th>
|
||||
<th align='left'>$Lang::tr{'ipblocklist name'}</th>
|
||||
<th align='left'>$Lang::tr{'ipblocklist category'}</th>
|
||||
<th align='center'>$Lang::tr{'ipblocklist enable'}</th>
|
||||
</tr>
|
||||
END
|
||||
|
||||
# Iterate through the list of sources
|
||||
my $lines = 0;
|
||||
|
||||
foreach my $blocklist (@blocklists) {
|
||||
# Display blocklist name or provide a link to the website if available.
|
||||
my $website = "$blocklist";
|
||||
if ($IPblocklist::List::sources{$blocklist}{info}) {
|
||||
$website ="<a href='$IPblocklist::List::sources{$blocklist}{info}' target='_blank'>$blocklist</a>";
|
||||
}
|
||||
|
||||
# Get the full name for the blocklist.
|
||||
my $name = &CGI::escapeHTML( $IPblocklist::List::sources{$blocklist}{'name'} );
|
||||
|
||||
# Get category for this blocklist.
|
||||
my $category = $Lang::tr{"ipblocklist category $IPblocklist::List::sources{$blocklist}{'category'}"};
|
||||
|
||||
# Determine if the blocklist is enabled.
|
||||
my $enable = '';
|
||||
$enable = 'checked' if ($settings{$blocklist} eq 'on');
|
||||
|
||||
# Set colour for the table columns.
|
||||
my $col = ($lines++ % 2) ? "bgcolor='$color{'color20'}'" : "bgcolor='$color{'color22'}'";
|
||||
|
||||
|
||||
print <<END;
|
||||
<tr $col>
|
||||
<td>$website</td>
|
||||
<td>$name</td>
|
||||
<td>$category</td>
|
||||
<td align='center'><input type='checkbox' name="$blocklist" id="$blocklist"$enable></td>
|
||||
</tr>
|
||||
END
|
||||
}
|
||||
|
||||
# The save button at the bottom of the table
|
||||
print <<END;
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<table style='width:100%;'>
|
||||
<tr>
|
||||
<td colspan='3' display:inline align='right'><input type='submit' name='ACTION' value='$Lang::tr{'save'}'></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
END
|
||||
|
||||
&Header::closebox();
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# sub error()
|
||||
#
|
||||
# Shows error messages
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
sub error {
|
||||
&Header::openbox('100%', 'left', $headline);
|
||||
print "<class name='base'>$errormessage\n";
|
||||
print " </class>\n";
|
||||
&Header::closebox();
|
||||
}
|
||||
366
html/cgi-bin/logs.cgi/ipblocklists.dat
Executable file
366
html/cgi-bin/logs.cgi/ipblocklists.dat
Executable file
@@ -0,0 +1,366 @@
|
||||
#!/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;
|
||||
|
||||
# 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";
|
||||
|
||||
require "${General::swroot}/ipblocklist-functions.pl";
|
||||
require "${General::swroot}/ipblocklist/sources";
|
||||
|
||||
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}/ipblocklist/settings", \%settings);
|
||||
|
||||
# Get all available blocklists.
|
||||
my @blocklists = &IPblocklist::get_blocklists();
|
||||
|
||||
foreach my $blocklist (@blocklists)
|
||||
{
|
||||
$lists{$blocklist} = {} if ($settings{$blocklist} 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 (<FILE>)
|
||||
{
|
||||
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 (<FILE>) {
|
||||
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{'ipblocklist logs'}, 1, '');
|
||||
&Header::openbigbox('100%', 'left', '', $errormessage);
|
||||
|
||||
|
||||
if ($errormessage) {
|
||||
&Header::openbox('100%', 'left', $Lang::tr{'error messages'});
|
||||
print "<font class='base'>$errormessage </font>\n";
|
||||
&Header::closebox();
|
||||
}
|
||||
|
||||
&Header::openbox('100%', 'left', "$Lang::tr{'settings'}");
|
||||
|
||||
print <<END
|
||||
<form method='post' action='$ENV{'SCRIPT_NAME'}'>
|
||||
<table width='100%'>
|
||||
<tr>
|
||||
<td width='10%' class='base'>$Lang::tr{'month'}: </td>
|
||||
<td width='10%'>
|
||||
<select name='MONTH'>
|
||||
END
|
||||
;
|
||||
my $month;
|
||||
for ($month = 0; $month < 12; $month++)
|
||||
{
|
||||
print "\t<option ";
|
||||
if ($month == $cgiparams{'MONTH'}) {
|
||||
print "selected='selected' ";
|
||||
}
|
||||
print "value='$month'>$longmonths[$month]</option>\n";
|
||||
}
|
||||
print <<END
|
||||
</select>
|
||||
</td>
|
||||
<td width='10%' class='base' align='right'> $Lang::tr{'day'}: </td>
|
||||
<td width='40%'>
|
||||
<select name='DAY'>
|
||||
END
|
||||
;
|
||||
for ($day = 1; $day <= 31; $day++)
|
||||
{
|
||||
print "\t<option ";
|
||||
if ($day == $cgiparams{'DAY'}) {
|
||||
print "selected='selected' ";
|
||||
}
|
||||
print "value='$day'>$day</option>\n";
|
||||
}
|
||||
|
||||
print <<END
|
||||
</select>
|
||||
</td>
|
||||
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day before'}' value='<<' /></td>
|
||||
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day after'}' value='>>' /></td>
|
||||
<td width='20%' align='right'><input type='submit' name='ACTION' value='$Lang::tr{'update'}' /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
END
|
||||
;
|
||||
|
||||
&Header::closebox();
|
||||
|
||||
&Header::openbox('100%', 'left', $Lang::tr{'firewall log'});
|
||||
print "<p><b>$Lang::tr{'ipblocklist hits'} $longmonthstr $daystr: $lines</b></p>";
|
||||
|
||||
my %color = ();
|
||||
my %mainsettings = ();
|
||||
&General::readhash("${General::swroot}/main/settings", \%mainsettings);
|
||||
&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color);
|
||||
|
||||
my @lists = sort keys (%lists);
|
||||
|
||||
print <<END
|
||||
<table width='100%' class='tbl'>
|
||||
<tr>
|
||||
<th align='center' class='boldbase' rowspan='2'></th>
|
||||
<th align='left' class='boldbase' rowspan='2'><b>$Lang::tr{'ipblocklist id'}</b></th>
|
||||
<th align='left' class='boldbase' rowspan='2'><b>$Lang::tr{'ipblocklist category'}</b></th>
|
||||
<th align='center' class='boldbase' colspan='2'><b>$Lang::tr{'ipblocklist input'}</b></th>
|
||||
<th align='center' class='boldbase' colspan='2'><b>$Lang::tr{'ipblocklist output'}</b></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align='center' class='boldbase'>$Lang::tr{'count'}</th>
|
||||
<th align='center' class='boldbase'>$Lang::tr{'percentage'}</th>
|
||||
<th align='center' class='boldbase'>$Lang::tr{'count'}</th>
|
||||
<th align='center' class='boldbase'>$Lang::tr{'percentage'}</th>
|
||||
</tr>
|
||||
END
|
||||
;
|
||||
|
||||
$lines = 0;
|
||||
my $lists = join ',', @lists;
|
||||
|
||||
foreach my $list (@lists)
|
||||
{
|
||||
my $col = ($lines++ % 2) ? "bgcolor='$color{'color20'}'" : "bgcolor='$color{'color22'}'";
|
||||
my $category = exists( $IPblocklist::List::sources{$list}) ? $Lang::tr{"ipblocklist category $IPblocklist::List::sources{$list}{'category'}"} : ' ';
|
||||
|
||||
print "<tr>";
|
||||
|
||||
print "<td align='center' $col><form method='post' action='showrequestfromblocklist.dat'><input type='hidden' name='MONTH' value='$cgiparams{'MONTH'}'> <input type='hidden' name='DAY' value='$cgiparams{'DAY'}'> <input type='hidden' name='blocklist' value='$list'><input type='hidden' name='blocklists' value='$lists'> <input type='submit' value='$Lang::tr{'details'}'></form></td>";
|
||||
|
||||
if (exists($IPblocklist::List::sources{$list}) and $IPblocklist::List::sources{$list}{'info'})
|
||||
{
|
||||
print "<td $col><a href='$IPblocklist::List::sources{$list}{info}' target='_blank'>$list</a></td>";
|
||||
}
|
||||
else
|
||||
{
|
||||
print "<td $col>$list</td>";
|
||||
}
|
||||
|
||||
print "<td $col>$category</td>";
|
||||
|
||||
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 "<td align='center' class='boldbase' $col>$count</th>";
|
||||
print "<td align='center' class='boldbase' $col>$percent%</th>";
|
||||
}
|
||||
|
||||
print "</tr>";
|
||||
}
|
||||
print <<END
|
||||
</table>
|
||||
END
|
||||
;
|
||||
|
||||
&Header::closebox();
|
||||
&Header::closebigbox();
|
||||
&Header::closepage();
|
||||
|
||||
sub checkversion {
|
||||
#Automatic Updates is disabled
|
||||
return "0","0";
|
||||
}
|
||||
@@ -59,6 +59,7 @@ my %sections = (
|
||||
'dhcp' => '(dhcpd: )',
|
||||
'dma' => '(dma: |dma\[.*\]: |postfix/\w*\[\d*\]: )',
|
||||
'guardian' => '(guardian\[.*\]: )',
|
||||
'ipblocklist' => '(ipblocklist: )',
|
||||
'ipfire' => '(ipfire: )',
|
||||
'ipsec' => '(ipsec_[\w_]+: |pluto\[.*\]: |charon: |vpnwatch: )',
|
||||
'kernel' => '(kernel: (?!DROP_))',
|
||||
@@ -89,6 +90,7 @@ my %trsections = (
|
||||
'dhcp' => "$Lang::tr{'dhcp server'}",
|
||||
'dma' => 'Mail',
|
||||
'guardian' => "$Lang::tr{'guardian'}",
|
||||
'ipblocklist' => "$Lang::tr{'ipblocklist'}",
|
||||
'ipfire' => 'IPFire',
|
||||
'ipsec' => 'IPSec',
|
||||
'kernel' => "$Lang::tr{'kernel'}",
|
||||
|
||||
414
html/cgi-bin/logs.cgi/showrequestfromblocklist.dat
Executable file
414
html/cgi-bin/logs.cgi/showrequestfromblocklist.dat
Executable file
@@ -0,0 +1,414 @@
|
||||
#!/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 @blocklists;
|
||||
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{'blocklist'} = shift @temp;
|
||||
$cgiparams{'blocklists'} = 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{'blocklists'})
|
||||
{
|
||||
@blocklists = split ',', $cgiparams{'blocklists'};
|
||||
}
|
||||
|
||||
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 $blocklist = $cgiparams{blocklist};
|
||||
|
||||
if (!$skip)
|
||||
{
|
||||
while (<FILE>) {
|
||||
if (/^${monthstr} ${daystr} ..:..:.. [\w\-]+ kernel:.*BLKLST_(\w+)\s?IN=.*/) {
|
||||
if($1 eq $blocklist){
|
||||
$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 (<FILE>) {
|
||||
if (/^${monthstr} ${daystr} ..:..:.. [\w\-]+ kernel:.*BLKLST_(\w+)\s?IN=.*/) {
|
||||
if($1 eq $blocklist){
|
||||
$log[$lines] = $_;
|
||||
$lines++;
|
||||
}
|
||||
}
|
||||
}
|
||||
close (FILE);
|
||||
}
|
||||
}
|
||||
|
||||
&Header::showhttpheaders();
|
||||
&Header::openpage($Lang::tr{'ipblocklist log list'}, 1, '');
|
||||
&Header::openbigbox('100%', 'left', '', $errormessage);
|
||||
|
||||
if ($errormessage) {
|
||||
&Header::openbox('100%', 'left', $Lang::tr{'error messages'});
|
||||
print "<font class='base'>$errormessage </font>\n";
|
||||
&Header::closebox();
|
||||
}
|
||||
|
||||
&Header::openbox('100%', 'left', "$Lang::tr{'settings'}:");
|
||||
|
||||
print <<END
|
||||
<form method='post' action='$ENV{'SCRIPT_NAME'}'>
|
||||
<input type='hidden' name='blocklists' value='$cgiparams{blocklists}'>
|
||||
<table width='100%'>
|
||||
<tr>
|
||||
<td width='10%' class='base'>$Lang::tr{'month'}: </td>
|
||||
<td width='10%'>
|
||||
<select name='MONTH'>
|
||||
END
|
||||
;
|
||||
my $month;
|
||||
for ($month = 0; $month < 12; $month++)
|
||||
{
|
||||
print "\t<option ";
|
||||
if ($month == $cgiparams{'MONTH'}) {
|
||||
print "selected='selected' "; }
|
||||
print "value='$month'>$longmonths[$month]</option>\n";
|
||||
}
|
||||
print <<END
|
||||
</select>
|
||||
</td>
|
||||
<td width='10%' class='base' align='right'> $Lang::tr{'day'}: </td>
|
||||
<td width='40%'>
|
||||
<select name='DAY'>
|
||||
END
|
||||
;
|
||||
for ($day = 1; $day <= 31; $day++)
|
||||
{
|
||||
print "\t<option ";
|
||||
if ($day == $cgiparams{'DAY'}) {
|
||||
print "selected='selected' "; }
|
||||
print "value='$day'>$day</option>\n";
|
||||
}
|
||||
print <<END
|
||||
</select>
|
||||
</td>
|
||||
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day before'}' value='<<' /></td>
|
||||
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day after'}' value='>>' /></td>
|
||||
<td width='10%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'update'}' /></td>
|
||||
<tr><td width='15%'>$Lang::tr{'ipblocklist id'}</td><td><select name='blocklist'>
|
||||
END
|
||||
;
|
||||
|
||||
foreach my $option (@blocklists)
|
||||
{
|
||||
my $selected = $option eq $cgiparams{blocklist} ? ' selected' : '';
|
||||
print "<option value='$option'$selected>$option</option>";
|
||||
}
|
||||
|
||||
print <<END
|
||||
</select></td></tr>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
END
|
||||
;
|
||||
|
||||
&Header::closebox();
|
||||
|
||||
&Header::openbox('100%', 'left', $Lang::tr{'ipblocklist log list'});
|
||||
print "<p><b>$Lang::tr{'firewall hits'} $longmonthstr $daystr: $lines</b></p>";
|
||||
|
||||
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 <<END
|
||||
<table width='100%'>
|
||||
<tr>
|
||||
<td width='12%' align='center' class='boldbase'><b>$Lang::tr{'time'}</b></td>
|
||||
<td width='6%' align='center' class='boldbase'><b>$Lang::tr{'iface'}</b></td>
|
||||
<td width='6%' align='center' class='boldbase'><b>$Lang::tr{'proto'}</b></td>
|
||||
<td width='18%' align='center' class='boldbase'><b>$Lang::tr{'source'}</b></td>
|
||||
<td width='15%' align='center' class='boldbase'><b>$Lang::tr{'src port'}</b></td>
|
||||
<td width='18%' align='center' class='boldbase'><b>$Lang::tr{'destination'}</b></td>
|
||||
<td width='15%' align='center' class='boldbase'><b>$Lang::tr{'dst port'}</b></td>
|
||||
</tr>
|
||||
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+)\s?IN=/)) {
|
||||
if($1 eq $blocklist) {
|
||||
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 "<tr bgcolor='${Header::table1colour}'>\n";
|
||||
}
|
||||
else {
|
||||
print "<tr bgcolor='${Header::table2colour}'>\n";
|
||||
}
|
||||
print <<END
|
||||
<td align='center'>$time</td>
|
||||
<td align='center'>$iface</td>
|
||||
<td align='center'>$protostr</td>
|
||||
<td align='center'>
|
||||
<table width='100%' cellpadding='0' cellspacing='0'><tr>
|
||||
<td align='center'><a href='/cgi-bin/ipinfo.cgi?ip=$srcaddr'>$srcaddr</a></td>
|
||||
</tr></table>
|
||||
</td>
|
||||
<td align='center'>$srcport</td>
|
||||
<td align='center'>
|
||||
<table width='100%' cellpadding='0' cellspacing='0'><tr>
|
||||
<td align='center'><a href='/cgi-bin/ipinfo.cgi?ip=$dstaddr'>$dstaddr</a></td>
|
||||
</tr></table>
|
||||
</td>
|
||||
<td align='center'>$dstport</td>
|
||||
</tr>
|
||||
END
|
||||
;
|
||||
$lines++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print <<END
|
||||
</table>
|
||||
END
|
||||
;
|
||||
|
||||
&oldernewer();
|
||||
|
||||
print"<table width='100%'><tr><td align='center'><a href='/cgi-bin/logs.cgi/ipblocklists.dat'><img src='/images/back.png' alt='$Lang::tr{'back'}' title='$Lang::tr{'back'}' /></a></td></tr></table>";
|
||||
|
||||
&Header::closebox();
|
||||
|
||||
&Header::closebigbox();
|
||||
|
||||
&Header::closepage();
|
||||
|
||||
sub oldernewer
|
||||
{
|
||||
print <<END
|
||||
<table width='100%'>
|
||||
<tr>
|
||||
END
|
||||
;
|
||||
|
||||
my $blocklists = join ',', @blocklists;
|
||||
|
||||
print "<td align='center' width='50%'>";
|
||||
if ($prev != -1) {
|
||||
print "<a href='/cgi-bin/logs.cgi/showrequestfromblocklist.dat?$prev,$cgiparams{'MONTH'},$cgiparams{'DAY'},$cgiparams{blocklist},$blocklists'>$Lang::tr{'older'}</a>";
|
||||
}
|
||||
else {
|
||||
print "$Lang::tr{'older'}";
|
||||
}
|
||||
print "</td>\n";
|
||||
|
||||
print "<td align='center' width='50%'>";
|
||||
if ($next != -1) {
|
||||
print "<a href='/cgi-bin/logs.cgi/showrequestfromblocklist.dat?$next,$cgiparams{'MONTH'},$cgiparams{'DAY'},$cgiparams{blocklist},$blocklists'>$Lang::tr{'newer'}</a>";
|
||||
}
|
||||
else {
|
||||
print "$Lang::tr{'newer'}";
|
||||
}
|
||||
print "</td>\n";
|
||||
|
||||
print <<END
|
||||
</tr>
|
||||
</table>
|
||||
END
|
||||
;
|
||||
}
|
||||
@@ -1585,6 +1585,33 @@
|
||||
'ip basic info' => 'Basic IP information',
|
||||
'ip info' => 'IP information',
|
||||
'ip info for' => 'IP information for',
|
||||
'ipblocklist' => 'IP Address Blocklists',
|
||||
'ipblocklist blocklist settings' => 'Blocklist settings',
|
||||
'ipblocklist category' => 'Category',
|
||||
'ipblocklist category application' => 'Application',
|
||||
'ipblocklist category attacker' => 'Attacker',
|
||||
'ipblocklist category c and c' => 'Malware C&C',
|
||||
'ipblocklist category composite' => 'Composite',
|
||||
'ipblocklist category invalid' => 'Invalid Address',
|
||||
'ipblocklist category reputation' => 'Reputation',
|
||||
'ipblocklist category scanner' => 'Scanner',
|
||||
'ipblocklist could not download blocklist' => 'Could not download blocklist',
|
||||
'ipblocklist disable mid' => 'because it is included in',
|
||||
'ipblocklist disable post' => '',
|
||||
'ipblocklist disable pre' => 'Disabling',
|
||||
'ipblocklist download error' => 'A download error occurs.',
|
||||
'ipblocklist empyt blocklist received' => 'An empty blocklist has been received.',
|
||||
'ipblocklist enable' => 'Enable',
|
||||
'ipblocklist entries' => 'Entries',
|
||||
'ipblocklist hits' => 'Total number of blocklist hits for',
|
||||
'ipblocklist id' => 'Blocklist',
|
||||
'ipblocklist input' => 'Packets Dropped In',
|
||||
'ipblocklist log list' => 'Firewall log (blocklist)',
|
||||
'ipblocklist log' => 'Log dropped packets',
|
||||
'ipblocklist logs' => 'IP Address Blocklist Logs',
|
||||
'ipblocklist name' => 'Name',
|
||||
'ipblocklist output' => 'Packets Dropped Out',
|
||||
'ipblocklist use ipblocklists' => 'Enable IP Blocklists',
|
||||
'ipfire has now rebooted' => 'IPFire is rebooting now.',
|
||||
'ipfire has now shutdown' => 'IPFire is shutting down now.',
|
||||
'ipfire side' => 'IPFire side:',
|
||||
|
||||
@@ -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 ipblocklist 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/locationblock firewall/input firewall/outgoing \
|
||||
fwhosts/customnetworks fwhosts/customhosts fwhosts/customgroups fwhosts/customservicegrp fwhosts/customlocationgrp fwlogs/ipsettings fwlogs/portsettings \
|
||||
fwhosts/customnetworks fwhosts/customhosts fwhosts/customgroups fwhosts/customservicegrp fwhosts/customlocationgrp fwlogs/ipsettings fwlogs/portsettings ipblocklist/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 \
|
||||
|
||||
53
lfs/ipblocklist-sources
Normal file
53
lfs/ipblocklist-sources
Normal file
@@ -0,0 +1,53 @@
|
||||
###############################################################################
|
||||
# #
|
||||
# IPFire.org - A linux based firewall #
|
||||
# Copyright (C) 2007-2022 IPFire development team #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# Definitions
|
||||
###############################################################################
|
||||
|
||||
include Config
|
||||
|
||||
VER = ipfire
|
||||
|
||||
THISAPP = ipblocklist-sources
|
||||
TARGET = $(DIR_INFO)/$(THISAPP)
|
||||
|
||||
###############################################################################
|
||||
# Top-level Rules
|
||||
###############################################################################
|
||||
|
||||
install : $(TARGET)
|
||||
|
||||
check :
|
||||
|
||||
download :
|
||||
|
||||
b2 :
|
||||
|
||||
###############################################################################
|
||||
# Installation Details
|
||||
###############################################################################
|
||||
|
||||
$(TARGET) :
|
||||
@$(PREBUILD)
|
||||
mkdir -p /var/ipfire/ipblocklist
|
||||
install -v -m 0644 $(DIR_SRC)/config/ipblocklist/sources /var/ipfire/ipblocklist
|
||||
|
||||
@$(POSTBUILD)
|
||||
@@ -98,6 +98,9 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
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/ipblocklist /usr/share/logwatch/scripts/services/ipblocklist
|
||||
cp -f $(DIR_SRC)/config/logwatch/ipblocklist.conf /usr/share/logwatch/dist.conf/services/ipblocklist.conf
|
||||
|
||||
-mkdir -p /var/cache/logwatch
|
||||
chmod -v 777 /var/cache/logwatch
|
||||
-mkdir -p /var/log/logwatch
|
||||
|
||||
@@ -165,4 +165,8 @@ endif
|
||||
-mkdir -pv /opt/pakfire/db/core
|
||||
echo "$(CORE)" > /opt/pakfire/db/core/mine
|
||||
|
||||
# IPblocklist.
|
||||
-mkdir -pv /var/lib/ipblocklist
|
||||
chown nobody:nobody /var/lib/ipblocklist
|
||||
|
||||
@$(POSTBUILD)
|
||||
|
||||
1
make.sh
1
make.sh
@@ -1439,6 +1439,7 @@ buildipfire() {
|
||||
lfsmake2 hyperscan
|
||||
lfsmake2 suricata
|
||||
lfsmake2 ids-ruleset-sources
|
||||
lfsmake2 ipblocklist-sources
|
||||
lfsmake2 squid
|
||||
lfsmake2 squidguard
|
||||
lfsmake2 calamaris
|
||||
|
||||
@@ -180,6 +180,14 @@ iptables_init() {
|
||||
iptables -A HOSTILE_DROP -m limit --limit 10/second -j LOG --log-prefix "DROP_HOSTILE "
|
||||
iptables -A HOSTILE_DROP -j DROP -m comment --comment "DROP_HOSTILE"
|
||||
|
||||
# IP Address Blocklist chains
|
||||
iptables -N BLOCKLISTIN
|
||||
iptables -N BLOCKLISTOUT
|
||||
iptables -A INPUT ! -p icmp -j BLOCKLISTIN
|
||||
iptables -A FORWARD ! -p icmp -j BLOCKLISTIN
|
||||
iptables -A FORWARD ! -p icmp -j BLOCKLISTOUT
|
||||
iptables -A OUTPUT ! -p icmp -j BLOCKLISTOUT
|
||||
|
||||
# IPS (Guardian) chains
|
||||
iptables -N GUARDIAN
|
||||
iptables -A INPUT -j GUARDIAN
|
||||
|
||||
173
src/scripts/update-ipblocklists
Normal file
173
src/scripts/update-ipblocklists
Normal file
@@ -0,0 +1,173 @@
|
||||
#!/usr/bin/perl
|
||||
###############################################################################
|
||||
# #
|
||||
# IPFire.org - A linux based firewall #
|
||||
# Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
use strict;
|
||||
use POSIX;
|
||||
|
||||
# Load perl module to talk to the kernel syslog.
|
||||
use Sys::Syslog qw(:DEFAULT setlogsock);
|
||||
|
||||
require '/var/ipfire/general-functions.pl';
|
||||
require "${General::swroot}/ipblocklist-functions.pl";
|
||||
require "${General::swroot}/lang.pl";
|
||||
|
||||
# Hash to store the settings.
|
||||
my %settings = ();
|
||||
|
||||
# The user and group name as which this script should be run.
|
||||
my $run_as = 'nobody';
|
||||
|
||||
# Get user and group id of the user.
|
||||
my ( $uid, $gid ) = ( getpwnam $run_as )[ 2, 3 ];
|
||||
|
||||
# Check if the script currently runs as root.
|
||||
if ( $> == 0 ) {
|
||||
# Drop privileges and switch to the specified user and group.
|
||||
POSIX::setgid( $gid );
|
||||
POSIX::setuid( $uid );
|
||||
}
|
||||
|
||||
# Establish the connection to the syslog service.
|
||||
openlog('ipblocklist', 'cons', 'user');
|
||||
|
||||
# Grab the configured providers.
|
||||
&General::readhash("${General::swroot}/ipblocklist/settings", \%settings);
|
||||
|
||||
# Check if the blocklist feature is enabled.
|
||||
unless ($settings{'ENABLE'} eq "on") {
|
||||
# Exit.
|
||||
exit 0;
|
||||
}
|
||||
|
||||
# Check if the red device is active.
|
||||
unless (-e "${General::swroot}/red/active") {
|
||||
# Log to syslog.
|
||||
&_log_to_syslog("<ERROR> Could not update any blocklist - The system is offline!");
|
||||
|
||||
# Exit.
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Get all available blocklists.
|
||||
my @blocklists = &IPblocklist::get_blocklists();
|
||||
|
||||
# Array to store successfully update blocklists.
|
||||
# They need to be reloaded.
|
||||
my @updated_blocklists = ();
|
||||
|
||||
# Gather the details, when a list got modified last time.
|
||||
my %modified = ();
|
||||
|
||||
# Read-in data if the file exists.
|
||||
&General::readhash($IPblocklist::modified_file, \%modified ) if (-e $IPblocklist::modified_file);
|
||||
|
||||
# Loop through the array of blocklists.
|
||||
foreach my $blocklist (@blocklists) {
|
||||
# Skip if the blocklist is not enabled.
|
||||
next if($settings{$blocklist} ne "on");
|
||||
|
||||
# Get current time.
|
||||
my $time = time();
|
||||
|
||||
# Get time, when the blocklist has been downloaded last.
|
||||
my $last_download_time = $modified{$blocklist};
|
||||
|
||||
# Get the holdoff rate in seconds for the current processed blocklist.
|
||||
my $rate_time = &IPblocklist::get_holdoff_rate($blocklist);
|
||||
|
||||
# Calculate holdoff time.
|
||||
my $holdoff_time = $last_download_time + $rate_time;
|
||||
|
||||
# Check if enough time has passed since the last download of the list.
|
||||
if ($time <= $holdoff_time) {
|
||||
# To frequent updates, log to syslog.
|
||||
&_log_to_syslog("<INFO> Skipping $blocklist blocklist - Too frequent update attempts!");
|
||||
|
||||
# Skip this provider.
|
||||
next;
|
||||
}
|
||||
|
||||
# Try to download and update the blocklist.
|
||||
my $return = &IPblocklist::download_and_create_blocklist($blocklist);
|
||||
|
||||
# Check if we got a return code.
|
||||
if ($return) {
|
||||
# Handle different return codes.
|
||||
if ($return eq "not_modified") {
|
||||
# Log notice to syslog.
|
||||
&_log_to_syslog("<INFO> Skipping $blocklist blocklist - It has not been modified!");
|
||||
} elsif ($return eq "dl_error") {
|
||||
# Log error to the syslog.
|
||||
&_log_to_syslog("<ERROR> Could not update $blocklist blocklist - Download error\!");
|
||||
} else {
|
||||
# Log error to syslog.
|
||||
&_log_to_syslog("<ERROR> Could not update $blocklist blocklist - Unexpected error\!");
|
||||
}
|
||||
} else {
|
||||
# Log successfull update.
|
||||
&_log_to_syslog("<INFO> Successfully updated $blocklist blocklist.");
|
||||
|
||||
# Add the list to the array of updated blocklists.
|
||||
push(@updated_blocklists, $blocklist);
|
||||
}
|
||||
}
|
||||
|
||||
# Check if a blocklist has been updated and therefore needs to be reloaded.
|
||||
if (@updated_blocklists) {
|
||||
# Loop through the array.
|
||||
foreach my $updated_blocklist (@updated_blocklists) {
|
||||
# Get the blocklist file.
|
||||
my $ipset_db_file = &IPblocklist::get_ipset_db_file($updated_blocklist);
|
||||
|
||||
# Call safe system function to reload/update the blocklist.
|
||||
&General::system("ipset", "restore", "-f", "$ipset_db_file");
|
||||
|
||||
# The set name contains a "v4" as suffix.
|
||||
my $set_name = "$updated_blocklist" . "v4";
|
||||
|
||||
# Swap the sets to use the new one.
|
||||
&General::system("ipset", "swap", "$set_name", "$updated_blocklist");
|
||||
|
||||
# Destroy the old blocklist.
|
||||
&General::system("ipset", "destroy", "$set_name");
|
||||
}
|
||||
}
|
||||
|
||||
END {
|
||||
# Close connection to syslog.
|
||||
closelog();
|
||||
}
|
||||
|
||||
#
|
||||
# Tiny function to sent the error message to the syslog.
|
||||
#
|
||||
sub _log_to_syslog($) {
|
||||
my ($message) = @_;
|
||||
|
||||
# The syslog function works best with an array based input,
|
||||
# so generate one before passing the message details to syslog.
|
||||
my @syslog = ("ERR", "$message");
|
||||
|
||||
# Send the log message.
|
||||
syslog(@syslog);
|
||||
}
|
||||
|
||||
1;
|
||||
Reference in New Issue
Block a user