mirror of https://github.com/fail2ban/fail2ban
Merge branch 0.10 to 0.11, restores merge-point after rebased PR gh-1866 (mistakenly created and merged on 0.11th base);
commit
aa140f0fa7
25
ChangeLog
25
ChangeLog
|
@ -6,6 +6,31 @@
|
||||||
Fail2Ban: Changelog
|
Fail2Ban: Changelog
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
Incompatibility list (compared to v.0.9):
|
||||||
|
-----------
|
||||||
|
|
||||||
|
* Filter (or `failregex`) internal capture-groups:
|
||||||
|
|
||||||
|
- If you've your own `failregex` or custom filters using conditional match `(?P=host)`, you should
|
||||||
|
rewrite the regex like in example below resp. using `(?:(?P=ip4)|(?P=ip6)` instead of `(?P=host)`
|
||||||
|
(or `(?:(?P=ip4)|(?P=ip6)|(?P=dns))` corresponding your `usedns` and `raw` settings).
|
||||||
|
|
||||||
|
Of course you can always your own capture-group (like below `_cond_ip_`) to do this.
|
||||||
|
```
|
||||||
|
testln="1500000000 failure from 192.0.2.1: bad host 192.0.2.1"
|
||||||
|
fail2ban-regex "$testln" "^\s*failure from (?P<_cond_ip_><HOST>): bad host (?P=_cond_ip_)$"
|
||||||
|
```
|
||||||
|
- New internal groups (currently reserved for internal usage):
|
||||||
|
`ip4`, `ip6`, `dns`, `fid`, `fport`, additionally `user` and another captures in lower case if
|
||||||
|
mapping from tag `<F-*>` used in failregex (e. g. `user` by `<F-USER>`).
|
||||||
|
|
||||||
|
* v.0.10 uses more precise date template handling, that can be theoretically incompatible to some
|
||||||
|
user configurations resp. `datepattern`.
|
||||||
|
|
||||||
|
* Since v0.10 fail2ban supports the matching of the IPv6 addresses, but not all ban actions are
|
||||||
|
IPv6-capable now.
|
||||||
|
|
||||||
|
|
||||||
ver. 0.11.0-dev-0 (2017/??/??) - development nightly edition
|
ver. 0.11.0-dev-0 (2017/??/??) - development nightly edition
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,9 @@ class ActionReader(DefinitionInitConfigReader):
|
||||||
if actname is None:
|
if actname is None:
|
||||||
actname = file_
|
actname = file_
|
||||||
initOpts["actname"] = actname
|
initOpts["actname"] = actname
|
||||||
|
# always supply jail name as name parameter if not specified in options:
|
||||||
|
if initOpts.get("name") is None:
|
||||||
|
initOpts["name"] = jailName
|
||||||
self._name = actname
|
self._name = actname
|
||||||
DefinitionInitConfigReader.__init__(
|
DefinitionInitConfigReader.__init__(
|
||||||
self, file_, jailName, initOpts, **kwargs)
|
self, file_, jailName, initOpts, **kwargs)
|
||||||
|
|
|
@ -231,6 +231,9 @@ class FilterPyinotify(FileFilter):
|
||||||
return True
|
return True
|
||||||
except KeyError: # pragma: no cover
|
except KeyError: # pragma: no cover
|
||||||
pass
|
pass
|
||||||
|
# EnvironmentError is parent of IOError, OSError, etc.
|
||||||
|
except EnvironmentError as e: # pragma: no cover (normally unreached)
|
||||||
|
logSys.error("Remove file monitor for %s causes %s", path, e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _addDirWatcher(self, path_dir):
|
def _addDirWatcher(self, path_dir):
|
||||||
|
@ -249,6 +252,9 @@ class FilterPyinotify(FileFilter):
|
||||||
self.__monitor.rm_watch(wdInt)
|
self.__monitor.rm_watch(wdInt)
|
||||||
except KeyError: # pragma: no cover
|
except KeyError: # pragma: no cover
|
||||||
pass
|
pass
|
||||||
|
# EnvironmentError is parent of IOError, OSError, etc.
|
||||||
|
except EnvironmentError as e: # pragma: no cover (normally unreached)
|
||||||
|
logSys.error("Remove monitor for the parent directory %s causes %s", path_dir, e)
|
||||||
logSys.debug("Removed monitor for the parent directory %s", path_dir)
|
logSys.debug("Removed monitor for the parent directory %s", path_dir)
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -69,10 +69,14 @@ class DNSUtils:
|
||||||
for fam, ipfam in ((socket.AF_INET, IPAddr.FAM_IPv4), (socket.AF_INET6, IPAddr.FAM_IPv6)):
|
for fam, ipfam in ((socket.AF_INET, IPAddr.FAM_IPv4), (socket.AF_INET6, IPAddr.FAM_IPv6)):
|
||||||
try:
|
try:
|
||||||
for result in socket.getaddrinfo(dns, None, fam, 0, socket.IPPROTO_TCP):
|
for result in socket.getaddrinfo(dns, None, fam, 0, socket.IPPROTO_TCP):
|
||||||
ip = IPAddr(result[4][0], ipfam)
|
# if getaddrinfo returns something unexpected:
|
||||||
|
if len(result) < 4 or not len(result[4]): continue
|
||||||
|
# get ip from `(2, 1, 6, '', ('127.0.0.1', 0))`,be sure we've an ip-string
|
||||||
|
# (some python-versions resp. host configurations causes returning of integer there):
|
||||||
|
ip = IPAddr(str(result[4][0]), ipfam)
|
||||||
if ip.isValid:
|
if ip.isValid:
|
||||||
ips.append(ip)
|
ips.append(ip)
|
||||||
except socket.error as e:
|
except Exception as e:
|
||||||
saveerr = e
|
saveerr = e
|
||||||
if not ips and saveerr:
|
if not ips and saveerr:
|
||||||
logSys.warning("Unable to find a corresponding IP address for %s: %s", dns, saveerr)
|
logSys.warning("Unable to find a corresponding IP address for %s: %s", dns, saveerr)
|
||||||
|
|
|
@ -33,7 +33,7 @@ from ..client import configparserinc
|
||||||
from ..client.jailreader import JailReader
|
from ..client.jailreader import JailReader
|
||||||
from ..client.filterreader import FilterReader
|
from ..client.filterreader import FilterReader
|
||||||
from ..client.jailsreader import JailsReader
|
from ..client.jailsreader import JailsReader
|
||||||
from ..client.actionreader import ActionReader
|
from ..client.actionreader import ActionReader, CommandAction
|
||||||
from ..client.configurator import Configurator
|
from ..client.configurator import Configurator
|
||||||
from ..server.mytime import MyTime
|
from ..server.mytime import MyTime
|
||||||
from ..version import version
|
from ..version import version
|
||||||
|
@ -571,7 +571,8 @@ class JailsReaderTest(LogCaptureTestCase):
|
||||||
['set', 'brokenaction', 'addaction', 'brokenaction'],
|
['set', 'brokenaction', 'addaction', 'brokenaction'],
|
||||||
['multi-set', 'brokenaction', 'action', 'brokenaction', [
|
['multi-set', 'brokenaction', 'action', 'brokenaction', [
|
||||||
['actionban', 'hit with big stick <ip>'],
|
['actionban', 'hit with big stick <ip>'],
|
||||||
['actname', 'brokenaction']
|
['actname', 'brokenaction'],
|
||||||
|
['name', 'brokenaction']
|
||||||
]],
|
]],
|
||||||
['add', 'parse_to_end_of_jail.conf', 'auto'],
|
['add', 'parse_to_end_of_jail.conf', 'auto'],
|
||||||
['set', 'parse_to_end_of_jail.conf', 'addfailregex', '<IP>'],
|
['set', 'parse_to_end_of_jail.conf', 'addfailregex', '<IP>'],
|
||||||
|
@ -612,6 +613,16 @@ class JailsReaderTest(LogCaptureTestCase):
|
||||||
# all must have some actionban defined
|
# all must have some actionban defined
|
||||||
self.assertTrue(actionReader._opts.get('actionban', '').strip(),
|
self.assertTrue(actionReader._opts.get('actionban', '').strip(),
|
||||||
msg="Action file %r is lacking actionban" % actionConfig)
|
msg="Action file %r is lacking actionban" % actionConfig)
|
||||||
|
# test name of jail is set in options (also if not supplied within parameters):
|
||||||
|
opts = actionReader.getCombined(
|
||||||
|
ignore=CommandAction._escapedTags | set(('timeout', 'bantime')))
|
||||||
|
self.assertEqual(opts.get('name'), 'TEST',
|
||||||
|
msg="Action file %r does not contains jail-name 'f2b-TEST'" % actionConfig)
|
||||||
|
# and the name is substituted (test several actions surely contains name-interpolation):
|
||||||
|
if actionName in ('pf', 'iptables-allports', 'iptables-multiport'):
|
||||||
|
#print('****', actionName, opts.get('actionstart', ''))
|
||||||
|
self.assertIn('f2b-TEST', opts.get('actionstart', ''),
|
||||||
|
msg="Action file %r: interpolation of actionstart does not contains jail-name 'f2b-TEST'" % actionConfig)
|
||||||
|
|
||||||
def testReadStockJailConf(self):
|
def testReadStockJailConf(self):
|
||||||
jails = JailsReader(basedir=CONFIG_DIR, share_config=CONFIG_DIR_SHARE_CFG) # we are running tests from root project dir atm
|
jails = JailsReader(basedir=CONFIG_DIR, share_config=CONFIG_DIR_SHARE_CFG) # we are running tests from root project dir atm
|
||||||
|
|
|
@ -1852,6 +1852,10 @@ class DNSUtilsNetworkTests(unittest.TestCase):
|
||||||
self.assertTrue(IPAddr("93.184.216.34").isInNet(ips))
|
self.assertTrue(IPAddr("93.184.216.34").isInNet(ips))
|
||||||
self.assertTrue(IPAddr("2606:2800:220:1:248:1893:25c8:1946").isInNet(ips))
|
self.assertTrue(IPAddr("2606:2800:220:1:248:1893:25c8:1946").isInNet(ips))
|
||||||
|
|
||||||
|
def testIPAddr_wrongDNS_IP(self):
|
||||||
|
DNSUtils.dnsToIp('`this`.dns-is-wrong.`wrong-nic`-dummy')
|
||||||
|
DNSUtils.ipToName('*')
|
||||||
|
|
||||||
def testIPAddr_Cached(self):
|
def testIPAddr_Cached(self):
|
||||||
ips = [DNSUtils.dnsToIp('example.com'), DNSUtils.dnsToIp('example.com')]
|
ips = [DNSUtils.dnsToIp('example.com'), DNSUtils.dnsToIp('example.com')]
|
||||||
for ip1, ip2 in zip(ips, ips):
|
for ip1, ip2 in zip(ips, ips):
|
||||||
|
|
Loading…
Reference in New Issue