mirror of https://github.com/fail2ban/fail2ban
Merge branch 'master' into debian-release
* master: (27 commits) ENH: server.py -- addLogPath with tail=True ENH: set/getFile for ticket.py -- found in source distribution of 0.8.4 NF: adding unittests for previous commit ENH: removed expansion for few Date and Revision SVN keywords ENH: sshd.conf -- allow user names to have spaces and trailing spaces in the line Removed duplicate entry for DataCha0s/2\.0 in badbots (closes: #519557) BF: return declaration of TABLE back (thanks to michaelberg79) Update server/datetemplate.py format output of matches data. ENH: minor unittest to see if tickets carry correct 'matches' ENH: introduced usa of Ticket.__matches throughout ENH: added 'matches' to the Ticket(s) and deprecated "custom" constructors for derived *Tickets ENH: modelines for emacs and vim to assure consistent indentation scheme (tabs) ENH: failmanager -- additional debug message about # of known failures ENH: rudimentary __str__ for the ticket ENH: more human-accessible printout of the dates if any comparison fails ENH: few debug messages and use MyTime.localtime instead of straight time.time ENH: Added localtime() to MyTime BF: set TZ to CEST while unittesting so dates matching would work ENH: added a .pylintrc to help with consistent appearance and catch obvious problems ... Conflicts: MANIFEST -- wasn't present before due to base on source distribution server/ticket.py -- strange conflict -- should be benignpull/23/head
commit
cd38985e61
|
@ -0,0 +1,37 @@
|
||||||
|
# Custom pylint configuration for the Fail2Ban project
|
||||||
|
#
|
||||||
|
# Set your PYLINTRC environment variable to point to this file
|
||||||
|
# e.g.
|
||||||
|
# export PYLINTRC=$PWD/.pylintrc
|
||||||
|
|
||||||
|
[FORMAT]
|
||||||
|
indent-string='\t'
|
||||||
|
|
||||||
|
[BASIC]
|
||||||
|
# Fail2Ban uses non-conventional to Python world camel-casing
|
||||||
|
# These regexps were originally borrowed from 0.4.x series of
|
||||||
|
# PyMVPA which had similar conventions.
|
||||||
|
|
||||||
|
# Regular expression which should only match correct module names
|
||||||
|
module-rgx=(([a-z][a-z0-9_]*)|([A-Z][a-zA-Z0-9_]+))$
|
||||||
|
|
||||||
|
attr-rgx=[a-z_][a-zA-Z0-9_]{2,30}
|
||||||
|
|
||||||
|
# Regular expression which should only match correct class names
|
||||||
|
class-rgx=[A-Z_]+[a-zA-Z0-9]+$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct function names
|
||||||
|
function-rgx=[a-z_]+[a-z_][a-zA-Z0-9]*$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct method names
|
||||||
|
method-rgx=([a-z_]|__)[a-zA-Z0-9]*(__)?$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct argument names
|
||||||
|
argument-rgx=[a-z][a-zA-Z0-9]*_*[a-zA-Z0-9]*_*[a-zA-Z0-9]*_?$
|
||||||
|
|
||||||
|
# Regular expression which should only match correct variable names
|
||||||
|
variable-rgx=([a-z_]+[a-zA-Z0-9]*_*[a-zA-Z0-9]*_*[a-zA-Z0-9]*_?||(__.*__))$||[A-Z]
|
||||||
|
|
||||||
|
# Regular expression which should only match correct module level names
|
||||||
|
# Default: (([A-Z_][A-Z1-9_]*)|(__.*__))$
|
||||||
|
const-rgx=([a-z_]+[a-zA-Z0-9]*_*[a-zA-Z0-9]*_*[a-zA-Z0-9]*_?|__.*__)$||[A-Z]
|
|
@ -0,0 +1,127 @@
|
||||||
|
README
|
||||||
|
ChangeLog
|
||||||
|
TODO
|
||||||
|
THANKS
|
||||||
|
COPYING
|
||||||
|
fail2ban-client
|
||||||
|
fail2ban-server
|
||||||
|
fail2ban-testcases
|
||||||
|
fail2ban-regex
|
||||||
|
client/configreader.py
|
||||||
|
client/configparserinc.py
|
||||||
|
client/jailreader.py
|
||||||
|
client/fail2banreader.py
|
||||||
|
client/jailsreader.py
|
||||||
|
client/beautifier.py
|
||||||
|
client/filterreader.py
|
||||||
|
client/actionreader.py
|
||||||
|
client/__init__.py
|
||||||
|
client/configurator.py
|
||||||
|
client/csocket.py
|
||||||
|
server/asyncserver.py
|
||||||
|
server/filter.py
|
||||||
|
server/filtergamin.py
|
||||||
|
server/filterpoll.py
|
||||||
|
server/iso8601.py
|
||||||
|
server/server.py
|
||||||
|
server/actions.py
|
||||||
|
server/faildata.py
|
||||||
|
server/failmanager.py
|
||||||
|
server/datedetector.py
|
||||||
|
server/jailthread.py
|
||||||
|
server/transmitter.py
|
||||||
|
server/action.py
|
||||||
|
server/ticket.py
|
||||||
|
server/jail.py
|
||||||
|
server/jails.py
|
||||||
|
server/__init__.py
|
||||||
|
server/banmanager.py
|
||||||
|
server/datetemplate.py
|
||||||
|
server/mytime.py
|
||||||
|
server/failregex.py
|
||||||
|
testcases/banmanagertestcase.py
|
||||||
|
testcases/failmanagertestcase.py
|
||||||
|
testcases/clientreadertestcase.py
|
||||||
|
testcases/filtertestcase.py
|
||||||
|
testcases/__init__.py
|
||||||
|
testcases/datedetectortestcase.py
|
||||||
|
testcases/actiontestcase.py
|
||||||
|
testcases/servertestcase.py
|
||||||
|
testcases/files/testcase01.log
|
||||||
|
testcases/files/testcase02.log
|
||||||
|
testcases/files/testcase03.log
|
||||||
|
testcases/files/testcase04.log
|
||||||
|
setup.py
|
||||||
|
setup.cfg
|
||||||
|
common/__init__.py
|
||||||
|
common/helpers.py
|
||||||
|
common/version.py
|
||||||
|
common/protocol.py
|
||||||
|
config/jail.conf
|
||||||
|
config/filter.d/common.conf
|
||||||
|
config/filter.d/apache-auth.conf
|
||||||
|
config/filter.d/apache-badbots.conf
|
||||||
|
config/filter.d/apache-nohome.conf
|
||||||
|
config/filter.d/apache-noscript.conf
|
||||||
|
config/filter.d/apache-overflows.conf
|
||||||
|
config/filter.d/courierlogin.conf
|
||||||
|
config/filter.d/couriersmtp.conf
|
||||||
|
config/filter.d/cyrus-imap.conf
|
||||||
|
config/filter.d/exim.conf
|
||||||
|
config/filter.d/gssftpd.conf
|
||||||
|
config/filter.d/lighttpd-fastcgi.conf
|
||||||
|
config/filter.d/named-refused.conf
|
||||||
|
config/filter.d/postfix.conf
|
||||||
|
config/filter.d/proftpd.conf
|
||||||
|
config/filter.d/pure-ftpd.conf
|
||||||
|
config/filter.d/qmail.conf
|
||||||
|
config/filter.d/pam-generic.conf
|
||||||
|
config/filter.d/php-url-fopen.conf
|
||||||
|
config/filter.d/sasl.conf
|
||||||
|
config/filter.d/sieve.conf
|
||||||
|
config/filter.d/sshd.conf
|
||||||
|
config/filter.d/sshd-ddos.conf
|
||||||
|
config/filter.d/vsftpd.conf
|
||||||
|
config/filter.d/webmin-auth.conf
|
||||||
|
config/filter.d/wuftpd.conf
|
||||||
|
config/filter.d/xinetd-fail.conf
|
||||||
|
config/action.d/complain.conf
|
||||||
|
config/action.d/dshield.conf
|
||||||
|
config/action.d/hostsdeny.conf
|
||||||
|
config/action.d/ipfw.conf
|
||||||
|
config/action.d/ipfilter.conf
|
||||||
|
config/action.d/iptables.conf
|
||||||
|
config/action.d/iptables-allports.conf
|
||||||
|
config/action.d/iptables-multiport.conf
|
||||||
|
config/action.d/iptables-multiport-log.conf
|
||||||
|
config/action.d/iptables-new.conf
|
||||||
|
config/action.d/mail.conf
|
||||||
|
config/action.d/mail-buffered.conf
|
||||||
|
config/action.d/mail-whois.conf
|
||||||
|
config/action.d/mail-whois-lines.conf
|
||||||
|
config/action.d/mynetwatchman.conf
|
||||||
|
config/action.d/sendmail.conf
|
||||||
|
config/action.d/sendmail-buffered.conf
|
||||||
|
config/action.d/sendmail-whois.conf
|
||||||
|
config/action.d/sendmail-whois-lines.conf
|
||||||
|
config/action.d/shorewall.conf
|
||||||
|
config/fail2ban.conf
|
||||||
|
man/fail2ban-client.1
|
||||||
|
man/fail2ban-client.h2m
|
||||||
|
man/fail2ban-server.1
|
||||||
|
man/fail2ban-server.h2m
|
||||||
|
man/fail2ban-regex.1
|
||||||
|
man/fail2ban-regex.h2m
|
||||||
|
man/generate-man
|
||||||
|
files/gentoo-initd
|
||||||
|
files/gentoo-confd
|
||||||
|
files/redhat-initd
|
||||||
|
files/macosx-initd
|
||||||
|
files/solaris-fail2ban.xml
|
||||||
|
files/solaris-svc-fail2ban
|
||||||
|
files/suse-initd
|
||||||
|
files/cacti/fail2ban_stats.sh
|
||||||
|
files/cacti/cacti_host_template_fail2ban.xml
|
||||||
|
files/cacti/README
|
||||||
|
files/nagios/check_fail2ban
|
||||||
|
files/nagios/f2ban.txt
|
14
README
14
README
|
@ -26,8 +26,8 @@ Optional:
|
||||||
|
|
||||||
To install, just do:
|
To install, just do:
|
||||||
|
|
||||||
> tar xvfj fail2ban-0.8.4.tar.bz2
|
> tar xvfj fail2ban-0.8.5.tar.bz2
|
||||||
> cd fail2ban-0.8.4
|
> cd fail2ban-0.8.5
|
||||||
> python setup.py install
|
> python setup.py install
|
||||||
|
|
||||||
This will install Fail2Ban into /usr/share/fail2ban. The executable scripts are
|
This will install Fail2Ban into /usr/share/fail2ban. The executable scripts are
|
||||||
|
@ -64,15 +64,7 @@ Cyril Jaquier: <cyril.jaquier@fail2ban.org>
|
||||||
Thanks:
|
Thanks:
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Kévin Drapel, Marvin Rouge, Sireyessire, Robert Edeker, Tom Pike, Iain Lea,
|
See THANKS file.
|
||||||
Andrey G. Grozin, Yaroslav Halchenko, Jonathan Kamens, Stephen Gildea, Markus
|
|
||||||
Hoffmann, Mark Edgington, Patrick Börjesson, kojiro, zugeschmiert, Tyler, Nick
|
|
||||||
Munger, Christoph Haas, Justin Shore, Joël Bertrand, René Berber, mEDI, Axel
|
|
||||||
Thimm, Eric Gerbier, Christian Rauch, Michael C. Haller, Jonathan Underwood,
|
|
||||||
Hanno 'Rince' Wagner, Daniel B. Cid, David Nutter, Raphaël Marichez, Guillaume
|
|
||||||
Delvit, Vaclav Misek, Adrien Clerc, Michael Hanselmann, Vincent Deffontaines,
|
|
||||||
Bill Heaton, Russell Odom, Christos Psonis, Arturo 'Buanzo' Busleiman and many
|
|
||||||
others.
|
|
||||||
|
|
||||||
License:
|
License:
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
Fail2Ban is an open source project with many contributions from its
|
||||||
|
users community. Below is an alphabetically sorted partial list of the
|
||||||
|
contributors to the project. If you have been left off, please let us
|
||||||
|
know (preferably send a pull request on github with the "fix") and you
|
||||||
|
will be added
|
||||||
|
|
||||||
|
Adrien Clerc
|
||||||
|
Andrey G. Grozin
|
||||||
|
Arturo 'Buanzo' Busleiman
|
||||||
|
Axel Thimm
|
||||||
|
Bill Heaton
|
||||||
|
Christian Rauch
|
||||||
|
Christoph Haas
|
||||||
|
Christos Psonis
|
||||||
|
Daniel B. Cid
|
||||||
|
David Nutter
|
||||||
|
Eric Gerbier
|
||||||
|
Guillaume Delvit
|
||||||
|
Hanno 'Rince' Wagner
|
||||||
|
Iain Lea
|
||||||
|
Jonathan Kamens
|
||||||
|
Jonathan Underwood
|
||||||
|
Joël Bertrand
|
||||||
|
Justin Shore
|
||||||
|
Kévin Drapel
|
||||||
|
kojiro
|
||||||
|
Mark Edgington
|
||||||
|
Markus Hoffmann
|
||||||
|
Marvin Rouge
|
||||||
|
mEDI
|
||||||
|
Michael C. Haller
|
||||||
|
Michael Hanselmann
|
||||||
|
NickMunger
|
||||||
|
Patrick Börjesson
|
||||||
|
Raphaël Marichez
|
||||||
|
René Berber
|
||||||
|
Robert Edeker
|
||||||
|
Russell Odom
|
||||||
|
Sireyessire
|
||||||
|
Stephen Gildea
|
||||||
|
Tom Pike
|
||||||
|
Tyler
|
||||||
|
Vaclav Misek
|
||||||
|
Vincent Deffontaines
|
||||||
|
Yaroslav Halchenko
|
||||||
|
Yehuda Katz
|
||||||
|
zugeschmiert
|
2
TODO
2
TODO
|
@ -4,7 +4,7 @@
|
||||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
ToDo $Revision$
|
ToDo
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
Legend:
|
Legend:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -87,4 +90,4 @@ class ActionReader(ConfigReader):
|
||||||
stream.append(head + ["setcinfo", self.__file, p, self.__cInfo[p]])
|
stream.append(head + ["setcinfo", self.__file, p, self.__cInfo[p]])
|
||||||
|
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -75,4 +78,4 @@ class Configurator:
|
||||||
for opt in self.__streams["jails"]:
|
for opt in self.__streams["jails"]:
|
||||||
cmds.append(opt)
|
cmds.append(opt)
|
||||||
return cmds
|
return cmds
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -55,4 +58,4 @@ class Fail2banReader(ConfigReader):
|
||||||
elif opt == "logtarget":
|
elif opt == "logtarget":
|
||||||
stream.append(["set", "logtarget", self.__opts[opt]])
|
stream.append(["set", "logtarget", self.__opts[opt]])
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -71,4 +74,4 @@ class FilterReader(ConfigReader):
|
||||||
if regex != '':
|
if regex != '':
|
||||||
stream.append(["set", self.__name, "addignoreregex", regex])
|
stream.append(["set", self.__name, "addignoreregex", regex])
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -84,4 +87,4 @@ class JailsReader(ConfigReader):
|
||||||
stream.append(["start", jail.getName()])
|
stream.append(["start", jail.getName()])
|
||||||
|
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -27,12 +30,12 @@ __license__ = "GPL"
|
||||||
|
|
||||||
|
|
||||||
def formatExceptionInfo():
|
def formatExceptionInfo():
|
||||||
""" Author: Arturo 'Buanzo' Busleiman """
|
""" Author: Arturo 'Buanzo' Busleiman """
|
||||||
import sys
|
import sys
|
||||||
cla, exc = sys.exc_info()[:2]
|
cla, exc = sys.exc_info()[:2]
|
||||||
excName = cla.__name__
|
excName = cla.__name__
|
||||||
try:
|
try:
|
||||||
excArgs = exc.__dict__["args"]
|
excArgs = exc.__dict__["args"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
excArgs = str(exc)
|
excArgs = str(exc)
|
||||||
return (excName, excArgs)
|
return (excName, excArgs)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -32,10 +32,16 @@ __daemon_re = [\[\(]?%(_daemon)s(?:\(\S+\))?[\]\)]?:?
|
||||||
# EXAMPLES: sshd[31607], pop(pam_unix)[4920]
|
# EXAMPLES: sshd[31607], pop(pam_unix)[4920]
|
||||||
__daemon_combs_re = (?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:)
|
__daemon_combs_re = (?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:)
|
||||||
|
|
||||||
|
# Some messages have a kernel prefix with a timestamp
|
||||||
|
# EXAMPLES: kernel: [769570.846956]
|
||||||
|
__kernel_prefix = kernel: \[\d+\.\d+\]
|
||||||
|
|
||||||
|
__hostname = \S+
|
||||||
|
|
||||||
#
|
#
|
||||||
# Common line prefixes (beginnings) which could be used in filters
|
# Common line prefixes (beginnings) which could be used in filters
|
||||||
#
|
#
|
||||||
# [hostname] [vserver tag] daemon_id spaces
|
# [hostname] [vserver tag] daemon_id spaces
|
||||||
# this can be optional (for instance if we match named native log files)
|
# this can be optional (for instance if we match named native log files)
|
||||||
__prefix_line = \s*(?:\S+ )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s*
|
__prefix_line = \s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s*
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
||||||
# Values: TEXT
|
# Values: TEXT
|
||||||
#
|
#
|
||||||
failregex = (?i): warning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?$
|
failregex = (?i): warning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$
|
||||||
|
|
||||||
# Option: ignoreregex
|
# Option: ignoreregex
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -26,7 +29,7 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
|
|
||||||
import unittest, logging, sys
|
import unittest, logging, sys, time, os
|
||||||
|
|
||||||
from common.version import version
|
from common.version import version
|
||||||
from testcases import banmanagertestcase
|
from testcases import banmanagertestcase
|
||||||
|
@ -40,6 +43,11 @@ from server.mytime import MyTime
|
||||||
|
|
||||||
# Set the time to a fixed, known value
|
# Set the time to a fixed, known value
|
||||||
# Sun Aug 14 12:00:00 CEST 2005
|
# Sun Aug 14 12:00:00 CEST 2005
|
||||||
|
|
||||||
|
# yoh: we need to adjust TZ to match the one used by Cyril so all the timestamps match
|
||||||
|
old_TZ = os.environ.get('TZ', None)
|
||||||
|
os.environ['TZ'] = 'Europe/Zurich'
|
||||||
|
time.tzset()
|
||||||
MyTime.setTime(1124013600)
|
MyTime.setTime(1124013600)
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
|
@ -74,3 +82,10 @@ tests.addTest(unittest.makeSuite(datedetectortestcase.DateDetectorTest))
|
||||||
# Tests runner
|
# Tests runner
|
||||||
testRunner = unittest.TextTestRunner()
|
testRunner = unittest.TextTestRunner()
|
||||||
testRunner.run(tests)
|
testRunner.run(tests)
|
||||||
|
|
||||||
|
# Just for the sake of it reset the TZ
|
||||||
|
# yoh is planing to move all this into setup/teardown methods within tests
|
||||||
|
os.environ.pop('TZ')
|
||||||
|
if old_TZ:
|
||||||
|
os.environ['TZ'] = old_TZ
|
||||||
|
time.tzset()
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -158,6 +161,7 @@ class Actions(JailThread):
|
||||||
aInfo["ip"] = bTicket.getIP()
|
aInfo["ip"] = bTicket.getIP()
|
||||||
aInfo["failures"] = bTicket.getAttempt()
|
aInfo["failures"] = bTicket.getAttempt()
|
||||||
aInfo["time"] = bTicket.getTime()
|
aInfo["time"] = bTicket.getTime()
|
||||||
|
aInfo["matches"] = "".join(bTicket.getMatches())
|
||||||
if self.__banManager.addBanTicket(bTicket):
|
if self.__banManager.addBanTicket(bTicket):
|
||||||
logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
|
logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
|
||||||
for action in self.__actions:
|
for action in self.__actions:
|
||||||
|
@ -198,6 +202,7 @@ class Actions(JailThread):
|
||||||
aInfo["ip"] = ticket.getIP()
|
aInfo["ip"] = ticket.getIP()
|
||||||
aInfo["failures"] = ticket.getAttempt()
|
aInfo["failures"] = ticket.getAttempt()
|
||||||
aInfo["time"] = ticket.getTime()
|
aInfo["time"] = ticket.getTime()
|
||||||
|
aInfo["matches"] = "".join(ticket.getMatches())
|
||||||
logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
|
logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
|
||||||
for action in self.__actions:
|
for action in self.__actions:
|
||||||
action.execActionUnban(aInfo)
|
action.execActionUnban(aInfo)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -130,7 +133,7 @@ class BanManager:
|
||||||
ip = ticket.getIP()
|
ip = ticket.getIP()
|
||||||
#lastTime = ticket.getTime()
|
#lastTime = ticket.getTime()
|
||||||
lastTime = MyTime.time()
|
lastTime = MyTime.time()
|
||||||
banTicket = BanTicket(ip, lastTime)
|
banTicket = BanTicket(ip, lastTime, ticket.getMatches())
|
||||||
banTicket.setAttempt(ticket.getAttempt())
|
banTicket.setAttempt(ticket.getAttempt())
|
||||||
return banTicket
|
return banTicket
|
||||||
createBanTicket = staticmethod(createBanTicket)
|
createBanTicket = staticmethod(createBanTicket)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# emacs: -*- mode: python; coding: utf-8; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -30,6 +32,10 @@ import re, time
|
||||||
from mytime import MyTime
|
from mytime import MyTime
|
||||||
import iso8601
|
import iso8601
|
||||||
|
|
||||||
|
import logging
|
||||||
|
logSys = logging.getLogger("fail2ban.datetemplate")
|
||||||
|
|
||||||
|
|
||||||
class DateTemplate:
|
class DateTemplate:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -76,7 +82,7 @@ class DateEpoch(DateTemplate):
|
||||||
dateMatch = self.matchDate(line)
|
dateMatch = self.matchDate(line)
|
||||||
if dateMatch:
|
if dateMatch:
|
||||||
# extract part of format which represents seconds since epoch
|
# extract part of format which represents seconds since epoch
|
||||||
date = list(time.localtime(float(dateMatch.group())))
|
date = list(MyTime.localtime(float(dateMatch.group())))
|
||||||
return date
|
return date
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,20 +92,20 @@ class DateEpoch(DateTemplate):
|
||||||
# standard.
|
# standard.
|
||||||
|
|
||||||
class DateStrptime(DateTemplate):
|
class DateStrptime(DateTemplate):
|
||||||
|
|
||||||
TABLE = dict()
|
TABLE = dict()
|
||||||
TABLE["Jan"] = []
|
TABLE["Jan"] = ["Sty"]
|
||||||
TABLE["Feb"] = [u"Fév"]
|
TABLE["Feb"] = [u"Fév", "Lut"]
|
||||||
TABLE["Mar"] = [u"Mär"]
|
TABLE["Mar"] = [u"Mär", "Mar"]
|
||||||
TABLE["Apr"] = ["Avr"]
|
TABLE["Apr"] = ["Avr", "Kwi"]
|
||||||
TABLE["May"] = ["Mai"]
|
TABLE["May"] = ["Mai", "Maj"]
|
||||||
TABLE["Jun"] = []
|
TABLE["Jun"] = ["Lip"]
|
||||||
TABLE["Jul"] = []
|
TABLE["Jul"] = ["Sie"]
|
||||||
TABLE["Aug"] = ["Aou"]
|
TABLE["Aug"] = ["Aou", "Wrz"]
|
||||||
TABLE["Sep"] = []
|
TABLE["Sep"] = ["Sie"]
|
||||||
TABLE["Oct"] = ["Okt"]
|
TABLE["Oct"] = [u"Paź"]
|
||||||
TABLE["Nov"] = []
|
TABLE["Nov"] = ["Lis"]
|
||||||
TABLE["Dec"] = [u"Déc", "Dez"]
|
TABLE["Dec"] = [u"Déc", "Dez", "Gru"]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
DateTemplate.__init__(self)
|
DateTemplate.__init__(self)
|
||||||
|
@ -116,6 +122,8 @@ class DateStrptime(DateTemplate):
|
||||||
for t in DateStrptime.TABLE:
|
for t in DateStrptime.TABLE:
|
||||||
for m in DateStrptime.TABLE[t]:
|
for m in DateStrptime.TABLE[t]:
|
||||||
if date.find(m) >= 0:
|
if date.find(m) >= 0:
|
||||||
|
logSys.debug(u"Replacing %r with %r in %r" %
|
||||||
|
(m, t, date))
|
||||||
return date.replace(m, t)
|
return date.replace(m, t)
|
||||||
return date
|
return date
|
||||||
convertLocale = staticmethod(convertLocale)
|
convertLocale = staticmethod(convertLocale)
|
||||||
|
@ -145,6 +153,9 @@ class DateStrptime(DateTemplate):
|
||||||
# If the date is greater than the current time, we suppose
|
# If the date is greater than the current time, we suppose
|
||||||
# that the log is not from this year but from the year before
|
# that the log is not from this year but from the year before
|
||||||
if time.mktime(date) > MyTime.time():
|
if time.mktime(date) > MyTime.time():
|
||||||
|
logSys.debug(
|
||||||
|
u"Correcting deduced year from %d to %d since %f > %f" %
|
||||||
|
(date[0], date[0]-1, time.mktime(date), MyTime.time()))
|
||||||
date[0] -= 1
|
date[0] -= 1
|
||||||
elif date[1] == 1 and date[2] == 1:
|
elif date[1] == 1 and date[2] == 1:
|
||||||
# If it is Jan 1st, it is either really Jan 1st or there
|
# If it is Jan 1st, it is either really Jan 1st or there
|
||||||
|
@ -169,7 +180,7 @@ class DateTai64n(DateTemplate):
|
||||||
value = dateMatch.group()
|
value = dateMatch.group()
|
||||||
seconds_since_epoch = value[2:17]
|
seconds_since_epoch = value[2:17]
|
||||||
# convert seconds from HEX into local time stamp
|
# convert seconds from HEX into local time stamp
|
||||||
date = list(time.localtime(int(seconds_since_epoch, 16)))
|
date = list(MyTime.localtime(int(seconds_since_epoch, 16)))
|
||||||
return date
|
return date
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -35,16 +38,24 @@ class FailData:
|
||||||
self.__retry = 0
|
self.__retry = 0
|
||||||
self.__lastTime = 0
|
self.__lastTime = 0
|
||||||
self.__lastReset = 0
|
self.__lastReset = 0
|
||||||
|
self.__matches = []
|
||||||
|
|
||||||
def setRetry(self, value):
|
def setRetry(self, value):
|
||||||
self.__retry = value
|
self.__retry = value
|
||||||
|
# keep only the last matches or reset entirely
|
||||||
|
self.__matches = self.__matches[-min(len(self.__matches, value)):] \
|
||||||
|
if value else []
|
||||||
|
|
||||||
def getRetry(self):
|
def getRetry(self):
|
||||||
return self.__retry
|
return self.__retry
|
||||||
|
|
||||||
def inc(self):
|
def getMatches(self):
|
||||||
|
return self.__matches
|
||||||
|
|
||||||
|
def inc(self, matches=None):
|
||||||
self.__retry += 1
|
self.__retry += 1
|
||||||
|
self.__matches += matches or []
|
||||||
|
|
||||||
def setLastTime(self, value):
|
def setLastTime(self, value):
|
||||||
if value > self.__lastTime:
|
if value > self.__lastTime:
|
||||||
self.__lastTime = value
|
self.__lastTime = value
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -88,19 +91,22 @@ class FailManager:
|
||||||
self.__lock.acquire()
|
self.__lock.acquire()
|
||||||
ip = ticket.getIP()
|
ip = ticket.getIP()
|
||||||
unixTime = ticket.getTime()
|
unixTime = ticket.getTime()
|
||||||
|
matches = ticket.getMatches()
|
||||||
if self.__failList.has_key(ip):
|
if self.__failList.has_key(ip):
|
||||||
fData = self.__failList[ip]
|
fData = self.__failList[ip]
|
||||||
if fData.getLastReset() < unixTime - self.__maxTime:
|
if fData.getLastReset() < unixTime - self.__maxTime:
|
||||||
fData.setLastReset(unixTime)
|
fData.setLastReset(unixTime)
|
||||||
fData.setRetry(0)
|
fData.setRetry(0)
|
||||||
fData.inc()
|
fData.inc(matches)
|
||||||
fData.setLastTime(unixTime)
|
fData.setLastTime(unixTime)
|
||||||
else:
|
else:
|
||||||
fData = FailData()
|
fData = FailData()
|
||||||
fData.inc()
|
fData.inc(matches)
|
||||||
fData.setLastReset(unixTime)
|
fData.setLastReset(unixTime)
|
||||||
fData.setLastTime(unixTime)
|
fData.setLastTime(unixTime)
|
||||||
self.__failList[ip] = fData
|
self.__failList[ip] = fData
|
||||||
|
logSys.debug("Currently have failures from %d IPs: %s"
|
||||||
|
% (len(self.__failList), self.__failList.keys()))
|
||||||
self.__failTotal += 1
|
self.__failTotal += 1
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
@ -134,7 +140,7 @@ class FailManager:
|
||||||
if data.getRetry() >= self.__maxRetry:
|
if data.getRetry() >= self.__maxRetry:
|
||||||
self.__delFailure(ip)
|
self.__delFailure(ip)
|
||||||
# Create a FailTicket from BanData
|
# Create a FailTicket from BanData
|
||||||
failTicket = FailTicket(ip, data.getLastTime())
|
failTicket = FailTicket(ip, data.getLastTime(), data.getMatches())
|
||||||
failTicket.setAttempt(data.getRetry())
|
failTicket.setAttempt(data.getRetry())
|
||||||
return failTicket
|
return failTicket
|
||||||
raise FailManagerEmpty
|
raise FailManagerEmpty
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -278,7 +281,7 @@ class Filter(JailThread):
|
||||||
logSys.debug("Ignore %s" % ip)
|
logSys.debug("Ignore %s" % ip)
|
||||||
continue
|
continue
|
||||||
logSys.debug("Found %s" % ip)
|
logSys.debug("Found %s" % ip)
|
||||||
self.failManager.addFailure(FailTicket(ip, unixTime))
|
self.failManager.addFailure(FailTicket(ip, unixTime, [line]))
|
||||||
|
|
||||||
##
|
##
|
||||||
# Returns true if the line should be ignored.
|
# Returns true if the line should be ignored.
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 et:
|
||||||
|
|
||||||
# Copyright (c) 2007 Michael Twomey
|
# Copyright (c) 2007 Michael Twomey
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -76,4 +79,10 @@ class MyTime:
|
||||||
else:
|
else:
|
||||||
return time.gmtime(MyTime.myTime)
|
return time.gmtime(MyTime.myTime)
|
||||||
gmtime = staticmethod(gmtime)
|
gmtime = staticmethod(gmtime)
|
||||||
|
|
||||||
|
def localtime(x=None):
|
||||||
|
if MyTime.myTime == None or x is not None:
|
||||||
|
return time.localtime(x)
|
||||||
|
else:
|
||||||
|
return time.localtime(MyTime.myTime)
|
||||||
|
localtime = staticmethod(localtime)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -31,12 +34,25 @@ logSys = logging.getLogger("fail2ban")
|
||||||
|
|
||||||
class Ticket:
|
class Ticket:
|
||||||
|
|
||||||
def __init__(self, ip, time):
|
def __init__(self, ip, time, matches=None):
|
||||||
|
"""Ticket constructor
|
||||||
|
|
||||||
|
@param ip the IP address
|
||||||
|
@param time the ban time
|
||||||
|
@param matches (log) lines caused the ticket
|
||||||
|
"""
|
||||||
|
|
||||||
self.__ip = ip
|
self.__ip = ip
|
||||||
self.__time = time
|
self.__time = time
|
||||||
self.__attempt = 0
|
self.__attempt = 0
|
||||||
self.__file = None
|
self.__file = None
|
||||||
|
self.__matches = matches or []
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "%s: ip=%s time=%s #attempts=%d" % \
|
||||||
|
(self.__class__, self.__ip, self.__time, self.__attempt)
|
||||||
|
|
||||||
|
|
||||||
def setIP(self, value):
|
def setIP(self, value):
|
||||||
self.__ip = value
|
self.__ip = value
|
||||||
|
|
||||||
|
@ -61,11 +77,12 @@ class Ticket:
|
||||||
def getAttempt(self):
|
def getAttempt(self):
|
||||||
return self.__attempt
|
return self.__attempt
|
||||||
|
|
||||||
|
def getMatches(self):
|
||||||
|
return self.__matches
|
||||||
|
|
||||||
|
|
||||||
class FailTicket(Ticket):
|
class FailTicket(Ticket):
|
||||||
|
pass
|
||||||
def __init__(self, ip, time):
|
|
||||||
Ticket.__init__(self, ip, time)
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -74,14 +91,4 @@ class FailTicket(Ticket):
|
||||||
# This class extends the Ticket class. It is mainly used by the BanManager.
|
# This class extends the Ticket class. It is mainly used by the BanManager.
|
||||||
|
|
||||||
class BanTicket(Ticket):
|
class BanTicket(Ticket):
|
||||||
|
pass
|
||||||
##
|
|
||||||
# Constructor.
|
|
||||||
#
|
|
||||||
# Call the Ticket (parent) constructor and initialize default
|
|
||||||
# values.
|
|
||||||
# @param ip the IP address
|
|
||||||
# @param time the ban time
|
|
||||||
|
|
||||||
def __init__(self, ip, time):
|
|
||||||
Ticket.__init__(self, ip, time)
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -261,4 +264,4 @@ class Transmitter:
|
||||||
name = command[0]
|
name = command[0]
|
||||||
return self.__server.statusJail(name)
|
return self.__server.statusJail(name)
|
||||||
raise Exception("Invalid command (no status)")
|
raise Exception("Invalid command (no status)")
|
||||||
|
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -1,4 +1,6 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -22,4 +25,4 @@ __author__ = "Cyril Jaquier"
|
||||||
__version__ = "$Revision$"
|
__version__ = "$Revision$"
|
||||||
__date__ = "$Date$"
|
__date__ = "$Date$"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -44,4 +47,4 @@ class ExecuteAction(unittest.TestCase):
|
||||||
self.__action.setActionCheck("[ -e /tmp/fail2ban.test ]")
|
self.__action.setActionCheck("[ -e /tmp/fail2ban.test ]")
|
||||||
|
|
||||||
self.assertTrue(self.__action.execActionBan(None))
|
self.assertTrue(self.__action.execActionBan(None))
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -53,4 +56,4 @@ class AddFailure(unittest.TestCase):
|
||||||
def _testInListNOK(self):
|
def _testInListNOK(self):
|
||||||
ticket = BanTicket('111.111.1.111', 1167605999.0)
|
ticket = BanTicket('111.111.1.111', 1167605999.0)
|
||||||
self.assertFalse(self.__banManager.inBanList(ticket))
|
self.assertFalse(self.__banManager.inBanList(ticket))
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -40,4 +43,4 @@ class JailReaderTest(unittest.TestCase):
|
||||||
expected = ['mail-whois', {'name': 'SSH'}]
|
expected = ['mail-whois', {'name': 'SSH'}]
|
||||||
result = JailReader.splitAction(action)
|
result = JailReader.splitAction(action)
|
||||||
self.assertEquals(expected, result)
|
self.assertEquals(expected, result)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -64,4 +67,4 @@ class DateDetectorTest(unittest.TestCase):
|
||||||
#
|
#
|
||||||
# self.assertEqual(self.__datedetector.getTime(log), date)
|
# self.assertEqual(self.__datedetector.getTime(log), date)
|
||||||
# self.assertEqual(self.__datedetector.getUnixTime(log), dateUnix)
|
# self.assertEqual(self.__datedetector.getUnixTime(log), dateUnix)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -25,6 +28,8 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
import time
|
||||||
|
|
||||||
from server.filterpoll import FilterPoll
|
from server.filterpoll import FilterPoll
|
||||||
from server.filter import FileFilter, DNSUtils
|
from server.filter import FileFilter, DNSUtils
|
||||||
from server.failmanager import FailManager
|
from server.failmanager import FailManager
|
||||||
|
@ -94,26 +99,44 @@ class GetFailures(unittest.TestCase):
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""Call after every test case."""
|
"""Call after every test case."""
|
||||||
|
|
||||||
|
def _assertEqualEntries(self, found, output):
|
||||||
|
"""Little helper to unify comparisons with the target entries
|
||||||
|
|
||||||
|
and report helpful failure reports instead of millions of seconds ;)
|
||||||
|
"""
|
||||||
|
self.assertEqual(found[:2], output[:2])
|
||||||
|
found_time, output_time = \
|
||||||
|
time.localtime(found[2]),\
|
||||||
|
time.localtime(output[2])
|
||||||
|
self.assertEqual(found_time, output_time)
|
||||||
|
if len(found) > 3: # match matches
|
||||||
|
self.assertEqual(found[3], output[3])
|
||||||
|
|
||||||
|
|
||||||
def testGetFailures01(self):
|
def testGetFailures01(self):
|
||||||
output = ('193.168.0.128', 3, 1124013599.0)
|
output = ('193.168.0.128', 3, 1124013599.0,
|
||||||
|
['Aug 14 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 193.168.0.128\n']*3)
|
||||||
|
|
||||||
self.__filter.addLogPath(GetFailures.FILENAME_01)
|
self.__filter.addLogPath(GetFailures.FILENAME_01)
|
||||||
self.__filter.addFailRegex("(?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) <HOST>")
|
self.__filter.addFailRegex("(?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) <HOST>")
|
||||||
|
|
||||||
self.__filter.getFailures(GetFailures.FILENAME_01)
|
self.__filter.getFailures(GetFailures.FILENAME_01)
|
||||||
|
|
||||||
ticket = self.__filter.failManager.toBan()
|
ticket = self.__filter.failManager.toBan()
|
||||||
|
|
||||||
attempts = ticket.getAttempt()
|
attempts = ticket.getAttempt()
|
||||||
date = ticket.getTime()
|
date = ticket.getTime()
|
||||||
ip = ticket.getIP()
|
ip = ticket.getIP()
|
||||||
found = (ip, attempts, date)
|
matches = ticket.getMatches()
|
||||||
|
found = (ip, attempts, date, matches)
|
||||||
self.assertEqual(found, output)
|
|
||||||
|
self._assertEqualEntries(found, output)
|
||||||
|
|
||||||
def testGetFailures02(self):
|
def testGetFailures02(self):
|
||||||
output = ('141.3.81.106', 4, 1124013539.0)
|
output = ('141.3.81.106', 4, 1124013539.0,
|
||||||
|
['Aug 14 11:%d:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:141.3.81.106 port 51332 ssh2\n'
|
||||||
|
% m for m in 53, 54, 57, 58])
|
||||||
|
|
||||||
self.__filter.addLogPath(GetFailures.FILENAME_02)
|
self.__filter.addLogPath(GetFailures.FILENAME_02)
|
||||||
self.__filter.addFailRegex("Failed .* from <HOST>")
|
self.__filter.addFailRegex("Failed .* from <HOST>")
|
||||||
|
@ -125,9 +148,10 @@ class GetFailures(unittest.TestCase):
|
||||||
attempts = ticket.getAttempt()
|
attempts = ticket.getAttempt()
|
||||||
date = ticket.getTime()
|
date = ticket.getTime()
|
||||||
ip = ticket.getIP()
|
ip = ticket.getIP()
|
||||||
found = (ip, attempts, date)
|
matches = ticket.getMatches()
|
||||||
|
found = (ip, attempts, date, matches)
|
||||||
|
|
||||||
self.assertEqual(found, output)
|
self._assertEqualEntries(found, output)
|
||||||
|
|
||||||
def testGetFailures03(self):
|
def testGetFailures03(self):
|
||||||
output = ('203.162.223.135', 6, 1124013544.0)
|
output = ('203.162.223.135', 6, 1124013544.0)
|
||||||
|
@ -144,7 +168,7 @@ class GetFailures(unittest.TestCase):
|
||||||
ip = ticket.getIP()
|
ip = ticket.getIP()
|
||||||
found = (ip, attempts, date)
|
found = (ip, attempts, date)
|
||||||
|
|
||||||
self.assertEqual(found, output)
|
self._assertEqualEntries(found, output)
|
||||||
|
|
||||||
def testGetFailures04(self):
|
def testGetFailures04(self):
|
||||||
output = [('212.41.96.186', 4, 1124013600.0),
|
output = [('212.41.96.186', 4, 1124013600.0),
|
||||||
|
@ -182,7 +206,7 @@ class GetFailures(unittest.TestCase):
|
||||||
ip = ticket.getIP()
|
ip = ticket.getIP()
|
||||||
found = (ip, attempts, date)
|
found = (ip, attempts, date)
|
||||||
|
|
||||||
self.assertEqual(found, output)
|
self._assertEqualEntries(found, output)
|
||||||
|
|
||||||
def testGetFailuresIgnoreRegex(self):
|
def testGetFailuresIgnoreRegex(self):
|
||||||
output = ('141.3.81.106', 8, 1124013541.0)
|
output = ('141.3.81.106', 8, 1124013541.0)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
|
||||||
|
# vi: set ft=python sts=4 ts=4 sw=4 noet :
|
||||||
|
|
||||||
# This file is part of Fail2Ban.
|
# This file is part of Fail2Ban.
|
||||||
#
|
#
|
||||||
# Fail2Ban is free software; you can redistribute it and/or modify
|
# Fail2Ban is free software; you can redistribute it and/or modify
|
||||||
|
@ -124,4 +127,4 @@ class Transmitter(unittest.TestCase):
|
||||||
jail = self.__server.jails[name]
|
jail = self.__server.jails[name]
|
||||||
self.assertEqual(jail.getFilter().failManager.size(), 0)
|
self.assertEqual(jail.getFilter().failManager.size(), 0)
|
||||||
self.assertEqual(jail.getAction().banManager.size(), 2)
|
self.assertEqual(jail.getAction().banManager.size(), 2)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue