mirror of https://github.com/fail2ban/fail2ban
commit
3ac6166b48
|
@ -22,7 +22,7 @@
|
||||||
Fail2Ban reads log file that contains password failure report
|
Fail2Ban reads log file that contains password failure report
|
||||||
and bans the corresponding IP addresses using firewall rules.
|
and bans the corresponding IP addresses using firewall rules.
|
||||||
|
|
||||||
This tools starts/stops fail2ban server or does client/server communication,
|
This tool starts/stops fail2ban server or does client/server communication
|
||||||
to change/read parameters of the server or jails.
|
to change/read parameters of the server or jails.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -31,7 +31,7 @@ import time
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
# Check if local fail2ban module exists, and use if it exists by
|
# 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
|
# modifying the path. This is done so that tests can be used in dev
|
||||||
# environment.
|
# environment.
|
||||||
if os.path.exists("fail2ban/__init__.py"):
|
if os.path.exists("fail2ban/__init__.py"):
|
||||||
sys.path.insert(0, ".")
|
sys.path.insert(0, ".")
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
# _grep_logs_args = 'test'
|
# _grep_logs_args = 'test'
|
||||||
# (printf %%b "Log-excerpt contains 'test':\n"; %(_grep_logs)s; printf %%b "Log-excerpt contains 'test':\n") | mail ...
|
# (printf %%b "Log-excerpt contains 'test':\n"; %(_grep_logs)s; printf %%b "Log-excerpt contains 'test':\n") | mail ...
|
||||||
#
|
#
|
||||||
_grep_logs = logpath="<logpath>"; grep <grepopts> -E %(_grep_logs_args)s $logpath | <greplimit>
|
_grep_logs = logpath="<logpath>"; grep <grepopts> -E %(_grep_logs_args)s $logpath | <greplimit>
|
||||||
_grep_logs_args = "(^|[^0-9a-fA-F:])$(echo '<ip>' | sed 's/\./\\./g')([^0-9a-fA-F:]|$)"
|
_grep_logs_args = "(^|[^0-9a-fA-F:])$(echo '<ip>' | sed 's/\./\\./g')([^0-9a-fA-F:]|$)"
|
||||||
|
|
||||||
# Used for actions, that should not by executed if ticket was restored:
|
# Used for actions, that should not by executed if ticket was restored:
|
||||||
_bypass_if_restored = if [ '<restored>' = '1' ]; then exit 0; fi;
|
_bypass_if_restored = if [ '<restored>' = '1' ]; then exit 0; fi;
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
greplimit = tail -n <grepmax>
|
greplimit = tail -n <grepmax>
|
||||||
grepmax = 1000
|
grepmax = 1000
|
||||||
grepopts = -m <grepmax>
|
grepopts = -m <grepmax>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
# Author: Yaroslav Halchenko
|
# Author: Yaroslav Halchenko
|
||||||
# Modified: Cyril Jaquier
|
# Modified: Cyril Jaquier
|
||||||
|
|
||||||
__author__ = 'Yaroslav Halhenko, Serg G. Brester (aka sebres)'
|
__author__ = 'Yaroslav Halchenko, Serg G. Brester (aka sebres)'
|
||||||
__copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko, 2015 Serg G. Brester (aka sebres)'
|
__copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko, 2015 Serg G. Brester (aka sebres)'
|
||||||
__license__ = 'GPL'
|
__license__ = 'GPL'
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ class LineStats(object):
|
||||||
class Fail2banRegex(object):
|
class Fail2banRegex(object):
|
||||||
|
|
||||||
def __init__(self, opts):
|
def __init__(self, opts):
|
||||||
# set local protected memebers from given options:
|
# set local protected members from given options:
|
||||||
self.__dict__.update(dict(('_'+o,v) for o,v in opts.__dict__.iteritems()))
|
self.__dict__.update(dict(('_'+o,v) for o,v in opts.__dict__.iteritems()))
|
||||||
self._maxlines_set = False # so we allow to override maxlines in cmdline
|
self._maxlines_set = False # so we allow to override maxlines in cmdline
|
||||||
self._datepattern_set = False
|
self._datepattern_set = False
|
||||||
|
|
|
@ -128,10 +128,10 @@ class Fail2banServer(Fail2banCmdLine):
|
||||||
def getServerPath():
|
def getServerPath():
|
||||||
startdir = sys.path[0]
|
startdir = sys.path[0]
|
||||||
exe = os.path.abspath(os.path.join(startdir, SERVER))
|
exe = os.path.abspath(os.path.join(startdir, SERVER))
|
||||||
if not os.path.isfile(exe): # may be uresolved in test-cases, so get relative starter (client):
|
if not os.path.isfile(exe): # may be unresolved in test-cases, so get relative starter (client):
|
||||||
startdir = os.path.dirname(sys.argv[0])
|
startdir = os.path.dirname(sys.argv[0])
|
||||||
exe = os.path.abspath(os.path.join(startdir, SERVER))
|
exe = os.path.abspath(os.path.join(startdir, SERVER))
|
||||||
if not os.path.isfile(exe): # may be uresolved in test-cases, so try to get relative bin-directory:
|
if not os.path.isfile(exe): # may be unresolved in test-cases, so try to get relative bin-directory:
|
||||||
startdir = os.path.dirname(os.path.abspath(__file__))
|
startdir = os.path.dirname(os.path.abspath(__file__))
|
||||||
startdir = os.path.join(os.path.dirname(os.path.dirname(startdir)), "bin")
|
startdir = os.path.join(os.path.dirname(os.path.dirname(startdir)), "bin")
|
||||||
exe = os.path.abspath(os.path.join(startdir, SERVER))
|
exe = os.path.abspath(os.path.join(startdir, SERVER))
|
||||||
|
|
|
@ -34,7 +34,7 @@ from .server.mytime import MyTime
|
||||||
|
|
||||||
|
|
||||||
PREFER_ENC = locale.getpreferredencoding()
|
PREFER_ENC = locale.getpreferredencoding()
|
||||||
# correct prefered encoding if lang not set in environment:
|
# correct preferred encoding if lang not set in environment:
|
||||||
if PREFER_ENC.startswith('ANSI_'): # pragma: no cover
|
if PREFER_ENC.startswith('ANSI_'): # pragma: no cover
|
||||||
if all((os.getenv(v) in (None, "") for v in ('LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LANG'))):
|
if all((os.getenv(v) in (None, "") for v in ('LANGUAGE', 'LC_ALL', 'LC_CTYPE', 'LANG'))):
|
||||||
PREFER_ENC = 'UTF-8';
|
PREFER_ENC = 'UTF-8';
|
||||||
|
|
|
@ -312,7 +312,7 @@ class CommandAction(ActionBase):
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
if not name.startswith('_') and not self.__init and not callable(value):
|
if not name.startswith('_') and not self.__init and not callable(value):
|
||||||
# special case for some pasrameters:
|
# special case for some parameters:
|
||||||
if name in ('timeout', 'bantime'):
|
if name in ('timeout', 'bantime'):
|
||||||
value = str(MyTime.str2seconds(value))
|
value = str(MyTime.str2seconds(value))
|
||||||
# parameters changed - clear properties and substitution cache:
|
# parameters changed - clear properties and substitution cache:
|
||||||
|
@ -337,7 +337,7 @@ class CommandAction(ActionBase):
|
||||||
def _properties(self):
|
def _properties(self):
|
||||||
"""A dictionary of the actions properties.
|
"""A dictionary of the actions properties.
|
||||||
|
|
||||||
This is used to subsitute "tags" in the commands.
|
This is used to substitute "tags" in the commands.
|
||||||
"""
|
"""
|
||||||
# if we have a properties - return it:
|
# if we have a properties - return it:
|
||||||
if self.__properties is not None:
|
if self.__properties is not None:
|
||||||
|
@ -383,7 +383,7 @@ class CommandAction(ActionBase):
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise RuntimeError("Error %s action %s/%s: %r" % (operation, self._jail, self._name, e))
|
raise RuntimeError("Error %s action %s/%s: %r" % (operation, self._jail, self._name, e))
|
||||||
|
|
||||||
COND_FAMILIES = {'inet4':1, 'inet6':1}
|
COND_FAMILIES = ('inet4', 'inet6')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _startOnDemand(self):
|
def _startOnDemand(self):
|
||||||
|
@ -460,13 +460,13 @@ class CommandAction(ActionBase):
|
||||||
"""Executes the "actionflush" command.
|
"""Executes the "actionflush" command.
|
||||||
|
|
||||||
Command executed in order to flush all bans at once (e. g. by stop/shutdown
|
Command executed in order to flush all bans at once (e. g. by stop/shutdown
|
||||||
the system), instead of unbunning of each single ticket.
|
the system), instead of unbanning of each single ticket.
|
||||||
|
|
||||||
Replaces the tags in the action command with actions properties
|
Replaces the tags in the action command with actions properties
|
||||||
and executes the resulting command.
|
and executes the resulting command.
|
||||||
"""
|
"""
|
||||||
family = []
|
family = []
|
||||||
# cumulate started families, if started on demand (conditional):
|
# collect started families, if started on demand (conditional):
|
||||||
if self._startOnDemand:
|
if self._startOnDemand:
|
||||||
for f in CommandAction.COND_FAMILIES:
|
for f in CommandAction.COND_FAMILIES:
|
||||||
if self.__started.get(f) == 1: # only real started:
|
if self.__started.get(f) == 1: # only real started:
|
||||||
|
@ -482,7 +482,7 @@ class CommandAction(ActionBase):
|
||||||
and executes the resulting command.
|
and executes the resulting command.
|
||||||
"""
|
"""
|
||||||
family = []
|
family = []
|
||||||
# cumulate started families, if started on demand (conditional):
|
# collect started families, if started on demand (conditional):
|
||||||
if self._startOnDemand:
|
if self._startOnDemand:
|
||||||
for f in CommandAction.COND_FAMILIES:
|
for f in CommandAction.COND_FAMILIES:
|
||||||
if self.__started.get(f) == 1: # only real started:
|
if self.__started.get(f) == 1: # only real started:
|
||||||
|
|
|
@ -415,7 +415,7 @@ class Actions(JailThread, Mapping):
|
||||||
diftm = ticket.getTime() - bTicket.getTime()
|
diftm = ticket.getTime() - bTicket.getTime()
|
||||||
# log already banned with following level:
|
# log already banned with following level:
|
||||||
# DEBUG - before 3 seconds - certain interval for it, because of possible latency by recognizing in backends, etc.
|
# DEBUG - before 3 seconds - certain interval for it, because of possible latency by recognizing in backends, etc.
|
||||||
# NOTICE - before 60 seconds - may still occurre if action are slow, or very high load in backend,
|
# NOTICE - before 60 seconds - may still occur if action is slow, or very high load in backend,
|
||||||
# WARNING - after 60 seconds - very long time, something may be wrong
|
# WARNING - after 60 seconds - very long time, something may be wrong
|
||||||
ll = logging.DEBUG if diftm < 3 \
|
ll = logging.DEBUG if diftm < 3 \
|
||||||
else logging.NOTICE if diftm < 60 \
|
else logging.NOTICE if diftm < 60 \
|
||||||
|
|
|
@ -927,11 +927,11 @@ class FileFilter(Filter):
|
||||||
if e.errno != 2: # errno.ENOENT
|
if e.errno != 2: # errno.ENOENT
|
||||||
logSys.exception(e)
|
logSys.exception(e)
|
||||||
return False
|
return False
|
||||||
except OSError as e: # pragma: no cover - requires race condition to tigger this
|
except OSError as e: # pragma: no cover - requires race condition to trigger this
|
||||||
logSys.error("Error opening %s", filename)
|
logSys.error("Error opening %s", filename)
|
||||||
logSys.exception(e)
|
logSys.exception(e)
|
||||||
return False
|
return False
|
||||||
except Exception as e: # pragma: no cover - Requires implemention error in FileContainer to generate
|
except Exception as e: # pragma: no cover - Requires implementation error in FileContainer to generate
|
||||||
logSys.error("Internal error in FileContainer open method - please report as a bug to https://github.com/fail2ban/fail2ban/issues")
|
logSys.error("Internal error in FileContainer open method - please report as a bug to https://github.com/fail2ban/fail2ban/issues")
|
||||||
logSys.exception(e)
|
logSys.exception(e)
|
||||||
return False
|
return False
|
||||||
|
@ -1039,7 +1039,7 @@ class FileFilter(Filter):
|
||||||
movecntr -= 1
|
movecntr -= 1
|
||||||
if movecntr <= 0:
|
if movecntr <= 0:
|
||||||
break
|
break
|
||||||
# we have found large area without any date mached
|
# we have found large area without any date matched
|
||||||
# or end of search - try min position (because can be end of previous line):
|
# or end of search - try min position (because can be end of previous line):
|
||||||
if minp != lastPos:
|
if minp != lastPos:
|
||||||
lastPos = tryPos = minp
|
lastPos = tryPos = minp
|
||||||
|
|
|
@ -158,7 +158,7 @@ class FilterPoll(FileFilter):
|
||||||
self.__prevStats[filename] = stats
|
self.__prevStats[filename] = stats
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# stil alive (may be deleted because multi-threaded):
|
# still alive (may be deleted because multi-threaded):
|
||||||
if not self.getLog(filename) or self.__prevStats.get(filename) is None:
|
if not self.getLog(filename) or self.__prevStats.get(filename) is None:
|
||||||
logSys.warning("Log %r seems to be down: %s", filename, e)
|
logSys.warning("Log %r seems to be down: %s", filename, e)
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -9,5 +9,5 @@ where = conf
|
||||||
failregex = failure <_daemon> <one> (filter.d/test.%(where)s) <HOST>
|
failregex = failure <_daemon> <one> (filter.d/test.%(where)s) <HOST>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
# test parameter, should be overriden in jail by "filter=test[one=1,...]"
|
# test parameter, should be overridden in jail by "filter=test[one=1,...]"
|
||||||
one = *1*
|
one = *1*
|
||||||
|
|
Loading…
Reference in New Issue