From b28dfb965a373e9a67add2f51b659bc1b95fd944 Mon Sep 17 00:00:00 2001 From: Yannik Sembritzki Date: Wed, 3 Jan 2018 18:39:30 +0100 Subject: [PATCH 01/13] Fix filter not catching asterisk requests with quote character in username (fixes #2010) --- config/filter.d/asterisk.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/filter.d/asterisk.conf b/config/filter.d/asterisk.conf index e94754c0..5ebbe92b 100644 --- a/config/filter.d/asterisk.conf +++ b/config/filter.d/asterisk.conf @@ -25,7 +25,7 @@ failregex = ^%(__prefix_line)s%(log_prefix)s Registration from '[^']*' failed fo ^%(__prefix_line)s%(log_prefix)s hacking attempt detected ''$ ^%(__prefix_line)s%(log_prefix)s SecurityEvent="(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)"(?:(?:,(?!RemoteAddress=)\w+="[^"]*")*|.*?),RemoteAddress="IPV[46]/(UDP|TCP|WS)//\d+"(?:,(?!RemoteAddress=)\w+="[^"]*")*$ ^%(__prefix_line)s%(log_prefix)s "Rejecting unknown SIP connection from "$ - ^%(__prefix_line)s%(log_prefix)s Request (?:'[^']*' )?from '[^']*' failed for '(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$ + ^%(__prefix_line)s%(log_prefix)s Request (?:'[^']*' )?from '.*' failed for '(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$ # FreePBX (todo: make optional in v.0.10): # ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )[^:]+: Friendly Scanner from $ From a53ee46ad465230f002b1eb998437fd4ddd7ca3b Mon Sep 17 00:00:00 2001 From: Yannik Sembritzki Date: Wed, 3 Jan 2018 18:48:11 +0100 Subject: [PATCH 02/13] add test for asterisk pjsip attack with quote in username --- fail2ban/tests/files/logs/asterisk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fail2ban/tests/files/logs/asterisk b/fail2ban/tests/files/logs/asterisk index 837011e0..523631f6 100644 --- a/fail2ban/tests/files/logs/asterisk +++ b/fail2ban/tests/files/logs/asterisk @@ -80,9 +80,8 @@ Nov 4 18:30:40 localhost asterisk[32229]: NOTICE[32257]: chan_sip.c:23417 in han [2016-05-23 10:18:16] NOTICE[19388] res_pjsip/pjsip_distributor.c: Request from '"1000" ' failed for '1.2.3.4:48336' (callid: 276666022) - Failed to authenticate # failJSON: { "time": "2016-05-23T10:18:16", "match": true , "host": "1.2.3.4" } [2016-05-23 10:18:16] NOTICE[19388] res_pjsip/pjsip_distributor.c: Request from '"1000" ' failed for '1.2.3.4:48336' (callid: 276666022) - Error to authenticate -# Failed authentication with pjsip on Asterisk 13+ -# failJSON: { "time": "2016-06-08T23:40:26", "match": true , "host": "2.3.4.5" } -[2016-06-08 23:40:26] NOTICE[32497] res_pjsip/pjsip_distributor.c: Request from '"317" ' failed for '2.3.4.5:5089' (callid: 206f178f-896564cb-57573f49@1.2.3.4) - No matching endpoint found +# failJSON: { "time": "2017-12-14T22:18:00", "match": true , "host": "1.2.3.4" } +[2017-12-14 22:18:00] NOTICE[1943] res_pjsip/pjsip_distributor.c: Request 'INVITE' from '' failed for '185.107.94.10:43678' (callid: UmOkE9yQPGOsF3Az24YTRe..) - No matching endpoint found # failJSON: { "time": "2016-06-09T00:01:02", "match": true , "host": "192.0.2.1" } [2016-06-09 00:01:02] NOTICE [22382] manager.c: 192.0.2.1 failed to authenticate as 'admin' From 184202c6aaaa62fd28f3b7cd677b9edc371d4ffd Mon Sep 17 00:00:00 2001 From: Yannik Sembritzki Date: Wed, 3 Jan 2018 18:49:38 +0100 Subject: [PATCH 03/13] remove duplicate testcase --- fail2ban/tests/files/logs/asterisk | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fail2ban/tests/files/logs/asterisk b/fail2ban/tests/files/logs/asterisk index 523631f6..27535db0 100644 --- a/fail2ban/tests/files/logs/asterisk +++ b/fail2ban/tests/files/logs/asterisk @@ -92,10 +92,6 @@ Nov 4 18:30:40 localhost asterisk[32229]: NOTICE[32257]: chan_sip.c:23417 in han # failJSON: { "time": "2016-05-06T07:08:09", "match": true, "host": "192.0.2.5" } [2016-05-06 07:08:09] NOTICE[6772] manager.c: 192.0.2.5 failed to authenticate as 'Admin' -# PJSip Errors -# failJSON: { "time": "2016-05-06T07:08:09", "match": true, "host": "192.0.2.6" } -[2016-05-06 07:08:09] NOTICE[17103] res_pjsip/pjsip_distributor.c: Request from '"test1" ' failed for '192.0.2.6:5678' (callid: deadbeef) - No matching endpoint found - # # FreePBX Warnings # #_dis_failJSON: { "time": "2016-05-06T07:08:09", "match": true, "host": "192.0.2.4" } # [2016-05-06 07:08:09] WARNING[6410][C-00000bac] Ext. 50048943556071: Friendly Scanner from 192.0.2.4 From eaf5e88692499fb91adb52a41d6d95add4a37515 Mon Sep 17 00:00:00 2001 From: Yannik Sembritzki Date: Wed, 3 Jan 2018 19:00:09 +0100 Subject: [PATCH 04/13] replace actual offenders ip with 1.2.3.4 --- fail2ban/tests/files/logs/asterisk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fail2ban/tests/files/logs/asterisk b/fail2ban/tests/files/logs/asterisk index 27535db0..f5f4d419 100644 --- a/fail2ban/tests/files/logs/asterisk +++ b/fail2ban/tests/files/logs/asterisk @@ -81,7 +81,7 @@ Nov 4 18:30:40 localhost asterisk[32229]: NOTICE[32257]: chan_sip.c:23417 in han # failJSON: { "time": "2016-05-23T10:18:16", "match": true , "host": "1.2.3.4" } [2016-05-23 10:18:16] NOTICE[19388] res_pjsip/pjsip_distributor.c: Request from '"1000" ' failed for '1.2.3.4:48336' (callid: 276666022) - Error to authenticate # failJSON: { "time": "2017-12-14T22:18:00", "match": true , "host": "1.2.3.4" } -[2017-12-14 22:18:00] NOTICE[1943] res_pjsip/pjsip_distributor.c: Request 'INVITE' from '' failed for '185.107.94.10:43678' (callid: UmOkE9yQPGOsF3Az24YTRe..) - No matching endpoint found +[2017-12-14 22:18:00] NOTICE[1943] res_pjsip/pjsip_distributor.c: Request 'INVITE' from '' failed for '1.2.3.4:43678' (callid: UmOkE9yQPGOsF3Az24YTRe..) - No matching endpoint found # failJSON: { "time": "2016-06-09T00:01:02", "match": true , "host": "192.0.2.1" } [2016-06-09 00:01:02] NOTICE [22382] manager.c: 192.0.2.1 failed to authenticate as 'admin' From 94f0b15c320f007a9cd7cce97d12f45318b5553d Mon Sep 17 00:00:00 2001 From: Yannik Sembritzki Date: Mon, 8 Jan 2018 14:54:32 +0100 Subject: [PATCH 05/13] Allow faster parsing of hosts without ' characters in them --- config/filter.d/asterisk.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/filter.d/asterisk.conf b/config/filter.d/asterisk.conf index 5ebbe92b..0cb1b70a 100644 --- a/config/filter.d/asterisk.conf +++ b/config/filter.d/asterisk.conf @@ -25,7 +25,7 @@ failregex = ^%(__prefix_line)s%(log_prefix)s Registration from '[^']*' failed fo ^%(__prefix_line)s%(log_prefix)s hacking attempt detected ''$ ^%(__prefix_line)s%(log_prefix)s SecurityEvent="(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)"(?:(?:,(?!RemoteAddress=)\w+="[^"]*")*|.*?),RemoteAddress="IPV[46]/(UDP|TCP|WS)//\d+"(?:,(?!RemoteAddress=)\w+="[^"]*")*$ ^%(__prefix_line)s%(log_prefix)s "Rejecting unknown SIP connection from "$ - ^%(__prefix_line)s%(log_prefix)s Request (?:'[^']*' )?from '.*' failed for '(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$ + ^%(__prefix_line)s%(log_prefix)s Request (?:'[^']*' )?from '(?:[^']*|.*?)' failed for '(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$ # FreePBX (todo: make optional in v.0.10): # ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )[^:]+: Friendly Scanner from $ From aab54bb0dde72831fb85660304b0a320e5f8da2c Mon Sep 17 00:00:00 2001 From: Yannik Sembritzki Date: Mon, 8 Jan 2018 22:29:43 +0100 Subject: [PATCH 06/13] don't replace normal test case with specialized test case --- fail2ban/tests/files/logs/asterisk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fail2ban/tests/files/logs/asterisk b/fail2ban/tests/files/logs/asterisk index f5f4d419..5e68772a 100644 --- a/fail2ban/tests/files/logs/asterisk +++ b/fail2ban/tests/files/logs/asterisk @@ -80,6 +80,8 @@ Nov 4 18:30:40 localhost asterisk[32229]: NOTICE[32257]: chan_sip.c:23417 in han [2016-05-23 10:18:16] NOTICE[19388] res_pjsip/pjsip_distributor.c: Request from '"1000" ' failed for '1.2.3.4:48336' (callid: 276666022) - Failed to authenticate # failJSON: { "time": "2016-05-23T10:18:16", "match": true , "host": "1.2.3.4" } [2016-05-23 10:18:16] NOTICE[19388] res_pjsip/pjsip_distributor.c: Request from '"1000" ' failed for '1.2.3.4:48336' (callid: 276666022) - Error to authenticate +# failJSON: { "time": "2016-06-08T23:40:26", "match": true , "host": "2.3.4.5" } +[2016-06-08 23:40:26] NOTICE[32497] res_pjsip/pjsip_distributor.c: Request from '"317" ' failed for '2.3.4.5:5089' (callid: 206f178f-896564cb-57573f49@1.2.3.4) - No matching endpoint found # failJSON: { "time": "2017-12-14T22:18:00", "match": true , "host": "1.2.3.4" } [2017-12-14 22:18:00] NOTICE[1943] res_pjsip/pjsip_distributor.c: Request 'INVITE' from '' failed for '1.2.3.4:43678' (callid: UmOkE9yQPGOsF3Az24YTRe..) - No matching endpoint found From a1d1498561fdfea527d44c8fc75f69e27b6d5a1f Mon Sep 17 00:00:00 2001 From: "Serg G. Brester" Date: Tue, 9 Jan 2018 21:13:02 +0100 Subject: [PATCH 07/13] Restore log-entries not affected by #2011 --- fail2ban/tests/files/logs/asterisk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fail2ban/tests/files/logs/asterisk b/fail2ban/tests/files/logs/asterisk index 5e68772a..0955cfe7 100644 --- a/fail2ban/tests/files/logs/asterisk +++ b/fail2ban/tests/files/logs/asterisk @@ -81,7 +81,7 @@ Nov 4 18:30:40 localhost asterisk[32229]: NOTICE[32257]: chan_sip.c:23417 in han # failJSON: { "time": "2016-05-23T10:18:16", "match": true , "host": "1.2.3.4" } [2016-05-23 10:18:16] NOTICE[19388] res_pjsip/pjsip_distributor.c: Request from '"1000" ' failed for '1.2.3.4:48336' (callid: 276666022) - Error to authenticate # failJSON: { "time": "2016-06-08T23:40:26", "match": true , "host": "2.3.4.5" } -[2016-06-08 23:40:26] NOTICE[32497] res_pjsip/pjsip_distributor.c: Request from '"317" ' failed for '2.3.4.5:5089' (callid: 206f178f-896564cb-57573f49@1.2.3.4) - No matching endpoint found +[2016-06-08 23:40:26] NOTICE[32497] res_pjsip/pjsip_distributor.c: Request from '"317" ' failed for '2.3.4.5:5089' (callid: 206f178f-896564cb-57573f49@1.2.3.4) - No matching endpoint found # failJSON: { "time": "2017-12-14T22:18:00", "match": true , "host": "1.2.3.4" } [2017-12-14 22:18:00] NOTICE[1943] res_pjsip/pjsip_distributor.c: Request 'INVITE' from '' failed for '1.2.3.4:43678' (callid: UmOkE9yQPGOsF3Az24YTRe..) - No matching endpoint found @@ -94,6 +94,10 @@ Nov 4 18:30:40 localhost asterisk[32229]: NOTICE[32257]: chan_sip.c:23417 in han # failJSON: { "time": "2016-05-06T07:08:09", "match": true, "host": "192.0.2.5" } [2016-05-06 07:08:09] NOTICE[6772] manager.c: 192.0.2.5 failed to authenticate as 'Admin' +# PJSip Errors +# failJSON: { "time": "2016-05-06T07:08:09", "match": true, "host": "192.0.2.6" } +[2016-05-06 07:08:09] NOTICE[17103] res_pjsip/pjsip_distributor.c: Request from '"test1" ' failed for '192.0.2.6:5678' (callid: deadbeef) - No matching endpoint found + # # FreePBX Warnings # #_dis_failJSON: { "time": "2016-05-06T07:08:09", "match": true, "host": "192.0.2.4" } # [2016-05-06 07:08:09] WARNING[6410][C-00000bac] Ext. 50048943556071: Friendly Scanner from 192.0.2.4 From f7e2d3610bb98d4dc01076811bd393b11e8c5f4f Mon Sep 17 00:00:00 2001 From: "Serg G. Brester" Date: Tue, 9 Jan 2018 21:19:01 +0100 Subject: [PATCH 08/13] Update ChangeLog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 1010d6d7..1917f079 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,7 @@ releases. - fixed failregex AMI Asterisk authentification failed (see gh-1302) - removed invalid (vulnerable) regex blocking IPs using forign data (from header "from") thus not the IP-address that really originates the request (see gh-1927) + - fixed failregex for the SQL-injection attempts with single-quotes in connect-string (see gh-2011) * filter.d/dovecot.conf: - fixed failregex, see gh-1879 (partially cherry-picked from gh-1880) - extended to match pam_authenticate failures with "Permission denied" (gh-1897) From 3d9a112c8f5369102592c752fd7c2bd1cb395ebc Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 Jan 2018 10:55:19 +0100 Subject: [PATCH 09/13] cherry-pick newer version of extractOptions, in order to avoid large discrepancy between 0.10 and 0.9 config-parsers: allow to use dual parameter lists (coming through substitutions), e. g.: `name[p1=0, p2="..."][p3='...']`; simplified explanation: `][` treats as `,` in new version. cherry-picked from 0.10. --- fail2ban/client/jailreader.py | 27 ++++----------------------- fail2ban/helpers.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/fail2ban/client/jailreader.py b/fail2ban/client/jailreader.py index 5725f606..fcaffe21 100644 --- a/fail2ban/client/jailreader.py +++ b/fail2ban/client/jailreader.py @@ -27,14 +27,13 @@ __license__ = "GPL" import glob import json import os.path -import re 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 extractOptions, splitwords # Gets the instance of the logger. logSys = getLogger(__name__) @@ -42,10 +41,6 @@ logSys = getLogger(__name__) class JailReader(ConfigReader): - optionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$") - optionExtractRE = re.compile( - r'([\w\-_\.]+)=(?:"([^"]*)"|\'([^\']*)\'|([^,]*))(?:,|$)') - def __init__(self, name, force_enable=False, **kwargs): ConfigReader.__init__(self, **kwargs) self.__name = name @@ -121,7 +116,7 @@ class JailReader(ConfigReader): if self.isEnabled(): # Read filter if self.__opts["filter"]: - filterName, filterOpt = JailReader.extractOptions( + filterName, filterOpt = extractOptions( self.__opts["filter"]) self.__filter = FilterReader( filterName, self.__name, filterOpt, share_config=self.share_config, basedir=self.getBaseDir()) @@ -150,7 +145,7 @@ class JailReader(ConfigReader): try: if not act: # skip empty actions continue - actName, actOpt = JailReader.extractOptions(act) + actName, actOpt = extractOptions(act) if actName.endswith(".py"): self.__actions.append([ "set", @@ -244,18 +239,4 @@ 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 +JailReader.extractOptions = staticmethod(extractOptions) diff --git a/fail2ban/helpers.py b/fail2ban/helpers.py index aef39835..4443a672 100644 --- a/fail2ban/helpers.py +++ b/fail2ban/helpers.py @@ -137,3 +137,32 @@ def splitwords(s): if not s: return [] return filter(bool, map(str.strip, re.split('[ ,\n]+', s))) + + +# +# 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 From c190631f8842b884199354f34f0ad8caf02051a2 Mon Sep 17 00:00:00 2001 From: Danila Vershinin Date: Thu, 5 Oct 2017 18:26:11 +0300 Subject: [PATCH 10/13] New ban action firewallcmd-ipset-allports. Closes #1167 --- ChangeLog | 1 + .../action.d/firewallcmd-ipset-allports.conf | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 config/action.d/firewallcmd-ipset-allports.conf diff --git a/ChangeLog b/ChangeLog index 1917f079..1cdb28b7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -47,6 +47,7 @@ releases. * filter.d/kerio.conf - filter extended with new rules (see gh-1455) * filter.d/phpmyadmin-syslog.conf - new filter for phpMyAdmin using syslog for auth logging * filter.d/zoneminder.conf - new filter for ZoneMinder (gh-1376) +* action.d/firewallcmd-ipset-allports.conf - new firewallcmd-ipset-allports action (gh-1167) ver. 0.9.7 (2017/05/11) - awaiting-victory diff --git a/config/action.d/firewallcmd-ipset-allports.conf b/config/action.d/firewallcmd-ipset-allports.conf new file mode 100644 index 00000000..eb940ee0 --- /dev/null +++ b/config/action.d/firewallcmd-ipset-allports.conf @@ -0,0 +1,51 @@ +# Fail2Ban action file for firewall-cmd/ipset +# +# This requires: +# ipset (package: ipset) +# firewall-cmd (package: firewalld) +# +# This is for ipset protocol 6 (and hopefully later) (ipset v6.14). +# Use ipset -V to see the protocol and version. +# +# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels. +# +# If you are running on an older kernel you make need to patch in external +# modules. + +[INCLUDES] + +before = iptables-common.conf + +[Definition] + +actionstart = ipset create fail2ban- hash:ip timeout + firewall-cmd --direct --add-rule ipv4 filter 0 -m set --match-set fail2ban- src -j + +actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m set --match-set fail2ban- src -j + ipset flush fail2ban- + ipset destroy fail2ban- + +actionban = ipset add fail2ban- timeout -exist + +actionunban = ipset del fail2ban- -exist + +[Init] + +# Option: chain +# Notes specifies the iptables chain to which the fail2ban rules should be +# added +# Values: [ STRING ] +# +chain = INPUT_direct + +# Option: bantime +# Notes: specifies the bantime in seconds (handled internally rather than by fail2ban) +# Values: [ NUM ] Default: 600 + +bantime = 600 + + +# DEV NOTES: +# +# Author: Edgar Hoch and Daniel Black +# firewallcmd-new / iptables-ipset-proto6 combined for maximium goodness \ No newline at end of file From 131b94e11e6a1e05655aad31458556ab2529f24d Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 Jan 2018 10:11:11 +0100 Subject: [PATCH 11/13] firewallcmd-ipset-allports: implemented in `action.d/firewallcmd-ipset.conf` now (`action.d/firewallcmd-ipset-allports.conf` removed), usage: banaction = firewallcmd-ipset[actiontype=""] --- .../action.d/firewallcmd-ipset-allports.conf | 51 ------------------- config/action.d/firewallcmd-ipset.conf | 21 +++++++- 2 files changed, 19 insertions(+), 53 deletions(-) delete mode 100644 config/action.d/firewallcmd-ipset-allports.conf diff --git a/config/action.d/firewallcmd-ipset-allports.conf b/config/action.d/firewallcmd-ipset-allports.conf deleted file mode 100644 index eb940ee0..00000000 --- a/config/action.d/firewallcmd-ipset-allports.conf +++ /dev/null @@ -1,51 +0,0 @@ -# Fail2Ban action file for firewall-cmd/ipset -# -# This requires: -# ipset (package: ipset) -# firewall-cmd (package: firewalld) -# -# This is for ipset protocol 6 (and hopefully later) (ipset v6.14). -# Use ipset -V to see the protocol and version. -# -# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels. -# -# If you are running on an older kernel you make need to patch in external -# modules. - -[INCLUDES] - -before = iptables-common.conf - -[Definition] - -actionstart = ipset create fail2ban- hash:ip timeout - firewall-cmd --direct --add-rule ipv4 filter 0 -m set --match-set fail2ban- src -j - -actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m set --match-set fail2ban- src -j - ipset flush fail2ban- - ipset destroy fail2ban- - -actionban = ipset add fail2ban- timeout -exist - -actionunban = ipset del fail2ban- -exist - -[Init] - -# Option: chain -# Notes specifies the iptables chain to which the fail2ban rules should be -# added -# Values: [ STRING ] -# -chain = INPUT_direct - -# Option: bantime -# Notes: specifies the bantime in seconds (handled internally rather than by fail2ban) -# Values: [ NUM ] Default: 600 - -bantime = 600 - - -# DEV NOTES: -# -# Author: Edgar Hoch and Daniel Black -# firewallcmd-new / iptables-ipset-proto6 combined for maximium goodness \ No newline at end of file diff --git a/config/action.d/firewallcmd-ipset.conf b/config/action.d/firewallcmd-ipset.conf index 38b0f3d3..62b6e7c2 100644 --- a/config/action.d/firewallcmd-ipset.conf +++ b/config/action.d/firewallcmd-ipset.conf @@ -19,9 +19,9 @@ before = iptables-common.conf [Definition] actionstart = ipset create fail2ban- hash:ip timeout - firewall-cmd --direct --add-rule ipv4 filter 0 -p -m multiport --dports -m set --match-set fail2ban- src -j + firewall-cmd --direct --add-rule ipv4 filter 0 -m set --match-set fail2ban- src -j -actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -p -m multiport --dports -m set --match-set fail2ban- src -j +actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m set --match-set fail2ban- src -j ipset flush fail2ban- ipset destroy fail2ban- @@ -44,6 +44,23 @@ chain = INPUT_direct bantime = 600 +# Option: actiontype +# Notes.: defines additions to the blocking rule +# Values: leave empty to block all attempts from the host +# Default: Value of the multiport +actiontype = + +# Option: allports +# Notes.: default addition to block all ports +# Usage.: use in jail config: banaction = firewallcmd-ipset[actiontype=] +# for all protocols: banaction = firewallcmd-ipset[actiontype=""] +allports = -p + +# Option: multiport +# Notes.: addition to block access only to specific ports +# Usage.: use in jail config: banaction = firewallcmd-ipset[actiontype=] +multiport = -p -m multiport --dports + # DEV NOTES: # From 029cd5aa24be005f840d35271e31546da61015e5 Mon Sep 17 00:00:00 2001 From: "Serg G. Brester" Date: Wed, 10 Jan 2018 11:47:59 +0100 Subject: [PATCH 12/13] Update ChangeLog --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1cdb28b7..49a34e02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -44,10 +44,10 @@ releases. ### Enhancements * action.d/cloudflare.conf - Cloudflare API v4 implementation (gh-1651) +* action.d/firewallcmd-ipset.conf - new parameter `actiontype`, provides `allports` capability (gh-1167) * filter.d/kerio.conf - filter extended with new rules (see gh-1455) * filter.d/phpmyadmin-syslog.conf - new filter for phpMyAdmin using syslog for auth logging * filter.d/zoneminder.conf - new filter for ZoneMinder (gh-1376) -* action.d/firewallcmd-ipset-allports.conf - new firewallcmd-ipset-allports action (gh-1167) ver. 0.9.7 (2017/05/11) - awaiting-victory From c36fbdf743c94fbc6bf5cc4da58a1d7298a94809 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 Jan 2018 12:13:07 +0100 Subject: [PATCH 13/13] test cases extended in order to cover `firewallcmd-ipset` with `allports` --- fail2ban/tests/servertestcase.py | 40 +++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/fail2ban/tests/servertestcase.py b/fail2ban/tests/servertestcase.py index 39601db9..a5e93d2d 100644 --- a/fail2ban/tests/servertestcase.py +++ b/fail2ban/tests/servertestcase.py @@ -1645,7 +1645,7 @@ class ServerConfigReaderTests(LogCaptureTestCase): r"`firewall-cmd --direct --remove-rule ipv6 filter f2b-j-w-fwcmd-ap 0 -s 2001:db8:: -j REJECT --reject-with icmp6-port-unreachable`", ), }), - # firewallcmd-ipset -- + # firewallcmd-ipset (multiport) -- ('j-w-fwcmd-ipset', 'firewallcmd-ipset[name=%(__name__)s, bantime="10m", port="http", protocol="tcp", chain=""]', { 'ip4': (' f2b-j-w-fwcmd-ipset ',), 'ip6': (' f2b-j-w-fwcmd-ipset6 ',), 'ip4-start': ( @@ -1683,6 +1683,44 @@ class ServerConfigReaderTests(LogCaptureTestCase): r"`ipset del f2b-j-w-fwcmd-ipset6 2001:db8:: -exist`", ), }), + # firewallcmd-ipset (allports) -- + ('j-w-fwcmd-ipset-ap', 'firewallcmd-ipset[name=%(__name__)s, bantime="10m", actiontype=, protocol="tcp", chain=""]', { + 'ip4': (' f2b-j-w-fwcmd-ipset-ap ',), 'ip6': (' f2b-j-w-fwcmd-ipset-ap6 ',), + 'ip4-start': ( + "`ipset create f2b-j-w-fwcmd-ipset-ap hash:ip timeout 600`", + "`firewall-cmd --direct --add-rule ipv4 filter INPUT_direct 0 -p tcp -m set --match-set f2b-j-w-fwcmd-ipset-ap src -j REJECT --reject-with icmp-port-unreachable`", + ), + 'ip6-start': ( + "`ipset create f2b-j-w-fwcmd-ipset-ap6 hash:ip timeout 600 family inet6`", + "`firewall-cmd --direct --add-rule ipv6 filter INPUT_direct 0 -p tcp -m set --match-set f2b-j-w-fwcmd-ipset-ap6 src -j REJECT --reject-with icmp6-port-unreachable`", + ), + 'flush': ( + "`ipset flush f2b-j-w-fwcmd-ipset-ap`", + "`ipset flush f2b-j-w-fwcmd-ipset-ap6`", + ), + 'stop': ( + "`firewall-cmd --direct --remove-rule ipv4 filter INPUT_direct 0 -p tcp -m set --match-set f2b-j-w-fwcmd-ipset-ap src -j REJECT --reject-with icmp-port-unreachable`", + "`ipset flush f2b-j-w-fwcmd-ipset-ap`", + "`ipset destroy f2b-j-w-fwcmd-ipset-ap`", + "`firewall-cmd --direct --remove-rule ipv6 filter INPUT_direct 0 -p tcp -m set --match-set f2b-j-w-fwcmd-ipset-ap6 src -j REJECT --reject-with icmp6-port-unreachable`", + "`ipset flush f2b-j-w-fwcmd-ipset-ap6`", + "`ipset destroy f2b-j-w-fwcmd-ipset-ap6`", + ), + 'ip4-check': (), + 'ip6-check': (), + 'ip4-ban': ( + r"`ipset add f2b-j-w-fwcmd-ipset-ap 192.0.2.1 timeout 600 -exist`", + ), + 'ip4-unban': ( + r"`ipset del f2b-j-w-fwcmd-ipset-ap 192.0.2.1 -exist`", + ), + 'ip6-ban': ( + r"`ipset add f2b-j-w-fwcmd-ipset-ap6 2001:db8:: timeout 600 -exist`", + ), + 'ip6-unban': ( + r"`ipset del f2b-j-w-fwcmd-ipset-ap6 2001:db8:: -exist`", + ), + }), ) server = TestServer() transm = server._Server__transm