mirror of https://github.com/fail2ban/fail2ban
Merge branch '0.10' into 0.11
# Conflicts: # config/action.d/firewallcmd-ipset.conf # fail2ban/server/jail.py # fail2ban/tests/servertestcase.pypull/2019/merge
commit
7e5d8f37fd
10
ChangeLog
10
ChangeLog
|
@ -49,6 +49,7 @@ ver. 0.11.0-dev-0 (2017/??/??) - development nightly edition
|
|||
* `action.d/pf.conf`:
|
||||
- fixed syntax error in achnor definition (documentation, see gh-1919);
|
||||
- enclose ports in braces for multiport jails (see gh-1925);
|
||||
* `action.d/firewallcmd-ipset.conf`: fixed create of set for ipv6 (missing `family inet6`, gh-1990)
|
||||
* `filter.d/sshd.conf`: extended failregex for modes "extra"/"aggressive": now finds all possible (also future)
|
||||
forms of "no matching (cipher|mac|MAC|compression method|key exchange method|host key type) found",
|
||||
see "ssherr.c" for all possible SSH_ERR_..._ALG_MATCH errors (gh-1943, gh-1944);
|
||||
|
@ -60,12 +61,21 @@ ver. 0.11.0-dev-0 (2017/??/??) - development nightly edition
|
|||
(corresponds %H, but allows space if not zero-padded).
|
||||
- %l - one- or two-digit number giving the hour of the day (12-11) on a 12-hour clock,
|
||||
(corresponds %I, but allows space if not zero-padded).
|
||||
* `filter.d/exim.conf`: added mode `aggressive` to ban flood resp. DDOS-similar failures (gh-1983);
|
||||
* New Actions:
|
||||
- `action.d/nginx-block-map.conf` - in order to ban not IP-related tickets via nginx (session blacklisting in
|
||||
nginx-location with map-file);
|
||||
|
||||
### Enhancements
|
||||
* jail.conf: extended with new parameter `mode` for the filters supporting it (gh-1988);
|
||||
* action.d/pf.conf: extended with bulk-unban, command `actionflush` in order to flush all bans at once.
|
||||
* Introduced new parameters for logging within fail2ban-server (gh-1980).
|
||||
Usage `logtarget = target[facility=..., datetime=on|off, format="..."]`:
|
||||
- `facility` - specify syslog facility (default `daemon`, see https://docs.python.org/2/library/logging.handlers.html#sysloghandler
|
||||
for the list of facilities);
|
||||
- `datetime` - add date-time to the message (default on, ignored if `format` specified);
|
||||
- `format` - specify own format how it will be logged, for example for short-log into STDOUT:
|
||||
`fail2ban-server -f --logtarget 'stdout[format="%(relativeCreated)5d | %(message)s"]' start`;
|
||||
|
||||
|
||||
ver. 0.10.1 (2017/10/12) - succeeded-before-friday-the-13th
|
||||
|
|
|
@ -18,7 +18,7 @@ before = firewallcmd-common.conf
|
|||
|
||||
[Definition]
|
||||
|
||||
actionstart = ipset create <ipmset> hash:ip
|
||||
actionstart = ipset create <ipmset> hash:ip<familyopt>
|
||||
firewall-cmd --direct --add-rule <family> filter <chain> 0 -p <protocol> -m multiport --dports <port> -m set --match-set <ipmset> src -j <blocktype>
|
||||
|
||||
actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 -p <protocol> -m multiport --dports <port> -m set --match-set <ipmset> src -j <blocktype>
|
||||
|
@ -41,10 +41,12 @@ actionunban = ipset del <ipmset> <ip> -exist
|
|||
chain = INPUT_direct
|
||||
|
||||
ipmset = f2b-<name>
|
||||
familyopt =
|
||||
|
||||
[Init?family=inet6]
|
||||
|
||||
ipmset = f2b-<name>6
|
||||
familyopt = <sp>family inet6
|
||||
|
||||
|
||||
# DEV NOTES:
|
||||
|
|
|
@ -24,6 +24,21 @@ failregex = ^%(pid)s %(host_info)ssender verify fail for <\S+>: (?:Unknown user|
|
|||
^%(pid)s SMTP protocol error in "[^"]+(?:"+[^"]*(?="))*?" %(host_info)sAUTH command used when not advertised\s*$
|
||||
^%(pid)s no MAIL in SMTP connection from (?:[^\[\( ]* )?(?:\(\S*\) )?%(host_info)sD=\d\S*s(?: C=\S*)?\s*$
|
||||
^%(pid)s (?:[\w\-]+ )?SMTP connection from (?:[^\[\( ]* )?(?:\(\S*\) )?%(host_info)sclosed by DROP in ACL\s*$
|
||||
<mdre-<mode>>
|
||||
|
||||
mdre-aggressive = ^%(pid)s no host name found for IP address <HOST>$
|
||||
^%(pid)s no IP address found for host \S+ \(during SMTP connection from \[<HOST>\]\)$
|
||||
|
||||
mdre-normal =
|
||||
|
||||
# Parameter `mode` - `normal` or `aggressive`.
|
||||
# Aggressive mode can be used to match flood and ddos-similar log-entries like:
|
||||
# 'no host found for IP', 'no IP found for host'.
|
||||
# Note this is not an authentication failures, so it may produce lots of false
|
||||
# positives on misconfigured MTAs.
|
||||
# Ex.:
|
||||
# filter = exim[mode=aggressive]
|
||||
mode = normal
|
||||
|
||||
ignoreregex =
|
||||
|
||||
|
|
|
@ -36,10 +36,10 @@ ngx_limit_req_zones = [^"]+
|
|||
# Use following full expression if you should range limit request to specified
|
||||
# servers, requests, referrers etc. only :
|
||||
#
|
||||
# failregex = ^\s*\[error\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
|
||||
# failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
|
||||
|
||||
# Shortly, much faster and stable version of regexp:
|
||||
failregex = ^\s*\[error\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,
|
||||
failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,
|
||||
|
||||
ignoreregex =
|
||||
|
||||
|
|
|
@ -154,10 +154,13 @@ logencoding = auto
|
|||
enabled = false
|
||||
|
||||
|
||||
# "mode" defines the mode of the filter (see corresponding filter implementation for more info).
|
||||
mode = normal
|
||||
|
||||
# "filter" defines the filter to use by the jail.
|
||||
# By default jails have names matching their filter name
|
||||
#
|
||||
filter = %(__name__)s
|
||||
filter = %(__name__)s[mode=%(mode)s]
|
||||
|
||||
|
||||
#
|
||||
|
@ -274,8 +277,7 @@ action = %(action_)s
|
|||
# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
|
||||
# normal (default), ddos, extra or aggressive (combines all).
|
||||
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
|
||||
mode = normal
|
||||
filter = sshd[mode=%(mode)s]
|
||||
#mode = normal
|
||||
port = ssh
|
||||
logpath = %(sshd_log)s
|
||||
backend = %(sshd_backend)s
|
||||
|
@ -573,7 +575,6 @@ backend = %(syslog_backend)s
|
|||
[postfix]
|
||||
# To use another modes set filter parameter "mode" in jail.local:
|
||||
mode = more
|
||||
filter = postfix[mode=%(mode)s]
|
||||
port = smtp,465,submission
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
|
@ -599,8 +600,7 @@ backend = %(syslog_backend)s
|
|||
# To use more aggressive modes set filter parameter "mode" in jail.local:
|
||||
# normal (default), extra or aggressive
|
||||
# See "tests/files/logs/sendmail-reject" or "filter.d/sendmail-reject.conf" for usage example and details.
|
||||
mode = normal
|
||||
filter = sendmail-reject[mode=%(mode)s]
|
||||
#mode = normal
|
||||
port = smtp,465,submission
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
@ -636,7 +636,8 @@ logpath = %(solidpop3d_log)s
|
|||
|
||||
|
||||
[exim]
|
||||
|
||||
# see filter.d/exim.conf for further modes supported from filter:
|
||||
#mode = normal
|
||||
port = smtp,465,submission
|
||||
logpath = %(exim_main_log)s
|
||||
|
||||
|
@ -906,17 +907,14 @@ logpath = /var/log/haproxy.log
|
|||
|
||||
[slapd]
|
||||
port = ldap,ldaps
|
||||
filter = slapd
|
||||
logpath = /var/log/slapd.log
|
||||
|
||||
[domino-smtp]
|
||||
port = smtp,ssmtp
|
||||
filter = domino-smtp
|
||||
logpath = /home/domino01/data/IBM_TECHNICAL_SUPPORT/console.log
|
||||
|
||||
[phpmyadmin-syslog]
|
||||
port = http,https
|
||||
filter = phpmyadmin-syslog
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
|
|
@ -46,12 +46,12 @@ except ImportError:
|
|||
FilterSystemd = None
|
||||
|
||||
from ..version import version
|
||||
from .jailreader import JailReader
|
||||
from .filterreader import FilterReader
|
||||
from ..server.filter import Filter, FileContainer
|
||||
from ..server.failregex import Regex, RegexException
|
||||
|
||||
from ..helpers import str2LogLevel, getVerbosityFormat, FormatterWithTraceBack, getLogger, PREFER_ENC
|
||||
from ..helpers import str2LogLevel, getVerbosityFormat, FormatterWithTraceBack, getLogger, \
|
||||
extractOptions, PREFER_ENC
|
||||
# Gets the instance of the logger.
|
||||
logSys = getLogger("fail2ban")
|
||||
|
||||
|
@ -287,7 +287,7 @@ class Fail2banRegex(object):
|
|||
fltFile = None
|
||||
fltOpt = {}
|
||||
if regextype == 'fail':
|
||||
fltName, fltOpt = JailReader.extractOptions(value)
|
||||
fltName, fltOpt = extractOptions(value)
|
||||
if fltName is not None:
|
||||
if "." in fltName[~5:]:
|
||||
tryNames = (fltName,)
|
||||
|
@ -606,7 +606,7 @@ class Fail2banRegex(object):
|
|||
return False
|
||||
output( "Use systemd journal" )
|
||||
output( "Use encoding : %s" % self._encoding )
|
||||
backend, beArgs = JailReader.extractOptions(cmd_log)
|
||||
backend, beArgs = extractOptions(cmd_log)
|
||||
flt = FilterSystemd(None, **beArgs)
|
||||
flt.setLogEncoding(self._encoding)
|
||||
myjournal = flt.getJournalReader()
|
||||
|
|
|
@ -33,8 +33,7 @@ from .configreader import ConfigReaderUnshared, ConfigReader
|
|||
from .filterreader import FilterReader
|
||||
from .actionreader import ActionReader
|
||||
from ..version import version
|
||||
from ..helpers import getLogger
|
||||
from ..helpers import splitwords
|
||||
from ..helpers import getLogger, extractOptions, splitwords
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = getLogger(__name__)
|
||||
|
@ -42,15 +41,6 @@ logSys = getLogger(__name__)
|
|||
|
||||
class JailReader(ConfigReader):
|
||||
|
||||
# regex, to extract list of options:
|
||||
optionCRE = re.compile(r"^([^\[]+)(?:\[(.*)\])?\s*$", re.DOTALL)
|
||||
# regex, to iterate over single option in option list, syntax:
|
||||
# `action = act[p1="...", p2='...', p3=...]`, where the p3=... not contains `,` or ']'
|
||||
# since v0.10 separator extended with `]\s*[` for support of multiple option groups, syntax
|
||||
# `action = act[p1=...][p2=...]`
|
||||
optionExtractRE = re.compile(
|
||||
r'([\w\-_\.]+)=(?:"([^"]*)"|\'([^\']*)\'|([^,\]]*))(?:,|\]\s*\[|$)', re.DOTALL)
|
||||
|
||||
def __init__(self, name, force_enable=False, **kwargs):
|
||||
ConfigReader.__init__(self, **kwargs)
|
||||
self.__name = name
|
||||
|
@ -141,7 +131,7 @@ class JailReader(ConfigReader):
|
|||
# Read filter
|
||||
flt = self.__opts["filter"]
|
||||
if flt:
|
||||
filterName, filterOpt = JailReader.extractOptions(flt)
|
||||
filterName, filterOpt = extractOptions(flt)
|
||||
if not filterName:
|
||||
raise JailDefError("Invalid filter definition %r" % flt)
|
||||
self.__filter = FilterReader(
|
||||
|
@ -171,7 +161,7 @@ class JailReader(ConfigReader):
|
|||
try:
|
||||
if not act: # skip empty actions
|
||||
continue
|
||||
actName, actOpt = JailReader.extractOptions(act)
|
||||
actName, actOpt = extractOptions(act)
|
||||
if not actName:
|
||||
raise JailDefError("Invalid action definition %r" % act)
|
||||
if actName.endswith(".py"):
|
||||
|
@ -275,22 +265,5 @@ class JailReader(ConfigReader):
|
|||
stream.insert(0, ["add", self.__name, backend])
|
||||
return stream
|
||||
|
||||
@staticmethod
|
||||
def extractOptions(option):
|
||||
match = JailReader.optionCRE.match(option)
|
||||
if not match:
|
||||
# TODO proper error handling
|
||||
return None, None
|
||||
option_name, optstr = match.groups()
|
||||
option_opts = dict()
|
||||
if optstr:
|
||||
for optmatch in JailReader.optionExtractRE.finditer(optstr):
|
||||
opt = optmatch.group(1)
|
||||
value = [
|
||||
val for val in optmatch.group(2,3,4) if val is not None][0]
|
||||
option_opts[opt.strip()] = value.strip()
|
||||
return option_name, option_opts
|
||||
|
||||
|
||||
class JailDefError(Exception):
|
||||
pass
|
||||
|
|
|
@ -237,6 +237,34 @@ else:
|
|||
return uni_decode(x, enc, 'replace')
|
||||
|
||||
|
||||
#
|
||||
# Following function used for parse options from parameter (e.g. `name[p1=0, p2="..."][p3='...']`).
|
||||
#
|
||||
|
||||
# regex, to extract list of options:
|
||||
OPTION_CRE = re.compile(r"^([^\[]+)(?:\[(.*)\])?\s*$", re.DOTALL)
|
||||
# regex, to iterate over single option in option list, syntax:
|
||||
# `action = act[p1="...", p2='...', p3=...]`, where the p3=... not contains `,` or ']'
|
||||
# since v0.10 separator extended with `]\s*[` for support of multiple option groups, syntax
|
||||
# `action = act[p1=...][p2=...]`
|
||||
OPTION_EXTRACT_CRE = re.compile(
|
||||
r'([\w\-_\.]+)=(?:"([^"]*)"|\'([^\']*)\'|([^,\]]*))(?:,|\]\s*\[|$)', re.DOTALL)
|
||||
|
||||
def extractOptions(option):
|
||||
match = OPTION_CRE.match(option)
|
||||
if not match:
|
||||
# TODO proper error handling
|
||||
return None, None
|
||||
option_name, optstr = match.groups()
|
||||
option_opts = dict()
|
||||
if optstr:
|
||||
for optmatch in OPTION_EXTRACT_CRE.finditer(optstr):
|
||||
opt = optmatch.group(1)
|
||||
value = [
|
||||
val for val in optmatch.group(2,3,4) if val is not None][0]
|
||||
option_opts[opt.strip()] = value.strip()
|
||||
return option_name, option_opts
|
||||
|
||||
#
|
||||
# Following facilities used for safe recursive interpolation of
|
||||
# tags (<tag>) in tagged options.
|
||||
|
|
|
@ -29,8 +29,7 @@ import random
|
|||
import Queue
|
||||
|
||||
from .actions import Actions
|
||||
from ..client.jailreader import JailReader
|
||||
from ..helpers import getLogger, MyTime
|
||||
from ..helpers import getLogger, extractOptions, MyTime
|
||||
from .mytime import MyTime
|
||||
|
||||
# Gets the instance of the logger.
|
||||
|
@ -90,7 +89,7 @@ class Jail(object):
|
|||
return "%s(%r)" % (self.__class__.__name__, self.name)
|
||||
|
||||
def _setBackend(self, backend):
|
||||
backend, beArgs = JailReader.extractOptions(backend)
|
||||
backend, beArgs = extractOptions(backend)
|
||||
backend = backend.lower() # to assure consistent matching
|
||||
|
||||
backends = self._BACKENDS
|
||||
|
|
|
@ -38,7 +38,7 @@ from .filter import FileFilter, JournalFilter
|
|||
from .transmitter import Transmitter
|
||||
from .asyncserver import AsyncServer, AsyncServerException
|
||||
from .. import version
|
||||
from ..helpers import getLogger, str2LogLevel, getVerbosityFormat, excepthook
|
||||
from ..helpers import getLogger, extractOptions, str2LogLevel, getVerbosityFormat, excepthook
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = getLogger(__name__)
|
||||
|
@ -577,6 +577,7 @@ class Server:
|
|||
|
||||
def setLogTarget(self, target):
|
||||
# check reserved targets in uppercase, don't change target, because it can be file:
|
||||
target, logOptions = extractOptions(target)
|
||||
systarget = target.upper()
|
||||
with self.__loggingLock:
|
||||
# don't set new handlers if already the same
|
||||
|
@ -589,7 +590,12 @@ class Server:
|
|||
# set a format which is simpler for console use
|
||||
fmt = "%(name)-24s[%(process)d]: %(levelname)-7s %(message)s"
|
||||
if systarget == "SYSLOG":
|
||||
facility = logging.handlers.SysLogHandler.LOG_DAEMON
|
||||
facility = logOptions.get('facility', 'DAEMON').upper()
|
||||
try:
|
||||
facility = getattr(logging.handlers.SysLogHandler, 'LOG_' + facility)
|
||||
except AttributeError: # pragma: no cover
|
||||
logSys.error("Unable to set facility %r, using 'DAEMON'", logOptions.get('facility'))
|
||||
facility = logging.handlers.SysLogHandler.LOG_DAEMON
|
||||
if self.__syslogSocket == "auto":
|
||||
import platform
|
||||
self.__syslogSocket = self.__autoSyslogSocketPaths.get(
|
||||
|
@ -640,9 +646,16 @@ class Server:
|
|||
if self.__verbose is None:
|
||||
self.__verbose = logging.DEBUG - logger.getEffectiveLevel() + 1
|
||||
# If handler don't already add date to the message:
|
||||
addtime = systarget not in ("SYSLOG", "SYSOUT")
|
||||
addtime = logOptions.get('datetime')
|
||||
if addtime is not None:
|
||||
addtime = addtime in ('1', 'on', 'true', 'yes')
|
||||
else:
|
||||
addtime = systarget not in ("SYSLOG", "SYSOUT")
|
||||
# If log-format is redefined in options:
|
||||
if logOptions.get('format', '') != '':
|
||||
fmt = logOptions.get('format')
|
||||
# verbose log-format:
|
||||
if self.__verbose is not None and self.__verbose > 2: # pragma: no cover
|
||||
elif self.__verbose is not None and self.__verbose > 2: # pragma: no cover
|
||||
fmt = getVerbosityFormat(self.__verbose-1,
|
||||
addtime=addtime)
|
||||
elif addtime:
|
||||
|
|
|
@ -30,7 +30,7 @@ import tempfile
|
|||
import unittest
|
||||
from ..client.configreader import ConfigReader, ConfigReaderUnshared, NoSectionError
|
||||
from ..client import configparserinc
|
||||
from ..client.jailreader import JailReader
|
||||
from ..client.jailreader import JailReader, extractOptions
|
||||
from ..client.filterreader import FilterReader
|
||||
from ..client.jailsreader import JailsReader
|
||||
from ..client.actionreader import ActionReader, CommandAction
|
||||
|
@ -260,25 +260,25 @@ class JailReaderTest(LogCaptureTestCase):
|
|||
# Simple example
|
||||
option = "mail-whois[name=SSH]"
|
||||
expected = ('mail-whois', {'name': 'SSH'})
|
||||
result = JailReader.extractOptions(option)
|
||||
result = extractOptions(option)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
self.assertEqual(('mail.who_is', {}), JailReader.extractOptions("mail.who_is"))
|
||||
self.assertEqual(('mail.who_is', {'a':'cat', 'b':'dog'}), JailReader.extractOptions("mail.who_is[a=cat,b=dog]"))
|
||||
self.assertEqual(('mail--ho_is', {}), JailReader.extractOptions("mail--ho_is"))
|
||||
self.assertEqual(('mail.who_is', {}), extractOptions("mail.who_is"))
|
||||
self.assertEqual(('mail.who_is', {'a':'cat', 'b':'dog'}), extractOptions("mail.who_is[a=cat,b=dog]"))
|
||||
self.assertEqual(('mail--ho_is', {}), extractOptions("mail--ho_is"))
|
||||
|
||||
self.assertEqual(('mail--ho_is', {}), JailReader.extractOptions("mail--ho_is['s']"))
|
||||
self.assertEqual(('mail--ho_is', {}), extractOptions("mail--ho_is['s']"))
|
||||
#self.printLog()
|
||||
#self.assertLogged("Invalid argument ['s'] in ''s''")
|
||||
|
||||
self.assertEqual(('mail', {'a': ','}), JailReader.extractOptions("mail[a=',']"))
|
||||
self.assertEqual(('mail', {'a': ','}), extractOptions("mail[a=',']"))
|
||||
|
||||
#self.assertRaises(ValueError, JailReader.extractOptions ,'mail-how[')
|
||||
#self.assertRaises(ValueError, extractOptions ,'mail-how[')
|
||||
|
||||
# Empty option
|
||||
option = "abc[]"
|
||||
expected = ('abc', {})
|
||||
result = JailReader.extractOptions(option)
|
||||
result = extractOptions(option)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
# More complex examples
|
||||
|
@ -296,11 +296,11 @@ class JailReaderTest(LogCaptureTestCase):
|
|||
'opt10': "",
|
||||
'opt11': "",
|
||||
})
|
||||
result = JailReader.extractOptions(option)
|
||||
result = extractOptions(option)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
# And multiple groups (`][` instead of `,`)
|
||||
result = JailReader.extractOptions(option.replace(',', ']['))
|
||||
result = extractOptions(option.replace(',', ']['))
|
||||
expected2 = (expected[0],
|
||||
dict((k, v.replace(',', '][')) for k, v in expected[1].iteritems())
|
||||
)
|
||||
|
@ -439,7 +439,7 @@ class FilterReaderTest(unittest.TestCase):
|
|||
|
||||
def testFilterReaderSubstitionKnown(self):
|
||||
output = [['set', 'jailname', 'addfailregex', 'to=test,sweet@example.com,test2,sweet@example.com fromip=<IP>']]
|
||||
filterName, filterOpt = JailReader.extractOptions(
|
||||
filterName, filterOpt = extractOptions(
|
||||
'substition[honeypot="<sweet>,<known/honeypot>", sweet="test,<known/honeypot>,test2"]')
|
||||
filterReader = FilterReader('substition', "jailname", filterOpt,
|
||||
share_config=TEST_FILES_DIR_SHARE_CFG, basedir=TEST_FILES_DIR)
|
||||
|
@ -650,7 +650,7 @@ class JailsReaderTest(LogCaptureTestCase):
|
|||
if jail == 'INCLUDES':
|
||||
continue
|
||||
filterName = jails.get(jail, 'filter')
|
||||
filterName, filterOpt = JailReader.extractOptions(filterName)
|
||||
filterName, filterOpt = extractOptions(filterName)
|
||||
allFilters.add(filterName)
|
||||
self.assertTrue(len(filterName))
|
||||
# moreover we must have a file for it
|
||||
|
@ -669,7 +669,7 @@ class JailsReaderTest(LogCaptureTestCase):
|
|||
# somewhat duplicating here what is done in JailsReader if
|
||||
# the jail is enabled
|
||||
for act in actions.split('\n'):
|
||||
actName, actOpt = JailReader.extractOptions(act)
|
||||
actName, actOpt = extractOptions(act)
|
||||
self.assertTrue(len(actName))
|
||||
self.assertTrue(isinstance(actOpt, dict))
|
||||
if actName == 'iptables-multiport':
|
||||
|
@ -696,7 +696,7 @@ class JailsReaderTest(LogCaptureTestCase):
|
|||
if not (a.endswith('common.conf') or a.endswith('-aggressive.conf')))
|
||||
# get filters of all jails (filter names without options inside filter[...])
|
||||
filters_jail = set(
|
||||
JailReader.extractOptions(jail.options['filter'])[0] for jail in jails.jails
|
||||
extractOptions(jail.options['filter'])[0] for jail in jails.jails
|
||||
)
|
||||
self.maxDiff = None
|
||||
self.assertTrue(filters.issubset(filters_jail),
|
||||
|
|
|
@ -201,7 +201,7 @@ def _start_params(tmp, use_stock=False, use_stock_cfg=None,
|
|||
_write_file(pjoin(cfg, "fail2ban.conf"), "w",
|
||||
"[Definition]",
|
||||
"loglevel = INFO",
|
||||
"logtarget = " + logtarget,
|
||||
"logtarget = " + logtarget.replace('%', '%%'),
|
||||
"syslogsocket = auto",
|
||||
"socket = " + pjoin(tmp, "f2b.sock"),
|
||||
"pidfile = " + pjoin(tmp, "f2b.pid"),
|
||||
|
@ -767,7 +767,8 @@ class Fail2banServerTest(Fail2banClientServerBase):
|
|||
def testKillAfterStart(self, tmp):
|
||||
try:
|
||||
# to prevent fork of test-cases process, start server in background via command:
|
||||
startparams = _start_params(tmp, logtarget=pjoin(tmp, "f2b.log"))
|
||||
startparams = _start_params(tmp, logtarget=pjoin(tmp,
|
||||
'f2b.log[format="SRV: %(relativeCreated)3d | %(message)s", datetime=off]'))
|
||||
# start (in new process, using the same python version):
|
||||
cmd = (sys.executable, pjoin(BIN, SERVER))
|
||||
logSys.debug('Start %s ...', cmd)
|
||||
|
|
|
@ -83,3 +83,17 @@
|
|||
2017-11-28 14:14:31 SMTP protocol error in "aUtH lOgIn" H=(roxzgj) [192.0.2.5] AUTH command used when not advertised
|
||||
# failJSON: { "time": "2017-11-28T14:14:32", "match": true , "host": "192.0.2.6", "desc": "quoted injecting on AUTH command" }
|
||||
2017-11-28 14:14:32 SMTP protocol error in "aUtH lOgIn" H=(test) [8.8.8.8]" H=(roxzgj) [192.0.2.6] AUTH command used when not advertised
|
||||
|
||||
## no matches with `mode = normal`:
|
||||
|
||||
# failJSON: { "match": false , "desc": "aggressive mode only" }
|
||||
2017-12-03 08:32:00 no host name found for IP address 192.0.2.8
|
||||
# failJSON: { "match": false , "desc": "aggressive mode only" }
|
||||
2017-12-03 08:51:35 no IP address found for host test.example.com (during SMTP connection from [192.0.2.9])
|
||||
|
||||
# filterOptions: [{"mode": "aggressive"}]
|
||||
|
||||
# failJSON: { "time": "2017-12-03T08:32:00", "match": true , "host": "192.0.2.8", "desc": "no host found for IP" }
|
||||
2017-12-03 08:32:00 no host name found for IP address 192.0.2.8
|
||||
# failJSON: { "time": "2017-12-03T08:51:35", "match": true , "host": "192.0.2.9", "desc": "no IP found for host" }
|
||||
2017-12-03 08:51:35 no IP address found for host test.example.com (during SMTP connection from [192.0.2.9])
|
||||
|
|
|
@ -42,7 +42,7 @@ from ..server.ticket import BanTicket
|
|||
from ..server.utils import Utils
|
||||
from .dummyjail import DummyJail
|
||||
from .utils import LogCaptureTestCase
|
||||
from ..helpers import getLogger, PREFER_ENC
|
||||
from ..helpers import getLogger, extractOptions, PREFER_ENC
|
||||
from .. import version
|
||||
|
||||
try:
|
||||
|
@ -831,8 +831,8 @@ class TransmitterLogging(TransmitterBase):
|
|||
for logTarget in logTargets:
|
||||
os.remove(logTarget)
|
||||
|
||||
self.setGetTest("logtarget", "STDOUT")
|
||||
self.setGetTest("logtarget", "STDERR")
|
||||
self.setGetTest("logtarget", 'STDOUT[format="%(message)s"]', 'STDOUT')
|
||||
self.setGetTest("logtarget", 'STDERR[datetime=off]', 'STDERR')
|
||||
|
||||
def testLogTargetSYSLOG(self):
|
||||
if not os.path.exists("/dev/log"):
|
||||
|
@ -1043,7 +1043,7 @@ class LoggingTests(LogCaptureTestCase):
|
|||
os.remove(f)
|
||||
|
||||
|
||||
from clientreadertestcase import ActionReader, JailReader, JailsReader, CONFIG_DIR, STOCK
|
||||
from clientreadertestcase import ActionReader, JailsReader, CONFIG_DIR, STOCK
|
||||
|
||||
class ServerConfigReaderTests(LogCaptureTestCase):
|
||||
|
||||
|
@ -1166,7 +1166,7 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
|||
|
||||
def getDefaultJailStream(self, jail, act):
|
||||
act = act.replace('%(__name__)s', jail)
|
||||
actName, actOpt = JailReader.extractOptions(act)
|
||||
actName, actOpt = extractOptions(act)
|
||||
stream = [
|
||||
['add', jail, 'polling'],
|
||||
# ['set', jail, 'addfailregex', 'DUMMY-REGEX <HOST>'],
|
||||
|
@ -1674,7 +1674,7 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
|||
"`firewall-cmd --direct --add-rule ipv4 filter INPUT_direct 0 -p tcp -m multiport --dports http -m set --match-set f2b-j-w-fwcmd-ipset src -j REJECT --reject-with icmp-port-unreachable`",
|
||||
),
|
||||
'ip6-start': (
|
||||
"`ipset create f2b-j-w-fwcmd-ipset6 hash:ip`",
|
||||
"`ipset create f2b-j-w-fwcmd-ipset6 hash:ip family inet6`",
|
||||
"`firewall-cmd --direct --add-rule ipv6 filter INPUT_direct 0 -p tcp -m multiport --dports http -m set --match-set f2b-j-w-fwcmd-ipset6 src -j REJECT --reject-with icmp6-port-unreachable`",
|
||||
),
|
||||
'stop': (
|
||||
|
|
Loading…
Reference in New Issue