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 banned
pull/716/head
sebres 2014-08-15 11:39:55 +02:00
commit 62c755c1d5
28 changed files with 441 additions and 24 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ htmlcov
*.rej
*.bak
__pycache__
.vagrant/

181
3rdparty/logwatch/fail2ban vendored Executable file
View File

@ -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:

View File

@ -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
View File

@ -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

30
Vagrantfile vendored Normal file
View File

@ -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

View File

@ -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 =

View File

@ -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

View File

@ -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 =

View File

@ -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 =

View File

@ -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

View File

@ -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

View File

@ -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$

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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":

View File

@ -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"],

View File

@ -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:

View File

@ -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"

View File

@ -28,6 +28,7 @@ import time
import json
from ..helpers import getLogger
from .. import version
# Gets the instance of the logger.
logSys = getLogger(__name__)
@ -102,7 +103,9 @@ class Transmitter:
elif command[0] == "get":
return self.__commandGet(command[1:])
elif command[0] == "status":
return self.status(command[1:])
return self.status(command[1:])
elif command[0] == "version":
return version.version
raise Exception("Invalid command")
def __commandSet(self, command):

View File

@ -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

View File

@ -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" }

View File

@ -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]

View File

@ -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'

View File

@ -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)

View File

@ -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))

View File

@ -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