diff --git a/3rdparty/logwatch/fail2ban b/3rdparty/logwatch/fail2ban deleted file mode 100755 index 087eb529..00000000 --- a/3rdparty/logwatch/fail2ban +++ /dev/null @@ -1,181 +0,0 @@ -#!/usr/bin/perl -########################################################################## -# $Id: fail2ban 150 2013-06-18 22:19:38Z mtremaine $ -########################################################################## -# $Log: fail2ban,v $ -# Revision 1.5 2008/08/18 16:07:46 mike -# Patches from Paul Gear -mgt -# -# Revision 1.4 2008/06/30 23:07:51 kirk -# fixed copyright holders for files where I know who they should be -# -# Revision 1.3 2008/03/24 23:31:26 kirk -# added copyright/license notice to each script -# -# Revision 1.2 2006/12/15 04:53:59 bjorn -# Additional filtering, by Willi Mann. -# -# Revision 1.1 2006/05/30 19:04:26 bjorn -# Added fail2ban service, written by Yaroslav Halchenko. -# -# Written by Yaroslav Halchenko for fail2ban -# -########################################################################## - -######################################################## -## Copyright (c) 2008 Yaroslav Halchenko -## 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 an 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. -######################################################### - -use strict; -use Logwatch ':all'; - -my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; -my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; -my $IgnoreHost = $ENV{'sshd_ignore_host'} || ""; -my $DebugCounter = 0; -my $ReInitializations = 0; -my @IptablesErrors = (); -my @ActionErrors = (); -my $NotValidIP = 0; # reported invalid IPs number -my @OtherList = (); - -my %ServicesBans = (); - -if ( $Debug >= 5 ) { - print STDERR "\n\nDEBUG: Inside Fail2Ban Filter \n\n"; - $DebugCounter = 1; -} - -while (defined(my $ThisLine = )) { - if ( $Debug >= 5 ) { - print STDERR "DEBUG($DebugCounter): $ThisLine"; - $DebugCounter++; - } - chomp($ThisLine); - if ( ($ThisLine =~ /..,... DEBUG: /) or - ($ThisLine =~ /..,... \S*\s*: DEBUG /) or # syntax of 0.7.? fail2ban - ($ThisLine =~ /..,... INFO: (Fail2Ban v.* is running|Exiting|Enabled sections:)/) or - ($ThisLine =~ /INFO\s+Log rotation detected for/) or - ($ThisLine =~ /INFO\s+Jail.+(?:stopped|started|uses poller)/) or - ($ThisLine =~ /INFO\s+Changed logging target to/) or - ($ThisLine =~ /INFO\s+Creating new jail/) or - ($ThisLine =~ /..,... \S+\s*: INFO\s+(Set |Socket|Exiting|Gamin|Created|Added|Using)/) or # syntax of 0.7.? fail2ban - ($ThisLine =~ /..,... WARNING: Verbose level is /) or - ($ThisLine =~ /..,... WARNING: Restoring firewall rules/) - ) - { - if ( $Debug >= 6 ) { - print STDERR "DEBUG($DebugCounter): line ignored\n"; - } - } elsif ( my ($Service,$Action,$Host) = ($ThisLine =~ m/WARNING:?\s\[?(.*?)[]:]?\s(Ban|Unban)[^\.]* (\S+)/)) { - if ( $Debug >= 6 ) { - print STDERR "DEBUG($DebugCounter): Found $Action for $Service from $Host\n"; - } - $ServicesBans{$Service}{$Host}{$Action}++; - $ServicesBans{$Service}{"(all)"}{$Action}++; - } elsif ( my ($Service,$Host,$NumFailures) = ($ThisLine =~ m/INFO: (\S+): (.+) has (\d+) login failure\(s\). Banned./)) { - if ($Debug >= 4) { - print STDERR "DEBUG: Found host $Host trying to access $Service - failed $NumFailures times\n"; - } - push @{$ServicesBans{$Service}{$Host}{'Failures'}}, $NumFailures; - } elsif ( my ($Service,$Host) = ($ThisLine =~ m/ ERROR:\s(.*):\s(\S+)\salready in ban list/)) { - $ServicesBans{$Service}{$Host}{'AlreadyInTheList'}++; - } elsif ( my ($Service,$Host) = ($ThisLine =~ m/WARNING\s*\[(.*)\]\s*(\S+)\s*already banned/)) { - $ServicesBans{$Service}{$Host}{'AlreadyInTheList'}++; - } elsif ( my ($Service,$Host) = ($ThisLine =~ m/ WARNING:\s(.*):\sReBan (\S+)/)) { - $ServicesBans{$Service}{$Host}{'ReBan'}++; - } elsif ($ThisLine =~ / ERROR:?\s*(Execution of command )?\'?iptables/) { - push @IptablesErrors, "$ThisLine\n"; - } elsif ($ThisLine =~ /ERROR.*returned \d+$/) { - push @ActionErrors, "$ThisLine\n"; - } elsif (($ThisLine =~ /..,... WARNING: \#\S+ reinitialization of firewalls/) or - ($ThisLine =~ / ERROR\s*Invariant check failed. Trying to restore a sane environment/)) { - $ReInitializations++; - } elsif ($ThisLine =~ /..,... WARNING: is not a valid IP address/) { - # just ignore - this will be fixed within fail2ban and is harmless warning - } - else - { - # Report any unmatched entries... - push @OtherList, "$ThisLine\n"; - } -} - -########################################################### - - -if (keys %ServicesBans) { - printf("\nBanned services with Fail2Ban: Bans:Unbans\n"); - foreach my $service (sort {$a cmp $b} keys %ServicesBans) { - printf(" %-55s [%3d:%-3d]\n", "$service:", - $ServicesBans{$service}{'(all)'}{'Ban'}, - $ServicesBans{$service}{'(all)'}{'Unban'}); - delete $ServicesBans{$service}{'(all)'}; - my $totalSort = TotalCountOrder(%{$ServicesBans{$service}}, \&SortIP); - if ($Detail >= 5) { - foreach my $ip (sort $totalSort keys %{$ServicesBans{$service}}) { - my $name = LookupIP($ip); - printf(" %-53s %3d:%-3d\n", - $name, - $ServicesBans{$service}{$ip}{'Ban'}, - $ServicesBans{$service}{$ip}{'Unban'}); - if (($Detail >= 10) and ($ServicesBans{$service}{$ip}{'Failures'}>0)) { - print " Failed "; - foreach my $fails (@{$ServicesBans{$service}{$ip}{'Failures'}}) { - print " $fails"; - } - print " times"; - printf("\n %d Duplicate Ban attempts", $ServicesBans{$service}{$ip}{'AlreadyInTheList'}) ; - printf("\n %d ReBans due to rules reinitilizations", $ServicesBans{$service}{$ip}{'ReBan'}) ; - print "\n"; - } - } - } - } -} - - -if ($Detail>0) { - if ($#IptablesErrors > 0) { - printf("\n%d faulty iptables invocation(s)", $#IptablesErrors); - if ($Detail > 5) { - print ":\n"; - print @IptablesErrors ; - } - } - if ($#ActionErrors > 0) { - printf("\n%d error(s) returned from actions", $#ActionErrors); - if ($Detail > 5) { - print ":\n"; - print @ActionErrors ; - } - } - if ($ReInitializations > 0) { - printf("\n%d fail2ban rules reinitialization(s)", $ReInitializations); - } - if ($#OtherList >= 0) { - print "\n**Unmatched Entries**\n"; - print @OtherList; - } -} - -exit(0); - -# vi: shiftwidth=3 tabstop=3 syntax=perl et -# Local Variables: -# mode: perl -# perl-indent-level: 3 -# indent-tabs-mode: nil -# End: diff --git a/ChangeLog b/ChangeLog index 6a9bf03f..d92aec4a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -48,12 +48,16 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger * cyrus-imap -- also catch also failed logins via secured (imaps/pop3s). Regression was introduced while strengthening failregex in 0.8.11 (bd175f) Debian bug #755173 - * postfix-sasl -- added journalmatch. Thanks Luc Maisonobe + * postfix-sasl - added journalmatch. Thanks Luc Maisonobe + * postfix* - match with a new daemon string (postfix/submission/smtpd). + Closes gh-804 . Thanks Paul Traina + * apache - added filter for AH01630 client denied by server configuration. - New features: - New filters: - monit Thanks Jason H Martin - directadmin Thanks niorg + - apache-shellshock Thanks Eugene Hopkinson (SlowRiot) - New actions: - symbiosis-blacklist-allports for Bytemark symbiosis firewall - fail2ban-client can fetch the running server version diff --git a/THANKS b/THANKS index b9288d4d..0433f7ed 100644 --- a/THANKS +++ b/THANKS @@ -34,6 +34,7 @@ David Nutter Derek Atkins Eric Gerbier Enrico Labedzki +Eugene Hopkinson (SlowRiot) ftoppi François Boulogne Frédéric @@ -81,6 +82,7 @@ Mika (mkl) Nick Munger onorua Paul Marrapese +Paul Traina Noel Butler Patrick Börjesson Pressy diff --git a/config/filter.d/apache-auth.conf b/config/filter.d/apache-auth.conf index f4213487..8a63858d 100644 --- a/config/filter.d/apache-auth.conf +++ b/config/filter.d/apache-auth.conf @@ -10,7 +10,7 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s (AH01797: )?client denied by server configuration: (uri )?\S*(, referer: \S+)?\s*$ +failregex = ^%(_apache_error_client)s (AH(01797|01630): )?client denied by server configuration: (uri )?\S*(, referer: \S+)?\s*$ ^%(_apache_error_client)s (AH01617: )?user .*? authentication failure for "\S*": Password Mismatch(, referer: \S+)?$ ^%(_apache_error_client)s (AH01618: )?user .*? not found(: )?\S*(, referer: \S+)?\s*$ ^%(_apache_error_client)s (AH01614: )?client used wrong authentication scheme: \S*(, referer: \S+)?\s*$ diff --git a/config/filter.d/apache-shellshock.conf b/config/filter.d/apache-shellshock.conf new file mode 100644 index 00000000..39df1704 --- /dev/null +++ b/config/filter.d/apache-shellshock.conf @@ -0,0 +1,26 @@ +# Fail2Ban filter to block web requests containing custom headers attempting to exploit the shellshock bug +# +# + +[INCLUDES] + +# overwrite with apache-common.local if _apache_error_client is incorrect. +before = apache-common.conf + +[Definition] + +failregex = ^%(_apache_error_client)s (AH01215: )?/bin/(ba)?sh: warning: HTTP_.*?: ignoring function definition attempt(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH01215: )?/bin/(ba)?sh: error importing function definition for `HTTP_.*?'(, referer: \S+)?\s*$ + +ignoreregex = + + +# DEV Notes: +# +# https://wiki.apache.org/httpd/ListOfErrors for apache error IDs +# +# example log lines: +# [Thu Sep 25 09:27:18.813902 2014] [cgi:error] [pid 16860] [client 89.207.132.76:59635] AH01215: /bin/bash: warning: HTTP_TEST: ignoring function definition attempt +# [Thu Sep 25 09:29:56.141832 2014] [cgi:error] [pid 16864] [client 162.247.73.206:41273] AH01215: /bin/bash: error importing function definition for `HTTP_TEST' +# +# Author: Eugene Hopkinson (riot@riot.so) diff --git a/config/filter.d/postfix-sasl.conf b/config/filter.d/postfix-sasl.conf index c5f8e3bc..35b064d3 100644 --- a/config/filter.d/postfix-sasl.conf +++ b/config/filter.d/postfix-sasl.conf @@ -7,10 +7,12 @@ before = common.conf [Definition] -_daemon = postfix/smtpd +_daemon = postfix/(submission/)?smtp(d|s) failregex = ^%(__prefix_line)swarning: [-._\w]+\[\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$ +ignoreregex = + [Init] journalmatch = _SYSTEMD_UNIT=postfix.service diff --git a/config/filter.d/postfix.conf b/config/filter.d/postfix.conf index ff58c58c..a7a05e47 100644 --- a/config/filter.d/postfix.conf +++ b/config/filter.d/postfix.conf @@ -10,7 +10,7 @@ before = common.conf [Definition] -_daemon = postfix/smtpd +_daemon = postfix/(submission/)?smtp(d|s) failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[\]: 554 5\.7\.1 .*$ ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[\]: 450 4\.7\.1 : Helo command rejected: Host not found; from=<> to=<> proto=ESMTP helo= *$ diff --git a/config/jail.conf b/config/jail.conf index c48e6a7b..99729350 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -283,6 +283,11 @@ port = http,https logpath = %(apache_error_log)s maxretry = 2 +[apache-shellshock] + +port = http,https +logpath = $(apache_error_log)s +maxretry = 1 [nginx-http-auth] diff --git a/fail2ban/tests/action_d/test_badips.py b/fail2ban/tests/action_d/test_badips.py index 30e016ea..a7f148b1 100644 --- a/fail2ban/tests/action_d/test_badips.py +++ b/fail2ban/tests/action_d/test_badips.py @@ -22,11 +22,7 @@ import unittest import sys from ..dummyjail import DummyJail - -if os.path.exists('config/fail2ban.conf'): - CONFIG_DIR = "config" -else: - CONFIG_DIR='/etc/fail2ban' +from ..utils import CONFIG_DIR if sys.version_info >= (2,7): class BadIPsActionTest(unittest.TestCase): diff --git a/fail2ban/tests/action_d/test_smtp.py b/fail2ban/tests/action_d/test_smtp.py index a8a8a1a9..440db55c 100644 --- a/fail2ban/tests/action_d/test_smtp.py +++ b/fail2ban/tests/action_d/test_smtp.py @@ -30,10 +30,7 @@ else: from ..dummyjail import DummyJail -if os.path.exists('config/fail2ban.conf'): - CONFIG_DIR = "config" -else: - CONFIG_DIR='/etc/fail2ban' +from ..utils import CONFIG_DIR class TestSMTPServer(smtpd.SMTPServer): diff --git a/fail2ban/tests/clientreadertestcase.py b/fail2ban/tests/clientreadertestcase.py index ce19a50e..0ad3c66e 100644 --- a/fail2ban/tests/clientreadertestcase.py +++ b/fail2ban/tests/clientreadertestcase.py @@ -32,8 +32,10 @@ from ..client.configurator import Configurator from .utils import LogCaptureTestCase TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files") + +from .utils import CONFIG_DIR + STOCK = os.path.exists(os.path.join('config','fail2ban.conf')) -CONFIG_DIR='config' if STOCK else '/etc/fail2ban' IMPERFECT_CONFIG = os.path.join(os.path.dirname(__file__), 'config') diff --git a/fail2ban/tests/files/logs/apache-auth b/fail2ban/tests/files/logs/apache-auth index a01d2c76..5b7b3c48 100644 --- a/fail2ban/tests/files/logs/apache-auth +++ b/fail2ban/tests/files/logs/apache-auth @@ -19,6 +19,9 @@ # failJSON: { "time": "2013-07-20T21:34:49", "match": true , "host": "127.0.0.1" } [Sat Jul 20 21:34:49.453232 2013] [access_compat:error] [pid 17512:tid 140123104306944] [client 127.0.0.1:51380] AH01797: client denied by server configuration: /var/www/html/noentry/cant_get_me.html +# failJSON: { "time": "2014-09-14T21:44:43", "match": true , "host": "192.3.9.178" } +[Sun Sep 14 21:44:43.008606 2014] [authz_core:error] [pid 10691] [client 192.3.9.178:44271] AH01630: client denied by server configuration: /var/www/html/noentry/cant_get_me.html + # wget --http-user='' --http-password='' http://localhost/basic/file/cant_get_me.html -O /dev/null # failJSON: { "time": "2013-07-17T23:14:37", "match": true , "host": "127.0.0.1" } [Wed Jul 17 23:14:37 2013] [error] [client 127.0.0.1] user not found: /basic/anon/cant_get_me.html diff --git a/fail2ban/tests/files/logs/apache-shellshock b/fail2ban/tests/files/logs/apache-shellshock new file mode 100644 index 00000000..0acf4546 --- /dev/null +++ b/fail2ban/tests/files/logs/apache-shellshock @@ -0,0 +1,4 @@ +# failJSON: { "time": "2014-09-25T09:27:18", "match": true , "host": "89.207.132.76" } +[Thu Sep 25 09:27:18.813902 2014] [cgi:error] [pid 16860] [client 89.207.132.76:59635] AH01215: /bin/bash: warning: HTTP_TEST: ignoring function definition attempt +# failJSON: { "time": "2014-09-25T09:29:56", "match": true , "host": "162.247.73.206" } +[Thu Sep 25 09:29:56.141832 2014] [cgi:error] [pid 16864] [client 162.247.73.206:41273] AH01215: /bin/bash: error importing function definition for `HTTP_TEST' diff --git a/fail2ban/tests/files/logs/postfix-sasl b/fail2ban/tests/files/logs/postfix-sasl index ca306098..697ac424 100644 --- a/fail2ban/tests/files/logs/postfix-sasl +++ b/fail2ban/tests/files/logs/postfix-sasl @@ -5,3 +5,6 @@ Dec 2 22:24:22 hel postfix/smtpd[7676]: warning: 114-44-142-233.dynamic.hinet.n # failJSON: { "time": "2005-03-10T13:33:30", "match": true , "host": "1.1.1.1" } Mar 10 13:33:30 gandalf postfix/smtpd[3937]: warning: HOSTNAME[1.1.1.1]: SASL LOGIN authentication failed: authentication failure +#3 Example from postfix post-debian changes to rename to add "submission" to syslog name +# failJSON: { "time": "2004-09-06T00:44:56", "match": true , "host": "82.221.106.233" } +Sep 6 00:44:56 trianon postfix/submission/smtpd[11538]: warning: unknown[82.221.106.233]: SASL LOGIN authentication failed: UGFzc3dvcmQ6 diff --git a/fail2ban/tests/samplestestcase.py b/fail2ban/tests/samplestestcase.py index 132ade7b..e0831184 100644 --- a/fail2ban/tests/samplestestcase.py +++ b/fail2ban/tests/samplestestcase.py @@ -32,13 +32,9 @@ else: from ..server.filter import Filter from ..client.filterreader import FilterReader -from .utils import setUpMyTime, tearDownMyTime +from .utils import setUpMyTime, tearDownMyTime, CONFIG_DIR TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files") -if os.path.exists('config/fail2ban.conf'): - CONFIG_DIR = "config" -else: - CONFIG_DIR='/etc/fail2ban' class FilterSamplesRegex(unittest.TestCase): diff --git a/fail2ban/tests/utils.py b/fail2ban/tests/utils.py index 0cb8d5b8..912c5a90 100644 --- a/fail2ban/tests/utils.py +++ b/fail2ban/tests/utils.py @@ -34,6 +34,15 @@ from ..helpers import getLogger logSys = getLogger(__name__) +CONFIG_DIR = os.environ.get('FAIL2BAN_CONFIG_DIR', None) + +if not CONFIG_DIR: +# Use heuristic to figure out where configuration files are + if os.path.exists(os.path.join('config','fail2ban.conf')): + CONFIG_DIR = 'config' + else: + CONFIG_DIR = '/etc/fail2ban' + def mtimesleep(): # no sleep now should be necessary since polling tracks now not only # mtime but also ino and size diff --git a/files/logwatch/fail2ban b/files/logwatch/fail2ban new file mode 100755 index 00000000..56ae070b --- /dev/null +++ b/files/logwatch/fail2ban @@ -0,0 +1,209 @@ +#!/usr/bin/perl +########################################################################## +# $Id: fail2ban 150 2013-06-18 22:19:38Z mtremaine $ +########################################################################## +# $Log: fail2ban,v $ +# +# Revision 1.6 2014/08/11 16:07:46 yoh +# Patches from Yaroslav Halchenko to match adjusted in 0.9.x lines. +# Also reports now total number of hits (matches) along with Ban:Unban +# and relaxed regular expressions for matching any log level +# +# Revision 1.5 2008/08/18 16:07:46 mike +# Patches from Paul Gear -mgt +# +# Revision 1.4 2008/06/30 23:07:51 kirk +# fixed copyright holders for files where I know who they should be +# +# Revision 1.3 2008/03/24 23:31:26 kirk +# added copyright/license notice to each script +# +# Revision 1.2 2006/12/15 04:53:59 bjorn +# Additional filtering, by Willi Mann. +# +# Revision 1.1 2006/05/30 19:04:26 bjorn +# Added fail2ban service, written by Yaroslav Halchenko. +# +# Written by Yaroslav Halchenko for fail2ban +# +########################################################################## + +######################################################## +## Copyright (c) 2008 Yaroslav Halchenko +## 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 an 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. +######################################################### + +use strict; +use Logwatch ':all'; + +my $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; +my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; +my $IgnoreHost = $ENV{'sshd_ignore_host'} || ""; +my $DebugCounter = 0; +my $ReInitializations = 0; +my @ActionsErrors = (); +my @CommandsErrors = (); +my $NotValidIP = 0; # reported invalid IPs number +my @OtherList = (); + +my %ServicesBans = (); + +if ( $Debug >= 5 ) { + print STDERR "\n\nDEBUG: Inside Fail2Ban Filter \n\n"; + $DebugCounter = 1; +} + +while (defined(my $ThisLine = )) { + if ( $Debug >= 5 ) { + print STDERR "DEBUG($DebugCounter): $ThisLine"; + $DebugCounter++; + } + chomp($ThisLine); + if ( ($ThisLine =~ /..,... DEBUG: /) or + ($ThisLine =~ /..,... \S*\s*: DEBUG /) or # syntax of 0.7.? fail2ban + ($ThisLine =~ /..,... \S+: (Fail2Ban v.* is running|Exiting|Enabled sections:)/) or + ($ThisLine =~ /\S+\s+rollover performed on/) or + ($ThisLine =~ /\S+\s+Connected to .* persistent database/) or + ($ThisLine =~ /\S+\s+Jail '.*' uses .*/) or + ($ThisLine =~ /\S+\s+Initiated '.*' backend/) or + ($ThisLine =~ /\S+\s+Jail .* is not a JournalFilter instance/) or + ($ThisLine =~ /\S+\s+Log rotation detected for/) or + ($ThisLine =~ /\S+\s+Jail.+(?:stopped|started|uses poller)/) or + ($ThisLine =~ /\S+\s+Changed logging target to/) or + ($ThisLine =~ /\S+\s+Creating new jail/) or + ($ThisLine =~ /..,... \S+\s*: INFO\s+(Set |Socket|Exiting|Gamin|Created|Added|Using)/) or # syntax of 0.7.? fail2ban + ($ThisLine =~ /..,... \S+: Verbose level is /) or + ($ThisLine =~ /..,... \S+: Restoring firewall rules/) + ) + { + if ( $Debug >= 6 ) { + print STDERR "DEBUG($DebugCounter): line ignored\n"; + } + } elsif ( my ($LogLevel,$Service,$Action,$Host) = ($ThisLine =~ m/(WARNING|NOTICE):?\s+\[?(.*?)[]:]?\s(Ban|Unban)[^\.]* (\S+)/)) { + if ( $Debug >= 6 ) { + print STDERR "DEBUG($DebugCounter): Found $Action for $Service from $Host\n"; + } + $ServicesBans{$Service}{$Host}{$Action}++; + $ServicesBans{$Service}{"(all)"}{$Action}++; + } elsif ( my ($LogLevel,$Service,$Host) = ($ThisLine =~ m/(INFO|WARNING|NOTICE):?\s+\[?(.*?)[]:]?\sFound[^\.]* (\S+)/)) { + if ( $Debug >= 6 ) { + print STDERR "DEBUG($DebugCounter): Found hit for $Service from $Host\n"; + } + $ServicesBans{$Service}{$Host}{"Hit"}++; + $ServicesBans{$Service}{"(all)"}{"Hit"}++; + } elsif ( my ($Service,$Host,$NumFailures) = ($ThisLine =~ m/\S+:\s+(\S+): (.+) has (\d+) login failure\(s\). Banned./)) { + if ($Debug >= 4) { + print STDERR "DEBUG: Found host $Host trying to access $Service - failed $NumFailures times\n"; + } + push @{$ServicesBans{$Service}{$Host}{'Failures'}}, $NumFailures; + } elsif ( my ($Service,$Host) = ($ThisLine =~ m/ \S+:\s(.*):\s(\S+)\salready in ban list/)) { + $ServicesBans{$Service}{$Host}{'AlreadyInTheList'}++; + } elsif ( my ($Service,$Host) = ($ThisLine =~ m/\S+:?\s+\[?([^[]*?)[]:]?\s+(\S+)\salready banned/)) { + if ( $Debug >= 6 ) { + print STDERR "DEBUG($DebugCounter): Found hit for already banned $Host against $Service\n"; + } + $ServicesBans{$Service}{$Host}{'AlreadyInTheList'}++; + } elsif ( my ($Service,$Host) = ($ThisLine =~ m/ \S+:\s(.*):\sReBan (\S+)/)) { + $ServicesBans{$Service}{$Host}{'ReBan'}++; + } elsif ($ThisLine =~ / ERROR:?\s*(Execution of command )?\'?iptables/) { + push @ActionsErrors, "$ThisLine\n"; + } elsif ($ThisLine =~ / ERROR\s*Failed to execute.*action/) { + push @ActionsErrors, "$ThisLine\n"; + } elsif ($ThisLine =~ / WARNING Command \[.*\] has failed. Received/) { + push @CommandsErrors, "$ThisLine\n"; + } elsif ($ThisLine =~ /ERROR.*returned \d+$/) { + push @ActionsErrors, "$ThisLine\n"; + } elsif (($ThisLine =~ /..,... WARNING: \#\S+ reinitialization of firewalls/) or + ($ThisLine =~ / ERROR\s*Invariant check failed. Trying to restore a sane environment/)) { + $ReInitializations++; + } elsif ($ThisLine =~ /..,... WARNING: is not a valid IP address/) { + # just ignore - this will be fixed within fail2ban and is harmless warning + } + else + { + # Report any unmatched entries... + push @OtherList, "$ThisLine\n"; + } +} + +########################################################### + + +if (keys %ServicesBans) { + printf("\nBanned services with Fail2Ban: Bans:Unbans:Hits\n"); + foreach my $service (sort {$a cmp $b} keys %ServicesBans) { + printf(" %-55s [%3d:%d:%-3d]\n", "$service:", + $ServicesBans{$service}{'(all)'}{'Ban'}, + $ServicesBans{$service}{'(all)'}{'Unban'}, + $ServicesBans{$service}{'(all)'}{'Hit'}); + delete $ServicesBans{$service}{'(all)'}; + my $totalSort = TotalCountOrder(%{$ServicesBans{$service}}, \&SortIP); + if ($Detail >= 5) { + foreach my $ip (sort $totalSort keys %{$ServicesBans{$service}}) { + my $name = LookupIP($ip); + printf(" %-53s %3d:%d:%-3d\n", + $name, + $ServicesBans{$service}{$ip}{'Ban'}, + $ServicesBans{$service}{$ip}{'Unban'}, + $ServicesBans{$service}{$ip}{'Hit'}); + if (($Detail >= 10) and ($ServicesBans{$service}{$ip}{'Failures'}>0)) { + print " Failed "; + foreach my $fails (@{$ServicesBans{$service}{$ip}{'Failures'}}) { + print " $fails"; + } + print " times\n"; + } + if ($ServicesBans{$service}{$ip}{'AlreadyInTheList'}>0) { + printf(" %d Duplicate Ban attempt(s)\n", $ServicesBans{$service}{$ip}{'AlreadyInTheList'}) ; + } + if ($ServicesBans{$service}{$ip}{'ReBan'}>0) { + printf(" %d ReBan(s) due to rules reinitilizations\n", $ServicesBans{$service}{$ip}{'ReBan'}) ; + } + } + } + } +} + +if ($Detail>0) { + if ($#ActionsErrors >= 0) { + printf("\n%d faulty action invocation(s)", $#ActionsErrors+1); + if ($Detail > 5) { + print ":\n"; + print @ActionsErrors ; + } + } + if ($#CommandsErrors >= 0) { + printf("\n%d faulty command invocation(s) from client(s)", $#CommandsErrors+1); + if ($Detail > 5) { + print ":\n"; + print @CommandsErrors ; + } + } + if ($ReInitializations > 0) { + printf("\n%d fail2ban rules reinitialization(s)", $ReInitializations); + } + if ($#OtherList >= 0) { + print "\n**Unmatched Entries**\n"; + print @OtherList; + } +} + +exit(0); + +# vi: shiftwidth=3 tabstop=3 syntax=perl et +# Local Variables: +# mode: perl +# perl-indent-level: 3 +# indent-tabs-mode: nil +# End: diff --git a/files/logwatch/fail2ban-0.8.log b/files/logwatch/fail2ban-0.8.log new file mode 100644 index 00000000..f9d5f3d5 --- /dev/null +++ b/files/logwatch/fail2ban-0.8.log @@ -0,0 +1,2 @@ +2014-08-04 03:06:26,161 fail2ban.actions[4822]: WARNING [apache-badbots] Ban 37.152.91.34 +2014-08-05 03:06:26,448 fail2ban.actions[4822]: WARNING [apache-badbots] Unban 37.152.91.34 diff --git a/files/logwatch/fail2ban-0.9.log b/files/logwatch/fail2ban-0.9.log new file mode 100644 index 00000000..ad996a1c --- /dev/null +++ b/files/logwatch/fail2ban-0.9.log @@ -0,0 +1,52 @@ +2014-08-08 14:59:35,013 fail2ban.server.server[31122]: INFO Exiting Fail2ban +2014-08-08 14:59:36,041 fail2ban.server.server[21667]: INFO Changed logging target to /var/log/fail2ban.log for Fail2ban v0.9.0 +2014-08-08 14:59:36,043 fail2ban.server.database[21667]: INFO Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3' +2014-08-08 14:59:36,072 fail2ban.server.jail[21667]: INFO Creating new jail 'exim' +2014-08-08 14:59:36,137 fail2ban.server.jail[21667]: INFO Jail 'exim' uses pyinotify +2014-08-08 14:59:36,172 fail2ban.server.filter[21667]: INFO Set jail log file encoding to UTF-8 +2014-08-08 14:59:36,172 fail2ban.server.jail[21667]: INFO Initiated 'pyinotify' backend +2014-08-08 14:59:36,233 fail2ban.server.filter[21667]: INFO Added logfile = /var/log/exim4/mainlog +2014-08-08 14:59:36,249 fail2ban.server.filter[21667]: INFO Set maxRetry = 5 +2014-08-08 14:59:36,251 fail2ban.server.filter[21667]: INFO Set jail log file encoding to UTF-8 +2014-08-08 14:59:36,252 fail2ban.server.actions[21667]: INFO Set banTime = 600 +2014-08-08 14:59:36,254 fail2ban.server.filter[21667]: INFO Set findtime = 600 +2014-08-08 14:59:36,284 fail2ban.server.jail[21667]: INFO Creating new jail 'sshd' +2014-08-08 14:59:36,284 fail2ban.server.jail[21667]: INFO Jail 'sshd' uses pyinotify +2014-08-08 14:59:36,286 fail2ban.server.filter[21667]: INFO Set jail log file encoding to UTF-8 +2014-08-08 14:59:36,286 fail2ban.server.jail[21667]: INFO Initiated 'pyinotify' backend +2014-08-08 14:59:36,499 fail2ban.server.filter[21667]: INFO Added logfile = /var/log/auth.log +2014-08-08 14:59:36,510 fail2ban.server.filter[21667]: INFO Set maxRetry = 5 +2014-08-08 14:59:36,512 fail2ban.server.filter[21667]: INFO Set jail log file encoding to UTF-8 +2014-08-08 14:59:36,513 fail2ban.server.actions[21667]: INFO Set banTime = 600 +2014-08-08 14:59:36,514 fail2ban.server.filter[21667]: INFO Set findtime = 600 +2014-08-08 14:59:36,515 fail2ban.server.filter[21667]: INFO Set maxlines = 10 +2014-08-08 14:59:36,788 fail2ban.server.server[21667]: INFO Jail sshd is not a JournalFilter instance +2014-08-08 14:59:36,798 fail2ban.server.jail[21667]: INFO Jail 'exim' started +2014-08-08 14:59:36,802 fail2ban.server.jail[21667]: INFO Jail 'sshd' started +2014-08-08 15:01:30,120 fail2ban.server.transmitter[21667]: WARNING Command ['status', 'ssh'] has failed. Received UnknownJailException('ssh',) +2014-08-08 15:09:36,978 fail2ban.server.actions[21667]: NOTICE [sshd] Unban 116.10.191.199 +2014-08-08 15:09:37,187 fail2ban.server.action[21667]: ERROR rm -f /etc/symbiosis/firewall/blacklist.d/116.10.191.199.auto +iptables -D INPUT -s 116.10.191.199 -j DROP -- stdout: '' +2014-08-08 15:09:37,188 fail2ban.server.action[21667]: ERROR rm -f /etc/symbiosis/firewall/blacklist.d/116.10.191.199.auto +iptables -D INPUT -s 116.10.191.199 -j DROP -- stderr: 'iptables: Bad rule (does a matching rule exist in that chain?).\n' +2014-08-08 15:09:37,188 fail2ban.server.action[21667]: ERROR rm -f /etc/symbiosis/firewall/blacklist.d/116.10.191.199.auto +iptables -D INPUT -s 116.10.191.199 -j DROP -- returned 1 +2014-08-08 15:09:37,188 fail2ban.server.actions[21667]: ERROR Failed to execute unban jail 'sshd' action 'symbiosis-blacklist': Error unbanning 116.10.191.199 +2014-08-10 02:27:27,235 fail2ban.server.server[21667]: INFO rollover performed on /var/log/fail2ban.log +2014-08-10 02:27:28,109 fail2ban.server.filter[21667]: INFO Log rotation detected for /var/log/exim4/mainlog +2014-08-10 02:28:01,747 fail2ban.server.filter[21667]: INFO Log rotation detected for /var/log/auth.log +2014-08-10 02:33:29,500 fail2ban.server.filter[21667]: INFO [sshd] Found 86.101.234.57 +2014-08-10 02:46:06,846 fail2ban.server.filter[21667]: INFO [sshd] Found 220.130.163.247 +2014-08-10 03:10:43,794 fail2ban.server.filter[21667]: INFO [sshd] Found 220.130.163.247 +2014-08-10 06:49:27,446 fail2ban.server.actions[21667]: NOTICE [sshd] Ban 116.10.191.181 +2014-08-10 06:59:28,375 fail2ban.server.actions[21667]: NOTICE [sshd] Unban 116.10.191.181 +2014-08-10 20:06:41,576 fail2ban.server.actions[21667]: NOTICE [sshd] Unban 50.30.34.7 +2014-08-13 17:55:50,401 fail2ban.server.actions[17436]: NOTICE [sshd] 144.0.0.25 already banned +2014-08-10 20:06:41,785 fail2ban.server.action[21667]: ERROR rm -f /etc/symbiosis/firewall/blacklist.d/50.30.34.7.auto +iptables -D INPUT -s 50.30.34.7 -j DROP -- stdout: '' +2014-08-10 20:06:41,785 fail2ban.server.action[21667]: ERROR rm -f /etc/symbiosis/firewall/blacklist.d/50.30.34.7.auto +iptables -D INPUT -s 50.30.34.7 -j DROP -- stderr: 'iptables: Bad rule (does a matching rule exist in that chain?).\n' +2014-08-10 20:06:41,786 fail2ban.server.action[21667]: ERROR rm -f /etc/symbiosis/firewall/blacklist.d/50.30.34.7.auto +iptables -D INPUT -s 50.30.34.7 -j DROP -- returned 1 +2014-08-10 20:06:41,786 fail2ban.server.actions[21667]: ERROR Failed to execute unban jail 'sshd' action 'symbiosis-blacklist': Error unbanning 50.30.34.7 +2014-08-11 02:27:35,433 fail2ban.server.filter[21667]: INFO Log rotation detected for /var/log/exim4/mainlog