mirror of https://github.com/fail2ban/fail2ban
				
				
				
			Merge remote-tracking branch 'upstream/master' into ban-time-incr
Conflicts resolved: fail2ban/server/database.py fail2ban/tests/servertestcase.py delBan modified (if manually unban): delete from "bips" also (bad ips) delete all tickets of this ip, also if currently not bannedpull/716/head
						commit
						62c755c1d5
					
				|  | @ -8,3 +8,4 @@ htmlcov | |||
| *.rej | ||||
| *.bak | ||||
| __pycache__ | ||||
| .vagrant/ | ||||
|  |  | |||
|  | @ -0,0 +1,181 @@ | |||
| #!/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 <paul at libertysys.com> -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 <debian@onerussian.com> 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 = <STDIN>)) { | ||||
|     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: | ||||
							
								
								
									
										37
									
								
								ChangeLog
								
								
								
								
							
							
						
						
									
										37
									
								
								ChangeLog
								
								
								
								
							|  | @ -4,9 +4,22 @@ | |||
|                        |_| \__,_|_|_/___|_.__/\__,_|_||_| | ||||
| 
 | ||||
| ================================================================================ | ||||
| Fail2Ban (version 0.9.0.dev)                                          2014/xx/xx | ||||
| Fail2Ban (version 0.9.2.dev)                                          2014/xx/xx | ||||
| ================================================================================ | ||||
| 
 | ||||
| ver. 0.9.2 (2014/xx/xx) - increment ban time | ||||
| ---------- | ||||
| 
 | ||||
| - New features: | ||||
|    - increment ban time (+ observer) functionality introduced. | ||||
|      Thanks Serg G. Brester (sebres) | ||||
| 
 | ||||
| - Fixes: | ||||
|    - purge database will be executed now (within observer). | ||||
|    - database functionality extended with bad ips. | ||||
|    - restoring currently banned ip after service restart fixed  | ||||
|      (now < timeofban + bantime), ignore old log failures (already banned) | ||||
| 
 | ||||
| ver. 0.9.1 (2014/xx/xx) - better, faster, stronger | ||||
| ---------- | ||||
| 
 | ||||
|  | @ -37,18 +50,38 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger | |||
|    * Correct times for non-timezone date times formats during DST | ||||
|      Thanks Serg G. Brester (sebres) | ||||
|    * Pass a copy of, not original, aInfo into actions to avoid side-effects | ||||
|    * Per-distribution paths to the exim's main log | ||||
|    * Ignored IPs are no longer banned when being restored from persistent | ||||
|      database | ||||
|    * Manually unbanned IPs are now removed from persistent database, such they | ||||
|      wont be banned again when Fail2Ban is restarted | ||||
|    * Pass "bantime" parameter to the actions in default jail's action | ||||
|      definition(s) | ||||
|    * filters.d/sieve.conf - fixed typo in _daemon.  Thanks Jisoo Park | ||||
|    * 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 | ||||
| 
 | ||||
| - New features: | ||||
|    - Added monit filter thanks Jason H Martin. | ||||
|    - Added | ||||
|      - monit filter. Thanks Jason H Martin | ||||
|      - directadmin filter. Thanks niorg | ||||
|    - fail2ban-client can fetch the running server version | ||||
|    - Added Cloudflare API action | ||||
| 
 | ||||
| - Enhancements | ||||
|    * Fail2ban-regex - add print-all-matched option. Closes gh-652 | ||||
|    * Suppress fail2ban-client warnings for non-critical config options | ||||
|    * Match non "Bye Bye" disconnect messages for sshd locked account regex | ||||
|    * courier-smtp filter: | ||||
|      - match lines with user names | ||||
|      - match lines containing "535 Authentication failed" attempts | ||||
|    * Add <chain> tag to iptables-ipsets | ||||
|    * Realign fail2ban log output with white space to improve readability. Does | ||||
|      not affect SYSLOG output | ||||
|    * Log unhandled exceptions | ||||
|    * cyrus-imap: catch "user not found" attempts | ||||
| 
 | ||||
| ver. 0.9.0 (2014/03/14) - beta | ||||
| ---------- | ||||
|  |  | |||
							
								
								
									
										4
									
								
								THANKS
								
								
								
								
							
							
						
						
									
										4
									
								
								THANKS
								
								
								
								
							|  | @ -49,6 +49,7 @@ John Thoe | |||
| Jacques Lav!gnotte | ||||
| Ioan Indreias | ||||
| Jason H Martin | ||||
| Jisoo Park | ||||
| Joel M Snyder | ||||
| Jonathan Kamens | ||||
| Jonathan Lanning | ||||
|  | @ -62,6 +63,7 @@ kjohnsonecl | |||
| kojiro | ||||
| Lars Kneschke | ||||
| Lee Clemens | ||||
| leftyfb (Mike Rushton) | ||||
| Manuel Arostegui Ramirez | ||||
| Marcel Dopita | ||||
| Mark Edgington | ||||
|  | @ -80,6 +82,7 @@ onorua | |||
| Paul Marrapese | ||||
| Noel Butler | ||||
| Patrick Börjesson | ||||
| Pressy | ||||
| Raphaël Marichez | ||||
| RealRancor | ||||
| René Berber | ||||
|  | @ -88,6 +91,7 @@ Rolf Fokkens | |||
| Roman Gelfand | ||||
| Russell Odom | ||||
| SATO Kentaro | ||||
| Sean DuBois | ||||
| Sebastian Arcus | ||||
| Serg G. Brester (sebres) | ||||
| Sireyessire | ||||
|  |  | |||
|  | @ -0,0 +1,30 @@ | |||
| Vagrant.configure("2") do |config| | ||||
| 
 | ||||
|     config.vm.define "secure" do |secure| | ||||
|         secure.vm.box = "ubuntu/trusty64" | ||||
|         secure.vm.hostname = "secure.dev.fail2ban.org" | ||||
|         secure.vm.network "private_network", ip: "192.168.200.100" | ||||
| 
 | ||||
| #        secure.vm.synced_folder 'salt/roots', '/srv/salt' | ||||
| 
 | ||||
| #        secure.vm.provision :salt do |salt| | ||||
| #            salt.minion_config = 'salt/minion' | ||||
| #            salt.run_highstate = true | ||||
| #            salt.verbose = true | ||||
| #        end | ||||
|     end | ||||
| 
 | ||||
|     config.vm.define "attacker" do |attacker| | ||||
|         attacker.vm.box = "ubuntu/trusty64" | ||||
|         attacker.vm.hostname = "attacker.dev.fail2ban.org" | ||||
|         attacker.vm.network "private_network", ip: "192.168.200.150" | ||||
| 
 | ||||
| #        attacker.vm.synced_folder 'salt/roots', '/srv/salt' | ||||
| 
 | ||||
| #        attacker.vm.provision :salt do |salt| | ||||
| #            salt.minion_config = 'salt/minion' | ||||
| #            salt.run_highstate = true | ||||
| #            salt.verbose = true | ||||
| #        end | ||||
|     end | ||||
| end | ||||
|  | @ -0,0 +1,55 @@ | |||
| # | ||||
| # Author: Mike Rushton | ||||
| # | ||||
| # Referenced from from http://www.normyee.net/blog/2012/02/02/adding-cloudflare-support-to-fail2ban by NORM YEE | ||||
| # | ||||
| # To get your Cloudflare API key: https://www.cloudflare.com/my-account | ||||
| # | ||||
| 
 | ||||
| [Definition] | ||||
| 
 | ||||
| # Option:  actionstart | ||||
| # Notes.:  command executed once at the start of Fail2Ban. | ||||
| # Values:  CMD | ||||
| # | ||||
| actionstart = | ||||
| 
 | ||||
| # Option:  actionstop | ||||
| # Notes.:  command executed once at the end of Fail2Ban | ||||
| # Values:  CMD | ||||
| # | ||||
| actionstop = | ||||
| 
 | ||||
| # Option:  actioncheck | ||||
| # Notes.:  command executed once before each actionban command | ||||
| # Values:  CMD | ||||
| # | ||||
| actioncheck = | ||||
| 
 | ||||
| # Option:  actionban | ||||
| # Notes.:  command executed when banning an IP. Take care that the | ||||
| #          command is executed with Fail2Ban user rights. | ||||
| # Tags:    <ip>  IP address | ||||
| #          <failures>  number of failures | ||||
| #          <time>  unix timestamp of the ban time | ||||
| # Values:  CMD | ||||
| # | ||||
| actionban = curl https://www.cloudflare.com/api_json.html -d 'a=ban' -d 'tkn=<cftoken>' -d 'email=<cfuser>' -d 'key=<ip>' | ||||
| # Option:  actionunban | ||||
| # Notes.:  command executed when unbanning an IP. Take care that the | ||||
| #          command is executed with Fail2Ban user rights. | ||||
| # Tags:    <ip>  IP address | ||||
| #          <failures>  number of failures | ||||
| #          <time>  unix timestamp of the ban time | ||||
| # Values:  CMD | ||||
| # | ||||
| actionunban = curl https://www.cloudflare.com/api_json.html -d 'a=nul' -d 'tkn=<cftoken>' -d 'email=<cfuser>' -d 'key=<ip>' | ||||
| 
 | ||||
| 
 | ||||
| [Init] | ||||
| 
 | ||||
| # Default Cloudflare API token  | ||||
| cftoken =  | ||||
| 
 | ||||
| # Default Cloudflare username | ||||
| cfuser =  | ||||
|  | @ -1,9 +1,9 @@ | |||
| # Fail2Ban action configuration file for ufw | ||||
| # | ||||
| # You are required to run "ufw enable" before this will have an effect. | ||||
| # You are required to run "ufw enable" before this will have any effect. | ||||
| # | ||||
| # The insert position should be approprate to block the required traffic. | ||||
| # A number after an allow rule to the application won't be much use. | ||||
| # The insert position should be appropriate to block the required traffic. | ||||
| # A number after an allow rule to the application won't be of much use. | ||||
| 
 | ||||
| [Definition] | ||||
| 
 | ||||
|  | @ -19,7 +19,7 @@ actionunban = [ -n "<application>" ] && app="app <application>" ; ufw delete <bl | |||
| 
 | ||||
| [Init] | ||||
| # Option: insertpos | ||||
| # Notes.:  The postition number in the firewall list to insert the block rule | ||||
| # Notes.:  The position number in the firewall list to insert the block rule | ||||
| insertpos = 1 | ||||
| 
 | ||||
| # Option: blocktype | ||||
|  |  | |||
|  | @ -12,7 +12,8 @@ before = common.conf | |||
| 
 | ||||
| _daemon = courieresmtpd | ||||
| 
 | ||||
| failregex = ^%(__prefix_line)serror,relay=<HOST>,.*: 550 User unknown\.$ | ||||
| failregex = ^%(__prefix_line)serror,relay=<HOST>,.*: 550 User (<.*> )?unknown\.?$ | ||||
|             ^%(__prefix_line)serror,relay=<HOST>,msg="535 Authentication failed\.",cmd:( AUTH \S+)?( [0-9a-zA-Z\+/=]+)?$ | ||||
| 
 | ||||
| ignoreregex =  | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,9 +11,9 @@ before = common.conf | |||
| 
 | ||||
| [Definition] | ||||
| 
 | ||||
| _daemon = (?:cyrus/)?(?:imapd?|pop3d?) | ||||
| _daemon = (?:cyrus/)?(?:imap(d|s)?|pop3(d|s)?) | ||||
| 
 | ||||
| failregex = ^%(__prefix_line)sbadlogin: \S+ ?\[<HOST>\] \S+ .*?\[?SASL\(-13\): authentication failure: .*\]?$ | ||||
| failregex = ^%(__prefix_line)sbadlogin: \S+ ?\[<HOST>\] \S+ .*?\[?SASL\(-13\): (authentication failure|user not found): .*\]?$ | ||||
| 
 | ||||
| ignoreregex =  | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,23 @@ | |||
| # Fail2Ban configuration file for Directadmin | ||||
| # | ||||
| # | ||||
| # | ||||
| 
 | ||||
| [INCLUDES] | ||||
| 
 | ||||
| before = common.conf | ||||
| 
 | ||||
| [Definition] | ||||
| 
 | ||||
| failregex = ^: \'<HOST>\' \d{1,3} failed login attempt(s)?. \s* | ||||
| 
 | ||||
| ignoreregex =  | ||||
| 
 | ||||
| [Init] | ||||
| datepattern = ^%%Y:%%m:%%d-%%H:%%M:%%S | ||||
| 
 | ||||
| # | ||||
| # Requires Directadmin v1.45.3 or higher. http://www.directadmin.com/features.php?id=1590 | ||||
| # | ||||
| # Author: Cyril Roos | ||||
| 
 | ||||
|  | @ -11,4 +11,9 @@ _daemon = postfix/smtpd | |||
| 
 | ||||
| failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$ | ||||
| 
 | ||||
| [Init] | ||||
| 
 | ||||
| journalmatch = _SYSTEMD_UNIT=postfix.service | ||||
| 
 | ||||
| 
 | ||||
| # Author: Yaroslav Halchenko | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ before = common.conf | |||
| 
 | ||||
| [Definition] | ||||
| 
 | ||||
| _deamon = (?:cyrus/)?(?:tim)?sieved? | ||||
| _daemon = (?:cyrus/)?(?:tim)?sieved? | ||||
| 
 | ||||
| failregex = ^%(__prefix_line)sbadlogin: \S+ ?\[<HOST>\] \S+ authentication failure$ | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ | |||
| # | ||||
| # YOU SHOULD NOT MODIFY THIS FILE. | ||||
| # | ||||
| # It will probably be overwitten or improved in a distribution update. | ||||
| # It will probably be overwritten or improved in a distribution update. | ||||
| # | ||||
| # Provide customizations in a jail.local file or a jail.d/customisation.local. | ||||
| # For example to change the default bantime for all jails and to enable the | ||||
|  | @ -189,22 +189,22 @@ port = 0:65535 | |||
| banaction = iptables-multiport | ||||
| 
 | ||||
| # The simplest action to take: ban only | ||||
| action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||||
| action_ = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||||
| 
 | ||||
| # ban & send an e-mail with whois report to the destemail. | ||||
| action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||||
| action_mw = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||||
|             %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"] | ||||
| 
 | ||||
| # ban & send an e-mail with whois report and relevant log lines | ||||
| # to the destemail. | ||||
| action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||||
| action_mwl = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||||
|              %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"] | ||||
| 
 | ||||
| # See the IMPORTANT note in action.d/xarf-login-attack for when to use this action | ||||
| # | ||||
| # ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines | ||||
| # to the destemail. | ||||
| action_xarf = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||||
| action_xarf = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||||
|              xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath=%(logpath)s, port="%(port)s"] | ||||
| 
 | ||||
| 
 | ||||
|  | @ -539,13 +539,13 @@ logpath = %(solidpop3d_log)s | |||
| [exim] | ||||
| 
 | ||||
| port   = smtp,465,submission | ||||
| logpath = /var/log/exim/mainlog | ||||
| logpath = %(exim_main_log)s | ||||
| 
 | ||||
| 
 | ||||
| [exim-spam] | ||||
| 
 | ||||
| port   = smtp,465,submission | ||||
| logpath = /var/log/exim/mainlog | ||||
| logpath = %(exim_main_log)s | ||||
| 
 | ||||
| 
 | ||||
| [kerio] | ||||
|  | @ -747,3 +747,8 @@ enabled = false | |||
| logpath = /opt/sun/comms/messaging64/log/mail.log_current | ||||
| maxretry = 6 | ||||
| banaction = iptables-allports | ||||
| 
 | ||||
| [directadmin] | ||||
| enabled = false | ||||
| logpath = /var/log/directadmin/login.log | ||||
| port = 2222 | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ sshd_log = %(syslog_authpriv)s | |||
| dropbear_log = %(syslog_authpriv)s | ||||
| 
 | ||||
| # There is no sensible generic defaults for syslog log targets, thus | ||||
| # leaving them empty here so that no errors while parsing/interpollatin configs | ||||
| # leaving them empty here so that no errors while parsing/interpolating configs | ||||
| syslog_daemon = | ||||
| syslog_ftp = | ||||
| syslog_local0 = | ||||
|  | @ -22,6 +22,7 @@ syslog_user = | |||
| # from /etc/audit/auditd.conf | ||||
| auditd_log = /var/log/audit/audit.log | ||||
| 
 | ||||
| exim_main_log = /var/log/exim/mainlog | ||||
| 
 | ||||
| nginx_error_log = /var/log/nginx/error.log | ||||
| 
 | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ apache_error_log = /var/log/apache2/*error.log | |||
| 
 | ||||
| apache_access_log = /var/log/apache2/*access.log | ||||
| 
 | ||||
| exim_main_log = /var/log/exim4/mainlog | ||||
| 
 | ||||
| # was in debian squeezy but not in wheezy | ||||
| # /etc/proftpd/proftpd.conf (SystemLog) | ||||
|  |  | |||
|  | @ -32,4 +32,6 @@ apache_access_log = /var/log/httpd/*access_log | |||
| # proftpd_log = /var/log/proftpd/auth.log | ||||
| # Tested and it worked out in /var/log/messages so assuming syslog_ftp for now. | ||||
| 
 | ||||
| exim_main_log = /var/log/exim/main.log | ||||
| 
 | ||||
| mysql_log = /var/lib/mysql/mysqld.log | ||||
|  |  | |||
|  | @ -51,6 +51,8 @@ class Beautifier: | |||
| 		try: | ||||
| 			if inC[0] == "ping": | ||||
| 				msg = "Server replied: " + response | ||||
| 			elif inC[0] == "version": | ||||
| 				msg = response | ||||
| 			elif inC[0] == "start": | ||||
| 				msg = "Jail started" | ||||
| 			elif inC[0] == "stop": | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ protocol = [ | |||
| ["status", "gets the current status of the server"],  | ||||
| ["ping", "tests if the server is alive"],  | ||||
| ["help", "return this output"],  | ||||
| ["version", "return the server version"], | ||||
| ['', "LOGGING", ""], | ||||
| ["set loglevel <LEVEL>", "sets logging level to <LEVEL>. Levels: CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG"],  | ||||
| ["get loglevel", "gets the logging level"],  | ||||
|  |  | |||
|  | @ -194,6 +194,9 @@ class Actions(JailThread, Mapping): | |||
| 		ValueError | ||||
| 			If `ip` is not banned | ||||
| 		""" | ||||
| 		# Always delete ip from database (also if currently not banned) | ||||
| 		if self._jail.database is not None: | ||||
| 			self._jail.database.delBan(self._jail, ip) | ||||
| 		# Find the ticket with the IP. | ||||
| 		ticket = self.__banManager.getTicketByIP(ip) | ||||
| 		if ticket is not None: | ||||
|  |  | |||
|  | @ -400,15 +400,34 @@ class Fail2BanDb(object): | |||
| 		#TODO: Implement data parts once arbitrary match keys completed | ||||
| 		cur.execute( | ||||
| 			"INSERT INTO bans(jail, ip, timeofban, bantime, bancount, data) VALUES(?, ?, ?, ?, ?, ?)", | ||||
| 			(jail.name, ticket.getIP(), ticket.getTime(), ticket.getBanTime(jail.actions.getBanTime()), ticket.getBanCount(), | ||||
| 			(jail.name, ticket.getIP(), int(round(ticket.getTime())), ticket.getBanTime(jail.actions.getBanTime()), ticket.getBanCount(), | ||||
| 				{"matches": ticket.getMatches(), | ||||
| 					"failures": ticket.getAttempt()})) | ||||
| 		cur.execute( | ||||
| 			"INSERT OR REPLACE INTO bips(ip, jail, timeofban, bantime, bancount, data) VALUES(?, ?, ?, ?, ?, ?)", | ||||
| 			(ticket.getIP(), jail.name, ticket.getTime(), ticket.getBanTime(jail.actions.getBanTime()), ticket.getBanCount(), | ||||
| 			(ticket.getIP(), jail.name, int(round(ticket.getTime())), ticket.getBanTime(jail.actions.getBanTime()), ticket.getBanCount(), | ||||
| 				{"matches": ticket.getMatches(), | ||||
| 					"failures": ticket.getAttempt()})) | ||||
| 
 | ||||
| 	@commitandrollback | ||||
| 	def delBan(self, cur, jail, ip): | ||||
| 		"""Delete a ban from the database. | ||||
| 
 | ||||
| 		Parameters | ||||
| 		---------- | ||||
| 		jail : Jail | ||||
| 			Jail in which the ban has occurred. | ||||
| 		ticket : BanTicket | ||||
| 			Ticket of the ban to be removed. | ||||
| 		""" | ||||
| 		queryArgs = (jail.name, ip); | ||||
| 		cur.execute( | ||||
| 			"DELETE FROM bips WHERE jail = ? AND ip = ?",  | ||||
| 			queryArgs) | ||||
| 		cur.execute( | ||||
| 			"DELETE FROM bans WHERE jail = ? AND ip = ?",  | ||||
| 			queryArgs); | ||||
| 
 | ||||
| 	@commitandrollback | ||||
| 	def _getBans(self, cur, jail=None, bantime=None, ip=None): | ||||
| 		query = "SELECT ip, timeofban, data FROM bans WHERE 1" | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ import time | |||
| import json | ||||
| 
 | ||||
| from ..helpers import getLogger | ||||
| from .. import version | ||||
| 
 | ||||
| # Gets the instance of the logger. | ||||
| logSys = getLogger(__name__) | ||||
|  | @ -103,6 +104,8 @@ class Transmitter: | |||
| 			return self.__commandGet(command[1:]) | ||||
| 		elif command[0] == "status": | ||||
| 			return self.status(command[1:]) | ||||
| 		elif command[0] == "version": | ||||
| 			return version.version | ||||
| 		raise Exception("Invalid command") | ||||
| 	 | ||||
| 	def __commandSet(self, command): | ||||
|  |  | |||
|  | @ -173,6 +173,12 @@ class DatabaseTest(unittest.TestCase): | |||
| 		self.assertTrue( | ||||
| 			isinstance(self.db.getBans(jail=self.jail)[0], FailTicket)) | ||||
| 
 | ||||
| 	def testDelBan(self): | ||||
| 		self.testAddBan() | ||||
| 		ticket = self.db.getBans(jail=self.jail)[0] | ||||
| 		self.db.delBan(self.jail, ticket.getIP()) | ||||
| 		self.assertEqual(len(self.db.getBans(jail=self.jail)), 0) | ||||
| 
 | ||||
| 	def testGetBansWithTime(self): | ||||
| 		if Fail2BanDb is None: # pragma: no cover | ||||
| 			return | ||||
|  |  | |||
|  | @ -1,5 +1,9 @@ | |||
| # failJSON: { "time": "2005-04-10T03:47:57", "match": true , "host": "1.2.3.4" } | ||||
| Apr 10 03:47:57 web courieresmtpd: error,relay=::ffff:1.2.3.4,ident=tmf,from=<tmf@example.com>,to=<mailman-subscribe@example.com>: 550 User unknown. | ||||
| # failJSON: { "time": "2005-07-03T23:07:20", "match": true , "host": "1.2.3.4" } | ||||
| Jul  3 23:07:20 szerver courieresmtpd: error,relay=::ffff:1.2.3.4,msg="535 Authentication failed.",cmd: YWRvYmVhZG9iZQ== | ||||
| # failJSON: { "time": "2005-07-04T18:39:39", "match": true , "host": "1.2.3.4" } | ||||
| Jul  4 18:39:39 mail courieresmtpd: error,relay=::ffff:1.2.3.4,from=<picaro@astroboymail.com>,to=<user@update.net>: 550 User <benny> unknown | ||||
| # failJSON: { "time": "2005-07-06T03:42:28", "match": true , "host": "1.2.3.4" } | ||||
| Jul  6 03:42:28 whistler courieresmtpd: error,relay=::ffff:1.2.3.4,from=<>,to=<admin at memcpy>: 550 User unknown. | ||||
| # failJSON: { "time": "2004-11-21T23:16:17", "match": true , "host": "1.2.3.4" } | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| # failJSON: { "time": "2005-01-04T21:51:05", "match": true , "host": "127.0.0.1" } | ||||
| Jan 4 21:51:05 hostname cyrus/imap[5355]: badlogin: localhost.localdomain [127.0.0.1] plaintext cyrus@localdomain SASL(-13): authentication failure: checkpass failed | ||||
| # failJSON: { "time": "2005-01-04T21:51:05", "match": true , "host": "127.0.0.1", "desc": "For secure imaps" } | ||||
| Jan 4 21:51:05 hostname cyrus/imaps[5355]: badlogin: localhost.localdomain [127.0.0.1] plaintext cyrus@localdomain SASL(-13): authentication failure: checkpass failed | ||||
| # failJSON: { "time": "2005-02-20T17:23:32", "match": true , "host": "198.51.100.23" } | ||||
| Feb 20 17:23:32 domain cyrus/pop3[18635]: badlogin: localhost [198.51.100.23] plaintext administrator SASL(-13): authentication failure: checkpass failed | ||||
| # failJSON: { "time": "2005-02-20T17:23:32", "match": true , "host": "1.2.3.4" } | ||||
|  | @ -10,4 +12,7 @@ Jun 8 18:11:13 lampserver imap[4480]: badlogin: example.com [198.51.100.45] DIGE | |||
| Dec 21 10:01:57 hostname imapd[18454]: badlogin: example.com [198.51.100.57] CRAM-MD5 [SASL(-13): authentication failure: incorrect digest response] | ||||
| # failJSON: { "time": "2004-12-30T16:03:27", "match": true , "host": "1.2.3.4" } | ||||
| Dec 30 16:03:27 somehost imapd[2517]: badlogin: local-somehost[1.2.3.4] OTP [SASL(-13): authentication failure: External SSF not good enough] | ||||
| 
 | ||||
| # failJSON: { "time": "2005-07-17T22:55:56", "match": true , "host": "1.2.3.4" } | ||||
| Jul 17 22:55:56 derry cyrus/imaps[7568]: badlogin: serafinat.xxxxxx [1.2.3.4] plain [SASL(-13): user not found: user: pressy@derry property: cmusaslsecretPLAIN not found in sasldb] | ||||
| # failJSON: { "time": "2005-07-18T16:46:42", "match": true , "host": "1.2.3.4" } | ||||
| Jul 18 16:46:42 derry cyrus/imaps[27449]: badlogin: serafinat.xxxxxx [1.2.3.4] PLAIN [SASL(-13): user not found: Password verification failed] | ||||
|  |  | |||
|  | @ -0,0 +1,14 @@ | |||
| # failJSON: { "time": "2014-07-02T00:17:45", "match": true , "host": "3.2.1.4" } | ||||
| 2014:07:02-00:17:45: '3.2.1.4' 2 failed login attempts. Account 'test' | ||||
| 
 | ||||
| # failJSON: { "time": "2014-07-02T13:07:40", "match": true , "host": "40.40.123.231" } | ||||
| 2014:07:02-13:07:40: '40.40.123.231' 13 failed login attempts. Account 'admin' | ||||
| 
 | ||||
| # failJSON: { "time": "2014-07-02T13:07:50", "match": true , "host": "40.40.123.231" } | ||||
| 2014:07:02-13:07:50: '40.40.123.231' 5 failed login attempt. Invalid account 'user%2Ename' | ||||
| 
 | ||||
| # failJSON: { "time": "2014-07-02T13:28:39", "match": false , "host": "12.12.123.231" } | ||||
| 2014:07:02-13:28:39: '12.12.123.231' successful login to 'nobody' after 1 attempts | ||||
| 
 | ||||
| # failJSON: { "time": "2014-07-02T13:29:38", "match": true , "host": "1.2.3.4" } | ||||
| 2014:07:02-13:29:38: '1.2.3.4' 2 failed login attempts. Account 'user' via 'admin' | ||||
|  | @ -24,6 +24,7 @@ __license__ = "GPL" | |||
| 
 | ||||
| from __builtin__ import open as fopen | ||||
| import unittest | ||||
| import getpass | ||||
| import os | ||||
| import sys | ||||
| import time | ||||
|  | @ -349,10 +350,20 @@ class LogFileMonitor(LogCaptureTestCase): | |||
| 		# shorter wait time for not modified status | ||||
| 		return not self.isModified(0.4) | ||||
| 
 | ||||
| 	def testNoLogFile(self): | ||||
| 	def testUnaccessibleLogFile(self): | ||||
| 		os.chmod(self.name, 0) | ||||
| 		self.filter.getFailures(self.name) | ||||
| 		self.assertTrue(self._is_logged('Unable to open %s' % self.name)) | ||||
| 		failure_was_logged = self._is_logged('Unable to open %s' % self.name) | ||||
| 		is_root = getpass.getuser() == 'root' | ||||
| 		# If ran as root, those restrictive permissions would not | ||||
| 		# forbid log to be read. | ||||
| 		self.assertTrue(failure_was_logged != is_root) | ||||
| 
 | ||||
| 	def testNoLogFile(self): | ||||
| 		_killfile(self.file, self.name) | ||||
| 		self.filter.getFailures(self.name) | ||||
| 		failure_was_logged = self._is_logged('Unable to open %s' % self.name) | ||||
| 		self.assertTrue(failure_was_logged) | ||||
| 
 | ||||
| 	def testRemovingFailRegex(self): | ||||
| 		self.filter.delFailRegex(0) | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ from ..server.jail import Jail | |||
| from ..server.jailthread import JailThread | ||||
| from .utils import LogCaptureTestCase | ||||
| from ..helpers import getLogger | ||||
| from .. import version | ||||
| 
 | ||||
| try: | ||||
| 	from ..server import filtersystemd | ||||
|  | @ -148,6 +149,9 @@ class Transmitter(TransmitterBase): | |||
| 	def testPing(self): | ||||
| 		self.assertEqual(self.transm.proceed(["ping"]), (0, "pong")) | ||||
| 
 | ||||
| 	def testVersion(self): | ||||
| 		self.assertEqual(self.transm.proceed(["version"]), (0, version.version)) | ||||
| 
 | ||||
| 	def testSleep(self): | ||||
| 		t0 = time.time() | ||||
| 		self.assertEqual(self.transm.proceed(["sleep", "1"]), (0, None)) | ||||
|  |  | |||
|  | @ -71,6 +71,9 @@ tests if the server is alive | |||
| .TP | ||||
| \fBhelp\fR | ||||
| return this output | ||||
| .TP | ||||
| \fBversion\fR | ||||
| return the server version | ||||
| .IP | ||||
| LOGGING | ||||
| .TP | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 sebres
						sebres