diff options
Diffstat (limited to 'config/action.d')
50 files changed, 944 insertions, 1035 deletions
diff --git a/config/action.d/abuseipdb.conf b/config/action.d/abuseipdb.conf index c53ed489..ed958c86 100644 --- a/config/action.d/abuseipdb.conf +++ b/config/action.d/abuseipdb.conf @@ -21,14 +21,13 @@ # # Example, for ssh bruteforce (in section [sshd] of `jail.local`): # action = %(known/action)s -# %(action_abuseipdb)s[abuseipdb_apikey="my-api-key", abuseipdb_category="18,22"] +# abuseipdb[abuseipdb_apikey="my-api-key", abuseipdb_category="18,22"] # -# See below for catagories. +# See below for categories. # -# Original Ref: https://wiki.shaunc.com/wikka.php?wakka=ReportingToAbuseIPDBWithFail2Ban # Added to fail2ban by Andrew James Collett (ajcollett) -## abuseIPDB Catagories, `the abuseipdb_category` MUST be set in the jail.conf action call. +## abuseIPDB Categories, `the abuseipdb_category` MUST be set in the jail.conf action call. # Example, for ssh bruteforce: action = %(action_abuseipdb)s[abuseipdb_category="18,22"] # ID Title Description # 3 Fraud Orders @@ -47,6 +46,9 @@ [Definition] +# bypass action for restored tickets +norestored = 1 + # Option: actionstart # Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD @@ -80,13 +82,10 @@ actioncheck = # wherever you install the helper script. For the PHP helper script, see # <https://wiki.shaunc.com/wikka.php?wakka=ReportingToAbuseIPDBWithFail2Ban> # -# --ciphers ecdhe_ecdsa_aes_256_sha is used to workaround a -# "NSS error -12286" from curl as it attempts to connect using -# SSLv3. See https://www.centos.org/forums/viewtopic.php?t=52732 # Tags: See jail.conf(5) man page # Values: CMD # -actionban = lgm=$(printf '%%s\n...' "<matches>"); curl --fail --tlsv1.1 --data "key=<abuseipdb_apikey>" --data-urlencode "comment=$lgm" --data "ip=<ip>" --data "category=<abuseipdb_category>" "https://www.abuseipdb.com/report/json" +actionban = lgm=$(printf '%%.1000s\n...' "<matches>"); curl -sSf "https://api.abuseipdb.com/api/v2/report" -H "Accept: application/json" -H "Key: <abuseipdb_apikey>" --data-urlencode "comment=$lgm" --data-urlencode "ip=<ip>" --data "categories=<abuseipdb_category>" # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the @@ -101,5 +100,5 @@ actionunban = # Notes Your API key from abuseipdb.com # Values: STRING Default: None # Register for abuseipdb [https://www.abuseipdb.com], get api key and set below. -# You will need to set the catagory in the action call. +# You will need to set the category in the action call. abuseipdb_apikey = diff --git a/config/action.d/apprise.conf b/config/action.d/apprise.conf new file mode 100644 index 00000000..37c42ea2 --- /dev/null +++ b/config/action.d/apprise.conf @@ -0,0 +1,49 @@ +# Fail2Ban configuration file +# +# Author: Chris Caron <lead2gold@gmail.com> +# +# + +[Definition] + +# Option: actionstart +# Notes.: command executed once at the start of Fail2Ban. +# Values: CMD +# +actionstart = printf %%b "The jail <name> as been started successfully." | <apprise> -t "[Fail2Ban] <name>: started on `uname -n`" + +# Option: actionstop +# Notes.: command executed once at the end of Fail2Ban +# Values: CMD +# +actionstop = printf %%b "The jail <name> has been stopped." | <apprise> -t "[Fail2Ban] <name>: stopped on `uname -n`" + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionban = printf %%b "The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>" | <apprise> -n "warning" -t "[Fail2Ban] <name>: banned <ip> from `uname -n`" + +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionunban = + +[Init] + +# Define location of the default apprise configuration file to use +# +config = /etc/fail2ban/apprise.conf +# +apprise = apprise -c "<config>" diff --git a/config/action.d/badips.conf b/config/action.d/badips.conf deleted file mode 100644 index 6f9513f6..00000000 --- a/config/action.d/badips.conf +++ /dev/null @@ -1,19 +0,0 @@ -# Fail2ban reporting to badips.com -# -# Note: This reports an IP only and does not actually ban traffic. Use -# another action in the same jail if you want bans to occur. -# -# Set the category to the appropriate value before use. -# -# To get see register and optional key to get personalised graphs see: -# http://www.badips.com/blog/personalized-statistics-track-the-attackers-of-all-your-servers-with-one-key - -[Definition] - -actionban = curl --fail --user-agent "<agent>" http://www.badips.com/add/<category>/<ip> - -[Init] - -# Option: category -# Notes.: Values are from the list here: http://www.badips.com/get/categories -category = diff --git a/config/action.d/badips.py b/config/action.d/badips.py deleted file mode 100644 index 4e50890c..00000000 --- a/config/action.d/badips.py +++ /dev/null @@ -1,389 +0,0 @@ -# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*- -# vi: set ft=python sts=4 ts=4 sw=4 noet : - -# This file is part of Fail2Ban. -# -# Fail2Ban 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. -# -# Fail2Ban 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 Fail2Ban; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -import sys -if sys.version_info < (2, 7): # pragma: no cover - raise ImportError("badips.py action requires Python >= 2.7") -import json -import threading -import logging -if sys.version_info >= (3, ): # pragma: 2.x no cover - from urllib.request import Request, urlopen - from urllib.parse import urlencode - from urllib.error import HTTPError -else: # pragma: 3.x no cover - from urllib2 import Request, urlopen, HTTPError - from urllib import urlencode - -from fail2ban.server.actions import ActionBase - - -class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable - """Fail2Ban action which reports bans to badips.com, and also - blacklist bad IPs listed on badips.com by using another action's - ban method. - - Parameters - ---------- - jail : Jail - The jail which the action belongs to. - name : str - Name assigned to the action. - category : str - Valid badips.com category for reporting failures. - score : int, optional - Minimum score for bad IPs. Default 3. - age : str, optional - Age of last report for bad IPs, per badips.com syntax. - Default "24h" (24 hours) - key : str, optional - Key issued by badips.com to report bans, for later retrieval - of personalised content. - banaction : str, optional - Name of banaction to use for blacklisting bad IPs. If `None`, - no blacklist of IPs will take place. - Default `None`. - bancategory : str, optional - Name of category to use for blacklisting, which can differ - from category used for reporting. e.g. may want to report - "postfix", but want to use whole "mail" category for blacklist. - Default `category`. - bankey : str, optional - Key issued by badips.com to blacklist IPs reported with the - associated key. - updateperiod : int, optional - Time in seconds between updating bad IPs blacklist. - Default 900 (15 minutes) - agent : str, optional - User agent transmitted to server. - Default `Fail2Ban/ver.` - - Raises - ------ - ValueError - If invalid `category`, `score`, `banaction` or `updateperiod`. - """ - - TIMEOUT = 10 - _badips = "https://www.badips.com" - def _Request(self, url, **argv): - return Request(url, headers={'User-Agent': self.agent}, **argv) - - def __init__(self, jail, name, category, score=3, age="24h", key=None, - banaction=None, bancategory=None, bankey=None, updateperiod=900, agent="Fail2Ban", - timeout=TIMEOUT): - super(BadIPsAction, self).__init__(jail, name) - - self.timeout = timeout - self.agent = agent - self.category = category - self.score = score - self.age = age - self.key = key - self.banaction = banaction - self.bancategory = bancategory or category - self.bankey = bankey - self.updateperiod = updateperiod - - self._bannedips = set() - # Used later for threading.Timer for updating badips - self._timer = None - - @staticmethod - def isAvailable(timeout=1): - try: - response = urlopen(Request("/".join([BadIPsAction._badips]), - headers={'User-Agent': "Fail2Ban"}), timeout=timeout) - return True, '' - except Exception as e: # pragma: no cover - return False, e - - def logError(self, response, what=''): # pragma: no cover - sporadical (502: Bad Gateway, etc) - messages = {} - try: - messages = json.loads(response.read().decode('utf-8')) - except: - pass - self._logSys.error( - "%s. badips.com response: '%s'", what, - messages.get('err', 'Unknown')) - - def getCategories(self, incParents=False): - """Get badips.com categories. - - Returns - ------- - set - Set of categories. - - Raises - ------ - HTTPError - Any issues with badips.com request. - ValueError - If badips.com response didn't contain necessary information - """ - try: - response = urlopen( - self._Request("/".join([self._badips, "get", "categories"])), timeout=self.timeout) - except HTTPError as response: # pragma: no cover - self.logError(response, "Failed to fetch categories") - raise - else: - response_json = json.loads(response.read().decode('utf-8')) - if not 'categories' in response_json: - err = "badips.com response lacked categories specification. Response was: %s" \ - % (response_json,) - self._logSys.error(err) - raise ValueError(err) - categories = response_json['categories'] - categories_names = set( - value['Name'] for value in categories) - if incParents: - categories_names.update(set( - value['Parent'] for value in categories - if "Parent" in value)) - return categories_names - - def getList(self, category, score, age, key=None): - """Get badips.com list of bad IPs. - - Parameters - ---------- - category : str - Valid badips.com category. - score : int - Minimum score for bad IPs. - age : str - Age of last report for bad IPs, per badips.com syntax. - key : str, optional - Key issued by badips.com to fetch IPs reported with the - associated key. - - Returns - ------- - set - Set of bad IPs. - - Raises - ------ - HTTPError - Any issues with badips.com request. - """ - try: - url = "?".join([ - "/".join([self._badips, "get", "list", category, str(score)]), - urlencode({'age': age})]) - if key: - url = "&".join([url, urlencode({'key': key})]) - self._logSys.debug('badips.com: get list, url: %r', url) - response = urlopen(self._Request(url), timeout=self.timeout) - except HTTPError as response: # pragma: no cover - self.logError(response, "Failed to fetch bad IP list") - raise - else: - return set(response.read().decode('utf-8').split()) - - @property - def category(self): - """badips.com category for reporting IPs. - """ - return self._category - - @category.setter - def category(self, category): - if category not in self.getCategories(): - self._logSys.error("Category name '%s' not valid. " - "see badips.com for list of valid categories", - category) - raise ValueError("Invalid category: %s" % category) - self._category = category - - @property - def bancategory(self): - """badips.com bancategory for fetching IPs. - """ - return self._bancategory - - @bancategory.setter - def bancategory(self, bancategory): - if bancategory != "any" and bancategory not in self.getCategories(incParents=True): - self._logSys.error("Category name '%s' not valid. " - "see badips.com for list of valid categories", - bancategory) - raise ValueError("Invalid bancategory: %s" % bancategory) - self._bancategory = bancategory - - @property - def score(self): - """badips.com minimum score for fetching IPs. - """ - return self._score - - @score.setter - def score(self, score): - score = int(score) - if 0 <= score <= 5: - self._score = score - else: - raise ValueError("Score must be 0-5") - - @property - def banaction(self): - """Jail action to use for banning/unbanning. - """ - return self._banaction - - @banaction.setter - def banaction(self, banaction): - if banaction is not None and banaction not in self._jail.actions: - self._logSys.error("Action name '%s' not in jail '%s'", - banaction, self._jail.name) - raise ValueError("Invalid banaction") - self._banaction = banaction - - @property - def updateperiod(self): - """Period in seconds between banned bad IPs will be updated. - """ - return self._updateperiod - - @updateperiod.setter - def updateperiod(self, updateperiod): - updateperiod = int(updateperiod) - if updateperiod > 0: - self._updateperiod = updateperiod - else: - raise ValueError("Update period must be integer greater than 0") - - def _banIPs(self, ips): - for ip in ips: - try: - self._jail.actions[self.banaction].ban({ - 'ip': ip, - 'failures': 0, - 'matches': "", - 'ipmatches': "", - 'ipjailmatches': "", - }) - except Exception as e: - self._logSys.error( - "Error banning IP %s for jail '%s' with action '%s': %s", - ip, self._jail.name, self.banaction, e, - exc_info=self._logSys.getEffectiveLevel()<=logging.DEBUG) - else: - self._bannedips.add(ip) - self._logSys.debug( - "Banned IP %s for jail '%s' with action '%s'", - ip, self._jail.name, self.banaction) - - def _unbanIPs(self, ips): - for ip in ips: - try: - self._jail.actions[self.banaction].unban({ - 'ip': ip, - 'failures': 0, - 'matches': "", - 'ipmatches': "", - 'ipjailmatches': "", - }) - except Exception as e: - self._logSys.info( - "Error unbanning IP %s for jail '%s' with action '%s': %s", - ip, self._jail.name, self.banaction, e, - exc_info=self._logSys.getEffectiveLevel()<=logging.DEBUG) - else: - self._logSys.debug( - "Unbanned IP %s for jail '%s' with action '%s'", - ip, self._jail.name, self.banaction) - finally: - self._bannedips.remove(ip) - - def start(self): - """If `banaction` set, blacklists bad IPs. - """ - if self.banaction is not None: - self.update() - - def update(self): - """If `banaction` set, updates blacklisted IPs. - - Queries badips.com for list of bad IPs, removing IPs from the - blacklist if no longer present, and adds new bad IPs to the - blacklist. - """ - if self.banaction is not None: - if self._timer: - self._timer.cancel() - self._timer = None - - try: - ips = self.getList( - self.bancategory, self.score, self.age, self.bankey) - # Remove old IPs no longer listed - self._unbanIPs(self._bannedips - ips) - # Add new IPs which are now listed - self._banIPs(ips - self._bannedips) - - self._logSys.debug( - "Updated IPs for jail '%s'. Update again in %i seconds", - self._jail.name, self.updateperiod) - finally: - self._timer = threading.Timer(self.updateperiod, self.update) - self._timer.start() - - def stop(self): - """If `banaction` set, clears blacklisted IPs. - """ - if self.banaction is not None: - if self._timer: - self._timer.cancel() - self._timer = None - self._unbanIPs(self._bannedips.copy()) - - def ban(self, aInfo): - """Reports banned IP to badips.com. - - Parameters - ---------- - aInfo : dict - Dictionary which includes information in relation to - the ban. - - Raises - ------ - HTTPError - Any issues with badips.com request. - """ - try: - url = "/".join([self._badips, "add", self.category, str(aInfo['ip'])]) - if self.key: - url = "?".join([url, urlencode({'key': self.key})]) - self._logSys.debug('badips.com: ban, url: %r', url) - response = urlopen(self._Request(url), timeout=self.timeout) - except HTTPError as response: # pragma: no cover - self.logError(response, "Failed to ban") - raise - else: - messages = json.loads(response.read().decode('utf-8')) - self._logSys.debug( - "Response from badips.com report: '%s'", - messages['suc']) - -Action = BadIPsAction diff --git a/config/action.d/bsd-ipfw.conf b/config/action.d/bsd-ipfw.conf index 5116b0d8..444192d3 100644 --- a/config/action.d/bsd-ipfw.conf +++ b/config/action.d/bsd-ipfw.conf @@ -14,7 +14,10 @@ # Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # -actionstart = ipfw show | fgrep -c -m 1 -s 'table(<table>)' > /dev/null 2>&1 || ( ipfw show | awk 'BEGIN { b = <lowest_rule_num> } { if ($1 < b) {} else if ($1 == b) { b = $1 + 1 } else { e = b } } END { if (e) exit e <br> else exit b }'; num=$?; ipfw -q add $num <blocktype> <block> from table\(<table>\) to me <port>; echo $num > "<startstatefile>" ) +actionstart = ipfw show | fgrep -c -m 1 -s 'table(<table>)' > /dev/null 2>&1 || ( + num=$(ipfw show | awk 'BEGIN { b = <lowest_rule_num> } { if ($1 == b) { b = $1 + 1 } } END { print b }'); + ipfw -q add "$num" <blocktype> <block> from table\(<table>\) to me <port>; echo "$num" > "<startstatefile>" + ) # Option: actionstop diff --git a/config/action.d/cloudflare-token.conf b/config/action.d/cloudflare-token.conf new file mode 100644 index 00000000..287621eb --- /dev/null +++ b/config/action.d/cloudflare-token.conf @@ -0,0 +1,93 @@ +# +# Author: Logic-32 +# +# IMPORTANT +# +# Please set jail.local's permission to 640 because it contains your CF API token. +# +# This action depends on curl. +# +# To get your Cloudflare API token: https://developers.cloudflare.com/api/tokens/create/ +# +# Cloudflare Firewall API: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/endpoints/ + +[Definition] + +# Option: actionstart +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). +# Values: CMD +# +actionstart = + +# Option: actionstop +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) +# Values: CMD +# +actionstop = + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: <ip> IP address +# <failures> number of failures +# <time> unix timestamp of the ban time +# Values: CMD +actionban = curl -s -X POST "<_cf_api_url>" \ + <_cf_api_prms> \ + --data '{"mode":"<cfmode>","configuration":{"target":"<cftarget>","value":"<ip>"},"notes":"<notes>"}' + +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: <ip> IP address +# <failures> number of failures +# <time> unix timestamp of the ban time +# Values: CMD +# +actionunban = id=$(curl -s -X GET "<_cf_api_url>" \ + --data-urlencode "mode=<cfmode>" --data-urlencode "notes=<notes>" --data-urlencode "configuration.target=<cftarget>" --data-urlencode "configuration.value=<ip>" \ + <_cf_api_prms> \ + | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1)}}}' \ + | tr -d ' "' \ + | head -n 1) + if [ -z "$id" ]; then echo "<name>: id for <ip> cannot be found using target <cftarget>"; exit 0; fi; \ + curl -s -X DELETE "<_cf_api_url>/$id" \ + <_cf_api_prms> \ + --data '{"cascade": "none"}' + +_cf_api_url = https://api.cloudflare.com/client/v4/zones/<cfzone>/firewall/access_rules/rules +_cf_api_prms = -H "Authorization: Bearer <cftoken>" -H "Content-Type: application/json" + +[Init] + +# Declare your Cloudflare Authorization Bearer Token in the [DEFAULT] section of your jail.local file. + +# The Cloudflare <ZONE_ID> of hte domain you want to manage. +# +# cfzone = + +# Your personal Cloudflare token. Ideally restricted to just have "Zone.Firewall Services" permissions. +# +# cftoken = + +# Target of the firewall rule. Default is "ip" (v4). +# +cftarget = ip + +# The firewall mode Cloudflare should use. Default is "block" (deny access). +# Consider also "js_challenge" or other "allowed_modes" if you want. +# +cfmode = block + +# The message to include in the firewall IP banning rule. +# +notes = Fail2Ban <name> + +[Init?family=inet6] +cftarget = ip6 diff --git a/config/action.d/cloudflare.conf b/config/action.d/cloudflare.conf index 1c48a37f..4af87080 100644 --- a/config/action.d/cloudflare.conf +++ b/config/action.d/cloudflare.conf @@ -5,7 +5,7 @@ # # Please set jail.local's permission to 640 because it contains your CF API key. # -# This action depends on curl. +# This action depends on curl (and optionally jq). # Referenced from http://www.normyee.net/blog/2012/02/02/adding-cloudflare-support-to-fail2ban by NORM YEE # # To get your CloudFlare API Key: https://www.cloudflare.com/a/account/my-account @@ -43,9 +43,9 @@ actioncheck = # API v1 #actionban = curl -s -o /dev/null https://www.cloudflare.com/api_json.html -d 'a=ban' -d 'tkn=<cftoken>' -d 'email=<cfuser>' -d 'key=<ip>' # API v4 -actionban = curl -s -o /dev/null -X POST -H 'X-Auth-Email: <cfuser>' -H 'X-Auth-Key: <cftoken>' \ - -H 'Content-Type: application/json' -d '{ "mode": "block", "configuration": { "target": "ip", "value": "<ip>" } }' \ - https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules +actionban = curl -s -o /dev/null -X POST <_cf_api_prms> \ + -d '{"mode":"block","configuration":{"target":"<cftarget>","value":"<ip>"},"notes":"Fail2Ban <name>"}' \ + <_cf_api_url> # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the @@ -58,9 +58,14 @@ actionban = curl -s -o /dev/null -X POST -H 'X-Auth-Email: <cfuser>' -H 'X-Auth- # API v1 #actionunban = curl -s -o /dev/null https://www.cloudflare.com/api_json.html -d 'a=nul' -d 'tkn=<cftoken>' -d 'email=<cfuser>' -d 'key=<ip>' # API v4 -actionunban = curl -s -o /dev/null -X DELETE -H 'X-Auth-Email: <cfuser>' -H 'X-Auth-Key: <cftoken>' \ - https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/$(curl -s -X GET -H 'X-Auth-Email: <cfuser>' -H 'X-Auth-Key: <cftoken>' \ - 'https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?mode=block&configuration_target=ip&configuration_value=<ip>&page=1&per_page=1' | cut -d'"' -f6) +actionunban = id=$(curl -s -X GET <_cf_api_prms> \ + "<_cf_api_url>?mode=block&configuration_target=<cftarget>&configuration_value=<ip>&page=1&per_page=1¬es=Fail2Ban%%20<name>" \ + | { jq -r '.result[0].id' 2>/dev/null || tr -d '\n' | sed -nE 's/^.*"result"\s*:\s*\[\s*\{\s*"id"\s*:\s*"([^"]+)".*$/\1/p'; }) + if [ -z "$id" ]; then echo "<name>: id for <ip> cannot be found"; exit 0; fi; + curl -s -o /dev/null -X DELETE <_cf_api_prms> "<_cf_api_url>/$id" + +_cf_api_url = https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules +_cf_api_prms = -H 'X-Auth-Email: <cfuser>' -H 'X-Auth-Key: <cftoken>' -H 'Content-Type: application/json' [Init] @@ -76,3 +81,8 @@ actionunban = curl -s -o /dev/null -X DELETE -H 'X-Auth-Email: <cfuser>' -H 'X-A cftoken = cfuser = + +cftarget = ip + +[Init?family=inet6] +cftarget = ip6 diff --git a/config/action.d/complain.conf b/config/action.d/complain.conf index 3a5f882c..4d73b058 100644 --- a/config/action.d/complain.conf +++ b/config/action.d/complain.conf @@ -102,7 +102,7 @@ logpath = /dev/null # Notes.: Your system mail command. Is passed 2 args: subject and recipient # Values: CMD # -mailcmd = mail -s +mailcmd = mail -E 'set escape' -s # Option: mailargs # Notes.: Additional arguments to mail command. e.g. for standard Unix mail: diff --git a/config/action.d/dshield.conf b/config/action.d/dshield.conf index c128bef3..3d5a7a53 100644 --- a/config/action.d/dshield.conf +++ b/config/action.d/dshield.conf @@ -179,7 +179,7 @@ tcpflags = # Notes.: Your system mail command. Is passed 2 args: subject and recipient # Values: CMD # -mailcmd = mail -s +mailcmd = mail -E 'set escape' -s # Option: mailargs # Notes.: Additional arguments to mail command. e.g. for standard Unix mail: diff --git a/config/action.d/firewallcmd-ipset.conf b/config/action.d/firewallcmd-ipset.conf index a1065224..c36ba694 100644 --- a/config/action.d/firewallcmd-ipset.conf +++ b/config/action.d/firewallcmd-ipset.conf @@ -18,20 +18,45 @@ before = firewallcmd-common.conf [Definition] -actionstart = ipset create <ipmset> hash:ip timeout <default-timeout><familyopt> +actionstart = <ipstype_<ipsettype>/actionstart> firewall-cmd --direct --add-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype> -actionflush = ipset flush <ipmset> +actionflush = <ipstype_<ipsettype>/actionflush> actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype> <actionflush> - ipset destroy <ipmset> + <ipstype_<ipsettype>/actionstop> + +actionban = <ipstype_<ipsettype>/actionban> + +# actionprolong = %(actionban)s + +actionunban = <ipstype_<ipsettype>/actionunban> + +[ipstype_ipset] + +actionstart = ipset -exist create <ipmset> hash:ip timeout <default-ipsettime> <familyopt> + +actionflush = ipset flush <ipmset> -actionban = ipset add <ipmset> <ip> timeout <bantime> -exist +actionstop = ipset destroy <ipmset> -actionprolong = %(actionban)s +actionban = ipset -exist add <ipmset> <ip> timeout <ipsettime> -actionunban = ipset del <ipmset> <ip> -exist +actionunban = ipset -exist del <ipmset> <ip> + +[ipstype_firewalld] + +actionstart = firewall-cmd --direct --new-ipset=<ipmset> --type=hash:ip --option=timeout=<default-ipsettime> <firewalld_familyopt> + +# TODO: there doesn't seem to be an explicit way to invoke the ipset flush function using firewall-cmd +actionflush = + +actionstop = firewall-cmd --direct --delete-ipset=<ipmset> + +actionban = firewall-cmd --ipset=<ipmset> --add-entry=<ip> + +actionunban = firewall-cmd --ipset=<ipmset> --remove-entry=<ip> [Init] @@ -42,11 +67,25 @@ actionunban = ipset del <ipmset> <ip> -exist # chain = INPUT_direct -# Option: default-timeout +# Option: default-ipsettime # Notes: specifies default timeout in seconds (handled default ipset timeout only) -# Values: [ NUM ] Default: 600 +# Values: [ NUM ] Default: 0 (no timeout, managed by fail2ban by unban) +default-ipsettime = 0 + +# Option: ipsettime +# Notes: specifies ticket timeout (handled ipset timeout only) +# Values: [ NUM ] Default: 0 (managed by fail2ban by unban) +ipsettime = 0 + +# expresion to caclulate timeout from bantime, example: +# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>'] +timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0) -default-timeout = 600 +# Option: ipsettype +# Notes.: defines type of ipset used for match-set (firewalld or ipset) +# Values: firewalld or ipset +# Default: ipset +ipsettype = ipset # Option: actiontype # Notes.: defines additions to the blocking rule @@ -67,14 +106,16 @@ multiport = -p <protocol> -m multiport --dports <port> ipmset = f2b-<name> familyopt = +firewalld_familyopt = [Init?family=inet6] ipmset = f2b-<name>6 -familyopt = <sp>family inet6 +familyopt = family inet6 +firewalld_familyopt = --option=family=inet6 # DEV NOTES: # -# Author: Edgar Hoch and Daniel Black +# Author: Edgar Hoch, Daniel Black, Sergey Brester and Mihail Politaev # firewallcmd-new / iptables-ipset-proto6 combined for maximium goodness diff --git a/config/action.d/firewallcmd-rich-logging.conf b/config/action.d/firewallcmd-rich-logging.conf index badfee83..21e45087 100644 --- a/config/action.d/firewallcmd-rich-logging.conf +++ b/config/action.d/firewallcmd-rich-logging.conf @@ -1,6 +1,6 @@ # Fail2Ban configuration file # -# Author: Donald Yandt +# Authors: Donald Yandt, Sergey G. Brester # # Because of the rich rule commands requires firewalld-0.3.1+ # This action uses firewalld rich-rules which gives you a cleaner iptables since it stores rules according to zones and not @@ -10,36 +10,15 @@ # # If you use the --permanent rule you get a xml file in /etc/firewalld/zones/<zone>.xml that can be shared and parsed easliy # -# Example commands to view rules: -# firewall-cmd [--zone=<zone>] --list-rich-rules -# firewall-cmd [--zone=<zone>] --list-all -# firewall-cmd [--zone=zone] --query-rich-rule='rule' +# This is an derivative of firewallcmd-rich-rules.conf, see there for details and other parameters. [INCLUDES] -before = firewallcmd-common.conf +before = firewallcmd-rich-rules.conf [Definition] -actionstart = - -actionstop = - -actioncheck = - -# you can also use zones and/or service names. -# -# zone example: -# firewall-cmd --zone=<zone> --add-rich-rule="rule family='<family>' source address='<ip>' port port='<port>' protocol='<protocol>' log prefix='f2b-<name>' level='<level>' limit value='<rate>/m' <rich-blocktype>" -# -# service name example: -# firewall-cmd --zone=<zone> --add-rich-rule="rule family='<family>' source address='<ip>' service name='<service>' log prefix='f2b-<name>' level='<level>' limit value='<rate>/m' <rich-blocktype>" -# -# Because rich rules can only handle single or a range of ports we must split ports and execute the command for each port. Ports can be single and ranges separated by a comma or space for an example: http, https, 22-60, 18 smtp - -actionban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family='<family>' source address='<ip>' port port='$p' protocol='<protocol>' log prefix='f2b-<name>' level='<level>' limit value='<rate>/m' <rich-blocktype>"; done - -actionunban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family='<family>' source address='<ip>' port port='$p' protocol='<protocol>' log prefix='f2b-<name>' level='<level>' limit value='<rate>/m' <rich-blocktype>"; done +rich-suffix = log prefix='f2b-<name>' level='<level>' limit value='<rate>/m' <rich-blocktype> [Init] @@ -48,4 +27,3 @@ level = info # log rate per minute rate = 1 - diff --git a/config/action.d/firewallcmd-rich-rules.conf b/config/action.d/firewallcmd-rich-rules.conf index bed71797..75a27d88 100644 --- a/config/action.d/firewallcmd-rich-rules.conf +++ b/config/action.d/firewallcmd-rich-rules.conf @@ -35,8 +35,10 @@ actioncheck = # # Because rich rules can only handle single or a range of ports we must split ports and execute the command for each port. Ports can be single and ranges separated by a comma or space for an example: http, https, 22-60, 18 smtp -actionban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family='<family>' source address='<ip>' port port='$p' protocol='<protocol>' <rich-blocktype>"; done - -actionunban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family='<family>' source address='<ip>' port port='$p' protocol='<protocol>' <rich-blocktype>"; done +fwcmd_rich_rule = rule family='<family>' source address='<ip>' port port='$p' protocol='<protocol>' %(rich-suffix)s +actionban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="%(fwcmd_rich_rule)s"; done + +actionunban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="%(fwcmd_rich_rule)s"; done +rich-suffix = <rich-blocktype>
\ No newline at end of file diff --git a/config/action.d/helpers-common.conf b/config/action.d/helpers-common.conf index b036f68f..03422a87 100644 --- a/config/action.d/helpers-common.conf +++ b/config/action.d/helpers-common.conf @@ -4,8 +4,9 @@ # _grep_logs_args = 'test' # (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_args = "(^|[^0-9a-fA-F:])$(echo '<ip>' | sed 's/\./\\./g')([^0-9a-fA-F:]|$)" +_grep_logs = logpath="<logpath>"; grep <grepopts> %(_grep_logs_args)s $logpath | <greplimit> +# options `-wF` used to match only whole words and fixed string (not as pattern) +_grep_logs_args = -wF "<ip>" # Used for actions, that should not by executed if ticket was restored: _bypass_if_restored = if [ '<restored>' = '1' ]; then exit 0; fi; diff --git a/config/action.d/iptables-allports.conf b/config/action.d/iptables-allports.conf index caf9ab81..51c4694d 100644 --- a/config/action.d/iptables-allports.conf +++ b/config/action.d/iptables-allports.conf @@ -4,52 +4,12 @@ # Modified: Yaroslav O. Halchenko <debian@onerussian.com> # made active on all ports from original iptables.conf # -# +# Obsolete: superseded by iptables[type=allports] [INCLUDES] -before = iptables-common.conf - +before = iptables.conf [Definition] -# Option: actionstart -# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). -# Values: CMD -# -actionstart = <iptables> -N f2b-<name> - <iptables> -A f2b-<name> -j <returntype> - <iptables> -I <chain> -p <protocol> -j f2b-<name> - -# Option: actionstop -# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) -# Values: CMD -# -actionstop = <iptables> -D <chain> -p <protocol> -j f2b-<name> - <actionflush> - <iptables> -X f2b-<name> - -# Option: actioncheck -# Notes.: command executed once before each actionban command -# Values: CMD -# -actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]' - -# Option: actionban -# Notes.: command executed when banning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype> - -# Option: actionunban -# Notes.: command executed when unbanning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype> - -[Init] - +type = allports diff --git a/config/action.d/iptables-common.conf b/config/action.d/iptables-common.conf deleted file mode 100644 index e016ef2f..00000000 --- a/config/action.d/iptables-common.conf +++ /dev/null @@ -1,92 +0,0 @@ -# Fail2Ban configuration file -# -# Author: Daniel Black -# -# This is a included configuration file and includes the definitions for the iptables -# used in all iptables based actions by default. -# -# The user can override the defaults in iptables-common.local -# -# Modified: Alexander Koeppe <format_c@online.de>, Serg G. Brester <serg.brester@sebres.de> -# made config file IPv6 capable (see new section Init?family=inet6) - -[INCLUDES] - -after = iptables-blocktype.local - iptables-common.local -# iptables-blocktype.local is obsolete - -[Definition] - -# Option: actionflush -# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action) -# Values: CMD -# -actionflush = <iptables> -F f2b-<name> - - -[Init] - -# Option: chain -# Notes specifies the iptables chain to which the Fail2Ban rules should be -# added -# Values: STRING Default: INPUT -chain = INPUT - -# Default name of the chain -# -name = default - -# Option: port -# Notes.: specifies port to monitor -# Values: [ NUM | STRING ] Default: -# -port = ssh - -# Option: protocol -# Notes.: internally used by config reader for interpolations. -# Values: [ tcp | udp | icmp | all ] Default: tcp -# -protocol = tcp - -# Option: blocktype -# Note: This is what the action does with rules. This can be any jump target -# as per the iptables man page (section 8). Common values are DROP -# REJECT, REJECT --reject-with icmp-port-unreachable -# Values: STRING -blocktype = REJECT --reject-with icmp-port-unreachable - -# Option: returntype -# Note: This is the default rule on "actionstart". This should be RETURN -# in all (blocking) actions, except REJECT in allowing actions. -# Values: STRING -returntype = RETURN - -# Option: lockingopt -# Notes.: Option was introduced to iptables to prevent multiple instances from -# running concurrently and causing irratic behavior. -w was introduced -# in iptables 1.4.20, so might be absent on older systems -# See https://github.com/fail2ban/fail2ban/issues/1122 -# Values: STRING -lockingopt = -w - -# Option: iptables -# Notes.: Actual command to be executed, including common to all calls options -# Values: STRING -iptables = iptables <lockingopt> - - -[Init?family=inet6] - -# Option: blocktype (ipv6) -# Note: This is what the action does with rules. This can be any jump target -# as per the iptables man page (section 8). Common values are DROP -# REJECT, REJECT --reject-with icmp6-port-unreachable -# Values: STRING -blocktype = REJECT --reject-with icmp6-port-unreachable - -# Option: iptables (ipv6) -# Notes.: Actual command to be executed, including common to all calls options -# Values: STRING -iptables = ip6tables <lockingopt> - diff --git a/config/action.d/iptables-ipset-proto4.conf b/config/action.d/iptables-ipset-proto4.conf index 99ebbf8c..37624284 100644 --- a/config/action.d/iptables-ipset-proto4.conf +++ b/config/action.d/iptables-ipset-proto4.conf @@ -19,7 +19,7 @@ [INCLUDES] -before = iptables-common.conf +before = iptables.conf [Definition] @@ -28,7 +28,7 @@ before = iptables-common.conf # Values: CMD # actionstart = ipset --create f2b-<name> iphash - <iptables> -I <chain> -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype> + <_ipt_add_rules> # Option: actionflush @@ -41,7 +41,7 @@ actionflush = ipset --flush f2b-<name> # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # -actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype> +actionstop = <_ipt_del_rules> <actionflush> ipset --destroy f2b-<name> @@ -61,5 +61,6 @@ actionban = ipset --test f2b-<name> <ip> || ipset --add f2b-<name> <ip> # actionunban = ipset --test f2b-<name> <ip> && ipset --del f2b-<name> <ip> -[Init] +# Several capabilities used internaly: +rule-jump = -m set --match-set f2b-<name> src -j <blocktype> diff --git a/config/action.d/iptables-ipset-proto6-allports.conf b/config/action.d/iptables-ipset-proto6-allports.conf index c851233c..1aa7fd6f 100644 --- a/config/action.d/iptables-ipset-proto6-allports.conf +++ b/config/action.d/iptables-ipset-proto6-allports.conf @@ -15,65 +15,13 @@ # # Modified: Alexander Koeppe <format_c@online.de>, Serg G. Brester <serg.brester@sebres.de> # made config file IPv6 capable (see new section Init?family=inet6) +# +# Obsolete: superseded by iptables-ipset[type=allports] [INCLUDES] -before = iptables-common.conf +before = iptables-ipset.conf [Definition] -# Option: actionstart -# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). -# Values: CMD -# -actionstart = ipset create <ipmset> hash:ip timeout <default-timeout><familyopt> - <iptables> -I <chain> -m set --match-set <ipmset> src -j <blocktype> - -# Option: actionflush -# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action) -# Values: CMD -# -actionflush = ipset flush <ipmset> - -# Option: actionstop -# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) -# Values: CMD -# -actionstop = <iptables> -D <chain> -m set --match-set <ipmset> src -j <blocktype> - <actionflush> - ipset destroy <ipmset> - -# Option: actionban -# Notes.: command executed when banning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionban = ipset add <ipmset> <ip> timeout <bantime> -exist - -actionprolong = %(actionban)s - -# Option: actionunban -# Notes.: command executed when unbanning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionunban = ipset del <ipmset> <ip> -exist - -[Init] - -# Option: default-timeout -# Notes: specifies default timeout in seconds (handled default ipset timeout only) -# Values: [ NUM ] Default: 600 - -default-timeout = 600 - -ipmset = f2b-<name> -familyopt = - - -[Init?family=inet6] - -ipmset = f2b-<name>6 -familyopt = <sp>family inet6 +type = allports diff --git a/config/action.d/iptables-ipset-proto6.conf b/config/action.d/iptables-ipset-proto6.conf index 12c3ddd6..ef744984 100644 --- a/config/action.d/iptables-ipset-proto6.conf +++ b/config/action.d/iptables-ipset-proto6.conf @@ -15,65 +15,13 @@ # # Modified: Alexander Koeppe <format_c@online.de>, Serg G. Brester <serg.brester@sebres.de> # made config file IPv6 capable (see new section Init?family=inet6) +# +# Obsolete: superseded by iptables-ipset[type=multiport] [INCLUDES] -before = iptables-common.conf +before = iptables-ipset.conf [Definition] -# Option: actionstart -# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). -# Values: CMD -# -actionstart = ipset create <ipmset> hash:ip timeout <default-timeout><familyopt> - <iptables> -I <chain> -p <protocol> -m multiport --dports <port> -m set --match-set <ipmset> src -j <blocktype> - -# Option: actionflush -# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action) -# Values: CMD -# -actionflush = ipset flush <ipmset> - -# Option: actionstop -# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) -# Values: CMD -# -actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -m set --match-set <ipmset> src -j <blocktype> - <actionflush> - ipset destroy <ipmset> - -# Option: actionban -# Notes.: command executed when banning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionban = ipset add <ipmset> <ip> timeout <bantime> -exist - -actionprolong = %(actionban)s - -# Option: actionunban -# Notes.: command executed when unbanning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionunban = ipset del <ipmset> <ip> -exist - -[Init] - -# Option: default-timeout -# Notes: specifies default timeout in seconds (handled default ipset timeout only) -# Values: [ NUM ] Default: 600 - -default-timeout = 600 - -ipmset = f2b-<name> -familyopt = - - -[Init?family=inet6] - -ipmset = f2b-<name>6 -familyopt = <sp>family inet6 +type = multiport diff --git a/config/action.d/iptables-ipset.conf b/config/action.d/iptables-ipset.conf new file mode 100644 index 00000000..b44e6ec4 --- /dev/null +++ b/config/action.d/iptables-ipset.conf @@ -0,0 +1,90 @@ +# Fail2Ban configuration file +# +# Authors: Sergey G Brester (sebres), Daniel Black, Alexander Koeppe +# +# This is for ipset protocol 6 (and hopefully later) (ipset v6.14). +# Use ipset -V to see the protocol and version. Version 4 should use +# iptables-ipset-proto4.conf. +# +# This requires the program ipset which is normally in package called ipset. +# +# 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.conf + +[Definition] + +# Option: actionstart +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). +# Values: CMD +# +actionstart = ipset -exist create <ipmset> hash:ip timeout <default-ipsettime> <familyopt> + <_ipt_add_rules> + +# Option: actionflush +# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action) +# Values: CMD +# +actionflush = ipset flush <ipmset> + +# Option: actionstop +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) +# Values: CMD +# +actionstop = <_ipt_del_rules> + <actionflush> + ipset destroy <ipmset> + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionban = ipset -exist add <ipmset> <ip> timeout <ipsettime> + +# actionprolong = %(actionban)s + +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionunban = ipset -exist del <ipmset> <ip> + +# Several capabilities used internaly: + +rule-jump = -m set --match-set <ipmset> src -j <blocktype> + + +[Init] + +# Option: default-ipsettime +# Notes: specifies default timeout in seconds (handled default ipset timeout only) +# Values: [ NUM ] Default: 0 (no timeout, managed by fail2ban by unban) +default-ipsettime = 0 + +# Option: ipsettime +# Notes: specifies ticket timeout (handled ipset timeout only) +# Values: [ NUM ] Default: 0 (managed by fail2ban by unban) +ipsettime = 0 + +# expresion to caclulate timeout from bantime, example: +# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>'] +timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0) + +ipmset = f2b-<name> +familyopt = + + +[Init?family=inet6] + +ipmset = f2b-<name>6 +familyopt = family inet6 diff --git a/config/action.d/iptables-multiport-log.conf b/config/action.d/iptables-multiport-log.conf index df126dbf..322a7491 100644 --- a/config/action.d/iptables-multiport-log.conf +++ b/config/action.d/iptables-multiport-log.conf @@ -11,7 +11,7 @@ [INCLUDES] -before = iptables-common.conf +before = iptables.conf [Definition] diff --git a/config/action.d/iptables-multiport.conf b/config/action.d/iptables-multiport.conf index 41b00c54..008208e0 100644 --- a/config/action.d/iptables-multiport.conf +++ b/config/action.d/iptables-multiport.conf @@ -3,50 +3,12 @@ # Author: Cyril Jaquier # Modified by Yaroslav Halchenko for multiport banning # +# Obsolete: superseded by iptables[type=multiport] [INCLUDES] -before = iptables-common.conf +before = iptables.conf [Definition] -# Option: actionstart -# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). -# Values: CMD -# -actionstart = <iptables> -N f2b-<name> - <iptables> -A f2b-<name> -j <returntype> - <iptables> -I <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name> - -# Option: actionstop -# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) -# Values: CMD -# -actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name> - <actionflush> - <iptables> -X f2b-<name> - -# Option: actioncheck -# Notes.: command executed once before each actionban command -# Values: CMD -# -actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]' - -# Option: actionban -# Notes.: command executed when banning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype> - -# Option: actionunban -# Notes.: command executed when unbanning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype> - -[Init] - +type = multiport diff --git a/config/action.d/iptables-new.conf b/config/action.d/iptables-new.conf index 39a17099..170cb934 100644 --- a/config/action.d/iptables-new.conf +++ b/config/action.d/iptables-new.conf @@ -4,51 +4,12 @@ # Copied from iptables.conf and modified by Yaroslav Halchenko # to fulfill the needs of bugreporter dbts#350746. # -# +# Obsolete: superseded by iptables[pre-rule='-m state --state NEW<sp>'] [INCLUDES] -before = iptables-common.conf +before = iptables.conf [Definition] -# Option: actionstart -# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). -# Values: CMD -# -actionstart = <iptables> -N f2b-<name> - <iptables> -A f2b-<name> -j <returntype> - <iptables> -I <chain> -m state --state NEW -p <protocol> --dport <port> -j f2b-<name> - -# Option: actionstop -# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) -# Values: CMD -# -actionstop = <iptables> -D <chain> -m state --state NEW -p <protocol> --dport <port> -j f2b-<name> - <actionflush> - <iptables> -X f2b-<name> - -# Option: actioncheck -# Notes.: command executed once before each actionban command -# Values: CMD -# -actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]' - -# Option: actionban -# Notes.: command executed when banning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype> - -# Option: actionunban -# Notes.: command executed when unbanning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype> - -[Init] - +pre-rule = -m state --state NEW<sp>
\ No newline at end of file diff --git a/config/action.d/iptables-xt_recent-echo.conf b/config/action.d/iptables-xt_recent-echo.conf index 97449222..c3c175b3 100644 --- a/config/action.d/iptables-xt_recent-echo.conf +++ b/config/action.d/iptables-xt_recent-echo.conf @@ -7,10 +7,14 @@ [INCLUDES] -before = iptables-common.conf +before = iptables.conf [Definition] +_ipt_chain_rule = -m recent --update --seconds 3600 --name <iptname> -j <blocktype> +_ipt_for_proto-iter = +_ipt_for_proto-done = + # Option: actionstart # Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD @@ -33,7 +37,9 @@ before = iptables-common.conf # own rules. The 3600 second timeout is independent and acts as a # safeguard in case the fail2ban process dies unexpectedly. The # shorter of the two timeouts actually matters. -actionstart = if [ `id -u` -eq 0 ];then <iptables> -I <chain> -m recent --update --seconds 3600 --name <iptname> -j <blocktype>;fi +actionstart = if [ `id -u` -eq 0 ];then + { %(_ipt_check_rule)s >/dev/null 2>&1; } || { <iptables> -I <chain> %(_ipt_chain_rule)s; } + fi # Option: actionflush # @@ -46,13 +52,15 @@ actionflush = # Values: CMD # actionstop = echo / > /proc/net/xt_recent/<iptname> - if [ `id -u` -eq 0 ];then <iptables> -D <chain> -m recent --update --seconds 3600 --name <iptname> -j <blocktype>;fi + if [ `id -u` -eq 0 ];then + <iptables> -D <chain> %(_ipt_chain_rule)s; + fi # Option: actioncheck -# Notes.: command executed once before each actionban command +# Notes.: command executed as invariant check (error by ban) # Values: CMD # -actioncheck = test -e /proc/net/xt_recent/<iptname> +actioncheck = { <iptables> -C <chain> %(_ipt_chain_rule)s; } && test -e /proc/net/xt_recent/<iptname> # Option: actionban # Notes.: command executed when banning an IP. Take care that the @@ -72,7 +80,7 @@ actionunban = echo -<ip> > /proc/net/xt_recent/<iptname> [Init] -iptname = f2b-<name> +iptname = f2b-<name> [Init?family=inet6] diff --git a/config/action.d/iptables.conf b/config/action.d/iptables.conf index 8ed5fdad..67d496f5 100644 --- a/config/action.d/iptables.conf +++ b/config/action.d/iptables.conf @@ -1,28 +1,35 @@ # Fail2Ban configuration file # -# Author: Cyril Jaquier -# +# Authors: Sergey G. Brester (sebres), Cyril Jaquier, Daniel Black, +# Yaroslav O. Halchenko, Alexander Koeppe et al. # -[INCLUDES] +[Definition] -before = iptables-common.conf +# Option: type +# Notes.: type of the action. +# Values: [ oneport | multiport | allports ] Default: oneport +# +type = oneport -[Definition] +# Option: actionflush +# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action) +# Values: CMD +# +actionflush = <iptables> -F f2b-<name> # Option: actionstart # Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # -actionstart = <iptables> -N f2b-<name> - <iptables> -A f2b-<name> -j <returntype> - <iptables> -I <chain> -p <protocol> --dport <port> -j f2b-<name> +actionstart = { <iptables> -C f2b-<name> -j <returntype> >/dev/null 2>&1; } || { <iptables> -N f2b-<name> || true; <iptables> -A f2b-<name> -j <returntype>; } + <_ipt_add_rules> # Option: actionstop # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # -actionstop = <iptables> -D <chain> -p <protocol> --dport <port> -j f2b-<name> +actionstop = <_ipt_del_rules> <actionflush> <iptables> -X f2b-<name> @@ -30,7 +37,7 @@ actionstop = <iptables> -D <chain> -p <protocol> --dport <port> -j f2b-<name> # Notes.: command executed once before each actionban command # Values: CMD # -actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]' +actioncheck = <_ipt_check_rules> # Option: actionban # Notes.: command executed when banning an IP. Take care that the @@ -48,5 +55,108 @@ actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype> # actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype> +# Option: pre-rule +# Notes.: prefix parameter(s) inserted to the begin of rule. No default (empty) +# +pre-rule = + +rule-jump = -j <_ipt_rule_target> + +# Several capabilities used internaly: + +_ipt_for_proto-iter = for proto in $(echo '<protocol>' | sed 's/,/ /g'); do +_ipt_for_proto-done = done + +_ipt_add_rules = <_ipt_for_proto-iter> + { %(_ipt_check_rule)s >/dev/null 2>&1; } || { <iptables> -I <chain> %(_ipt_chain_rule)s; } + <_ipt_for_proto-done> + +_ipt_del_rules = <_ipt_for_proto-iter> + <iptables> -D <chain> %(_ipt_chain_rule)s + <_ipt_for_proto-done> + +_ipt_check_rules = <_ipt_for_proto-iter> + %(_ipt_check_rule)s + <_ipt_for_proto-done> + +_ipt_chain_rule = <pre-rule><ipt_<type>/_chain_rule> +_ipt_check_rule = <iptables> -C <chain> %(_ipt_chain_rule)s +_ipt_rule_target = f2b-<name> + +[ipt_oneport] + +_chain_rule = -p $proto --dport <port> <rule-jump> + +[ipt_multiport] + +_chain_rule = -p $proto -m multiport --dports <port> <rule-jump> + +[ipt_allports] + +_chain_rule = -p $proto <rule-jump> + + [Init] +# Option: chain +# Notes specifies the iptables chain to which the Fail2Ban rules should be +# added +# Values: STRING Default: INPUT +chain = INPUT + +# Default name of the chain +# +name = default + +# Option: port +# Notes.: specifies port to monitor +# Values: [ NUM | STRING ] Default: +# +port = ssh + +# Option: protocol +# Notes.: internally used by config reader for interpolations. +# Values: [ tcp | udp | icmp | all ] Default: tcp +# +protocol = tcp + +# Option: blocktype +# Note: This is what the action does with rules. This can be any jump target +# as per the iptables man page (section 8). Common values are DROP +# REJECT, REJECT --reject-with icmp-port-unreachable +# Values: STRING +blocktype = REJECT --reject-with icmp-port-unreachable + +# Option: returntype +# Note: This is the default rule on "actionstart". This should be RETURN +# in all (blocking) actions, except REJECT in allowing actions. +# Values: STRING +returntype = RETURN + +# Option: lockingopt +# Notes.: Option was introduced to iptables to prevent multiple instances from +# running concurrently and causing irratic behavior. -w was introduced +# in iptables 1.4.20, so might be absent on older systems +# See https://github.com/fail2ban/fail2ban/issues/1122 +# Values: STRING +lockingopt = -w + +# Option: iptables +# Notes.: Actual command to be executed, including common to all calls options +# Values: STRING +iptables = iptables <lockingopt> + + +[Init?family=inet6] + +# Option: blocktype (ipv6) +# Note: This is what the action does with rules. This can be any jump target +# as per the iptables man page (section 8). Common values are DROP +# REJECT, REJECT --reject-with icmp6-port-unreachable +# Values: STRING +blocktype = REJECT --reject-with icmp6-port-unreachable + +# Option: iptables (ipv6) +# Notes.: Actual command to be executed, including common to all calls options +# Values: STRING +iptables = ip6tables <lockingopt> diff --git a/config/action.d/ipthreat.conf b/config/action.d/ipthreat.conf new file mode 100644 index 00000000..193a60f2 --- /dev/null +++ b/config/action.d/ipthreat.conf @@ -0,0 +1,107 @@ +# IPThreat configuration file +# +# Added to fail2ban by Jeff Johnson (jjxtra) +# +# Action to report IP address to ipthreat.net +# +# You must sign up to obtain an API key from ipthreat.net and request bulk report permissions +# https://ipthreat.net/integrations +# +# IPThreat is a 100% free site and service, all data is licensed under a creative commons by attribution license +# Please do not integrate if you do not agree to the license +# +# IMPORTANT: +# +# Reporting an IP is a serious action. Make sure that it is legit. +# Consider using this action only for: +# * IP that has been banned more than once +# * High max retry to avoid user mis-typing password +# * Filters that are unlikely to be human error +# +# Example: +# ``` +# action = %(known/action)s +# ipthreat[] +# ``` +# +# The action accepts the following arguments: ipthreat[ipthreat_flags="8",ipthreat_system="SSH", ipthreat_apikey=...] +# In most cases your action could be as simple as: ipthreat[], since the default flags and system are set to the most correct default values. +# You can optionally override ipthreat_system and ipthreat_flags if desired. +# The ipthreat_apikey must be set at the bottom of this configuration file. +# +# `ipthreat_system` is a short name of the system attacked, i.e. SSH, SMTP, MYSQL, PHP, etc. +# +# For `ipthreat_flags`, most cases will use 8 (BruteForce) which is the default, but you could use others. +# You can use the name or the ordinal. +# Multiple values are comma separated. +# ``` +# Name Ordinal Description +# Dns 1 Abuse/attack of dns (domain name server) +# Fraud 2 General fraud, whether orders, misuse of payment info, etc +# DDos 4 Distributed denial of service attack, whether through http requests, large ping attack, etc +# BruteForce 8 Brute force login attack +# Proxy 16 IP is a proxy like TOR or other proxy server +# Spam 32 Email, comment or other type of spam +# Vpn 64 IP is part of a VPN +# Hacking 128 General hacking outside of brute force attack (includes vulnerability scans, sql injection, etc.). Use port scan flag instead if it's just probe on ports. +# BadBot 256 Bad bot that is not honoring robots.txt or just flooding with too many requests, etc +# Compromised 512 The ip has been taken over by malware or botnet +# Phishing 1024 The ip is involved in phishing or spoofing +# Iot 2048 The ip has targetted an iot (Internet of Things) device +# PortScan 4096 Port scan +# See https://ipthreat.net/bulkreportformat for more information +# ``` + +[Definition] + +# bypass action for restored tickets +norestored = 1 + +# Option: actionstart +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). +# Values: CMD +# +actionstart = + +# Option: actionstop +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) +# Values: CMD +# +actionstop = + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionban = curl -sSf "https://api.ipthreat.net/api/report" -X POST -H "Content-Type: application/json" -H "X-API-KEY: <ipthreat_apikey>" -d "{\"ip\":\"<ip>\",\"flags\":\"<ipthreat_flags>\",\"system\":\"<ipthreat_system>\",\"notes\":\"fail2ban\"}" + +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionunban = + +[Init] +# Option: ipthreat_apikey +# Notes Your API key from ipthreat.net +# Values: STRING Default: None +# Register for ipthreat [https://ipthreat.net], get api key and set below. +# You will need to set the flags and system in the action call in jail.conf +ipthreat_apikey = + +# By default, the ipthreat system is the name of the fail2ban jail +ipthreat_system = <name> + +# By default the ip threat flags is 8 (brute force), but you can override this per jail if desired +ipthreat_flags = 8
\ No newline at end of file diff --git a/config/action.d/mail-buffered.conf b/config/action.d/mail-buffered.conf index 325f185b..79b84104 100644 --- a/config/action.d/mail-buffered.conf +++ b/config/action.d/mail-buffered.conf @@ -17,7 +17,7 @@ actionstart = printf %%b "Hi,\n The jail <name> has been started successfully.\n Output will be buffered until <lines> lines are available.\n Regards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest> # Option: actionstop # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) @@ -28,13 +28,13 @@ actionstop = if [ -f <tmpfile> ]; then These hosts have been banned by Fail2Ban.\n `cat <tmpfile>` Regards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: Summary from <fq-hostname>" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: Summary from <fq-hostname>" <dest> rm <tmpfile> fi printf %%b "Hi,\n The jail <name> has been stopped.\n Regards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest> # Option: actioncheck # Notes.: command executed once before each actionban command @@ -55,7 +55,7 @@ actionban = printf %%b "`date`: <ip> (<failures> failures)\n" >> <tmpfile> These hosts have been banned by Fail2Ban.\n `cat <tmpfile>` \nRegards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: Summary" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: Summary" <dest> rm <tmpfile> fi diff --git a/config/action.d/mail-whois-common.conf b/config/action.d/mail-whois-common.conf index b0d27afc..ecf3a5d9 100644 --- a/config/action.d/mail-whois-common.conf +++ b/config/action.d/mail-whois-common.conf @@ -17,7 +17,7 @@ _whois = whois <ip> || echo "missing whois program" # character set before sending it to a mail program # make sure you have 'file' and 'iconv' commands installed when opting for that _whois_target_charset = UTF-8 -_whois_convert_charset = whois <ip> | +_whois_convert_charset = (%(_whois)s) | { WHOIS_OUTPUT=$(cat) ; WHOIS_CHARSET=$(printf %%b "$WHOIS_OUTPUT" | file -b --mime-encoding -) ; printf %%b "$WHOIS_OUTPUT" | iconv -f $WHOIS_CHARSET -t %(_whois_target_charset)s//TRANSLIT - ; } # choose between _whois and _whois_convert_charset in mail-whois-common.local diff --git a/config/action.d/mail-whois-lines.conf b/config/action.d/mail-whois-lines.conf index 3a3e56b2..d2818cb9 100644 --- a/config/action.d/mail-whois-lines.conf +++ b/config/action.d/mail-whois-lines.conf @@ -72,7 +72,7 @@ actionunban = # Notes.: Your system mail command. Is passed 2 args: subject and recipient # Values: CMD # -mailcmd = mail -s +mailcmd = mail -E 'set escape' -s # Default name of the chain # diff --git a/config/action.d/mail-whois.conf b/config/action.d/mail-whois.conf index 7fea34c4..ab33b616 100644 --- a/config/action.d/mail-whois.conf +++ b/config/action.d/mail-whois.conf @@ -20,7 +20,7 @@ norestored = 1 actionstart = printf %%b "Hi,\n The jail <name> has been started successfully.\n Regards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest> # Option: actionstop # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) @@ -29,7 +29,7 @@ actionstart = printf %%b "Hi,\n actionstop = printf %%b "Hi,\n The jail <name> has been stopped.\n Regards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest> # Option: actioncheck # Notes.: command executed once before each actionban command @@ -49,7 +49,7 @@ actionban = printf %%b "Hi,\n Here is more information about <ip> :\n `%(_whois_command)s`\n Regards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest> # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the diff --git a/config/action.d/mail.conf b/config/action.d/mail.conf index 5d8c0e15..f4838ddc 100644 --- a/config/action.d/mail.conf +++ b/config/action.d/mail.conf @@ -16,7 +16,7 @@ norestored = 1 actionstart = printf %%b "Hi,\n The jail <name> has been started successfully.\n Regards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest> # Option: actionstop # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) @@ -25,7 +25,7 @@ actionstart = printf %%b "Hi,\n actionstop = printf %%b "Hi,\n The jail <name> has been stopped.\n Regards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest> # Option: actioncheck # Notes.: command executed once before each actionban command @@ -43,7 +43,7 @@ actionban = printf %%b "Hi,\n The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>.\n Regards,\n - Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest> + Fail2Ban"|mail -E 'set escape' -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest> # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the diff --git a/config/action.d/nftables-allports.conf b/config/action.d/nftables-allports.conf index 6c69da39..908abe40 100644 --- a/config/action.d/nftables-allports.conf +++ b/config/action.d/nftables-allports.conf @@ -6,17 +6,12 @@ # Modified: Alexander Belykh <albel727@ngs.ru> # adapted for nftables # +# Obsolete: superseded by nftables[type=allports] [INCLUDES] -before = nftables-common.conf +before = nftables.conf [Definition] -# Option: nftables_mode -# Notes.: additional expressions for nftables filter rule -# Values: nftables expressions -# -nftables_mode = meta l4proto <protocol> - -[Init] +type = allports diff --git a/config/action.d/nftables-common.conf b/config/action.d/nftables-common.conf deleted file mode 100644 index 37045712..00000000 --- a/config/action.d/nftables-common.conf +++ /dev/null @@ -1,135 +0,0 @@ -# Fail2Ban configuration file -# -# Author: Daniel Black -# Author: Cyril Jaquier -# Modified: Yaroslav O. Halchenko <debian@onerussian.com> -# made active on all ports from original iptables.conf -# Modified: Alexander Belykh <albel727@ngs.ru> -# adapted for nftables -# -# This is a included configuration file and includes the definitions for the nftables -# used in all nftables based actions by default. -# -# The user can override the defaults in nftables-common.local - -[INCLUDES] - -after = nftables-common.local - -[Definition] - -# Option: nftables_mode -# Notes.: additional expressions for nftables filter rule -# Values: nftables expressions -# -nftables_mode = <protocol> dport \{ <port> \} - -# Option: actionstart -# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). -# Values: CMD -# -actionstart = <nftables> add set <nftables_family> <nftables_table> <set_name> \{ type <nftables_type>\; \} - <nftables> insert rule <nftables_family> <nftables_table> <chain> %(nftables_mode)s <address_family> saddr @<set_name> <blocktype> - -_nft_list = <nftables> --handle --numeric list chain <nftables_family> <nftables_table> <chain> -_nft_get_handle_id = grep -m1 '<address_family> saddr @<set_name> <blocktype> # handle' | grep -oe ' handle [0-9]*' - -# Option: actionstop -# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) -# Values: CMD -# -actionstop = HANDLE_ID=$(%(_nft_list)s | %(_nft_get_handle_id)s) - <nftables> delete rule <nftables_family> <nftables_table> <chain> $HANDLE_ID - <nftables> delete set <nftables_family> <nftables_table> <set_name> - -# Option: actioncheck -# Notes.: command executed once before each actionban command -# Values: CMD -# -actioncheck = <nftables> list chain <nftables_family> <nftables_table> <chain> | grep -q '@<set_name>[ \t]' - -# Option: actionban -# Notes.: command executed when banning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionban = <nftables> add element <nftables_family> <nftables_table> <set_name> \{ <ip> \} - -# Option: actionunban -# Notes.: command executed when unbanning an IP. Take care that the -# command is executed with Fail2Ban user rights. -# Tags: See jail.conf(5) man page -# Values: CMD -# -actionunban = <nftables> delete element <nftables_family> <nftables_table> <set_name> \{ <ip> \} - -[Init] - -# Option: nftables_type -# Notes.: address type to work with -# Values: [ipv4_addr | ipv6_addr] Default: ipv4_addr -# -nftables_type = ipv4_addr - -# Option: nftables_family -# Notes.: address family to work in -# Values: [ip | ip6 | inet] Default: inet -# -nftables_family = inet - -# Option: nftables_table -# Notes.: table in the address family to work in -# Values: STRING Default: filter -# -nftables_table = filter - -# Option: chain -# Notes specifies the nftables chain to which the Fail2Ban rules should be -# added -# Values: STRING Default: input -chain = input - -# Default name of the filtering set -# -name = default - -# Option: port -# Notes.: specifies port to monitor -# Values: [ NUM | STRING ] Default: -# -port = ssh - -# Option: protocol -# Notes.: internally used by config reader for interpolations. -# Values: [ tcp | udp ] Default: tcp -# -protocol = tcp - -# Option: blocktype -# Note: This is what the action does with rules. This can be any jump target -# as per the nftables man page (section 8). Common values are drop -# reject, reject with icmp type host-unreachable -# Values: STRING -blocktype = reject - -# Option: nftables -# Notes.: Actual command to be executed, including common to all calls options -# Values: STRING -nftables = nft - -# Option: set_name -# Notes.: The name of the nft set used to store banned addresses -# Values: STRING -set_name = f2b-<name> - -# Option: address_family -# Notes.: The family of the banned addresses -# Values: [ ip | ip6 ] -address_family = ip - -[Init?family=inet6] - -nftables_type = ipv6_addr -set_name = f2b-<name>6 -address_family = ip6 diff --git a/config/action.d/nftables-multiport.conf b/config/action.d/nftables-multiport.conf index d1afafb3..ba3ec92c 100644 --- a/config/action.d/nftables-multiport.conf +++ b/config/action.d/nftables-multiport.conf @@ -6,17 +6,12 @@ # Modified: Alexander Belykh <albel727@ngs.ru> # adapted for nftables # +# Obsolete: superseded by nftables[type=multiport] [INCLUDES] -before = nftables-common.conf +before = nftables.conf [Definition] -# Option: nftables_mode -# Notes.: additional expressions for nftables filter rule -# Values: nftables expressions -# -nftables_mode = <protocol> dport \{ <port> \} - -[Init] +type = multiport
\ No newline at end of file diff --git a/config/action.d/nftables.conf b/config/action.d/nftables.conf new file mode 100644 index 00000000..77cf3661 --- /dev/null +++ b/config/action.d/nftables.conf @@ -0,0 +1,203 @@ +# Fail2Ban configuration file +# +# Author: Daniel Black +# Author: Cyril Jaquier +# Modified: Yaroslav O. Halchenko <debian@onerussian.com> +# made active on all ports from original iptables.conf +# Modified: Alexander Belykh <albel727@ngs.ru> +# adapted for nftables +# +# This is a included configuration file and includes the definitions for the nftables +# used in all nftables based actions by default. +# +# The user can override the defaults in nftables-common.local +# Example: redirect flow to honeypot +# +# [Init] +# table_family = ip +# chain_type = nat +# chain_hook = prerouting +# chain_priority = -50 +# blocktype = counter redirect to 2222 + +[INCLUDES] + +after = nftables-common.local + +[Definition] + +# Option: type +# Notes.: type of the action. +# Values: [ multiport | allports ] Default: multiport +# +type = multiport + +rule_match-custom = +rule_match-allports = meta l4proto \{ <protocol> \} +rule_match-multiport = $proto dport \{ $(echo '<port>' | sed s/:/-/g) \} +match = <rule_match-<type>> + +# Option: rule_stat +# Notes.: statement for nftables filter rule. +# leaving it empty will block all (include udp and icmp) +# Values: nftables statement +# +rule_stat = %(match)s <addr_family> saddr @<addr_set> <blocktype> + +# optional interator over protocol's: +_nft_for_proto-custom-iter = +_nft_for_proto-custom-done = +_nft_for_proto-allports-iter = +_nft_for_proto-allports-done = +_nft_for_proto-multiport-iter = for proto in $(echo '<protocol>' | sed 's/,/ /g'); do +_nft_for_proto-multiport-done = done + +_nft_list = <nftables> -a list chain <table_family> <table> <chain> +_nft_get_handle_id = grep -oP '@<addr_set>\s+.*\s+\Khandle\s+(\d+)$' + +_nft_add_set = <nftables> add set <table_family> <table> <addr_set> \{ type <addr_type>\; \} + <_nft_for_proto-<type>-iter> + <nftables> add rule <table_family> <table> <chain> %(rule_stat)s + <_nft_for_proto-<type>-done> +_nft_del_set = { %(_nft_list)s | %(_nft_get_handle_id)s; } | while read -r hdl; do + <nftables> delete rule <table_family> <table> <chain> $hdl; done + <nftables> delete set <table_family> <table> <addr_set> + +# Option: _nft_shutdown_table +# Notes.: command executed after the stop in order to delete table (it checks that no sets are available): +# Values: CMD +# +_nft_shutdown_table = { <nftables> list table <table_family> <table> | grep -qP '^\s+set\s+'; } || { + <nftables> delete table <table_family> <table> + } + +# Option: actionstart +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). +# Values: CMD +# +actionstart = <nftables> add table <table_family> <table> + <nftables> -- add chain <table_family> <table> <chain> \{ type <chain_type> hook <chain_hook> priority <chain_priority> \; \} + %(_nft_add_set)s + +# Option: actionflush +# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action); +# uses `nft flush set ...` and as fallback (e. g. unsupported) recreates the set (with references) +# Values: CMD +# +actionflush = { <nftables> flush set <table_family> <table> <addr_set> 2> /dev/null; } || { + %(_nft_del_set)s + %(_nft_add_set)s + } + +# Option: actionstop +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) +# Values: CMD +# +actionstop = %(_nft_del_set)s + <_nft_shutdown_table> + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = <nftables> list chain <table_family> <table> <chain> | grep -q '@<addr_set>[ \t]' + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionban = <nftables> add element <table_family> <table> <addr_set> \{ <ip> \} + +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionunban = <nftables> delete element <table_family> <table> <addr_set> \{ <ip> \} + +[Init] + +# Option: table +# Notes.: main table to store chain and sets (automatically created on demand) +# Values: STRING Default: f2b-table +table = f2b-table + +# Option: table_family +# Notes.: address family to work in +# Values: [ip | ip6 | inet] Default: inet +table_family = inet + +# Option: chain +# Notes.: main chain to store rules +# Values: STRING Default: f2b-chain +chain = f2b-chain + +# Option: chain_type +# Notes.: refers to the kind of chain to be created +# Values: [filter | route | nat] Default: filter +# +chain_type = filter + +# Option: chain_hook +# Notes.: refers to the kind of chain to be created +# Values: [ prerouting | input | forward | output | postrouting ] Default: input +# +chain_hook = input + +# Option: chain_priority +# Notes.: priority in the chain. +# Values: NUMBER Default: -1 +# +chain_priority = -1 + +# Option: addr_type +# Notes.: address type to work with +# Values: [ipv4_addr | ipv6_addr] Default: ipv4_addr +# +addr_type = ipv4_addr + +# Default name of the filtering set +# +name = default + +# Option: port +# Notes.: specifies port to monitor +# Values: [ NUM | STRING ] Default: +# +port = ssh + +# Option: protocol +# Notes.: internally used by config reader for interpolations. +# Values: [ tcp | udp ] Default: tcp +# +protocol = tcp + +# Option: blocktype +# Note: This is what the action does with rules. This can be any jump target +# as per the nftables man page (section 8). Common values are drop, +# reject, reject with icmpx type host-unreachable, redirect to 2222 +# Values: STRING +blocktype = reject + +# Option: nftables +# Notes.: Actual command to be executed, including common to all calls options +# Values: STRING +nftables = nft + +# Option: addr_set +# Notes.: The name of the nft set used to store banned addresses +# Values: STRING +addr_set = addr-set-<name> + +# Option: addr_family +# Notes.: The family of the banned addresses +# Values: [ ip | ip6 ] +addr_family = ip + +[Init?family=inet6] +addr_family = ip6 +addr_type = ipv6_addr +addr_set = addr6-set-<name> diff --git a/config/action.d/nginx-block-map.conf b/config/action.d/nginx-block-map.conf index 33c15f9c..0de382bd 100644 --- a/config/action.d/nginx-block-map.conf +++ b/config/action.d/nginx-block-map.conf @@ -84,8 +84,15 @@ srv_cfg_path = /etc/nginx/ #srv_cmd = nginx -c %(srv_cfg_path)s/nginx.conf srv_cmd = nginx -# first test configuration is correct, hereafter send reload signal: -blck_lst_reload = %(srv_cmd)s -qt; if [ $? -eq 0 ]; then +# pid file (used to check nginx is running): +srv_pid = /run/nginx.pid + +# command used to check whether nginx is running and configuration is valid: +srv_is_running = [ -f "%(srv_pid)s" ] +srv_check_cmd = %(srv_is_running)s && %(srv_cmd)s -qt + +# first test nginx is running and configuration is correct, hereafter send reload signal: +blck_lst_reload = %(srv_check_cmd)s; if [ $? -eq 0 ]; then %(srv_cmd)s -s reload; if [ $? -ne 0 ]; then echo 'reload failed.'; fi; fi; @@ -103,6 +110,8 @@ actionstop = %(actionflush)s actioncheck = -actionban = echo "\\\\<fid> 1;" >> '%(blck_lst_file)s'; %(blck_lst_reload)s +_echo_blck_row = printf '\%%s 1;\n' "<fid>" + +actionban = %(_echo_blck_row)s >> '%(blck_lst_file)s'; %(blck_lst_reload)s -actionunban = id=$(echo "<fid>" | sed -e 's/[]\/$*.^|[]/\\&/g'); sed -i "/$id 1;/d" %(blck_lst_file)s; %(blck_lst_reload)s +actionunban = id=$(%(_echo_blck_row)s | sed -e 's/[]\/$*.^|[]/\\&/g'); sed -i "/^$id$/d" %(blck_lst_file)s; %(blck_lst_reload)s diff --git a/config/action.d/sendmail-buffered.conf b/config/action.d/sendmail-buffered.conf index 199c6ce5..13803f8b 100644 --- a/config/action.d/sendmail-buffered.conf +++ b/config/action.d/sendmail-buffered.conf @@ -24,7 +24,7 @@ actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on <fq-hostname> The jail <name> has been started successfully.\n Output will be buffered until <lines> lines are available.\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> # Option: actionstop # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) @@ -38,7 +38,7 @@ actionstop = if [ -f <tmpfile> ]; then These hosts have been banned by Fail2Ban.\n `cat <tmpfile>` Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> rm <tmpfile> fi printf %%b "Subject: [Fail2Ban] <name>: stopped on <fq-hostname> @@ -47,7 +47,7 @@ actionstop = if [ -f <tmpfile> ]; then Hi,\n The jail <name> has been stopped.\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> # Option: actioncheck # Notes.: command executed once before each actionban command @@ -71,7 +71,7 @@ actionban = printf %%b "`date`: <ip> (<failures> failures)\n" >> <tmpfile> These hosts have been banned by Fail2Ban.\n `cat <tmpfile>` Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> rm <tmpfile> fi diff --git a/config/action.d/sendmail-common.conf b/config/action.d/sendmail-common.conf index 9bf15054..1e31fadf 100644 --- a/config/action.d/sendmail-common.conf +++ b/config/action.d/sendmail-common.conf @@ -21,7 +21,7 @@ actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on <fq-hostname> Hi,\n The jail <name> has been started successfully.\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> # Option: actionstop # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) @@ -34,7 +34,7 @@ actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped on <fq-hostname> Hi,\n The jail <name> has been stopped.\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> # Option: actioncheck # Notes.: command executed once before each actionban command @@ -60,6 +60,10 @@ actionunban = [Init] +# Your system mail command +# +mailcmd = /usr/sbin/sendmail -f "<sender>" "<dest>" + # Recipient mail address # dest = root diff --git a/config/action.d/sendmail-geoip-lines.conf b/config/action.d/sendmail-geoip-lines.conf index b7c1bf36..b36e49a7 100644 --- a/config/action.d/sendmail-geoip-lines.conf +++ b/config/action.d/sendmail-geoip-lines.conf @@ -37,11 +37,11 @@ actionban = ( printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostn Country:`geoiplookup -f /usr/share/GeoIP/GeoIP.dat "<ip>" | cut -d':' -f2-` AS:`geoiplookup -f /usr/share/GeoIP/GeoIPASNum.dat "<ip>" | cut -d':' -f2-` hostname: <ip-host>\n\n - Lines containing failures of <ip>\n"; + Lines containing failures of <ip> (max <grepmax>)\n"; %(_grep_logs)s; printf %%b "\n Regards,\n - Fail2Ban" ) | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" ) | <mailcmd> [Init] diff --git a/config/action.d/sendmail-whois-ipjailmatches.conf b/config/action.d/sendmail-whois-ipjailmatches.conf index 06ea3a3e..7790ec53 100644 --- a/config/action.d/sendmail-whois-ipjailmatches.conf +++ b/config/action.d/sendmail-whois-ipjailmatches.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf [Definition] @@ -27,11 +28,11 @@ actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostnam The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>.\n\n Here is more information about <ip> :\n - `/usr/bin/whois <ip>`\n\n + `%(_whois_command)s`\n\n Matches for <name> with <ipjailfailures> failures IP:<ip>\n <ipjailmatches>\n\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> [Init] diff --git a/config/action.d/sendmail-whois-ipmatches.conf b/config/action.d/sendmail-whois-ipmatches.conf index 83bff1b4..e4717ca1 100644 --- a/config/action.d/sendmail-whois-ipmatches.conf +++ b/config/action.d/sendmail-whois-ipmatches.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf [Definition] @@ -27,11 +28,11 @@ actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostnam The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>.\n\n Here is more information about <ip> :\n - `/usr/bin/whois <ip>`\n\n + `%(_whois_command)s`\n\n Matches with <ipfailures> failures IP:<ip>\n <ipmatches>\n\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> [Init] diff --git a/config/action.d/sendmail-whois-lines.conf b/config/action.d/sendmail-whois-lines.conf index 4b947cb2..47ec6ed5 100644 --- a/config/action.d/sendmail-whois-lines.conf +++ b/config/action.d/sendmail-whois-lines.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf helpers-common.conf [Definition] @@ -27,13 +28,13 @@ actionban = ( printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostn Hi,\n The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>.\n\n - Here is more information about <ip> :\n - `/usr/bin/whois <ip> || echo missing whois program`\n\n - Lines containing failures of <ip>\n"; + Here is more information about <ip> :\n" + %(_whois_command)s; + printf %%b "\nLines containing failures of <ip> (max <grepmax>)\n"; %(_grep_logs)s; printf %%b "\n Regards,\n - Fail2Ban" ) | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" ) | <mailcmd> [Init] diff --git a/config/action.d/sendmail-whois-matches.conf b/config/action.d/sendmail-whois-matches.conf index 01520135..08215ea7 100644 --- a/config/action.d/sendmail-whois-matches.conf +++ b/config/action.d/sendmail-whois-matches.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf [Definition] @@ -27,11 +28,11 @@ actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostnam The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>.\n\n Here is more information about <ip> :\n - `/usr/bin/whois <ip>`\n\n + `%(_whois_command)s`\n\n Matches:\n <matches>\n\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> [Init] diff --git a/config/action.d/sendmail-whois.conf b/config/action.d/sendmail-whois.conf index 2fb01ed3..9e93cd32 100644 --- a/config/action.d/sendmail-whois.conf +++ b/config/action.d/sendmail-whois.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf [Definition] @@ -27,9 +28,9 @@ actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostnam The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>.\n\n Here is more information about <ip> :\n - `/usr/bin/whois <ip> || echo missing whois program`\n + `%(_whois_command)s`\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> [Init] diff --git a/config/action.d/sendmail.conf b/config/action.d/sendmail.conf index cf420915..ad9e8d79 100644 --- a/config/action.d/sendmail.conf +++ b/config/action.d/sendmail.conf @@ -27,7 +27,7 @@ actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostnam The IP <ip> has just been banned by Fail2Ban after <failures> attempts against <name>.\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest> + Fail2Ban" | <mailcmd> [Init] diff --git a/config/action.d/shorewall-ipset-proto6.conf b/config/action.d/shorewall-ipset-proto6.conf index 45be0c0a..eacb53d9 100644 --- a/config/action.d/shorewall-ipset-proto6.conf +++ b/config/action.d/shorewall-ipset-proto6.conf @@ -51,7 +51,7 @@ # Values: CMD # actionstart = if ! ipset -quiet -name list f2b-<name> >/dev/null; - then ipset -quiet -exist create f2b-<name> hash:ip timeout <default-timeout>; + then ipset -quiet -exist create f2b-<name> hash:ip timeout <default-ipsettime>; fi # Option: actionstop @@ -66,9 +66,9 @@ actionstop = ipset flush f2b-<name> # Tags: See jail.conf(5) man page # Values: CMD # -actionban = ipset add f2b-<name> <ip> timeout <bantime> -exist +actionban = ipset add f2b-<name> <ip> timeout <ipsettime> -exist -actionprolong = %(actionban)s +# actionprolong = %(actionban)s # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the @@ -78,8 +78,16 @@ actionprolong = %(actionban)s # actionunban = ipset del f2b-<name> <ip> -exist -# Option: default-timeout +# Option: default-ipsettime # Notes: specifies default timeout in seconds (handled default ipset timeout only) -# Values: [ NUM ] Default: 600 +# Values: [ NUM ] Default: 0 (no timeout, managed by fail2ban by unban) +default-ipsettime = 0 -default-timeout = 600 +# Option: ipsettime +# Notes: specifies ticket timeout (handled ipset timeout only) +# Values: [ NUM ] Default: 0 (managed by fail2ban by unban) +ipsettime = 0 + +# expresion to caclulate timeout from bantime, example: +# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>'] +timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0) diff --git a/config/action.d/shorewall.conf b/config/action.d/shorewall.conf index dcef8829..83d08d99 100644 --- a/config/action.d/shorewall.conf +++ b/config/action.d/shorewall.conf @@ -9,7 +9,7 @@ # connections. So if the attempter goes on trying using the same connection # he could even log in. In order to get the same behavior of the iptable # action (so that the ban is immediate) the /etc/shorewall/shorewall.conf -# file should me modified with "BLACKLISTNEWONLY=No". Note that as of +# file should be modified with "BLACKLISTNEWONLY=No". Note that as of # Shorewall 4.5.13 BLACKLISTNEWONLY is deprecated; however the equivalent # of BLACKLISTNEWONLY=No can now be achieved by setting BLACKLIST="ALL". # diff --git a/config/action.d/smtp.py b/config/action.d/smtp.py index 9cdfe327..5c27d0ff 100644 --- a/config/action.d/smtp.py +++ b/config/action.d/smtp.py @@ -159,25 +159,25 @@ class SMTPAction(ActionBase): try: self._logSys.debug("Connected to SMTP '%s', response: %i: %s", self.host, *smtp.connect(self.host)) - if self.user and self.password: + if self.user and self.password: # pragma: no cover (ATM no tests covering that) smtp.login(self.user, self.password) failed_recipients = smtp.sendmail( self.fromaddr, self.toaddr.split(", "), msg.as_string()) - except smtplib.SMTPConnectError: + except smtplib.SMTPConnectError: # pragma: no cover self._logSys.error("Error connecting to host '%s'", self.host) raise - except smtplib.SMTPAuthenticationError: + except smtplib.SMTPAuthenticationError: # pragma: no cover self._logSys.error( "Failed to authenticate with host '%s' user '%s'", self.host, self.user) raise - except smtplib.SMTPException: + except smtplib.SMTPException: # pragma: no cover self._logSys.error( "Error sending mail to host '%s' from '%s' to '%s'", self.host, self.fromaddr, self.toaddr) raise else: - if failed_recipients: + if failed_recipients: # pragma: no cover self._logSys.warning( "Email to '%s' failed to following recipients: %r", self.toaddr, failed_recipients) @@ -186,7 +186,7 @@ class SMTPAction(ActionBase): try: self._logSys.debug("Disconnected from '%s', response %i: %s", self.host, *smtp.quit()) - except smtplib.SMTPServerDisconnected: + except smtplib.SMTPServerDisconnected: # pragma: no cover pass # Not connected def start(self): diff --git a/config/action.d/symbiosis-blacklist-allports.conf b/config/action.d/symbiosis-blacklist-allports.conf index 6fb7d0af..7208b293 100644 --- a/config/action.d/symbiosis-blacklist-allports.conf +++ b/config/action.d/symbiosis-blacklist-allports.conf @@ -5,7 +5,7 @@ [INCLUDES] -before = iptables-common.conf +before = iptables.conf [Definition] @@ -41,6 +41,11 @@ actionban = echo 'all' >| /etc/symbiosis/firewall/blacklist.d/<ip>.auto actionunban = rm -f /etc/symbiosis/firewall/blacklist.d/<ip>.auto <iptables> -D <chain> -s <ip> -j <blocktype> || : +# [TODO] Flushing is currently not implemented for symbiosis blacklist.d +# +actionflush = + + [Init] # Option: chain diff --git a/config/action.d/ufw.conf b/config/action.d/ufw.conf index d2f731f2..c9ff7f37 100644 --- a/config/action.d/ufw.conf +++ b/config/action.d/ufw.conf @@ -13,16 +13,45 @@ actionstop = actioncheck = -actionban = [ -n "<application>" ] && app="app <application>" - ufw insert <insertpos> <blocktype> from <ip> to <destination> $app +# ufw does "quickly process packets for which we already have a connection" in before.rules, +# therefore all related sockets should be closed +# actionban is using `ss` to do so, this only handles IPv4 and IPv6. -actionunban = [ -n "<application>" ] && app="app <application>" - ufw delete <blocktype> from <ip> to <destination> $app +actionban = if [ -n "<application>" ] && ufw app info "<application>" + then + ufw <add> <blocktype> from <ip> to <destination> app "<application>" comment "<comment>" + else + ufw <add> <blocktype> from <ip> to <destination> comment "<comment>" + fi + <kill> + +actionunban = if [ -n "<application>" ] && ufw app info "<application>" + then + ufw delete <blocktype> from <ip> to <destination> app "<application>" + else + ufw delete <blocktype> from <ip> to <destination> + fi + +# Option: kill-mode +# Notes.: can be set to ss or conntrack (may be extended later with other modes) to immediately drop all connections from banned IP, default empty (no kill) +# Example: banaction = ufw[kill-mode=ss] +kill-mode = + +# intern conditional parameter used to provide killing mode after ban: +_kill_ = +_kill_ss = ss -K dst "[<ip>]" +_kill_conntrack = conntrack -D -s "<ip>" + +# Option: kill +# Notes.: can be used to specify custom killing feature, by default depending on option kill-mode +# Examples: banaction = ufw[kill='ss -K "( sport = :http || sport = :https )" dst "[<ip>]"'] +# banaction = ufw[kill='cutter "<ip>"'] +kill = <_kill_<kill-mode>> [Init] -# Option: insertpos -# Notes.: The position number in the firewall list to insert the block rule -insertpos = 1 +# Option: add +# Notes.: can be set to "insert 1" to insert a rule at certain position (here 1): +add = prepend # Option: blocktype # Notes.: reject or deny @@ -36,6 +65,10 @@ destination = any # Notes.: application from sudo ufw app list application = +# Option: comment +# Notes.: comment for rule added by fail2ban +comment = by Fail2Ban after <failures> attempts against <name> + # DEV NOTES: # # Author: Guilhem Lettron diff --git a/config/action.d/xarf-login-attack.conf b/config/action.d/xarf-login-attack.conf index 2b135c43..f348b2c4 100644 --- a/config/action.d/xarf-login-attack.conf +++ b/config/action.d/xarf-login-attack.conf @@ -41,7 +41,12 @@ actionstop = actioncheck = -actionban = oifs=${IFS}; IFS=.;SEP_IP=( <ip> ); set -- ${SEP_IP}; ADDRESSES=$(dig +short -t txt -q $4.$3.$2.$1.abuse-contacts.abusix.org); IFS=${oifs} +actionban = oifs=${IFS}; + RESOLVER_ADDR="%(addr_resolver)s" + if [ "<debug>" -gt 0 ]; then echo "try to resolve $RESOLVER_ADDR"; fi + ADDRESSES=$(dig +short -t txt -q $RESOLVER_ADDR | tr -d '"') + IFS=,; ADDRESSES=$(echo $ADDRESSES) + IFS=${oifs} IP=<ip> FROM=<sender> SERVICE=<service> @@ -51,26 +56,37 @@ actionban = oifs=${IFS}; IFS=.;SEP_IP=( <ip> ); set -- ${SEP_IP}; ADDRESSES=$(di PORT=<port> DATE=`LC_ALL=C date --date=@<time> +"%%a, %%d %%h %%Y %%T %%z"` if [ ! -z "$ADDRESSES" ]; then + oifs=${IFS}; IFS=,; ADDRESSES=$(echo $ADDRESSES) + IFS=${oifs} (printf -- %%b "<header>\n<message>\n<report>\n\n"; date '+Note: Local timezone is %%z (%%Z)'; - printf -- %%b "\n<ipmatches>\n\n<footer>") | <mailcmd> <mailargs> ${ADDRESSES//,/\" \"} + printf -- %%b "\n<ipmatches>\n\n<footer>") | <mailcmd> <mailargs> $ADDRESSES fi actionunban = -[Init] +# Server as resolver used in dig command +# +addr_resolver = <ip-rev>abuse-contacts.abusix.org + +# Option: boundary +# Notes: This can be overwritten to be safe for possible predictions +boundary = bfbb0f920793ac03cb8634bde14d8a1e + +_boundary = Abuse<time>-<boundary> + # Option: header # Notes: This is really a fixed value -header = Subject: abuse report about $IP - $DATE\nAuto-Submitted: auto-generated\nX-XARF: PLAIN\nContent-Transfer-Encoding: 7bit\nContent-Type: multipart/mixed; charset=utf8;\n boundary=Abuse-bfbb0f920793ac03cb8634bde14d8a1e;\n\n--Abuse-bfbb0f920793ac03cb8634bde14d8a1e\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf-8;\n +header = Subject: abuse report about $IP - $DATE\nAuto-Submitted: auto-generated\nX-XARF: PLAIN\nContent-Transfer-Encoding: 7bit\nContent-Type: multipart/mixed; charset=utf8;\n boundary=%(_boundary)s;\n\n--%(_boundary)s\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf-8;\n # Option: footer # Notes: This is really a fixed value and needs to match the report and header # mime delimiters -footer = \n\n--Abuse-bfbb0f920793ac03cb8634bde14d8a1e-- +footer = \n\n--%(_boundary)s-- # Option: report # Notes: Intended to be fixed -report = --Abuse-bfbb0f920793ac03cb8634bde14d8a1e\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf-8; name=\"report.txt\";\n\n---\nReported-From: $FROM\nCategory: abuse\nReport-ID: $REPORTID\nReport-Type: login-attack\nService: $SERVICE\nVersion: 0.2\nUser-Agent: Fail2ban v0.9\nDate: $DATE\nSource-Type: ip-address\nSource: $IP\nPort: $PORT\nSchema-URL: http://www.x-arf.org/schema/abuse_login-attack_0.1.2.json\nAttachment: text/plain\nOccurances: $FAILURES\nTLP: $TLP\n\n\n--Abuse-bfbb0f920793ac03cb8634bde14d8a1e\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf8; name=\"logfile.log\"; +report = --%(_boundary)s\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf-8; name=\"report.txt\";\n\n---\nReported-From: $FROM\nCategory: abuse\nReport-ID: $REPORTID\nReport-Type: login-attack\nService: $SERVICE\nVersion: 0.2\nUser-Agent: Fail2ban v0.9\nDate: $DATE\nSource-Type: ip-address\nSource: $IP\nPort: $PORT\nSchema-URL: http://www.x-arf.org/schema/abuse_login-attack_0.1.2.json\nAttachment: text/plain\nOccurances: $FAILURES\nTLP: $TLP\n\n\n--%(_boundary)s\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf8; name=\"logfile.log\"; # Option: Message # Notes: This can be modified by the users |