mirror of https://github.com/fail2ban/fail2ban
Merge branch '0.9' into py3
Conflicts: .travis.yml MANIFEST bin/fail2ban-regex fail2ban/server/filter.py fail2ban/tests/servertestcase.py setup.pypull/171/head
commit
fa0f8f9e6d
10
.travis.yml
10
.travis.yml
|
@ -7,12 +7,16 @@ python:
|
|||
- "2.7"
|
||||
- "3.2"
|
||||
- "3.3"
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
install:
|
||||
- pip install pyinotify
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.[6-7] ]] || [[ $TRAVIS_PYTHON_VERSION == 3.3 ]]; then pip install -q coveralls; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then sudo apt-get install -qq python-gamin; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then pip install -q coveralls; fi
|
||||
before_script:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then ./fail2ban-2to3; fi
|
||||
script:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.[6-7] ]] || [[ $TRAVIS_PYTHON_VERSION == 3.3 ]]; then coverage run --rcfile=.travis_coveragerc fail2ban-testcases; else python ./fail2ban-testcases; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then export PYTHONPATH="$PYTHONPATH:/usr/share/pyshared:/usr/lib/pyshared/python2.7"; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then coverage run --rcfile=.travis_coveragerc bin/fail2ban-testcases; else python bin/fail2ban-testcases; fi
|
||||
after_script:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.[6-7] ]] || [[ $TRAVIS_PYTHON_VERSION == 3.3 ]]; then coveralls; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then coveralls; fi
|
||||
|
|
|
@ -4,4 +4,3 @@ branch = True
|
|||
omit =
|
||||
/usr/*
|
||||
/home/travis/virtualenv/*
|
||||
server/filtergamin.py
|
||||
|
|
14
ChangeLog
14
ChangeLog
|
@ -4,9 +4,21 @@
|
|||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
================================================================================
|
||||
Fail2Ban (version 0.8.8) 2012/12/06
|
||||
Fail2Ban (version 0.9.0a) 20??/??/??
|
||||
================================================================================
|
||||
|
||||
|
||||
ver. 0.9.0 (20??/??/??) - alpha
|
||||
----------
|
||||
|
||||
Will carry all fixes in 0.8.x series and new features and enhancements
|
||||
|
||||
- Fixes:
|
||||
- New features:
|
||||
Steven Hiscocks
|
||||
* Multiline failregex. Close gh-54
|
||||
- Enhancements:
|
||||
|
||||
ver. 0.8.8 (2012/12/06) - stable
|
||||
----------
|
||||
- Fixes:
|
||||
|
|
12
DEVELOP
12
DEVELOP
|
@ -24,9 +24,9 @@ Request feature. You can find more details on the Fail2Ban wiki
|
|||
Testing
|
||||
=======
|
||||
|
||||
Existing tests can be run by executing `fail2ban-testcases`. This has options
|
||||
like --log-level that will probably be useful. `fail2ban-testcases --help` for
|
||||
full options.
|
||||
Existing tests can be run by executing `bin/fail2ban-testcases`. This has
|
||||
options like --log-level that will probably be useful.
|
||||
`bin/fail2ban-testcases --help` forfull options.
|
||||
|
||||
Test cases should cover all usual cases, all exception cases and all inside
|
||||
/ outside boundary conditions.
|
||||
|
@ -39,7 +39,7 @@ Install the package python-coverage to visualise your test coverage. Run the
|
|||
following (note: on Debian-based systems, the script is called
|
||||
`python-coverage`):
|
||||
|
||||
coverage run fail2ban-testcases
|
||||
coverage run bin/fail2ban-testcases
|
||||
coverage html
|
||||
|
||||
Then look at htmlcov/index.html and see how much coverage your test cases
|
||||
|
@ -249,7 +249,7 @@ Takes care about executing start/check/ban/unban/stop commands
|
|||
Releasing
|
||||
=========
|
||||
|
||||
# Ensure the version is correct in ./common/version.py
|
||||
# Ensure the version is correct in ./fail2ban/version.py
|
||||
|
||||
# Add/finalize the corresponding entry in the ChangeLog
|
||||
|
||||
|
@ -271,7 +271,7 @@ Releasing
|
|||
|
||||
# Run the following and update the wiki with output:
|
||||
|
||||
python -c 'import common.protocol; common.protocol.printWiki()'
|
||||
python -c 'import fail2ban.protocol; fail2ban.protocol.printWiki()'
|
||||
|
||||
# Email users and development list of release
|
||||
|
||||
|
|
113
MANIFEST
113
MANIFEST
|
@ -5,65 +5,66 @@ THANKS
|
|||
COPYING
|
||||
DEVELOP
|
||||
doc/run-rootless.txt
|
||||
fail2ban-client
|
||||
fail2ban-server
|
||||
fail2ban-testcases
|
||||
fail2ban-regex
|
||||
fail2ban-2to3
|
||||
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/filterpyinotify.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/files/testcase-usedns.log
|
||||
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/sockettestcase.py
|
||||
testcases/files/testcase01.log
|
||||
testcases/files/testcase02.log
|
||||
testcases/files/testcase03.log
|
||||
testcases/files/testcase04.log
|
||||
bin/fail2ban-client
|
||||
bin/fail2ban-server
|
||||
bin/fail2ban-testcases
|
||||
bin/fail2ban-regex
|
||||
fail2ban/client/configreader.py
|
||||
fail2ban/client/configparserinc.py
|
||||
fail2ban/client/jailreader.py
|
||||
fail2ban/client/fail2banreader.py
|
||||
fail2ban/client/jailsreader.py
|
||||
fail2ban/client/beautifier.py
|
||||
fail2ban/client/filterreader.py
|
||||
fail2ban/client/actionreader.py
|
||||
fail2ban/client/__init__.py
|
||||
fail2ban/client/configurator.py
|
||||
fail2ban/client/csocket.py
|
||||
fail2ban/server/asyncserver.py
|
||||
fail2ban/server/filter.py
|
||||
fail2ban/server/filterpyinotify.py
|
||||
fail2ban/server/filtergamin.py
|
||||
fail2ban/server/filterpoll.py
|
||||
fail2ban/server/iso8601.py
|
||||
fail2ban/server/server.py
|
||||
fail2ban/server/actions.py
|
||||
fail2ban/server/faildata.py
|
||||
fail2ban/server/failmanager.py
|
||||
fail2ban/server/datedetector.py
|
||||
fail2ban/server/jailthread.py
|
||||
fail2ban/server/transmitter.py
|
||||
fail2ban/server/action.py
|
||||
fail2ban/server/ticket.py
|
||||
fail2ban/server/jail.py
|
||||
fail2ban/server/jails.py
|
||||
fail2ban/server/__init__.py
|
||||
fail2ban/server/banmanager.py
|
||||
fail2ban/server/datetemplate.py
|
||||
fail2ban/server/mytime.py
|
||||
fail2ban/server/failregex.py
|
||||
fail2ban/tests/banmanagertestcase.py
|
||||
fail2ban/tests/failmanagertestcase.py
|
||||
fail2ban/tests/clientreadertestcase.py
|
||||
fail2ban/tests/filtertestcase.py
|
||||
fail2ban/tests/__init__.py
|
||||
fail2ban/tests/datedetectortestcase.py
|
||||
fail2ban/tests/actiontestcase.py
|
||||
fail2ban/tests/servertestcase.py
|
||||
fail2ban/tests/sockettestcase.py
|
||||
fail2ban/tests/utils.py
|
||||
fail2ban/tests/files/testcase01.log
|
||||
fail2ban/tests/files/testcase02.log
|
||||
fail2ban/tests/files/testcase03.log
|
||||
fail2ban/tests/files/testcase04.log
|
||||
fail2ban/tests/files/testcase-usedns.log
|
||||
setup.py
|
||||
setup.cfg
|
||||
common/__init__.py
|
||||
common/exceptions.py
|
||||
common/helpers.py
|
||||
common/version.py
|
||||
common/protocol.py
|
||||
fail2ban/__init__.py
|
||||
fail2ban/exceptions.py
|
||||
fail2ban/helpers.py
|
||||
fail2ban/version.py
|
||||
fail2ban/protocol.py
|
||||
config/jail.conf
|
||||
config/filter.d/common.conf
|
||||
config/filter.d/apache-auth.conf
|
||||
|
|
2
README
2
README
|
@ -4,7 +4,7 @@
|
|||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
================================================================================
|
||||
Fail2Ban (version 0.8.8) 2012/07/31
|
||||
Fail2Ban (version 0.9.0a0) 20??/??/??
|
||||
================================================================================
|
||||
|
||||
Fail2Ban scans log files like /var/log/pwdfail and bans IP that makes too many
|
||||
|
|
|
@ -25,19 +25,11 @@ __license__ = "GPL"
|
|||
import sys, string, os, pickle, re, logging, signal
|
||||
import getopt, time, shlex, socket
|
||||
|
||||
# Inserts our own modules path first in the list
|
||||
# fix for bug #343821
|
||||
try:
|
||||
from common.version import version
|
||||
except ImportError, e:
|
||||
sys.path.insert(1, "/usr/share/fail2ban")
|
||||
from common.version import version
|
||||
|
||||
# Now we can import the rest of modules
|
||||
from common.protocol import printFormatted
|
||||
from client.csocket import CSocket
|
||||
from client.configurator import Configurator
|
||||
from client.beautifier import Beautifier
|
||||
from fail2ban.version import version
|
||||
from fail2ban.protocol import printFormatted
|
||||
from fail2ban.client.csocket import CSocket
|
||||
from fail2ban.client.configurator import Configurator
|
||||
from fail2ban.client.beautifier import Beautifier
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client")
|
|
@ -23,19 +23,12 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012 Yaroslav Halchenko"
|
|||
__license__ = "GPL"
|
||||
|
||||
import getopt, sys, time, logging, os, locale
|
||||
|
||||
# Inserts our own modules path first in the list
|
||||
# fix for bug #343821
|
||||
try:
|
||||
from common.version import version
|
||||
except ImportError, e:
|
||||
sys.path.insert(1, "/usr/share/fail2ban")
|
||||
from common.version import version
|
||||
|
||||
from client.configparserinc import SafeConfigParserWithIncludes
|
||||
from ConfigParser import NoOptionError, NoSectionError, MissingSectionHeaderError
|
||||
from server.filter import Filter
|
||||
from server.failregex import RegexException
|
||||
|
||||
from fail2ban.version import version
|
||||
from fail2ban.client.configparserinc import SafeConfigParserWithIncludes
|
||||
from fail2ban.server.filter import Filter
|
||||
from fail2ban.server.failregex import RegexException
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.regex")
|
||||
|
@ -116,6 +109,7 @@ class Fail2banRegex:
|
|||
print " -h, --help display this help message"
|
||||
print " -V, --version print the version"
|
||||
print " -v, --verbose verbose output"
|
||||
print " -l INT, --maxlines=INT set maxlines for multi-line regex default: 1"
|
||||
print
|
||||
print "Log:"
|
||||
print " string a string representing a log line"
|
||||
|
@ -146,6 +140,14 @@ class Fail2banRegex:
|
|||
self.__verbose = True
|
||||
elif opt[0] in ["-e", "--encoding"]:
|
||||
self.encoding = opt[1]
|
||||
elif opt[0] in ["-l", "--maxlines"]:
|
||||
try:
|
||||
self.__filter.setMaxLines(int(opt[1]))
|
||||
except ValueError:
|
||||
print "Invlaid value for maxlines: %s" % (
|
||||
opt[1])
|
||||
fail2banRegex.dispUsage()
|
||||
sys.exit(-1)
|
||||
|
||||
#@staticmethod
|
||||
def logIsFile(value):
|
||||
|
@ -323,8 +325,8 @@ if __name__ == "__main__":
|
|||
fail2banRegex = Fail2banRegex()
|
||||
# Reads the command line options.
|
||||
try:
|
||||
cmdOpts = 'e:hVcv'
|
||||
cmdLongOpts = ['encoding=', 'help', 'version', 'verbose']
|
||||
cmdOpts = 'hVcvl:e:'
|
||||
cmdLongOpts = ['help', 'version', 'verbose', 'maxlines=', 'encoding=']
|
||||
optList, args = getopt.getopt(sys.argv[1:], cmdOpts, cmdLongOpts)
|
||||
except getopt.GetoptError:
|
||||
fail2banRegex.dispUsage()
|
|
@ -24,15 +24,8 @@ __license__ = "GPL"
|
|||
|
||||
import getopt, sys, logging, os
|
||||
|
||||
# Inserts our own modules path first in the list
|
||||
# fix for bug #343821
|
||||
try:
|
||||
from common.version import version
|
||||
except ImportError, e:
|
||||
sys.path.insert(1, "/usr/share/fail2ban")
|
||||
from common.version import version
|
||||
|
||||
from server.server import Server
|
||||
from fail2ban.version import version
|
||||
from fail2ban.server.server import Server
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban")
|
|
@ -27,18 +27,23 @@ __license__ = "GPL"
|
|||
|
||||
import unittest, logging, sys, time, os
|
||||
|
||||
from common.version import version
|
||||
from testcases import banmanagertestcase
|
||||
from testcases import clientreadertestcase
|
||||
from testcases import failmanagertestcase
|
||||
from testcases import filtertestcase
|
||||
from testcases import servertestcase
|
||||
from testcases import datedetectortestcase
|
||||
from testcases import actiontestcase
|
||||
from testcases import sockettestcase
|
||||
# Check if local fail2ban module exists, and use if it exists by
|
||||
# modifying the path. This is such that tests can be used in dev
|
||||
# environment.
|
||||
if os.path.exists("fail2ban/__init__.py"):
|
||||
sys.path.insert(0, ".")
|
||||
from fail2ban.version import version
|
||||
from fail2ban.tests import banmanagertestcase
|
||||
from fail2ban.tests import clientreadertestcase
|
||||
from fail2ban.tests import failmanagertestcase
|
||||
from fail2ban.tests import filtertestcase
|
||||
from fail2ban.tests import servertestcase
|
||||
from fail2ban.tests import datedetectortestcase
|
||||
from fail2ban.tests import actiontestcase
|
||||
from fail2ban.tests import sockettestcase
|
||||
|
||||
from testcases.utils import FormatterWithTraceBack
|
||||
from server.mytime import MyTime
|
||||
from fail2ban.tests.utils import FormatterWithTraceBack
|
||||
from fail2ban.server.mytime import MyTime
|
||||
|
||||
from optparse import OptionParser, Option
|
||||
|
||||
|
@ -147,6 +152,7 @@ tests.addTest(unittest.makeSuite(banmanagertestcase.AddFailure))
|
|||
# ClientReaders
|
||||
tests.addTest(unittest.makeSuite(clientreadertestcase.ConfigReaderTest))
|
||||
tests.addTest(unittest.makeSuite(clientreadertestcase.JailReaderTest))
|
||||
tests.addTest(unittest.makeSuite(clientreadertestcase.FilterReaderTest))
|
||||
tests.addTest(unittest.makeSuite(clientreadertestcase.JailsReaderTest))
|
||||
# CSocket and AsyncServer
|
||||
tests.addTest(unittest.makeSuite(sockettestcase.Socket))
|
||||
|
@ -168,20 +174,20 @@ tests.addTest(unittest.makeSuite(datedetectortestcase.DateDetectorTest))
|
|||
# Extensive use-tests of different available filters backends
|
||||
#
|
||||
|
||||
from server.filterpoll import FilterPoll
|
||||
from fail2ban.server.filterpoll import FilterPoll
|
||||
filters = [FilterPoll] # always available
|
||||
|
||||
# Additional filters available only if external modules are available
|
||||
# yoh: Since I do not know better way for parametric tests
|
||||
# with good old unittest
|
||||
try:
|
||||
from server.filtergamin import FilterGamin
|
||||
from fail2ban.server.filtergamin import FilterGamin
|
||||
filters.append(FilterGamin)
|
||||
except Exception, e: # pragma: no cover
|
||||
print "I: Skipping gamin backend testing. Got exception '%s'" % e
|
||||
|
||||
try:
|
||||
from server.filterpyinotify import FilterPyinotify
|
||||
from fail2ban.server.filterpyinotify import FilterPyinotify
|
||||
filters.append(FilterPyinotify)
|
||||
except Exception, e: # pragma: no cover
|
||||
print "I: Skipping pyinotify backend testing. Got exception '%s'" % e
|
|
@ -0,0 +1,31 @@
|
|||
# Fail2Ban configuration file for unsuccesfull MySQL authentication attempts
|
||||
#
|
||||
# Authors: Artur Penttinen
|
||||
# Yaroslav O. Halchenko
|
||||
#
|
||||
|
||||
[INCLUDES]
|
||||
|
||||
# Read common prefixes. If any customizations available -- read them from
|
||||
# common.local
|
||||
before = common.conf
|
||||
|
||||
|
||||
[Definition]
|
||||
|
||||
#_daemon = mysqld
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile. The
|
||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
||||
# be used for standard IP/hostname matching and is only an alias for
|
||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
||||
# Values: TEXT
|
||||
# 130322 11:26:54 [Warning] Access denied for user 'root'@'127.0.0.1' (using password: YES)
|
||||
failregex = Access denied for user '\w+'@'<HOST>' (to database '[^']*'|\(using password: (YES|NO)\))*\s*$
|
||||
|
||||
# Option: ignoreregex
|
||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
||||
# Values: TEXT
|
||||
#
|
||||
ignoreregex =
|
|
@ -352,6 +352,19 @@ action = iptables-multiport[name=asterisk-udp, port="5060,5061", protocol=udp]
|
|||
logpath = /var/log/asterisk/messages
|
||||
maxretry = 10
|
||||
|
||||
# To log wrong MySQL access attempts add to /etc/my.cnf:
|
||||
# log-error=/var/log/mysqld.log
|
||||
# log-warning = 2
|
||||
[mysqld-iptables]
|
||||
|
||||
enabled = false
|
||||
filter = mysqld-auth
|
||||
action = iptables[name=mysql, port=3306, protocol=tcp]
|
||||
sendmail-whois[name=MySQL, dest=root, sender=fail2ban@example.com]
|
||||
logpath = /var/log/mysqld.log
|
||||
maxretry = 5
|
||||
|
||||
|
||||
# Jail for more extended banning of persistent abusers
|
||||
# !!! WARNING !!!
|
||||
# Make sure that your loglevel specified in fail2ban.conf/.local
|
||||
|
|
|
@ -9,7 +9,7 @@ for python in /usr/{,local/}bin/python2.[0-9]{,.*}{,-dbg}
|
|||
do
|
||||
[ -e "$python" ] || continue
|
||||
echo "Testing using $python"
|
||||
$python ./fail2ban-testcases "$@" || failed+=" $python"
|
||||
$python bin/fail2ban-testcases "$@" || failed+=" $python"
|
||||
done
|
||||
|
||||
if [ ! -z "$failed" ]; then
|
||||
|
|
|
@ -31,7 +31,7 @@ import logging
|
|||
from configreader import ConfigReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class ActionReader(ConfigReader):
|
||||
|
|
@ -23,10 +23,10 @@ __license__ = "GPL"
|
|||
|
||||
import logging
|
||||
|
||||
from common.exceptions import UnknownJailException, DuplicateJailException
|
||||
from fail2ban.exceptions import UnknownJailException, DuplicateJailException
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
##
|
||||
# Beautify the output of the client.
|
|
@ -31,7 +31,7 @@ import logging, os
|
|||
from ConfigParser import SafeConfigParser
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class SafeConfigParserWithIncludes(SafeConfigParser):
|
||||
"""
|
|
@ -32,7 +32,7 @@ from configparserinc import SafeConfigParserWithIncludes
|
|||
from ConfigParser import NoOptionError, NoSectionError
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class ConfigReader(SafeConfigParserWithIncludes):
|
||||
|
|
@ -33,7 +33,7 @@ from fail2banreader import Fail2banReader
|
|||
from jailsreader import JailsReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class Configurator:
|
||||
|
|
@ -31,7 +31,7 @@ import logging
|
|||
from configreader import ConfigReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class Fail2banReader(ConfigReader):
|
||||
|
|
@ -31,7 +31,7 @@ import logging
|
|||
from configreader import ConfigReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class FilterReader(ConfigReader):
|
||||
|
|
@ -34,7 +34,7 @@ from filterreader import FilterReader
|
|||
from actionreader import ActionReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class JailReader(ConfigReader):
|
||||
|
||||
|
@ -65,6 +65,7 @@ class JailReader(ConfigReader):
|
|||
["string", "logencoding", "auto"],
|
||||
["string", "backend", "auto"],
|
||||
["int", "maxretry", 3],
|
||||
["int", "maxlines", 1],
|
||||
["int", "findtime", 600],
|
||||
["int", "bantime", 600],
|
||||
["string", "usedns", "warn"],
|
||||
|
@ -123,6 +124,8 @@ class JailReader(ConfigReader):
|
|||
backend = self.__opts[opt]
|
||||
elif opt == "maxretry":
|
||||
stream.append(["set", self.__name, "maxretry", self.__opts[opt]])
|
||||
elif opt == "maxlines":
|
||||
stream.append(["set", self.__name, "maxlines", self.__opts[opt]])
|
||||
elif opt == "ignoreip":
|
||||
for ip in self.__opts[opt].split():
|
||||
# Do not send a command if the rule is empty.
|
|
@ -32,7 +32,7 @@ from configreader import ConfigReader
|
|||
from jailreader import JailReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class JailsReader(ConfigReader):
|
||||
|
|
@ -68,6 +68,7 @@ protocol = [
|
|||
["set <JAIL> banip <IP>", "manually Ban <IP> for <JAIL>"],
|
||||
["set <JAIL> unbanip <IP>", "manually Unban <IP> in <JAIL>"],
|
||||
["set <JAIL> maxretry <RETRY>", "sets the number of failures <RETRY> before banning the host for <JAIL>"],
|
||||
["set <JAIL> maxlines <LINES>", "sets the number of <LINES> to buffer for regex search for <JAIL>"],
|
||||
["set <JAIL> addaction <ACT>", "adds a new action named <NAME> for <JAIL>"],
|
||||
["set <JAIL> delaction <ACT>", "removes the action <NAME> from <JAIL>"],
|
||||
["set <JAIL> setcinfo <ACT> <KEY> <VALUE>", "sets <VALUE> for <KEY> of the action <NAME> for <JAIL>"],
|
||||
|
@ -87,6 +88,7 @@ protocol = [
|
|||
["get <JAIL> bantime", "gets the time a host is banned for <JAIL>"],
|
||||
["get <JAIL> usedns", "gets the usedns setting for <JAIL>"],
|
||||
["get <JAIL> maxretry", "gets the number of failures allowed for <JAIL>"],
|
||||
["get <JAIL> maxlines", "gets the number of lines to buffer for <JAIL>"],
|
||||
["get <JAIL> addaction", "gets the last action which has been added for <JAIL>"],
|
||||
["get <JAIL> actionstart <ACT>", "gets the start command for the action <ACT> for <JAIL>"],
|
||||
["get <JAIL> actionstop <ACT>", "gets the stop command for the action <ACT> for <JAIL>"],
|
|
@ -32,7 +32,7 @@ import threading
|
|||
#from subprocess import call
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.actions.action")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
# Create a lock for running system commands
|
||||
_cmd_lock = threading.Lock()
|
|
@ -34,7 +34,7 @@ from mytime import MyTime
|
|||
import time, logging
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.actions")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
##
|
||||
# Execute commands.
|
|
@ -28,11 +28,12 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
|||
__license__ = "GPL"
|
||||
|
||||
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
||||
from common import helpers
|
||||
import asyncore, asynchat, socket, os, logging, sys, traceback
|
||||
|
||||
from fail2ban import helpers
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.server")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
##
|
||||
# Request handler class.
|
|
@ -33,7 +33,7 @@ from mytime import MyTime
|
|||
import logging
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.action")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
##
|
||||
# Banning Manager.
|
|
@ -33,7 +33,7 @@ from datetemplate import DateStrptime, DateTai64n, DateEpoch, DateISO8601
|
|||
from threading import Lock
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.filter.datedetector")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class DateDetector:
|
||||
|
||||
|
@ -155,6 +155,12 @@ class DateDetector:
|
|||
template.setRegex("^<\d{2}/\d{2}/\d{2}@\d{2}:\d{2}:\d{2}>")
|
||||
template.setPattern("<%m/%d/%y@%H:%M:%S>")
|
||||
self._appendTemplate(template)
|
||||
# MySQL: 130322 11:46:11
|
||||
template = DateStrptime()
|
||||
template.setName("MonthDayYear Hour:Minute:Second")
|
||||
template.setRegex("^\d{2}\d{2}\d{2} +\d{1,2}:\d{2}:\d{2}")
|
||||
template.setPattern("%y%m%d %H:%M:%S")
|
||||
self._appendTemplate(template)
|
||||
finally:
|
||||
self.__lock.release()
|
||||
|
|
@ -33,7 +33,7 @@ from mytime import MyTime
|
|||
import iso8601
|
||||
|
||||
import logging
|
||||
logSys = logging.getLogger("fail2ban.datetemplate")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DateTemplate:
|
|
@ -30,7 +30,7 @@ __license__ = "GPL"
|
|||
import logging
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class FailData:
|
||||
|
|
@ -33,7 +33,7 @@ from threading import Lock
|
|||
import logging
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.filter")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class FailManager:
|
||||
|
|
@ -48,10 +48,15 @@ class Regex:
|
|||
# Perform shortcuts expansions.
|
||||
# Replace "<HOST>" with default regular expression for host.
|
||||
regex = regex.replace("<HOST>", "(?:::f{4,6}:)?(?P<host>[\w\-.^_]+)")
|
||||
# Replace "<SKIPLINES>" with regular expression for multiple lines.
|
||||
regexSplit = regex.split("<SKIPLINES>")
|
||||
regex = regexSplit[0]
|
||||
for n, regexLine in enumerate(regexSplit[1:]):
|
||||
regex += "\n(?P<skiplines%i>(?:(.*\n)*?))" % n + regexLine
|
||||
if regex.lstrip() == '':
|
||||
raise RegexException("Cannot add empty regex")
|
||||
try:
|
||||
self._regexObj = re.compile(regex)
|
||||
self._regexObj = re.compile(regex, re.MULTILINE)
|
||||
self._regex = regex
|
||||
except sre_constants.error:
|
||||
raise RegexException("Unable to compile regular expression '%s'" %
|
||||
|
@ -76,6 +81,19 @@ class Regex:
|
|||
|
||||
def search(self, value):
|
||||
self._matchCache = self._regexObj.search(value)
|
||||
if self.hasMatched():
|
||||
# Find start of the first line where the match was found
|
||||
try:
|
||||
self._matchLineStart = self._matchCache.string.rindex(
|
||||
"\n", 0, self._matchCache.start() +1 ) + 1
|
||||
except ValueError:
|
||||
self._matchLineStart = 0
|
||||
# Find end of the last line where the match was found
|
||||
try:
|
||||
self._matchLineEnd = self._matchCache.string.index(
|
||||
"\n", self._matchCache.end() - 1) + 1
|
||||
except ValueError:
|
||||
self._matchLineEnd = len(self._matchCache.string)
|
||||
|
||||
##
|
||||
# Checks if the previous call to search() matched.
|
||||
|
@ -88,6 +106,54 @@ class Regex:
|
|||
else:
|
||||
return False
|
||||
|
||||
##
|
||||
# Returns skipped lines.
|
||||
#
|
||||
# This returns skipped lines captured by the <SKIPLINES> tag.
|
||||
# @return list of skipped lines
|
||||
|
||||
def getSkippedLines(self):
|
||||
if not self._matchCache:
|
||||
return []
|
||||
skippedLines = ""
|
||||
n = 0
|
||||
while True:
|
||||
try:
|
||||
skippedLines += self._matchCache.group("skiplines%i" % n)
|
||||
n += 1
|
||||
except IndexError:
|
||||
break
|
||||
return skippedLines.splitlines(True)
|
||||
|
||||
##
|
||||
# Returns unmatched lines.
|
||||
#
|
||||
# This returns unmatched lines including captured by the <SKIPLINES> tag.
|
||||
# @return list of unmatched lines
|
||||
|
||||
def getUnmatchedLines(self):
|
||||
if not self.hasMatched():
|
||||
return []
|
||||
unmatchedLines = (
|
||||
self._matchCache.string[:self._matchLineStart].splitlines(True)
|
||||
+ self.getSkippedLines()
|
||||
+ self._matchCache.string[self._matchLineEnd:].splitlines(True))
|
||||
return unmatchedLines
|
||||
|
||||
##
|
||||
# Returns matched lines.
|
||||
#
|
||||
# This returns matched lines by excluding those captured
|
||||
# by the <SKIPLINES> tag.
|
||||
# @return list of matched lines
|
||||
|
||||
def getMatchedLines(self):
|
||||
if not self.hasMatched():
|
||||
return []
|
||||
matchedLines = self._matchCache.string[
|
||||
self._matchLineStart:self._matchLineEnd].splitlines(True)
|
||||
return [line for line in matchedLines
|
||||
if line not in self.getSkippedLines()]
|
||||
|
||||
##
|
||||
# Exception dedicated to the class Regex.
|
|
@ -38,7 +38,7 @@ from failregex import FailRegex, Regex, RegexException
|
|||
import logging, re, os, fcntl, time, sys, locale, codecs
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.filter")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
##
|
||||
# Log reader class.
|
||||
|
@ -71,6 +71,12 @@ class Filter(JailThread):
|
|||
self.__findTime = 6000
|
||||
## The ignore IP list.
|
||||
self.__ignoreIpList = []
|
||||
## Size of line buffer
|
||||
self.__lineBufferSize = 1
|
||||
## Line buffer
|
||||
self.__lineBuffer = []
|
||||
## Store last time stamp, applicable for multi-line
|
||||
self.__lastTimeLine = ""
|
||||
|
||||
self.dateDetector = DateDetector()
|
||||
self.dateDetector.addDefaultTemplate()
|
||||
|
@ -206,6 +212,23 @@ class Filter(JailThread):
|
|||
def getMaxRetry(self):
|
||||
return self.failManager.getMaxRetry()
|
||||
|
||||
##
|
||||
# Set the maximum line buffer size.
|
||||
#
|
||||
# @param value the line buffer size
|
||||
|
||||
def setMaxLines(self, value):
|
||||
self.__lineBufferSize = max(1, value)
|
||||
logSys.info("Set maxLines = %i" % self.__lineBufferSize)
|
||||
|
||||
##
|
||||
# Get the maximum line buffer size.
|
||||
#
|
||||
# @return the line buffer size
|
||||
|
||||
def getMaxLines(self):
|
||||
return self.__lineBufferSize
|
||||
|
||||
##
|
||||
# Main loop.
|
||||
#
|
||||
|
@ -295,14 +318,17 @@ class Filter(JailThread):
|
|||
if timeMatch:
|
||||
# Lets split into time part and log part of the line
|
||||
timeLine = timeMatch.group()
|
||||
self.__lastTimeLine = timeLine
|
||||
# Lets leave the beginning in as well, so if there is no
|
||||
# anchore at the beginning of the time regexp, we don't
|
||||
# at least allow injection. Should be harmless otherwise
|
||||
logLine = line[:timeMatch.start()] + line[timeMatch.end():]
|
||||
else:
|
||||
timeLine = line
|
||||
timeLine = self.__lastTimeLine or line
|
||||
logLine = line
|
||||
return self.findFailure(timeLine, logLine)
|
||||
self.__lineBuffer = ((self.__lineBuffer +
|
||||
[logLine])[-self.__lineBufferSize:])
|
||||
return self.findFailure(timeLine, "".join(self.__lineBuffer))
|
||||
|
||||
def processLineAndAdd(self, line):
|
||||
"""Processes the line for failures and populates failManager
|
||||
|
@ -345,14 +371,15 @@ class Filter(JailThread):
|
|||
|
||||
def findFailure(self, timeLine, logLine):
|
||||
failList = list()
|
||||
# Checks if we must ignore this line.
|
||||
if self.ignoreLine(logLine):
|
||||
# The ignoreregex matched. Return.
|
||||
return failList
|
||||
# Iterates over all the regular expressions.
|
||||
for failRegex in self.__failRegex:
|
||||
failRegex.search(logLine)
|
||||
if failRegex.hasMatched():
|
||||
# Checks if we must ignore this match.
|
||||
if self.ignoreLine("".join(failRegex.getMatchedLines())):
|
||||
# The ignoreregex matched. Remove ignored match.
|
||||
self.__lineBuffer = failRegex.getUnmatchedLines()
|
||||
continue
|
||||
# The failregex matched.
|
||||
date = self.dateDetector.getUnixTime(timeLine)
|
||||
if date == None:
|
||||
|
@ -362,6 +389,7 @@ class Filter(JailThread):
|
|||
"in order to get support for this format."
|
||||
% (logLine, timeLine))
|
||||
else:
|
||||
self.__lineBuffer = failRegex.getUnmatchedLines()
|
||||
try:
|
||||
host = failRegex.getHost()
|
||||
ipMatch = DNSUtils.textToIp(host, self.__useDns)
|
|
@ -30,7 +30,7 @@ from mytime import MyTime
|
|||
import time, logging, gamin
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.filter")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
##
|
||||
# Log reader class.
|
|
@ -33,7 +33,7 @@ from mytime import MyTime
|
|||
import time, logging, os
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.filter")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
##
|
||||
# Log reader class.
|
|
@ -38,7 +38,7 @@ if not hasattr(pyinotify, '__version__') \
|
|||
from os.path import dirname, sep as pathsep
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.filter")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
##
|
||||
# Log reader class.
|
|
@ -28,7 +28,7 @@ import Queue, logging
|
|||
from actions import Actions
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.jail")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class Jail:
|
||||
|
|
@ -21,7 +21,7 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
|||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2013- Yaroslav Halchenko"
|
||||
__license__ = "GPL"
|
||||
|
||||
from common.exceptions import DuplicateJailException, UnknownJailException
|
||||
from fail2ban.exceptions import DuplicateJailException, UnknownJailException
|
||||
|
||||
from jail import Jail
|
||||
from threading import Lock
|
|
@ -31,7 +31,7 @@ from threading import Thread
|
|||
import logging
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.server")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class JailThread(Thread):
|
||||
|
|
@ -32,11 +32,11 @@ from jails import Jails
|
|||
from transmitter import Transmitter
|
||||
from asyncserver import AsyncServer
|
||||
from asyncserver import AsyncServerException
|
||||
from common import version
|
||||
from fail2ban import version
|
||||
import logging, logging.handlers, sys, os, signal
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.server")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class Server:
|
||||
|
||||
|
@ -223,6 +223,12 @@ class Server:
|
|||
def getMaxRetry(self, name):
|
||||
return self.__jails.getFilter(name).getMaxRetry()
|
||||
|
||||
def setMaxLines(self, name, value):
|
||||
self.__jails.getFilter(name).setMaxLines(value)
|
||||
|
||||
def getMaxLines(self, name):
|
||||
return self.__jails.getFilter(name).getMaxLines()
|
||||
|
||||
# Action
|
||||
def addAction(self, name, value):
|
||||
self.__jails.getAction(name).addAction(value)
|
||||
|
@ -326,7 +332,7 @@ class Server:
|
|||
logLevel = logging.WARNING
|
||||
elif value == 3:
|
||||
logLevel = logging.INFO
|
||||
logging.getLogger("fail2ban").setLevel(logLevel)
|
||||
logging.getLogger(__name__).parent.parent.setLevel(logLevel)
|
||||
finally:
|
||||
self.__loggingLock.release()
|
||||
|
||||
|
@ -375,9 +381,10 @@ class Server:
|
|||
return False
|
||||
# Removes previous handlers -- in reverse order since removeHandler
|
||||
# alter the list in-place and that can confuses the iterable
|
||||
for handler in logging.getLogger("fail2ban").handlers[::-1]:
|
||||
logger = logging.getLogger(__name__).parent.parent
|
||||
for handler in logger.handlers[::-1]:
|
||||
# Remove the handler.
|
||||
logging.getLogger("fail2ban").removeHandler(handler)
|
||||
logger.removeHandler(handler)
|
||||
# And try to close -- it might be closed already
|
||||
try:
|
||||
handler.flush()
|
||||
|
@ -390,7 +397,7 @@ class Server:
|
|||
# with older Pythons -- seems to be safe to ignore there
|
||||
# tell the handler to use this format
|
||||
hdlr.setFormatter(formatter)
|
||||
logging.getLogger("fail2ban").addHandler(hdlr)
|
||||
logger.addHandler(hdlr)
|
||||
# Does not display this message at startup.
|
||||
if not self.__logTarget == None:
|
||||
logSys.info("Changed logging target to %s for Fail2ban v%s" %
|
|
@ -30,7 +30,7 @@ __license__ = "GPL"
|
|||
import logging
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class Ticket:
|
||||
|
|
@ -30,7 +30,7 @@ __license__ = "GPL"
|
|||
import logging, time
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.comm")
|
||||
logSys = logging.getLogger(__name__)
|
||||
|
||||
class Transmitter:
|
||||
|
||||
|
@ -175,6 +175,10 @@ class Transmitter:
|
|||
value = command[2]
|
||||
self.__server.setMaxRetry(name, int(value))
|
||||
return self.__server.getMaxRetry(name)
|
||||
elif command[1] == "maxlines":
|
||||
value = command[2]
|
||||
self.__server.setMaxLines(name, int(value))
|
||||
return self.__server.getMaxLines(name)
|
||||
# command
|
||||
elif command[1] == "bantime":
|
||||
value = command[2]
|
||||
|
@ -256,6 +260,8 @@ class Transmitter:
|
|||
return self.__server.getFindTime(name)
|
||||
elif command[1] == "maxretry":
|
||||
return self.__server.getMaxRetry(name)
|
||||
elif command[1] == "maxlines":
|
||||
return self.__server.getMaxLines(name)
|
||||
# Action
|
||||
elif command[1] == "bantime":
|
||||
return self.__server.getBanTime(name)
|
|
@ -29,9 +29,10 @@ __license__ = "GPL"
|
|||
|
||||
import unittest, time
|
||||
import logging, sys
|
||||
from server.action import Action
|
||||
from StringIO import StringIO
|
||||
|
||||
from fail2ban.server.action import Action
|
||||
|
||||
class ExecuteAction(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
|
@ -28,8 +28,9 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
|||
__license__ = "GPL"
|
||||
|
||||
import unittest
|
||||
from server.banmanager import BanManager
|
||||
from server.ticket import BanTicket
|
||||
|
||||
from fail2ban.server.banmanager import BanManager
|
||||
from fail2ban.server.ticket import BanTicket
|
||||
|
||||
class AddFailure(unittest.TestCase):
|
||||
|
|
@ -22,10 +22,18 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
|||
__license__ = "GPL"
|
||||
|
||||
import os, shutil, tempfile, unittest
|
||||
from client.configreader import ConfigReader
|
||||
from client.jailreader import JailReader
|
||||
from client.jailsreader import JailsReader
|
||||
from client.configurator import Configurator
|
||||
|
||||
from fail2ban.client.configreader import ConfigReader
|
||||
from fail2ban.client.jailreader import JailReader
|
||||
from fail2ban.client.filterreader import FilterReader
|
||||
from fail2ban.client.jailsreader import JailsReader
|
||||
from fail2ban.client.configurator import Configurator
|
||||
|
||||
TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files")
|
||||
if os.path.exists('config/fail2ban.conf'):
|
||||
CONFIG_DIR='config'
|
||||
else:
|
||||
CONFIG_DIR='/etc/fail2ban'
|
||||
|
||||
class ConfigReaderTest(unittest.TestCase):
|
||||
|
||||
|
@ -98,7 +106,7 @@ option = %s
|
|||
class JailReaderTest(unittest.TestCase):
|
||||
|
||||
def testStockSSHJail(self):
|
||||
jail = JailReader('ssh-iptables', basedir='config') # we are running tests from root project dir atm
|
||||
jail = JailReader('ssh-iptables', basedir=CONFIG_DIR) # we are running tests from root project dir atm
|
||||
self.assertTrue(jail.read())
|
||||
self.assertTrue(jail.getOptions())
|
||||
self.assertFalse(jail.isEnabled())
|
||||
|
@ -109,6 +117,36 @@ class JailReaderTest(unittest.TestCase):
|
|||
expected = ['mail-whois', {'name': 'SSH'}]
|
||||
result = JailReader.splitAction(action)
|
||||
self.assertEquals(expected, result)
|
||||
|
||||
class FilterReaderTest(unittest.TestCase):
|
||||
|
||||
def testConvert(self):
|
||||
output = [['set', 'testcase01', 'addfailregex',
|
||||
"^\\s*(?:\\S+ )?(?:kernel: \\[\\d+\\.\\d+\\] )?(?:@vserver_\\S+ )"
|
||||
"?(?:(?:\\[\\d+\\])?:\\s+[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?|"
|
||||
"[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?(?:\\[\\d+\\])?:)?\\s*(?:"
|
||||
"error: PAM: )?Authentication failure for .* from <HOST>\\s*$"],
|
||||
['set', 'testcase01', 'addfailregex',
|
||||
"^\\s*(?:\\S+ )?(?:kernel: \\[\\d+\\.\\d+\\] )?(?:@vserver_\\S+ )"
|
||||
"?(?:(?:\\[\\d+\\])?:\\s+[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?|"
|
||||
"[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?(?:\\[\\d+\\])?:)?\\s*(?:"
|
||||
"error: PAM: )?User not known to the underlying authentication mo"
|
||||
"dule for .* from <HOST>\\s*$"],
|
||||
['set', 'testcase01', 'addfailregex',
|
||||
"^\\s*(?:\\S+ )?(?:kernel: \\[\\d+\\.\\d+\\] )?(?:@vserver_\\S+ )"
|
||||
"?(?:(?:\\[\\d+\\])?:\\s+[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?|"
|
||||
"[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?(?:\\[\\d+\\])?:)?\\s*(?:"
|
||||
"error: PAM: )?User not known to the\\nunderlying authentication."
|
||||
"+$<SKIPLINES>^.+ module for .* from <HOST>\\s*$"],
|
||||
['set', 'testcase01', 'addignoreregex',
|
||||
"^.+ john from host 192.168.1.1\\s*$"]]
|
||||
filterReader = FilterReader("testcase01", "testcase01")
|
||||
filterReader.setBaseDir(TEST_FILES_DIR)
|
||||
filterReader.read()
|
||||
#filterReader.getOptions(["failregex", "ignoreregex"])
|
||||
filterReader.getOptions(None)
|
||||
|
||||
self.assertEquals(filterReader.convert(), output)
|
||||
|
||||
class JailsReaderTest(unittest.TestCase):
|
||||
|
||||
|
@ -118,7 +156,7 @@ class JailsReaderTest(unittest.TestCase):
|
|||
self.assertRaises(ValueError, reader.read)
|
||||
|
||||
def testReadStockJailConf(self):
|
||||
jails = JailsReader(basedir='config') # we are running tests from root project dir atm
|
||||
jails = JailsReader(basedir=CONFIG_DIR) # we are running tests from root project dir atm
|
||||
self.assertTrue(jails.read()) # opens fine
|
||||
self.assertTrue(jails.getOptions()) # reads fine
|
||||
comm_commands = jails.convert()
|
||||
|
@ -129,7 +167,7 @@ class JailsReaderTest(unittest.TestCase):
|
|||
def testReadStockJailConfForceEnabled(self):
|
||||
# more of a smoke test to make sure that no obvious surprises
|
||||
# on users' systems when enabling shipped jails
|
||||
jails = JailsReader(basedir='config', force_enable=True) # we are running tests from root project dir atm
|
||||
jails = JailsReader(basedir=CONFIG_DIR, force_enable=True) # we are running tests from root project dir atm
|
||||
self.assertTrue(jails.read()) # opens fine
|
||||
self.assertTrue(jails.getOptions()) # reads fine
|
||||
comm_commands = jails.convert()
|
||||
|
@ -151,8 +189,8 @@ class JailsReaderTest(unittest.TestCase):
|
|||
|
||||
def testConfigurator(self):
|
||||
configurator = Configurator()
|
||||
configurator.setBaseDir('config')
|
||||
self.assertEqual(configurator.getBaseDir(), 'config')
|
||||
configurator.setBaseDir(CONFIG_DIR)
|
||||
self.assertEqual(configurator.getBaseDir(), CONFIG_DIR)
|
||||
|
||||
configurator.readEarly()
|
||||
opts = configurator.getEarlyOptions()
|
||||
|
@ -165,4 +203,4 @@ class JailsReaderTest(unittest.TestCase):
|
|||
# otherwise just a code smoke test)
|
||||
configurator._Configurator__jails.setBaseDir('/tmp')
|
||||
self.assertEqual(configurator._Configurator__jails.getBaseDir(), '/tmp')
|
||||
self.assertEqual(configurator.getBaseDir(), 'config')
|
||||
self.assertEqual(configurator.getBaseDir(), CONFIG_DIR)
|
|
@ -28,8 +28,9 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
|||
__license__ = "GPL"
|
||||
|
||||
import unittest
|
||||
from server.datedetector import DateDetector
|
||||
from server.datetemplate import DateTemplate
|
||||
|
||||
from fail2ban.server.datedetector import DateDetector
|
||||
from fail2ban.server.datetemplate import DateTemplate
|
||||
|
||||
class DateDetectorTest(unittest.TestCase):
|
||||
|
||||
|
@ -84,6 +85,7 @@ class DateDetectorTest(unittest.TestCase):
|
|||
"2005-01-23T21:59:59.252Z", #ISO 8601
|
||||
"2005-01-23T21:59:59-05:00Z", #ISO 8601 with TZ
|
||||
"<01/23/05@21:59:59>",
|
||||
"050123 21:59:59", # MySQL
|
||||
):
|
||||
log = sdate + "[sshd] error: PAM: Authentication failure"
|
||||
# exclude
|
|
@ -28,8 +28,9 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
|||
__license__ = "GPL"
|
||||
|
||||
import unittest, socket, time, pickle
|
||||
from server.failmanager import FailManager, FailManagerEmpty
|
||||
from server.ticket import FailTicket
|
||||
|
||||
from fail2ban.server.failmanager import FailManager, FailManagerEmpty
|
||||
from fail2ban.server.ticket import FailTicket
|
||||
|
||||
class AddFailure(unittest.TestCase):
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# Generic configuration items (to be used as interpolations) in other
|
||||
# filters or actions configurations
|
||||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[DEFAULT]
|
||||
|
||||
# Daemon definition is to be specialized (if needed) in .conf file
|
||||
_daemon = \S*
|
||||
|
||||
#
|
||||
# Shortcuts for easier comprehension of the failregex
|
||||
#
|
||||
# PID.
|
||||
# EXAMPLES: [123]
|
||||
__pid_re = (?:\[\d+\])
|
||||
|
||||
# Daemon name (with optional source_file:line or whatever)
|
||||
# EXAMPLES: pam_rhosts_auth, [sshd], pop(pam_unix)
|
||||
__daemon_re = [\[\(]?%(_daemon)s(?:\(\S+\))?[\]\)]?:?
|
||||
|
||||
# Combinations of daemon name and PID
|
||||
# EXAMPLES: sshd[31607], pop(pam_unix)[4920]
|
||||
__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
|
||||
#
|
||||
# [hostname] [vserver tag] daemon_id spaces
|
||||
# this can be optional (for instance if we match named native log files)
|
||||
__prefix_line = \s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s*
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[INCLUDES]
|
||||
|
||||
# Read common prefixes. If any customizations available -- read them from
|
||||
# common.local
|
||||
before = testcase-common.conf
|
||||
|
||||
|
||||
[Definition]
|
||||
|
||||
_daemon = sshd
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile. The
|
||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
||||
# be used for standard IP/hostname matching and is only an alias for
|
||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from <HOST>\s*$
|
||||
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
|
||||
^%(__prefix_line)s(?:error: PAM: )?User not known to the\nunderlying authentication.+$<SKIPLINES>^.+ module for .* from <HOST>\s*$
|
||||
|
||||
# Option: ignoreregex
|
||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
||||
# Values: TEXT
|
||||
#
|
||||
ignoreregex = ^.+ john from host 192.168.1.1\s*$
|
|
@ -0,0 +1,6 @@
|
|||
130324 0:04:00 [Warning] Access denied for user 'root'@'192.168.1.35' (using password: NO)
|
||||
130324 8:24:09 [Warning] Access denied for user 'root'@'220.95.238.171' (using password: NO)
|
||||
130324 17:56:13 [Warning] Access denied for user 'root'@'61.160.223.112' (using password: NO)
|
||||
130324 17:56:14 [Warning] Access denied for user 'root'@'61.160.223.112' (using password: YES)
|
||||
130324 19:01:39 [Warning] Access denied for user 'root'@'61.147.108.35' (using password: NO)
|
||||
130324 19:01:40 [Warning] Access denied for user 'root'@'61.147.108.35' (using password: YES)
|
|
@ -0,0 +1,35 @@
|
|||
Aug 14 11:58:58 yyyy rsyncd[9874]: connect from example.com (192.0.43.10)
|
||||
Aug 14 11:58:58 yyyy rsyncd[23864]: connect from example.com (192.0.43.10)
|
||||
Aug 14 11:59:58 yyyy rsyncd[23864]: rsync on xxx/ from example.com (192.0.43.10)
|
||||
Aug 14 11:59:58 yyyy rsyncd[23864]: building file list
|
||||
Aug 14 11:59:58 yyyy rsyncd[28101]: connect from irrelevant (192.0.43.11)
|
||||
Aug 14 11:59:58 yyyy rsyncd[28101]: rsync on xxx/ from irrelevant (192.0.43.11)
|
||||
Aug 14 11:59:58 yyyy rsyncd[28101]: building file list
|
||||
Aug 14 11:59:58 yyyy rsyncd[28101]: sent 294382 bytes received 781 bytes total size 29221543998
|
||||
Aug 14 11:59:58 yyyy rsyncd[18067]: sent 2833586339 bytes received 65115 bytes total size 29221543998
|
||||
Aug 14 11:59:58 yyyy smartd[2635]: Device: /dev/sdb [SAT], SMART Usage Attribute: 194 Temperature_Celsius changed from 116 to 115
|
||||
Aug 14 11:59:58 yyyy rsyncd[1762]: connect from irrelevant (192.0.43.11)
|
||||
Aug 14 11:59:58 yyyy rsyncd[1762]: rsync on xxx/ from irrelevant (192.0.43.11)
|
||||
|
||||
Aug 14 11:59:58 yyyy rsyncd[1762]: building file list
|
||||
Aug 14 11:59:58 yyyy rsyncd[1762]: sent 294382 bytes received 781 bytes total size 29221543998
|
||||
Aug 14 11:59:58 yyyy sendmail[30222]: r0NNNlC0030222: from=<bounce-25497-9881290652-user=example.com@example.com>, size=6420, class=0, nrcpts=1, msgid=<0.0.9881290652.3772024cf8879cycvau18081.0@example.com>, bodytype=8BITMIME, proto=ESMTP, daemon=MTA, relay=[192.0.43.15] (may be forged)
|
||||
Aug 14 11:59:58 yyyy smartd[2635]: Device: /dev/sda [SAT], starting scheduled Short Self-Test.
|
||||
Aug 14 11:59:58 yyyy smartd[2635]: Device: /dev/sdb [SAT], SMART Usage Attribute: 194 Temperature_Celsius changed from 115 to 116
|
||||
Aug 14 11:59:58 yyyy smartd[2635]: Device: /dev/sdb [SAT], starting scheduled Short Self-Test.
|
||||
Aug 14 11:59:58 yyyy smartd[2635]: Device: /dev/sda [SAT], previous self-test completed without error
|
||||
Aug 14 11:59:58 yyyy smartd[2635]: Device: /dev/sdb [SAT], previous self-test completed without error
|
||||
|
||||
|
||||
Aug 14 11:59:58 yyyy rsyncd[7788]: connect from irrelevant (192.0.43.11)
|
||||
Aug 14 11:59:58 yyyy rsyncd[7788]: rsync on xxx/ from irrelevant (192.0.43.11)
|
||||
Aug 14 11:59:58 yyyy rsyncd[7788]: building file list
|
||||
Aug 14 11:59:58 yyyy rsyncd[21919]: sent 2836906453 bytes received 6768 bytes total size 29221543998
|
||||
Aug 14 11:59:58 yyyy rsyncd[23864]: rsync error: timeout in data send/receive (code 30) at io.c(137) [sender=3.0.9]
|
||||
Aug 14 11:59:58 yyyy spamd[19119]: spamd: result: Y 11 - AWL,BAYES_50,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HTML_MESSAGE,RCVD_IN_BRBL_LASTEXT,RCVD_IN_PSBL,RCVD_IN_RP_RNBL,RDNS_NONE,URIBL_BLACK,URIBL_DBL_SPAM scantime=1.2,size=6910,user=sa-milt,uid=499,required_score=5.0,rhost=localhost,raddr=127.0.0.1,rport=57429,mid=<0.0.9881290652.3772024cf8879cycvau18081.0@example.com>,bayes=0.536244,autolearn=no
|
||||
Aug 14 11:59:58 yyyy rsyncd[5534]: connect from irrelevant (192.0.43.11)
|
||||
Aug 14 11:59:58 yyyy rsyncd[5534]: rsync on xxx/ from irrelevant (192.0.43.11)
|
||||
Aug 14 11:59:58 yyyy rsyncd[5534]: building file list
|
||||
Aug 14 11:59:58 yyyy rsyncd[7788]: rsync error: Received SIGINT
|
||||
Aug 14 11:59:58 yyyy rsyncd[5534]: sent 294382 bytes received 781 bytes total size 29221543998
|
||||
Aug 14 11:59:59 yyyy rsyncd[9874]: rsync error: timeout in data send/receive (code 30) at io.c(137) [sender=3.0.9]
|
|
@ -1,15 +1,15 @@
|
|||
Sep 21 22:03:07 [sshd] Invalid user toto from 212.41.96.185
|
||||
1124012400 [sshd] Invalid user fuck from 212.41.96.185
|
||||
1124012400 [sshd] Invalid user duck from 212.41.96.185
|
||||
Sep 21 21:03:38 [sshd] Invalid user toto from 212.41.96.185
|
||||
1124012500 [sshd] Invalid user fuck from 212.41.96.185
|
||||
1124012500 [sshd] Invalid user duck from 212.41.96.185
|
||||
Sep 21 21:03:46 [sshd] Invalid user toto from 212.41.96.185
|
||||
Aug 14 11:58:48 [sshd] Invalid user fuck from 212.41.96.185
|
||||
Aug 14 11:58:48 [sshd] Invalid user duck from 212.41.96.185
|
||||
Aug 14 11:59:58 [sshd] Invalid user toto from 212.41.96.185
|
||||
Sep 21 21:04:03 [sshd] Invalid user fuck from 212.41.96.185
|
||||
Sep 21 21:04:03 [sshd] Invalid user duck from 212.41.96.185
|
||||
- Last output repeated twice -
|
||||
2005/08/14 11:57:00 [sshd] Invalid user toto from 212.41.96.186
|
||||
2005/08/14 11:58:00 [sshd] Invalid user fuck from 212.41.96.186
|
||||
2005/08/14 11:58:00 [sshd] Invalid user duck from 212.41.96.186
|
||||
2005/08/14 11:59:00 [sshd] Invalid user toto from 212.41.96.186
|
||||
2005/08/14 12:00:00 [sshd] Invalid user fuck from 212.41.96.186
|
||||
2005/08/14 12:00:00 [sshd] Invalid user duck from 212.41.96.186
|
||||
- Last output repeated twice -
|
||||
Sep 21 21:09:01 [sshd] Invalid user toto from 212.41.96.185
|
|
@ -28,11 +28,13 @@ import sys
|
|||
import time
|
||||
import tempfile
|
||||
|
||||
from server.jail import Jail
|
||||
from server.filterpoll import FilterPoll
|
||||
from server.filter import FileFilter, DNSUtils
|
||||
from server.failmanager import FailManager
|
||||
from server.failmanager import FailManagerEmpty
|
||||
from fail2ban.server.jail import Jail
|
||||
from fail2ban.server.filterpoll import FilterPoll
|
||||
from fail2ban.server.filter import FileFilter, DNSUtils
|
||||
from fail2ban.server.failmanager import FailManager
|
||||
from fail2ban.server.failmanager import FailManagerEmpty
|
||||
|
||||
TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files")
|
||||
|
||||
#
|
||||
# Useful helpers
|
||||
|
@ -179,7 +181,7 @@ class IgnoreIP(unittest.TestCase):
|
|||
|
||||
class LogFile(unittest.TestCase):
|
||||
|
||||
FILENAME = "testcases/files/testcase01.log"
|
||||
FILENAME = os.path.join(TEST_FILES_DIR, "testcase01.log")
|
||||
|
||||
def setUp(self):
|
||||
"""Call before every test case."""
|
||||
|
@ -519,11 +521,12 @@ def get_monitor_failures_testcase(Filter_):
|
|||
|
||||
class GetFailures(unittest.TestCase):
|
||||
|
||||
FILENAME_01 = "testcases/files/testcase01.log"
|
||||
FILENAME_02 = "testcases/files/testcase02.log"
|
||||
FILENAME_03 = "testcases/files/testcase03.log"
|
||||
FILENAME_04 = "testcases/files/testcase04.log"
|
||||
FILENAME_USEDNS = "testcases/files/testcase-usedns.log"
|
||||
FILENAME_01 = os.path.join(TEST_FILES_DIR, "testcase01.log")
|
||||
FILENAME_02 = os.path.join(TEST_FILES_DIR, "testcase02.log")
|
||||
FILENAME_03 = os.path.join(TEST_FILES_DIR, "testcase03.log")
|
||||
FILENAME_04 = os.path.join(TEST_FILES_DIR, "testcase04.log")
|
||||
FILENAME_USEDNS = os.path.join(TEST_FILES_DIR, "testcase-usedns.log")
|
||||
FILENAME_MULTILINE = os.path.join(TEST_FILES_DIR, "testcase-multiline.log")
|
||||
|
||||
# so that they could be reused by other tests
|
||||
FAILURES_01 = ('193.168.0.128', 3, 1124013599.0,
|
||||
|
@ -629,6 +632,53 @@ class GetFailures(unittest.TestCase):
|
|||
|
||||
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
||||
|
||||
def testGetFailuresMultiLine(self):
|
||||
output = [("192.0.43.10", 2, 1124013599.0),
|
||||
("192.0.43.11", 1, 1124013598.0)]
|
||||
self.filter.addLogPath(GetFailures.FILENAME_MULTILINE)
|
||||
self.filter.addFailRegex("^.*rsyncd\[(?P<pid>\d+)\]: connect from .+ \(<HOST>\)$<SKIPLINES>^.+ rsyncd\[(?P=pid)\]: rsync error: .*$")
|
||||
self.filter.setMaxLines(100)
|
||||
self.filter.setMaxRetry(1)
|
||||
|
||||
self.filter.getFailures(GetFailures.FILENAME_MULTILINE)
|
||||
|
||||
_assert_correct_last_attempt(self, self.filter, output.pop())
|
||||
_assert_correct_last_attempt(self, self.filter, output.pop())
|
||||
|
||||
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
||||
|
||||
def testGetFailuresMultiLineIgnoreRegex(self):
|
||||
output = [("192.0.43.10", 2, 1124013599.0)]
|
||||
self.filter.addLogPath(GetFailures.FILENAME_MULTILINE)
|
||||
self.filter.addFailRegex("^.*rsyncd\[(?P<pid>\d+)\]: connect from .+ \(<HOST>\)$<SKIPLINES>^.+ rsyncd\[(?P=pid)\]: rsync error: .*$")
|
||||
self.filter.addIgnoreRegex("rsync error: Received SIGINT")
|
||||
self.filter.setMaxLines(100)
|
||||
self.filter.setMaxRetry(1)
|
||||
|
||||
self.filter.getFailures(GetFailures.FILENAME_MULTILINE)
|
||||
|
||||
_assert_correct_last_attempt(self, self.filter, output.pop())
|
||||
|
||||
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
||||
|
||||
def testGetFailuresMultiLineMultiRegex(self):
|
||||
output = [("192.0.43.10", 2, 1124013599.0),
|
||||
("192.0.43.11", 1, 1124013598.0),
|
||||
("192.0.43.15", 1, 1124013598.0)]
|
||||
self.filter.addLogPath(GetFailures.FILENAME_MULTILINE)
|
||||
self.filter.addFailRegex("^.*rsyncd\[(?P<pid>\d+)\]: connect from .+ \(<HOST>\)$<SKIPLINES>^.+ rsyncd\[(?P=pid)\]: rsync error: .*$")
|
||||
self.filter.addFailRegex("^.* sendmail\[.*, msgid=<(?P<msgid>[^>]+).*relay=\[<HOST>\].*$<SKIPLINES>^.+ spamd: result: Y \d+ .*,mid=<(?P=msgid)>(,bayes=[.\d]+)?(,autolearn=\S+)?\s*$")
|
||||
self.filter.setMaxLines(100)
|
||||
self.filter.setMaxRetry(1)
|
||||
|
||||
self.filter.getFailures(GetFailures.FILENAME_MULTILINE)
|
||||
|
||||
_assert_correct_last_attempt(self, self.filter, output.pop())
|
||||
_assert_correct_last_attempt(self, self.filter, output.pop())
|
||||
_assert_correct_last_attempt(self, self.filter, output.pop())
|
||||
|
||||
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
||||
|
||||
class DNSUtilsTests(unittest.TestCase):
|
||||
|
||||
def testUseDns(self):
|
|
@ -28,8 +28,11 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
|||
__license__ = "GPL"
|
||||
|
||||
import unittest, socket, time, tempfile, os, locale
|
||||
from server.server import Server
|
||||
from common.exceptions import UnknownJailException
|
||||
|
||||
from fail2ban.server.server import Server
|
||||
from fail2ban.exceptions import UnknownJailException
|
||||
|
||||
TEST_FILES_DIR = os.path.join(os.path.dirname(__file__), "files")
|
||||
|
||||
class StartStop(unittest.TestCase):
|
||||
|
||||
|
@ -279,14 +282,14 @@ class Transmitter(TransmitterBase):
|
|||
self.jailAddDelTest(
|
||||
"logpath",
|
||||
[
|
||||
"testcases/files/testcase01.log",
|
||||
"testcases/files/testcase02.log",
|
||||
"testcases/files/testcase03.log",
|
||||
os.path.join(TEST_FILES_DIR, "testcase01.log"),
|
||||
os.path.join(TEST_FILES_DIR, "testcase02.log"),
|
||||
os.path.join(TEST_FILES_DIR, "testcase03.log"),
|
||||
],
|
||||
self.jailName
|
||||
)
|
||||
# Try duplicates
|
||||
value = "testcases/files/testcase04.log"
|
||||
value = os.path.join(TEST_FILES_DIR, "testcase04.log")
|
||||
self.assertEqual(
|
||||
self.transm.proceed(["set", self.jailName, "addlogpath", value]),
|
||||
(0, [value]))
|
|
@ -28,8 +28,9 @@ __copyright__ = "Copyright (c) 2013 Steven Hiscocks"
|
|||
__license__ = "GPL"
|
||||
|
||||
import unittest, time, tempfile, os, threading
|
||||
from server.asyncserver import AsyncServer, AsyncServerException
|
||||
from client.csocket import CSocket
|
||||
|
||||
from fail2ban.server.asyncserver import AsyncServer, AsyncServerException
|
||||
from fail2ban.client.csocket import CSocket
|
||||
|
||||
class Socket(unittest.TestCase):
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Yaroslav Halchenko"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
||||
__license__ = "GPL"
|
||||
|
||||
version = "0.8.8"
|
||||
version = "0.9.0a0"
|
|
@ -0,0 +1,104 @@
|
|||
Description
|
||||
-----------
|
||||
This plugin checks if the fail2ban server is running and how many IPs are currently banned.
|
||||
You can use this plugin to monitor all the jails or just a specific jail.
|
||||
|
||||
|
||||
How to use
|
||||
----------
|
||||
Just have to run the following command:
|
||||
$ ./check_fail2ban --help
|
||||
|
||||
If you need to use this script with NRPE you just have to do the
|
||||
following steps:
|
||||
|
||||
1 allow your user to run the script with the sudo rights. Just add
|
||||
something like that in your /etc/sudoers (use visudo) :
|
||||
nagios ALL=(ALL) NOPASSWD: /<path-to>/check_fail2ban
|
||||
|
||||
2 then just add this kind of line in your NRPE config file :
|
||||
command[check_fail2ban]=/usr/bin/sudo /<path-to>/check_fail2ban
|
||||
|
||||
3 don't forget to restart your NRPE daemon
|
||||
|
||||
/!\ be careful to let no one able to update the check_fail2ban ;)
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Notes (from f2ban.txt)
|
||||
-----
|
||||
It seems that Fail2ban is currently not working, please login and check
|
||||
|
||||
HELP:
|
||||
|
||||
1.) stop the Service
|
||||
/etc/init.d/fail2ban stop
|
||||
|
||||
2.) delete the socket if available
|
||||
rm /tmp/fail2ban.sock
|
||||
|
||||
3.) start the Service
|
||||
/etc/init.d/fail2ban start
|
||||
|
||||
4.) check if fail2ban is working
|
||||
fail2ban-client ping
|
||||
Answer should be "pong"
|
||||
|
||||
5.) if the answer is not "pong" run away or CRY FOR HELP ;-)
|
||||
|
||||
|
||||
Help
|
||||
----
|
||||
|
||||
Usage: /<path-to>/check_fail2ban [-p] [-D "CHECK FAIL2BAN ACTIVITY"] [-v] [-c 2] [-w 1] [-s /<path-to>/socket] [-P /usr/bin/fail2ban-client]
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
Print detailed help screen
|
||||
-V, --version
|
||||
Print version information
|
||||
-D, --display=STRING
|
||||
To modify the output display
|
||||
default is "CHECK FAIL2BAN ACTIVITY"
|
||||
-P, --path-fail2ban_client=STRING
|
||||
Specify the path to the tw_cli binary
|
||||
default value is /usr/bin/fail2ban-client
|
||||
-c, --critical=INT
|
||||
Specify a critical threshold
|
||||
default is 2
|
||||
-w, --warning=INT
|
||||
Specify a warning threshold
|
||||
default is 1
|
||||
-s, --socket=STRING
|
||||
Specify a socket path
|
||||
default is unset
|
||||
-p, --perfdata
|
||||
If you want to activate the perfdata output
|
||||
-v, --verbose
|
||||
Show details for command-line debugging (Nagios may truncate the output)
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
# for a specific jail
|
||||
$ ./check_fail2ban --verbose -p -j ssh -w 1 -c 5 -P /usr/bin/fail2ban-client
|
||||
DEBUG : fail2ban_client_path: /usr/bin/fail2ban-client
|
||||
DEBUG : /usr/bin/fail2ban-client exists and is executable
|
||||
DEBUG : final fail2ban command: /usr/bin/fail2ban-client
|
||||
DEBUG : warning threshold : 1, critical threshold : 5
|
||||
DEBUG : it seems the connection with the fail2ban server is ok
|
||||
CHECK FAIL2BAN ACTIVITY - OK - 0 current banned IP(s) for the specific jail ssh | currentBannedIP=0
|
||||
|
||||
# for all the current jails
|
||||
$ ./check_fail2ban --verbose -p -w 1 -c 5 -P /usr/bin/fail2ban-client
|
||||
DEBUG : fail2ban_client_path: /usr/bin/fail2ban-client
|
||||
DEBUG : /usr/bin/fail2ban-client exists and is executable
|
||||
DEBUG : final fail2ban command: /usr/bin/fail2ban-client
|
||||
DEBUG : warning threshold : 1, critical threshold : 5
|
||||
DEBUG : it seems the connection with the fail2ban server is ok
|
||||
DEBUG : jails list: apache, ssh-ddos, ssh
|
||||
DEBUG : the jail apache has currently 0 banned IPs
|
||||
DEBUG : the jail ssh-ddos has currently 0 banned IPs
|
||||
DEBUG : the jail ssh has currently 0 banned IPs
|
||||
CHECK FAIL2BAN ACTIVITY - OK - 3 detected jails with 0 current banned IP(s) | currentBannedIP=0
|
|
@ -1,105 +1,346 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/perl
|
||||
|
||||
# -------------------------------------------------------
|
||||
# -=- <check_fail2ban> -=-
|
||||
# -------------------------------------------------------
|
||||
#
|
||||
# Usage: ./check_fail2ban
|
||||
###############################################################################################
|
||||
# Description:
|
||||
# This plugin will check the status of Fail2ban.
|
||||
# Description : This plugin checks if the fail2ban server is running
|
||||
# and how many IPs are currently banned.
|
||||
#
|
||||
#
|
||||
# Created: 2008-10-25 (Sebastian Mueller)
|
||||
# inspired by the work of Sebastian Mueller - http://www.elchtest.eu
|
||||
#
|
||||
#
|
||||
# Changes: 2008-10-26 fixed some issues (Sebastian Mueller)
|
||||
# Changes: 2009-01-25 add the second check, when server is not replying and the
|
||||
# process is hang-up (Sebastian Mueller)
|
||||
# Version : 0.1
|
||||
# -------------------------------------------------------
|
||||
# In :
|
||||
# - see the How to use section
|
||||
#
|
||||
# please visit my website http://www.elchtest.eu or my personal WIKI http://wiki.elchtest.eu
|
||||
# Out :
|
||||
# - only print on the standard output
|
||||
#
|
||||
################################################################################################
|
||||
# if you have any questions, send a mail to linux@krabbe-offline.de
|
||||
# Features :
|
||||
# - perfdata output
|
||||
# - works with only a specific jail
|
||||
#
|
||||
# this script is for my personal use. read the script before running/using it!!!
|
||||
# Fix Me/Todo :
|
||||
# - too many things ;) but let me know what do you think about it
|
||||
#
|
||||
# ####################################################################
|
||||
|
||||
# ####################################################################
|
||||
# GPL v2
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# YOU HAVE BEEN WARNED. THIS MAY DESTROY YOUR MACHINE. I ACCEPT NO RESPONSIBILITY.
|
||||
###############################################################################################
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
# ####################################################################
|
||||
|
||||
# ####################################################################
|
||||
# How to use :
|
||||
# ------------
|
||||
#
|
||||
# Just have to run the following command:
|
||||
# $ ./check_fail2ban --help
|
||||
#
|
||||
# If you need to use this script with NRPE you just have to do the
|
||||
# following steps:
|
||||
#
|
||||
# 1 allow your user to run the script with the sudo rights. Just add
|
||||
# something like that in your /etc/sudoers (use visudo) :
|
||||
# nagios ALL=(ALL) NOPASSWD: /<path-to>/check_fail2ban
|
||||
#
|
||||
# 2 then just add this kind of line in your NRPE config file :
|
||||
# command[check_fail2ban]=/usr/bin/sudo /<path-to>/check_fail2ban
|
||||
#
|
||||
# 3 don't forget to restart your NRPE daemon
|
||||
#
|
||||
#
|
||||
# /!\ be careful to let no one able to update the check_fail2ban ;)
|
||||
# ------------------------------------------------------------------------------
|
||||
#
|
||||
# ####################################################################
|
||||
|
||||
# ####################################################################
|
||||
# Changelog :
|
||||
# -----------
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Date:12/03/2013 Version:0.1 Author:Erwan Ben Souiden
|
||||
# >> creation
|
||||
# ####################################################################
|
||||
|
||||
# ####################################################################
|
||||
# Don't touch anything under this line!
|
||||
# You shall not pass - Gandalf is watching you
|
||||
# ####################################################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long qw(:config no_ignore_case);
|
||||
|
||||
# Generic variables
|
||||
# -----------------
|
||||
my $version = '0.1';
|
||||
my $author = 'Erwan Labynocle Ben Souiden';
|
||||
my $a_mail = 'erwan@aleikoum.net';
|
||||
my $script_name = 'check_fail2ban';
|
||||
my $verbose_value = 0;
|
||||
my $version_value = 0;
|
||||
my $more_value = 0;
|
||||
my $help_value = 0;
|
||||
my $perfdata_value = 0;
|
||||
my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);
|
||||
|
||||
# Plugin default variables
|
||||
# ------------------------
|
||||
my $display = 'CHECK FAIL2BAN ACTIVITY';
|
||||
my ($critical,$warning) = (2,1);
|
||||
my $fail2ban_client_path = '/usr/bin/fail2ban-client';
|
||||
my $fail2ban_socket = '';
|
||||
my $jail_specific = '';
|
||||
|
||||
GetOptions (
|
||||
'P=s' => \ $fail2ban_client_path,
|
||||
'path-fail2ban_client=s' => \ $fail2ban_client_path,
|
||||
'j=s' => \ $jail_specific,
|
||||
'jail=s' => \ $jail_specific,
|
||||
'w=i' => \ $warning,
|
||||
'warning=i' => \ $warning,
|
||||
'socket=s' => \ $fail2ban_socket,
|
||||
'S=s' => \ $fail2ban_socket,
|
||||
'c=i' => \ $critical,
|
||||
'critical=i' => \ $critical,
|
||||
'V' => \ $version_value,
|
||||
'version' => \ $version_value,
|
||||
'h' => \ $help_value,
|
||||
'H' => \ $help_value,
|
||||
'help' => \ $help_value,
|
||||
'display=s' => \ $display,
|
||||
'D=s' => \ $display,
|
||||
'perfdata' => \ $perfdata_value,
|
||||
'p' => \ $perfdata_value,
|
||||
'v' => \ $verbose_value,
|
||||
'verbose' => \ $verbose_value
|
||||
);
|
||||
|
||||
print_usage() if ($help_value);
|
||||
print_version() if ($version_value);
|
||||
|
||||
|
||||
SECOND_CHECK=0
|
||||
STATE_OK=0
|
||||
STATE_CRITICAL=2
|
||||
|
||||
######################################################################
|
||||
# Read the Status from fail2ban-client
|
||||
######################################################################
|
||||
check_processes_fail2ban()
|
||||
{
|
||||
|
||||
F2B=`sudo -u root fail2ban-client ping | awk -F " " '{print $3}'`
|
||||
exit_fail2ban=0
|
||||
|
||||
if [[ $F2B = "pong" ]]; then
|
||||
exit_fail2ban=$STATE_OK
|
||||
else
|
||||
exit_fail2ban=$STATE_CRITICAL
|
||||
fi
|
||||
# Syntax check of your specified options
|
||||
# --------------------------------------
|
||||
|
||||
print "DEBUG : fail2ban_client_path: $fail2ban_client_path\n" if ($verbose_value);
|
||||
if (($fail2ban_client_path eq "")) {
|
||||
print $display.'- one or more following arguments are missing: fail2ban_client_path'."\n";
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
######################################################################
|
||||
# first check in the Background, PID will be killed when no response
|
||||
# after 10 seconds, might be possible, otherwise the script will be
|
||||
# present in your memory all the time
|
||||
######################################################################
|
||||
|
||||
check_processes_fail2ban &
|
||||
pid=$!
|
||||
if(! -x $fail2ban_client_path) {
|
||||
print $display.' - '.$fail2ban_client_path.' is not executable by you'."\n";
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
print "DEBUG : $fail2ban_client_path exists and is executable\n" if ($verbose_value);
|
||||
|
||||
typeset -i i=0
|
||||
while ps $pid >/dev/null
|
||||
do
|
||||
sleep 1
|
||||
i=$i+1
|
||||
if [ $i -ge 10 ]
|
||||
then
|
||||
kill $pid
|
||||
SECOND_CHECK=1
|
||||
exit_fail2ban=$STATE_CRITICAL
|
||||
break
|
||||
fi
|
||||
done
|
||||
my $fail2ban_cmd = $fail2ban_client_path;
|
||||
$fail2ban_cmd .= " -s $fail2ban_socket" if ($fail2ban_socket);
|
||||
|
||||
######################################################################
|
||||
# when the Server response (does not mean the FAIL2BAN is working)
|
||||
# in the first step, then it will run again and test the Service
|
||||
# and provide the real status
|
||||
######################################################################
|
||||
print "DEBUG : final fail2ban command: $fail2ban_cmd\n" if ($verbose_value);
|
||||
|
||||
print "DEBUG : warning threshold : $warning, critical threshold : $critical\n" if ($verbose_value);
|
||||
if (($critical < 0) or ($warning < 0) or ($critical < $warning)) {
|
||||
print $display.' - the thresholds must be integers and the critical threshold higher or equal than the warning threshold'."\n";
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
|
||||
# Core script
|
||||
# -----------
|
||||
my ($how_many_jail,$how_many_banned,$return_print,$plugstate) = (0,0,"","OK");
|
||||
|
||||
|
||||
if [ $SECOND_CHECK -eq 0 ]; then
|
||||
check_processes_fail2ban
|
||||
elif [ $SECOND_CHECK -eq 1 ]; then
|
||||
exit_fail2ban=$STATE_CRITICAL
|
||||
fi
|
||||
### Test the connection to the fail2ban server
|
||||
my @command_output = `$fail2ban_cmd ping`;
|
||||
my $return_code = $?;
|
||||
if ($return_code) {
|
||||
print $display.'CRITICAL - non-zero exit code during testing fail2ban-client ping, check if the server is running and if you have the good permissions';
|
||||
exit $ERRORS{"CRITICAL"};
|
||||
}
|
||||
else {
|
||||
print "DEBUG : it seems the connection with the fail2ban server is ok\n" if ($verbose_value);
|
||||
}
|
||||
|
||||
|
||||
### Only if you specify one jail
|
||||
if ($jail_specific) {
|
||||
my $current_ban_number = currently_ban("$fail2ban_cmd","$jail_specific");
|
||||
if ($current_ban_number == -1) {
|
||||
print $display.' - CRITICAL - impossible to retrieve info about the jail '.$jail_specific;
|
||||
exit $ERRORS{"CRITICAL"};
|
||||
}
|
||||
else {
|
||||
$how_many_banned = int($current_ban_number);
|
||||
$return_print = $how_many_banned.' current banned IP(s) for the specific jail '.$jail_specific;
|
||||
}
|
||||
}
|
||||
### To analyze all the jail
|
||||
else {
|
||||
# Retrieve the jails list
|
||||
my @jail_list = obtain_jail_list("$fail2ban_cmd");
|
||||
if ($jail_list[0] eq "-1") {
|
||||
print $display.' - CRITICAL - impossible to retrieve the jail list'."\n";
|
||||
exit $ERRORS{"CRITICAL"};
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Main Menu
|
||||
######################################################################
|
||||
foreach (@jail_list) {
|
||||
$how_many_jail ++;
|
||||
|
||||
my $jail_name = $_;
|
||||
$jail_name =~ tr/ //ds;
|
||||
|
||||
my $current_ban_number = currently_ban("$fail2ban_cmd","$jail_name");
|
||||
if ($current_ban_number == -1) {
|
||||
print "DEBUG : problem to parse the current banned IPs for jail $jail_name\n" if ($verbose_value);
|
||||
}
|
||||
else {
|
||||
print "DEBUG : the jail $jail_name has currently $current_ban_number banned IPs\n" if ($verbose_value);
|
||||
$how_many_banned += int($current_ban_number);
|
||||
}
|
||||
}
|
||||
$return_print = $how_many_jail.' detected jails with '.$how_many_banned.' current banned IP(s)';
|
||||
}
|
||||
|
||||
### Final
|
||||
$plugstate = "CRITICAL" if ($how_many_banned >= $critical);
|
||||
$plugstate = "WARNING" if (($how_many_banned >= $warning) && ($how_many_banned < $critical));
|
||||
|
||||
$return_print = $display." - ".$plugstate." - ".$return_print;
|
||||
$return_print .= " | currentBannedIP=$how_many_banned" if ($perfdata_value);
|
||||
|
||||
print $return_print;
|
||||
exit $ERRORS{"$plugstate"};
|
||||
|
||||
|
||||
final_exit=$exit_fail2ban
|
||||
if [ $final_exit -eq 0 ]; then
|
||||
echo "SYSTEM OK - Fail2ban is working normally"
|
||||
exitstatus=$STATE_OK
|
||||
elif [ $final_exit -ne "0" ]; then
|
||||
echo "SYSTEM WARNING - Fail2Ban is not working"
|
||||
######################################################################
|
||||
# If don't have a Nagios Server for monitoring, remove the comment and
|
||||
# add your Mail Address. You can check it with a Cron Job once an hour.
|
||||
# put a txt file on your server and describe how to fix the issue, this
|
||||
# could be attached to the mail.
|
||||
######################################################################
|
||||
# mutt -s "FAIL2BAN NOT WORKING" your@example.com < /home/f2ban.txt
|
||||
# ####################################################################
|
||||
# function 1 : display the help
|
||||
# -----------------------------
|
||||
sub print_usage {
|
||||
print <<EOT;
|
||||
$script_name version $version by $author
|
||||
|
||||
exitstatus=$STATE_CRITICAL
|
||||
fi
|
||||
exit $exitstatus
|
||||
This plugin checks if the fail2ban server is running and how many IPs are currently banned.
|
||||
You can use this plugin to monitor all the jails or just a specific jail.
|
||||
|
||||
Usage: /<path-to>/$script_name [-p] [-D "$display"] [-v] [-c 2] [-w 1] [-s /<path-to>/socket] [-P /usr/bin/fail2ban-client]
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
Print detailed help screen
|
||||
-V, --version
|
||||
Print version information
|
||||
-D, --display=STRING
|
||||
To modify the output display
|
||||
default is "CHECK FAIL2BAN ACTIVITY"
|
||||
-P, --path-fail2ban_client=STRING
|
||||
Specify the path to the tw_cli binary
|
||||
default value is /usr/bin/fail2ban-client
|
||||
-c, --critical=INT
|
||||
Specify a critical threshold
|
||||
default is 2
|
||||
-w, --warning=INT
|
||||
Specify a warning threshold
|
||||
default is 1
|
||||
-s, --socket=STRING
|
||||
Specify a socket path
|
||||
default is unset
|
||||
-p, --perfdata
|
||||
If you want to activate the perfdata output
|
||||
-v, --verbose
|
||||
Show details for command-line debugging (Nagios may truncate the output)
|
||||
|
||||
Send email to $a_mail if you have questions
|
||||
regarding use of this software. To submit patches or suggest improvements,
|
||||
send email to $a_mail
|
||||
This plugin has been created by $author
|
||||
|
||||
Hope you will enjoy it ;)
|
||||
|
||||
Remember :
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
EOT
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
|
||||
# function 2 : display version information
|
||||
# ----------------------------------------
|
||||
sub print_version {
|
||||
print <<EOT;
|
||||
$script_name version $version
|
||||
EOT
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
|
||||
# function 3 : return the jail list
|
||||
# ---------------------------------
|
||||
sub obtain_jail_list {
|
||||
my ($fail2ban_client_path) = @_;
|
||||
|
||||
my @command_output = `$fail2ban_client_path status`;
|
||||
my $return_code = $?;
|
||||
if ($return_code) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
my @jail_list;
|
||||
foreach (@command_output) {
|
||||
if ($_=~/^.*Jail list:\t+(.*)/) {
|
||||
print "DEBUG : jails list: $1\n" if ($verbose_value);
|
||||
@jail_list = split(/,/, $1);
|
||||
}
|
||||
}
|
||||
|
||||
return @jail_list;
|
||||
}
|
||||
|
||||
# function 4 : return how many IP are currently ban for a given jail
|
||||
# ------------------------------------------------------------------
|
||||
sub currently_ban {
|
||||
my ($fail2ban_client_path,$jail_name) = @_;
|
||||
|
||||
my @command_output = `$fail2ban_client_path status $jail_name`;
|
||||
my $return_code = $?;
|
||||
if ($return_code) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
foreach (@command_output) {
|
||||
if ($_=~/^.*Currently banned:\t+(.*)/) {
|
||||
my $current_count = $1;
|
||||
$current_count =~ tr/ //ds;
|
||||
return $current_count;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
It seems that Fail2ban is currently not working, please login and check
|
||||
|
||||
HELP:
|
||||
|
||||
1.) stop the Service
|
||||
/etc/init.d/fail2ban stop
|
||||
|
||||
2.) delete the socket if available
|
||||
rm /tmp/fail2ban.sock
|
||||
|
||||
3.) start the Service
|
||||
/etc/init.d/fail2ban start
|
||||
|
||||
4.) check if fail2ban is working
|
||||
fail2ban-client ping
|
||||
Answer should be "pong"
|
||||
|
||||
5.) if the answer is not "pong" run away or CRY FOR HELP ;-)
|
|
@ -1,6 +1,3 @@
|
|||
[install]
|
||||
install-purelib=/usr/share/fail2ban
|
||||
|
||||
[sdist]
|
||||
formats=bztar
|
||||
|
||||
|
|
23
setup.py
23
setup.py
|
@ -32,11 +32,12 @@ except ImportError:
|
|||
# python 2.x
|
||||
from distutils.command.build_py import build_py
|
||||
from distutils.command.build_scripts import build_scripts
|
||||
from common.version import version
|
||||
from os.path import isfile, join, isdir
|
||||
import sys
|
||||
from glob import glob
|
||||
|
||||
from fail2ban.version import version
|
||||
|
||||
longdesc = '''
|
||||
Fail2Ban scans log files like /var/log/pwdfail or
|
||||
/var/log/apache/error_log and bans IP that makes
|
||||
|
@ -47,7 +48,7 @@ commands.'''
|
|||
setup(
|
||||
name = "fail2ban",
|
||||
version = version,
|
||||
description = "Ban IPs that make too many password failure",
|
||||
description = "Ban IPs that make too many password failures",
|
||||
long_description = longdesc,
|
||||
author = "Cyril Jaquier",
|
||||
author_email = "cyril.jaquier@fail2ban.org",
|
||||
|
@ -56,15 +57,21 @@ setup(
|
|||
platforms = "Posix",
|
||||
cmdclass = {'build_py': build_py, 'build_scripts': build_scripts},
|
||||
scripts = [
|
||||
'fail2ban-client',
|
||||
'fail2ban-server',
|
||||
'fail2ban-regex'
|
||||
'bin/fail2ban-client',
|
||||
'bin/fail2ban-server',
|
||||
'bin/fail2ban-regex',
|
||||
'bin/fail2ban-testcases',
|
||||
],
|
||||
packages = [
|
||||
'common',
|
||||
'client',
|
||||
'server'
|
||||
'fail2ban',
|
||||
'fail2ban.client',
|
||||
'fail2ban.server',
|
||||
'fail2ban.tests',
|
||||
],
|
||||
package_data = {
|
||||
'fail2ban.tests':
|
||||
['files/*.log', 'files/filter.d/*.conf'],
|
||||
},
|
||||
data_files = [
|
||||
('/etc/fail2ban',
|
||||
glob("config/*.conf")
|
||||
|
|
Loading…
Reference in New Issue