mkdir -p './dbus-1/session.d'
mkdir -p './dhcp/ddns-keys'
mkdir -p './fail2ban/fail2ban.d'
-mkdir -p './fail2ban/jail.d'
mkdir -p './glvnd/egl_vendor.d'
mkdir -p './guest-session'
mkdir -p './icinga/modules'
mkdir -p './letsencrypt/renewal-hooks/post'
mkdir -p './letsencrypt/renewal-hooks/pre'
mkdir -p './libpaper.d'
+mkdir -p './monit/conf-available'
mkdir -p './mono/certstore'
mkdir -p './mysql/mariadb.conf.d'
mkdir -p './netplan'
maybe chmod 0644 'bash_completion.d/desktop-file-validate'
maybe chmod 0644 'bash_completion.d/dkms'
maybe chmod 0644 'bash_completion.d/docker'
+maybe chmod 0644 'bash_completion.d/fail2ban'
maybe chmod 0644 'bash_completion.d/gem1.9.1'
maybe chmod 0644 'bash_completion.d/git-prompt'
maybe chmod 0644 'bash_completion.d/grub'
maybe chmod 0644 'default/devpts'
maybe chmod 0644 'default/docker'
maybe chmod 0644 'default/dovecot'
+maybe chmod 0644 'default/fail2ban'
maybe chmod 0644 'default/fetchmail'
maybe chmod 0644 'default/grub'
maybe chmod 0755 'default/grub.d'
maybe chmod 0755 'etckeeper/vcs.d/50vcs-cmd'
maybe chmod 0755 'fail2ban'
maybe chmod 0755 'fail2ban/action.d'
+maybe chmod 0644 'fail2ban/action.d/abuseipdb.conf'
maybe chmod 0664 'fail2ban/action.d/apf.conf'
maybe chmod 0664 'fail2ban/action.d/badips.conf'
maybe chmod 0664 'fail2ban/action.d/badips.py'
maybe chmod 0664 'fail2ban/action.d/dshield.conf'
maybe chmod 0664 'fail2ban/action.d/dummy.conf'
maybe chmod 0664 'fail2ban/action.d/firewallcmd-allports.conf'
+maybe chmod 0644 'fail2ban/action.d/firewallcmd-common.conf'
maybe chmod 0664 'fail2ban/action.d/firewallcmd-ipset.conf'
maybe chmod 0664 'fail2ban/action.d/firewallcmd-multiport.conf'
maybe chmod 0664 'fail2ban/action.d/firewallcmd-new.conf'
+maybe chmod 0644 'fail2ban/action.d/firewallcmd-rich-logging.conf'
+maybe chmod 0644 'fail2ban/action.d/firewallcmd-rich-rules.conf'
+maybe chmod 0644 'fail2ban/action.d/helpers-common.conf'
maybe chmod 0664 'fail2ban/action.d/hostsdeny.conf'
maybe chmod 0664 'fail2ban/action.d/ipfilter.conf'
maybe chmod 0664 'fail2ban/action.d/ipfw.conf'
maybe chmod 0664 'fail2ban/action.d/mail-whois.conf'
maybe chmod 0664 'fail2ban/action.d/mail.conf'
maybe chmod 0664 'fail2ban/action.d/mynetwatchman.conf'
+maybe chmod 0644 'fail2ban/action.d/netscaler.conf'
maybe chmod 0664 'fail2ban/action.d/nftables-allports.conf'
maybe chmod 0664 'fail2ban/action.d/nftables-common.conf'
maybe chmod 0664 'fail2ban/action.d/nftables-multiport.conf'
+maybe chmod 0644 'fail2ban/action.d/nginx-block-map.conf'
+maybe chmod 0644 'fail2ban/action.d/npf.conf'
maybe chmod 0664 'fail2ban/action.d/nsupdate.conf'
maybe chmod 0664 'fail2ban/action.d/osx-afctl.conf'
maybe chmod 0664 'fail2ban/action.d/osx-ipfw.conf'
maybe chmod 0664 'fail2ban/filter.d/courier-smtp.conf'
maybe chmod 0664 'fail2ban/filter.d/cyrus-imap.conf'
maybe chmod 0664 'fail2ban/filter.d/directadmin.conf'
+maybe chmod 0644 'fail2ban/filter.d/domino-smtp.conf'
maybe chmod 0664 'fail2ban/filter.d/dovecot.conf'
maybe chmod 0664 'fail2ban/filter.d/dropbear.conf'
maybe chmod 0664 'fail2ban/filter.d/drupal-auth.conf'
maybe chmod 0775 'fail2ban/filter.d/ignorecommands/apache-fakegooglebot'
maybe chmod 0664 'fail2ban/filter.d/kerio.conf'
maybe chmod 0664 'fail2ban/filter.d/lighttpd-auth.conf'
+maybe chmod 0644 'fail2ban/filter.d/mongodb-auth.conf'
maybe chmod 0664 'fail2ban/filter.d/monit.conf'
maybe chmod 0664 'fail2ban/filter.d/murmur.conf'
maybe chmod 0664 'fail2ban/filter.d/mysqld-auth.conf'
maybe chmod 0664 'fail2ban/filter.d/pam-generic.conf'
maybe chmod 0664 'fail2ban/filter.d/perdition.conf'
maybe chmod 0664 'fail2ban/filter.d/php-url-fopen.conf'
+maybe chmod 0644 'fail2ban/filter.d/phpmyadmin-syslog.conf'
maybe chmod 0664 'fail2ban/filter.d/portsentry.conf'
maybe chmod 0664 'fail2ban/filter.d/postfix-rbl.conf'
maybe chmod 0664 'fail2ban/filter.d/postfix-sasl.conf'
maybe chmod 0664 'fail2ban/filter.d/sendmail-auth.conf'
maybe chmod 0664 'fail2ban/filter.d/sendmail-reject.conf'
maybe chmod 0664 'fail2ban/filter.d/sieve.conf'
+maybe chmod 0644 'fail2ban/filter.d/slapd.conf'
maybe chmod 0664 'fail2ban/filter.d/sogo-auth.conf'
maybe chmod 0664 'fail2ban/filter.d/solid-pop3d.conf'
maybe chmod 0664 'fail2ban/filter.d/squid.conf'
maybe chmod 0664 'fail2ban/filter.d/webmin-auth.conf'
maybe chmod 0664 'fail2ban/filter.d/wuftpd.conf'
maybe chmod 0664 'fail2ban/filter.d/xinetd-fail.conf'
+maybe chmod 0644 'fail2ban/filter.d/zoneminder.conf'
maybe chmod 0664 'fail2ban/jail.conf'
maybe chmod 0755 'fail2ban/jail.d'
+maybe chmod 0644 'fail2ban/jail.d/defaults-debian.conf'
maybe chmod 0644 'fail2ban/jail.local'
+maybe chmod 0644 'fail2ban/paths-arch.conf'
maybe chmod 0664 'fail2ban/paths-common.conf'
maybe chmod 0664 'fail2ban/paths-debian.conf'
maybe chmod 0664 'fail2ban/paths-fedora.conf'
maybe chmod 0644 'logrotate.d/cups-daemon'
maybe chmod 0644 'logrotate.d/dbconfig-common'
maybe chmod 0644 'logrotate.d/dpkg'
+maybe chmod 0644 'logrotate.d/fail2ban'
maybe chmod 0644 'logrotate.d/homematic'
maybe chmod 0644 'logrotate.d/iptraf'
maybe chmod 0644 'logrotate.d/iptraf-ng'
maybe chmod 0644 'modules'
maybe chmod 0755 'modules-load.d'
maybe chmod 0644 'modules-load.d/cups-filters.conf'
+maybe chmod 0755 'monit'
+maybe chmod 0755 'monit/conf-available'
+maybe chmod 0755 'monit/monitrc.d'
+maybe chmod 0644 'monit/monitrc.d/fail2ban'
maybe chmod 0755 'mono'
maybe chmod 0755 'mono/2.0'
maybe chmod 0755 'mono/2.0/Browsers'
--- /dev/null
+# fail2ban bash-completion -*- shell-script -*-
+#
+# 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.
+
+__fail2ban_jails () {
+ "$1" status 2>/dev/null | awk -F"\t+" '/Jail list/{print $2}' | sed 's/, / /g'
+}
+__fail2ban_jail_actions () {
+ "$1" get "$2" actions 2>/dev/null | sed -n '$s/\([^,]\+\),\?/\1/gp'
+}
+__fail2ban_jail_action_properties () {
+ "$1" get "$2" actionproperties "$3" 2>/dev/null | sed -n '$s/\([^,]\+\),\?/\1/gp'
+}
+__fail2ban_jail_action_methods () {
+ "$1" get "$2" actionmethods "$3" 2>/dev/null | sed -n '$s/\([^,]\+\),\?/\1/gp'
+}
+
+_fail2ban () {
+ local cur prev words cword
+ _init_completion || return
+
+ case $prev in
+ -V|--version|-h|--help)
+ return 0 # No further completion valid
+ ;;
+ -c)
+ _filedir -d # Directories
+ return 0
+ ;;
+ -s|-p)
+ _filedir # Files
+ return 0
+ ;;
+ *)
+ if [[ "$cur" == "-"* ]];then
+ COMPREPLY=( $( compgen -W \
+ "$( _parse_help "$1" --help 2>/dev/null) -V" \
+ -- "$cur") )
+ return 0
+ fi
+ ;;
+ esac
+
+ if [[ "$1" == *"fail2ban-regex" ]];then
+ _filedir
+ return 0
+ elif [[ "$1" == *"fail2ban-client" ]];then
+ local cmd jail action
+ case $prev in
+ "$1")
+ COMPREPLY=( $( compgen -W \
+ "$( "$1" --help 2>/dev/null | awk '/^ [a-z]+/{print $1}')" \
+ -- "$cur") )
+ return 0
+ ;;
+ start|reload|stop|status)
+ COMPREPLY=( $(compgen -W "$(__fail2ban_jails "$1")" -- "$cur" ) )
+ return 0
+ ;;
+ set|get)
+ COMPREPLY=( $( compgen -W \
+ "$( "$1" --help 2>/dev/null | awk '/^ '$prev' [^<]/{print $2}')" \
+ -- "$cur") )
+ COMPREPLY+=( $(compgen -W "$(__fail2ban_jails "$1")" -- "$cur" ) )
+ return 0
+ ;;
+ *)
+ if [[ "${words[$cword-2]}" == "add" ]];then
+ COMPREPLY=( $( compgen -W "auto polling gamin pyinotify systemd" -- "$cur" ) )
+ return 0
+ elif [[ "${words[$cword-2]}" == "set" || "${words[$cword-2]}" == "get" ]];then
+ cmd="${words[cword-2]}"
+ # Handle in section below
+ elif [[ "${words[$cword-3]}" == "set" || "${words[$cword-3]}" == "get" ]];then
+ cmd="${words[$cword-3]}"
+ jail="${words[$cword-2]}"
+ # Handle in section below
+ elif [[ "${words[$cword-4]}" == "set" || "${words[$cword-4]}" == "get" && ${words[$cword-2]} == action* ]];then
+ cmd="${words[$cword-4]}"
+ jail="${words[$cword-3]}"
+ action="${words[$cword-1]}"
+ # Handle in section below
+ fi
+ ;;
+ esac
+
+ if [[ -z "$jail" && -n "$cmd" ]];then
+ case $prev in
+ loglevel)
+ if [[ "$cmd" == "set" ]];then
+ COMPREPLY=( $( compgen -W "CRITICAL ERROR WARNING NOTICE INFO DEBUG" -- "$cur" ) )
+ fi
+ return 0
+ ;;
+ logtarget)
+ if [[ "$cmd" == "set" ]];then
+ COMPREPLY=( $( compgen -W "STDOUT STDERR SYSLOG SYSOUT" -- "$cur" ) )
+ _filedir # And files
+ fi
+ return 0
+ ;;
+ *) # Jail name
+ COMPREPLY=( $( compgen -W \
+ "$( "$1" --help 2>/dev/null | awk '/^ '${cmd}' <JAIL>/{print $3}')" \
+ -- "$cur") )
+ return 0
+ ;;
+ esac
+ elif [[ -n "$jail" && -n "$action" ]];then
+ case ${words[$cwords-3]} in
+ action)
+ COMPREPLY=( $( compgen -W \
+ "$( __fail2ban_jail_action_properties "$1" "$jail" "$action")" \
+ -- "$cur" ) )
+ if [[ "$cmd" == "set" ]];then
+ COMPREPLY+=( $(compgen -W "$(__fail2ban_jail_action_methods "$1" "$jail" "$action")" -- "$cur" ) )
+ fi
+ return 0
+ ;;
+ esac
+ elif [[ -n "$jail" && $prev == action* ]];then
+ case $prev in
+ action|actionproperties|actionmethods)
+ COMPREPLY=( $(compgen -W "$(__fail2ban_jail_actions "$1" "$jail")" -- "$cur" ) )
+ return 0
+ ;;
+ esac
+ elif [[ -n "$jail" && "$cmd" == "set" ]];then
+ case $prev in
+ addlogpath)
+ _filedir
+ return 0
+ ;;
+ dellogpath|delignoreip)
+ COMPREPLY=( $( compgen -W \
+ "$( "$1" get "$jail" "${prev/del/}" 2>/dev/null | awk -F- '{print $2}')" \
+ -- "$cur" ) )
+ if [[ -z "$COMPREPLY" && "$prev" == "dellogpath" ]];then
+ _filedir
+ fi
+ return 0
+ ;;
+ delfailregex|delignoreregex)
+ COMPREPLY=( $( compgen -W \
+ "$( "$1" get "$jail" "${prev/del/}" 2>/dev/null | awk -F"[][]" '{print $2}')" \
+ -- "$cur" ) )
+ return 0
+ ;;
+ unbanip)
+ COMPREPLY=( $( compgen -W \
+ "$( "$1" status "$jail" 2>/dev/null | awk -F"\t+" '/IP list:/{print $2}')" \
+ -- "$cur" ) )
+ return 0
+ ;;
+ idle)
+ COMPREPLY=( $( compgen -W "on off" -- "$cur" ) )
+ return 0
+ ;;
+ usedns)
+ COMPREPLY=( $( compgen -W "yes no warn" -- "$cur" ) )
+ return 0
+ ;;
+ esac
+ fi
+
+ fi # fail2ban-client
+} &&
+complete -F _fail2ban fail2ban-client fail2ban-server fail2ban-regex
--- /dev/null
+# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Author: Cyril Jaquier
+#
+# $Revision$
+
+# Command line options for Fail2Ban. Refer to "fail2ban-client -h" for
+# valid options.
+FAIL2BAN_OPTS=""
+
+# Run fail2ban as a different user. If not set, fail2ban
+# will run as root.
+#
+# The user is not created automatically.
+# The user can be created e.g. with
+# useradd --system --no-create-home --home-dir / --groups adm fail2ban
+# Log files are readable by group adm by default. Adding the fail2ban
+# user to this group allows it to read the logfiles.
+#
+# Another manual step that needs to be taken is to allow write access
+# for fail2ban user to fail2ban log files. The /etc/init.d/fail2ban
+# script will change the ownership when starting fail2ban. Logrotate
+# needs to be configured separately, see /etc/logrotate.d/fail2ban.
+#
+# FAIL2BAN_USER="fail2ban"
--- /dev/null
+# Fail2ban configuration file
+#
+# Action to report IP address to abuseipdb.com
+# You must sign up to obtain an API key from abuseipdb.com.
+#
+# NOTE: These reports may include sensitive Info.
+# If you want cleaner reports that ensure no user data see the helper script at the below website.
+#
+# IMPORTANT:
+#
+# Reporting an IP of abuse is a serious complaint. Make sure that it is
+# serious. Fail2ban developers and network owners recommend you only use this
+# action for:
+# * The recidive where the IP has been banned multiple times
+# * Where maxretry has been set quite high, beyond the normal user typing
+# password incorrectly.
+# * For filters that have a low likelihood of receiving human errors
+#
+# This action relies on a api_key being added to the above action conf,
+# and the appropriate categories set.
+#
+# 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"]
+#
+# See below for catagories.
+#
+# 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.
+# Example, for ssh bruteforce: action = %(action_abuseipdb)s[abuseipdb_category="18,22"]
+# ID Title Description
+# 3 Fraud Orders
+# 4 DDoS Attack
+# 9 Open Proxy
+# 10 Web Spam
+# 11 Email Spam
+# 14 Port Scan
+# 18 Brute-Force
+# 19 Bad Web Bot
+# 20 Exploited Host
+# 21 Web App Attack
+# 22 SSH Secure Shell (SSH) abuse. Use this category in combination with more specific categories.
+# 23 IoT Targeted
+# See https://abuseipdb.com/categories for more descriptions
+
+[Definition]
+
+# Option: actionstart
+# Notes.: command executed once at the start of Fail2Ban.
+# Values: CMD
+#
+actionstart =
+
+# Option: actionstop
+# Notes.: command executed once 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.
+#
+# ** IMPORTANT! **
+#
+# By default, this posts directly to AbuseIPDB's API, unfortunately
+# this results in a lot of backslashes/escapes appearing in the
+# reports. This also may include info like your hostname.
+# If you have your own web server with PHP available, you can
+# use my (Shaun's) helper PHP script by commenting out the first #actionban
+# line below, uncommenting the second one, and pointing the URL at
+# 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 = curl --fail --ciphers ecdhe_ecdsa_aes_256_sha --data 'key=<abuseipdb_apikey>' --data-urlencode 'comment=<matches>' --data 'ip=<ip>' --data 'category=<abuseipdb_category>' "https://www.abuseipdb.com/report/json"
+
+# 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: abuseipdb_apikey
+# 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.
+abuseipdb_apikey =
from fail2ban.server.actions import ActionBase
-class BadIPsAction(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.
If invalid `category`, `score`, `banaction` or `updateperiod`.
"""
+ TIMEOUT = 10
_badips = "http://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"):
+ 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
# 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 getCategories(self, incParents=False):
"""Get badips.com categories.
"""
try:
response = urlopen(
- self._Request("/".join([self._badips, "get", "categories"])), None, 3)
+ self._Request("/".join([self._badips, "get", "categories"])), timeout=self.timeout)
except HTTPError as response:
messages = json.loads(response.read().decode('utf-8'))
self._logSys.error(
urlencode({'age': age})])
if key:
url = "&".join([url, urlencode({'key': key})])
- response = urlopen(self._Request(url))
+ response = urlopen(self._Request(url), timeout=self.timeout)
except HTTPError as response:
messages = json.loads(response.read().decode('utf-8'))
self._logSys.error(
url = "/".join([self._badips, "add", self.category, aInfo['ip']])
if self.key:
url = "?".join([url, urlencode({'key': self.key})])
- response = urlopen(self._Request(url))
+ response = urlopen(self._Request(url), timeout=self.timeout)
except HTTPError as response:
messages = json.loads(response.read().decode('utf-8'))
self._logSys.error(
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
-actionstart = ipfw show | fgrep -q 'table(<table>)' || ( ipfw show | awk 'BEGIN { b = 1 } { 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 || ( 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>" )
# Option: actionstop
# Values: STRING
#
blocktype = unreach port
+
+# Option: lowest_rule_num
+# Notes: When fail2ban starts with action and there is no rule for the given table yet
+# then fail2ban will start looking for an empty slot starting with this rule number.
+# Values: NUM
+lowest_rule_num = 111
+
+
# <time> unix timestamp of the ban time
# Values: CMD
#
-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 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
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# <time> unix timestamp of the ban time
# Values: CMD
#
-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 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)
[Init]
#
+[INCLUDES]
+
+before = helpers-common.conf
+
[Definition]
+# Used in test cases for coverage internal transformations
+debug = 0
+
+# bypass ban/unban for restored tickets
+norestored = 1
+
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
# Tags: See jail.conf(5) man page
# Values: CMD
#
-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}
- IP=<ip>
+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>
if [ ! -z "$ADDRESSES" ]; then
- (printf %%b "<message>\n"; date '+Note: Local timezone is %%z (%%Z)'; grep -E '(^|[^0-9])<ip>([^0-9]|$)' <logpath>) | <mailcmd> "Abuse from <ip>" <mailargs> ${ADDRESSES//,/\" \"}
+ ( printf %%b "<message>\n"; date '+Note: Local timezone is %%z (%%Z)';
+ printf %%b "\nLines containing failures of <ip> (max <grepmax>)\n";
+ %(_grep_logs)s;
+ ) | <mailcmd> "Abuse from <ip>" <mailargs> $ADDRESSES
fi
# Option: actionunban
#
actionunban =
-[Init]
+# Server as resolver used in dig command
+#
+addr_resolver = <ip-rev>abuse-contacts.abusix.org
+
+# Default message used for abuse content
+#
message = Dear Sir/Madam,\n\nWe have detected abuse from the IP address $IP, which according to a abusix.com is on your network. We would appreciate if you would investigate and take action as appropriate.\n\nLog lines are given below, but please ask if you require any further information.\n\n(If you are not the correct person to contact about this please accept our apologies - your e-mail address was extracted from the whois record by an automated process.)\n\n This mail was generated by Fail2Ban.\nThe recipient address of this report was provided by the Abuse Contact DB by abusix.com. abusix.com does not maintain the content of the database. All information which we pass out, derives from the RIR databases and is processed for ease of use. If you want to change or report non working abuse contacts please contact the appropriate RIR. If you have any further question, contact abusix.com directly via email (info@abusix.com). Information about the Abuse Contact Database can be found here: https://abusix.com/global-reporting/abuse-contact-db\nabusix.com is neither responsible nor liable for the content or accuracy of this message.\n
# Path to the log files which contain relevant lines for the abuser IP
#
mailargs =
+# Number of log lines to include in the email
+#
+#grepmax = 1000
+#grepopts = -m <grepmax>
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
-actionstart = touch /var/run/fail2ban/fail2ban.dummy
- printf %%b "<init>\n" >> /var/run/fail2ban/fail2ban.dummy
+actionstart = if [ ! -z '<target>' ]; then touch <target>; fi;
+ printf %%b "<init>\n" <to_target>
+ echo "%(debug)s started"
+
+# Option: actionflush
+# Notes.: command executed once to flush (clear) all IPS, by shutdown (resp. by stop of the jail or this action)
+# Values: CMD
+#
+actionflush = printf %%b "-*\n" <to_target>
+ echo "%(debug)s clear all"
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
-actionstop = rm -f /var/run/fail2ban/fail2ban.dummy
+actionstop = if [ ! -z '<target>' ]; then rm -f <target>; fi;
+ echo "%(debug)s stopped"
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionban = printf %%b "+<ip>\n" >> /var/run/fail2ban/fail2ban.dummy
+actionban = printf %%b "+<ip>\n" <to_target>
+ echo "%(debug)s banned <ip> (family: <family>)"
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionunban = printf %%b "-<ip>\n" >> /var/run/fail2ban/fail2ban.dummy
+actionunban = printf %%b "-<ip>\n" <to_target>
+ echo "%(debug)s unbanned <ip> (family: <family>)"
+
+
+debug = [<name>] <actname> <target> --
[Init]
init = 123
+target = /var/run/fail2ban/fail2ban.dummy
+to_target = >> <target>
[INCLUDES]
-before = iptables-blocktype.conf
+before = firewallcmd-common.conf
[Definition]
-actionstart = firewall-cmd --direct --add-chain ipv4 filter f2b-<name>
- firewall-cmd --direct --add-rule ipv4 filter f2b-<name> 1000 -j RETURN
- firewall-cmd --direct --add-rule ipv4 filter <chain> 0 -j f2b-<name>
+actionstart = firewall-cmd --direct --add-chain <family> filter f2b-<name>
+ firewall-cmd --direct --add-rule <family> filter f2b-<name> 1000 -j RETURN
+ firewall-cmd --direct --add-rule <family> filter <chain> 0 -j f2b-<name>
-actionstop = firewall-cmd --direct --remove-rule ipv4 filter <chain> 0 -j f2b-<name>
- firewall-cmd --direct --remove-rules ipv4 filter f2b-<name>
- firewall-cmd --direct --remove-chain ipv4 filter f2b-<name>
+actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 -j f2b-<name>
+ firewall-cmd --direct --remove-rules <family> filter f2b-<name>
+ firewall-cmd --direct --remove-chain <family> filter f2b-<name>
# Example actioncheck: firewall-cmd --direct --get-chains ipv4 filter | sed -e 's, ,\n,g' | grep -q '^f2b-recidive$'
-actioncheck = firewall-cmd --direct --get-chains ipv4 filter | sed -e 's, ,\n,g' | grep -q '^f2b-<name>$'
+actioncheck = firewall-cmd --direct --get-chains <family> filter | sed -e 's, ,\n,g' | grep -q '^f2b-<name>$'
-actionban = firewall-cmd --direct --add-rule ipv4 filter f2b-<name> 0 -s <ip> -j <blocktype>
+actionban = firewall-cmd --direct --add-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
-actionunban = firewall-cmd --direct --remove-rule ipv4 filter f2b-<name> 0 -s <ip> -j <blocktype>
-
-[Init]
-
-# Default name of the chain
-#
-name = default
-
-chain = INPUT_direct
+actionunban = firewall-cmd --direct --remove-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
# DEV NOTES:
#
--- /dev/null
+# Fail2Ban configuration file
+#
+# Author: Donald Yandt
+#
+
+[Init]
+
+# Option: name
+# Notes Default name of the chain
+# Values: STRING
+name = default
+
+# Option port
+# Notes Can also use port numbers separated by a comma and in rich-rules comma and/or space.
+# Value STRING Default: 1:65535
+port = 1:65535
+
+# Option: protocol
+# Notes [ tcp | udp | icmp | all ]
+# Values: STRING Default: tcp
+protocol = tcp
+
+# Option: family(ipv4)
+# Notes specifies the socket address family type
+# Values: STRING
+family = ipv4
+
+# Option: chain
+# Notes specifies the firewalld chain to which the Fail2Ban rules should be
+# added
+# Values: STRING Default: INPUT_direct
+chain = INPUT_direct
+
+# Option: zone
+# Notes use command firewall-cmd --get-active-zones to see a list of all active zones. See firewalld man pages for more information on zones
+# Values: STRING Default: public
+zone = public
+
+# Option: service
+# Notes use command firewall-cmd --get-services to see a list of services available
+# Examples services: amanda-client amanda-k5-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns freeipa-ldap freeipa-ldaps
+# freeipa-replication ftp high-availability http https imaps ipp ipp-client ipsec iscsi-target kadmin kerberos
+# kpasswd ldap ldaps libvirt libvirt-tls mdns mosh mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3s
+# postgresql privoxy proxy-dhcp puppetmaster radius rpc-bind rsyncd samba samba-client sane smtp squid ssh synergy
+# telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server
+# Values: STRING Default: ssh
+service = ssh
+
+# Option: rejecttype (ipv4)
+# Notes See iptables/firewalld man pages for ipv4 reject types.
+# Values: STRING
+rejecttype = icmp-port-unreachable
+
+# Option: blocktype (ipv4/ipv6)
+# Notes See iptables/firewalld man pages for jump targets. Common values are REJECT,
+# REJECT --reject-with icmp-port-unreachable, DROP
+# Values: STRING
+blocktype = REJECT --reject-with <rejecttype>
+
+# Option: rich-blocktype (ipv4/ipv6)
+# Notes See firewalld man pages for jump targets. Common values are reject,
+# reject type="icmp-port-unreachable", drop
+# Values: STRING
+rich-blocktype = reject type='<rejecttype>'
+
+[Init?family=inet6]
+
+# Option: family(ipv6)
+# Notes specifies the socket address family type
+# Values: STRING
+family = ipv6
+
+# Option: rejecttype (ipv6)
+# Note: See iptables/firewalld man pages for ipv6 reject types.
+# Values: STRING
+rejecttype = icmp6-port-unreachable
[INCLUDES]
-before = iptables-common.conf
+before = firewallcmd-common.conf
[Definition]
-actionstart = ipset create fail2ban-<name> hash:ip timeout <bantime>
- firewall-cmd --direct --add-rule ipv4 filter <chain> 0 -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j <blocktype>
+actionstart = ipset create <ipmset> hash:ip timeout <bantime><familyopt>
+ firewall-cmd --direct --add-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
-actionstop = firewall-cmd --direct --remove-rule ipv4 filter <chain> 0 -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j <blocktype>
- ipset flush fail2ban-<name>
- ipset destroy fail2ban-<name>
+actionflush = ipset flush <ipmset>
-actionban = ipset add fail2ban-<name> <ip> timeout <bantime> -exist
+actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
+ <actionflush>
+ ipset destroy <ipmset>
-actionunban = ipset del fail2ban-<name> <ip> -exist
+actionban = ipset add <ipmset> <ip> timeout <bantime> -exist
+
+actionunban = ipset del <ipmset> <ip> -exist
[Init]
bantime = 600
+# Option: actiontype
+# Notes.: defines additions to the blocking rule
+# Values: leave empty to block all attempts from the host
+# Default: Value of the multiport
+actiontype = <multiport>
+
+# Option: allports
+# Notes.: default addition to block all ports
+# Usage.: use in jail config: banaction = firewallcmd-ipset[actiontype=<allports>]
+# for all protocols: banaction = firewallcmd-ipset[actiontype=""]
+allports = -p <protocol>
+
+# Option: multiport
+# Notes.: addition to block access only to specific ports
+# Usage.: use in jail config: banaction = firewallcmd-ipset[actiontype=<multiport>]
+multiport = -p <protocol> -m multiport --dports <port>
+
+ipmset = f2b-<name>
+familyopt =
+
+[Init?family=inet6]
+
+ipmset = f2b-<name>6
+familyopt = <sp>family inet6
+
# DEV NOTES:
#
[INCLUDES]
-before = iptables-blocktype.conf
+before = firewallcmd-common.conf
[Definition]
-actionstart = firewall-cmd --direct --add-chain ipv4 filter f2b-<name>
- firewall-cmd --direct --add-rule ipv4 filter f2b-<name> 1000 -j RETURN
- firewall-cmd --direct --add-rule ipv4 filter <chain> 0 -m state --state NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
+actionstart = firewall-cmd --direct --add-chain <family> filter f2b-<name>
+ firewall-cmd --direct --add-rule <family> filter f2b-<name> 1000 -j RETURN
+ firewall-cmd --direct --add-rule <family> filter <chain> 0 -m conntrack --ctstate NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
-actionstop = firewall-cmd --direct --remove-rule ipv4 filter <chain> 0 -m state --state NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
- firewall-cmd --direct --remove-rules ipv4 filter f2b-<name>
- firewall-cmd --direct --remove-chain ipv4 filter f2b-<name>
+actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 -m conntrack --ctstate NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
+ firewall-cmd --direct --remove-rules <family> filter f2b-<name>
+ firewall-cmd --direct --remove-chain <family> filter f2b-<name>
# Example actioncheck: firewall-cmd --direct --get-chains ipv4 filter | sed -e 's, ,\n,g' | grep -q '^f2b-apache-modsecurity$'
-actioncheck = firewall-cmd --direct --get-chains ipv4 filter | sed -e 's, ,\n,g' | grep -q '^f2b-<name>$'
+actioncheck = firewall-cmd --direct --get-chains <family> filter | sed -e 's, ,\n,g' | grep -q '^f2b-<name>$'
-actionban = firewall-cmd --direct --add-rule ipv4 filter f2b-<name> 0 -s <ip> -j <blocktype>
-
-actionunban = firewall-cmd --direct --remove-rule ipv4 filter f2b-<name> 0 -s <ip> -j <blocktype>
-
-[Init]
-
-# Default name of the chain
-name = default
-
-chain = INPUT_direct
-
-# Could also use port numbers separated by a comma.
-port = 1:65535
-
-
-# Option: protocol
-# Values: [ tcp | udp | icmp | all ]
-
-protocol = tcp
-
-
-
-# DEV NOTES:
-#
-# Author: Donald Yandt
-# Uses "FirewallD" instead of the "iptables daemon".
-#
-#
-# Output:
-# actionstart:
-# $ firewall-cmd --direct --add-chain ipv4 filter f2b-apache-modsecurity
-# success
-# $ firewall-cmd --direct --add-rule ipv4 filter f2b-apache-modsecurity 1000 -j RETURN
-# success
-# $ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT_direct 0 -m state --state NEW -p tcp -m multiport --dports 80,443 -j f2b-apache-modsecurity
-# success
-# actioncheck:
-# $ firewall-cmd --direct --get-chains ipv4 filter f2b-apache-modsecurity | sed -e 's, ,\n,g' | grep -q '^f2b-apache-modsecurity$'
-# f2b-apache-modsecurity
+actionban = firewall-cmd --direct --add-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
+actionunban = firewall-cmd --direct --remove-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
[INCLUDES]
-before = iptables-common.conf
+before = firewallcmd-common.conf
[Definition]
-actionstart = firewall-cmd --direct --add-chain ipv4 filter f2b-<name>
- firewall-cmd --direct --add-rule ipv4 filter f2b-<name> 1000 -j RETURN
- firewall-cmd --direct --add-rule ipv4 filter <chain> 0 -m state --state NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
+actionstart = firewall-cmd --direct --add-chain <family> filter f2b-<name>
+ firewall-cmd --direct --add-rule <family> filter f2b-<name> 1000 -j RETURN
+ firewall-cmd --direct --add-rule <family> filter <chain> 0 -m state --state NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
-actionstop = firewall-cmd --direct --remove-rule ipv4 filter <chain> 0 -m state --state NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
- firewall-cmd --direct --remove-rules ipv4 filter f2b-<name>
- firewall-cmd --direct --remove-chain ipv4 filter f2b-<name>
+actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 -m state --state NEW -p <protocol> -m multiport --dports <port> -j f2b-<name>
+ firewall-cmd --direct --remove-rules <family> filter f2b-<name>
+ firewall-cmd --direct --remove-chain <family> filter f2b-<name>
-actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -q 'f2b-<name>$'
+actioncheck = firewall-cmd --direct --get-chains <family> filter | sed -e 's, ,\n,g' | grep -q 'f2b-<name>$'
-actionban = firewall-cmd --direct --add-rule ipv4 filter f2b-<name> 0 -s <ip> -j <blocktype>
+actionban = firewall-cmd --direct --add-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
-actionunban = firewall-cmd --direct --remove-rule ipv4 filter f2b-<name> 0 -s <ip> -j <blocktype>
-
-[Init]
-
-# Option: chain
-# Notes specifies the iptables chain to which the fail2ban rules should be
-# added
-# Values: [ STRING ]
-#
-chain = INPUT_direct
+actionunban = firewall-cmd --direct --remove-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
# DEV NOTES:
#
--- /dev/null
+# Fail2Ban configuration file
+#
+# Author: Donald Yandt
+#
+# 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
+# by chain. So for an example all deny rules will be listed under <zone>_deny and all log rules under <zone>_log.
+#
+# Also this action logs banned access attempts so you can filter that and increase ban time for offenders.
+#
+# 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'
+
+[INCLUDES]
+
+before = firewallcmd-common.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
+
+[Init]
+
+# log levels are "emerg", "alert", "crit", "error", "warning", "notice", "info" or "debug"
+level = info
+
+# log rate per minute
+rate = 1
+
--- /dev/null
+# Fail2Ban configuration file
+#
+# Author: Donald Yandt
+#
+# 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
+# by chain. So for an example all deny rules will be listed under <zone>_deny.
+#
+# 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'
+
+[INCLUDES]
+
+before = firewallcmd-common.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='ipv4' source address='<ip>' port port='<port>' protocol='<protocol>' <rich-blocktype>"
+#
+# service name example:
+# firewall-cmd --zone=<zone> --add-rich-rule="rule family='ipv4' source address='<ip>' service name='<service>' <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>' <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
+
+
--- /dev/null
+[DEFAULT]\r
+\r
+# Usage:\r
+# _grep_logs_args = 'test'\r
+# (printf %%b "Log-excerpt contains 'test':\n"; %(_grep_logs)s; printf %%b "Log-excerpt contains 'test':\n") | mail ...\r
+#\r
+_grep_logs = logpath="<logpath>"; grep <grepopts> -E %(_grep_logs_args)s $logpath | <greplimit>\r
+_grep_logs_args = "(^|[^0-9a-fA-F:])$(echo '<ip>' | sed 's/\./\\./g')([^0-9a-fA-F:]|$)"\r
+\r
+# Used for actions, that should not by executed if ticket was restored:\r
+_bypass_if_restored = if [ '<restored>' = '1' ]; then exit 0; fi;\r
+\r
+[Init]\r
+greplimit = tail -n <grepmax>\r
+grepmax = 1000\r
+grepopts = -m <grepmax>\r
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionban = IP=<ip> &&
- printf %%b "<daemon_list>: $IP\n" >> <file>
+actionban = IP=<ip> && printf %%b "<daemon_list>: $IP\n" >> <file>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionunban = echo "/^<daemon_list>: <ip>$/<br>d<br>w<br>q" | ed <file>
+actionunban = IP=$(echo <ip> | sed 's/\./\\./g') && sed -i "/^<daemon_list>: $IP$/d" <file>
[Init]
# Values: CMD
#
actionstop = <iptables> -D <chain> -p <protocol> -j f2b-<name>
- <iptables> -F f2b-<name>
+ <actionflush>
<iptables> -X f2b-<name>
# Option: actioncheck
# 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]
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.: 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>
+
actionstart = ipset --create f2b-<name> iphash
<iptables> -I <chain> -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> 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 f2b-<name>
+
# Option: actionstop
# Notes.: command executed once 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>
- ipset --flush f2b-<name>
+ <actionflush>
ipset --destroy f2b-<name>
# Option: actionban
#
# If you are running on an older kernel you make need to patch in external
# modules which probably won't be protocol version 6.
+#
+# 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]
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
-actionstart = ipset create f2b-<name> hash:ip timeout <bantime>
- <iptables> -I <chain> -m set --match-set f2b-<name> src -j <blocktype>
+actionstart = ipset create <ipmset> hash:ip timeout <bantime><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 once at the end of Fail2Ban
# Values: CMD
#
-actionstop = <iptables> -D <chain> -m set --match-set f2b-<name> src -j <blocktype>
- ipset flush f2b-<name>
- ipset destroy f2b-<name>
+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
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionban = ipset add f2b-<name> <ip> timeout <bantime> -exist
+actionban = ipset add <ipmset> <ip> timeout <bantime> -exist
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionunban = ipset del f2b-<name> <ip> -exist
+actionunban = ipset del <ipmset> <ip> -exist
[Init]
# Values: [ NUM ] Default: 600
#
bantime = 600
+
+ipmset = f2b-<name>
+familyopt =
+
+
+[Init?family=inet6]
+
+ipmset = f2b-<name>6
+familyopt = <sp>family inet6
#
# If you are running on an older kernel you make need to patch in external
# modules.
+#
+# 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]
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
-actionstart = ipset create f2b-<name> hash:ip timeout <bantime>
- <iptables> -I <chain> -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype>
+actionstart = ipset create <ipmset> hash:ip timeout <bantime><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 once 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>
- ipset flush f2b-<name>
- ipset destroy f2b-<name>
+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
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionban = ipset add f2b-<name> <ip> timeout <bantime> -exist
+actionban = ipset add <ipmset> <ip> timeout <bantime> -exist
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionunban = ipset del f2b-<name> <ip> -exist
+actionunban = ipset del <ipmset> <ip> -exist
[Init]
# Values: [ NUM ] Default: 600
#
bantime = 600
+
+ipmset = f2b-<name>
+familyopt =
+
+
+[Init?family=inet6]
+
+ipmset = f2b-<name>6
+familyopt = <sp>family inet6
<iptables> -I f2b-<name>-log -j LOG --log-prefix "$(expr f2b-<name> : '\(.\{1,23\}\)'):DROP " --log-level warning -m limit --limit 6/m --limit-burst 2
<iptables> -A f2b-<name>-log -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 = <iptables> -F f2b-<name>
+ <iptables> -F f2b-<name>-log
+
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
- <iptables> -F f2b-<name>
- <iptables> -F f2b-<name>-log
+ <actionflush>
<iptables> -X f2b-<name>
<iptables> -X f2b-<name>-log
# Values: CMD
#
actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
- <iptables> -F f2b-<name>
+ <actionflush>
<iptables> -X f2b-<name>
# Option: actioncheck
# Values: CMD
#
actionstop = <iptables> -D <chain> -m state --state NEW -p <protocol> --dport <port> -j f2b-<name>
- <iptables> -F f2b-<name>
+ <actionflush>
<iptables> -X f2b-<name>
# Option: actioncheck
#
# Author: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
#
-#
+# Modified: Alexander Koeppe <format_c@online.de>, Serg G. Brester <serg.brester@sebres.de>
+# made config file IPv6 capable
[INCLUDES]
# iptables-persistent package).
#
# Explanation of the rule below:
-# Check if any packets coming from an IP on the f2b-<name>
+# Check if any packets coming from an IP on the <iptname>
# list have been seen in the last 3600 seconds. If yes, update the
# timestamp for this IP and drop the packet. If not, let the packet
# through.
#
-# Fail2ban inserts blacklisted hosts into the f2b-<name> list
+# Fail2ban inserts blacklisted hosts into the <iptname> list
# and removes them from the list after some time, according to its
# 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 f2b-<name> -j <blocktype>;fi
+actionstart = if [ `id -u` -eq 0 ];then <iptables> -I <chain> -m recent --update --seconds 3600 --name <iptname> -j <blocktype>;fi
+
+# Option: actionflush
+#
+# [TODO] Flushing is currently not implemented for xt_recent
+#
+actionflush =
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
-actionstop = echo / > /proc/net/xt_recent/f2b-<name>
- if [ `id -u` -eq 0 ];then <iptables> -D <chain> -m recent --update --seconds 3600 --name f2b-<name> -j <blocktype>;fi
+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
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
-actioncheck = test -e /proc/net/xt_recent/f2b-<name>
+actioncheck = test -e /proc/net/xt_recent/<iptname>
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionban = echo +<ip> > /proc/net/xt_recent/f2b-<name>
+actionban = echo +<ip> > /proc/net/xt_recent/<iptname>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionunban = echo -<ip> > /proc/net/xt_recent/f2b-<name>
+actionunban = echo -<ip> > /proc/net/xt_recent/<iptname>
[Init]
+iptname = f2b-<name>
+
+[Init?family=inet6]
+
+iptname = f2b-<name>6
# Values: CMD
#
actionstop = <iptables> -D <chain> -p <protocol> --dport <port> -j f2b-<name>
- <iptables> -F f2b-<name>
+ <actionflush>
<iptables> -X f2b-<name>
# Option: actioncheck
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
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 `uname -n`" <dest>
+ Fail2Ban"|mail -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
These hosts have been banned by Fail2Ban.\n
`cat <tmpfile>`
Regards,\n
- Fail2Ban"|mail -s "[Fail2Ban] <name>: Summary from `uname -n`" <dest>
+ Fail2Ban"|mail -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 `uname -n`" <dest>
+ Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
# Option: actioncheck
# Notes.: command executed once before each actionban command
[INCLUDES]
before = mail-whois-common.conf
+ helpers-common.conf
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
actionstart = printf %%b "Hi,\n
The jail <name> has been started successfully.\n
Regards,\n
- Fail2Ban"|mail -s "[Fail2Ban] <name>: started on `uname -n`" <dest>
+ Fail2Ban" | <mailcmd> "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
actionstop = printf %%b "Hi,\n
The jail <name> has been stopped.\n
Regards,\n
- Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on `uname -n`" <dest>
+ Fail2Ban" | <mailcmd> "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionban = printf %%b "Hi,\n
+
+_ban_mail_content = ( printf %%b "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
- `%(_whois_command)s`\n\n
- Lines containing IP:<ip> in <logpath>\n
- `grep -E <grepopts> '(^|[^0-9])<ip>([^0-9]|$)' <logpath>`\n\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"|mail -s "[Fail2Ban] <name>: banned <ip> from `uname -n`" <dest>
+ Fail2Ban" )
+
+actionban = %(_ban_mail_content)s | <mailcmd> "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
[Init]
+# Option: mailcmd
+# Notes.: Your system mail command. Is passed 2 args: subject and recipient
+# Values: CMD
+#
+mailcmd = mail -s
+
# Default name of the chain
#
name = default
# Number of log lines to include in the email
#
-grepopts = -m 1000
+#grepmax = 1000
+#grepopts = -m <grepmax>
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
actionstart = printf %%b "Hi,\n
The jail <name> has been started successfully.\n
Regards,\n
- Fail2Ban"|mail -s "[Fail2Ban] <name>: started on `uname -n`" <dest>
+ Fail2Ban"|mail -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
actionstop = printf %%b "Hi,\n
The jail <name> has been stopped.\n
Regards,\n
- Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on `uname -n`" <dest>
+ Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
# Option: actioncheck
# Notes.: command executed once before each actionban command
Here is more information about <ip> :\n
`%(_whois_command)s`\n
Regards,\n
- Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from `uname -n`" <dest>
+ Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
actionstart = printf %%b "Hi,\n
The jail <name> has been started successfully.\n
Regards,\n
- Fail2Ban"|mail -s "[Fail2Ban] <name>: started on `uname -n`" <dest>
+ Fail2Ban"|mail -s "[Fail2Ban] <name>: started on <fq-hostname>" <dest>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
actionstop = printf %%b "Hi,\n
The jail <name> has been stopped.\n
Regards,\n
- Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on `uname -n`" <dest>
+ Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on <fq-hostname>" <dest>
# Option: actioncheck
# Notes.: command executed once before each actionban command
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 `uname -n`" <dest>
+ Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from <fq-hostname>" <dest>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
--- /dev/null
+# Fail2ban Citrix Netscaler Action
+# by Juliano Jeziorny
+# juliano@jeziorny.eu
+#
+# The script will add offender IPs to a dataset on netscaler, the dataset can then be used to block the IPs at a cs/vserver or global level
+# This dataset is then used to block IPs using responder policies on the netscaler.
+#
+# The script assumes using HTTPS with unsecure certificate to access the netscaler,
+# if you have a valid certificate installed remove the -k from the curl lines, or if you want http change it accordingly (and remove the -k)
+#
+# This action depends on curl
+#
+# You need to populate the 3 options inside Init
+#
+# ns_host: IP or hostname of netslcaer appliance
+# ns_auth: username:password, suggest base64 encoded for a little added security (echo -n "username:password" | base64)
+# ns_dataset: Name of the netscaler dataset holding the IPs to be blocked.
+#
+# For further details on how to use it please check http://blog.ckzone.eu/2017/01/fail2ban-action-for-citrix-netscaler.html
+
+[Init]
+ns_host =
+ns_auth =
+ns_dataset =
+
+[Definition]
+actionstart = curl -kH 'Authorization: Basic <ns_auth>' https://<ns_host>/nitro/v1/config
+
+actioncheck =
+
+actionban = curl -k -H 'Authorization: Basic <ns_auth>' -X PUT -d '{"policydataset_value_binding":{"name":"<ns_dataset>","value":"<ip>"}}' https://<ns_host>/nitro/v1/config/
+
+actionunban = curl -H 'Authorization: Basic <ns_auth>' -X DELETE -k "https://<ns_host>/nitro/v1/config/policydataset_value_binding/<ns_dataset>?args=value:<ip>"
# Notes.: additional expressions for nftables filter rule
# Values: nftables expressions
#
-nftables_mode = ip protocol <protocol>
+nftables_mode = meta l4proto <protocol>
[Init]
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
-actionstart = <nftables> add set <nftables_family> <nftables_table> f2b-<name> \{ type <nftables_type>\; \}
- <nftables> insert rule <nftables_family> <nftables_table> <chain> %(nftables_mode)s ip saddr @f2b-<name> <blocktype>
+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 'ip saddr @f2b-<name> <blocktype> # handle' | grep -oe ' handle [0-9]*'
+_nft_get_handle_id = grep -m1 '<address_family> saddr @<set_name> <blocktype> # handle' | grep -oe ' handle [0-9]*'
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
#
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> f2b-<name>
+ <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 '@f2b-<name>[ \t]'
+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
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionban = <nftables> add element <nftables_family> <nftables_table> f2b-<name> \{ <ip> \}
+actionban = <nftables> add element <nftables_family> <nftables_table> <set_name> \{ <ip> \}
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionunban = <nftables> delete element <nftables_family> <nftables_table> f2b-<name> \{ <ip> \}
+actionunban = <nftables> delete element <nftables_family> <nftables_table> <set_name> \{ <ip> \}
[Init]
# 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
--- /dev/null
+# Fail2Ban configuration file for black-listing via nginx
+#
+# Author: Serg G. Brester (aka sebres)
+#
+# To use 'nginx-block-map' action you should define some special blocks in your nginx configuration,
+# and use it hereafter in your locations (to notify fail2ban by failure, resp. nginx by ban).
+#
+# Example (argument "token_id" resp. cookie "session_id" used here as unique identifier for user):
+#
+# http {
+# ...
+# # maps to check user is blacklisted (banned in f2b):
+# #map $arg_token_id $blck_lst_tok { include blacklisted-tokens.map; }
+# map $cookie_session_id $blck_lst_ses { include blacklisted-sessions.map; }
+# ...
+# # special log-format to notify fail2ban about failures:
+# log_format f2b_session_errors '$msec failure "$cookie_session_id" - $remote_addr - $remote_user '
+# ;# '"$request" $status $bytes_sent '
+# # '"$http_referer" "$http_user_agent"';
+#
+# # location checking blacklisted values:
+# location ... {
+# # check banned sessionid:
+# if ($blck_lst_ses != "") {
+# try_files "" @f2b-banned;
+# }
+# ...
+# # notify fail2ban about a failure inside nginx:
+# error_page 401 = @notify-f2b;
+# ...
+# }
+# ...
+# # location for return with "403 Forbidden" if banned:
+# location @f2b-banned {
+# default_type text/html;
+# return 403 "<br/><center>
+# <b style=\"color:red; font-size:18pt; border:2pt solid black; padding:5pt;\">
+# You are banned!</b></center>";
+# }
+# ...
+# # location to notify fail2ban about a failure inside nginx:
+# location @notify-f2b {
+# access_log /var/log/nginx/f2b-auth-errors.log f2b_session_errors;
+# }
+# }
+# ...
+#
+# Note that quote-character (and possibly other special characters) are not allowed currently as session-id.
+# Thus please add any session-id validation rule in your locations (or in the corresponding backend-service),
+# like in example below:
+#
+# location ... {
+# if ($cookie_session_id !~ "^[\w\-]+$") {
+# return 403 "Wrong session-id"
+# }
+# ...
+# }
+#
+# The parameters for jail corresponding log-format (f2b_session_errors):
+#
+# [nginx-blck-lst]
+# filter =
+# datepattern = ^Epoch
+# failregex = ^ failure "<F-ID>[^"]+</F-ID>" - <ADDR>
+# usedns = no
+#
+# The same log-file can be used for IP-related jail (additionally to session-related, to ban very bad IPs):
+#
+# [nginx-blck-ip]
+# maxretry = 100
+# filter =
+# datepattern = ^Epoch
+# failregex = ^ failure "[^"]+" - <ADDR>
+# usedns = no
+#
+
+[Definition]
+
+# path to configuration of nginx (used to target nginx-instance in multi-instance system,
+# and as path for the blacklisted map):
+srv_cfg_path = /etc/nginx/
+
+# cmd-line arguments to supply to test/reload 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
+ %(srv_cmd)s -s reload; if [ $? -ne 0 ]; then echo 'reload failed.'; fi;
+ fi;
+
+# map-file for nginx, can be redefined using `action = nginx-block-map[blck_lst_file="/path/file.map"]`:
+blck_lst_file = %(srv_cfg_path)s/blacklisted-sessions.map
+
+# Action definition:
+
+actionstart_on_demand = false
+actionstart = touch '%(blck_lst_file)s'
+
+actionflush = truncate -s 0 '%(blck_lst_file)s'; %(blck_lst_reload)s
+
+actionstop = %(actionflush)s
+
+actioncheck =
+
+actionban = echo "\\\\<fid> 1;" >> '%(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
--- /dev/null
+# Fail2Ban configuration file
+#
+# NetBSD npf ban/unban
+#
+# Author: Nils Ratusznik <nils@NetBSD.org>
+# Based on pf.conf action file
+#
+
+[Definition]
+
+# Option: actionstart
+# Notes.: command executed once at the start of Fail2Ban.
+# Values: CMD
+#
+# we don't enable NPF automatically, as it will be enabled elsewhere
+actionstart =
+
+
+# Option: actionstop
+# Notes.: command executed once at the end of Fail2Ban
+# Values: CMD
+#
+# we don't disable NPF automatically either
+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 = /sbin/npfctl table <tablename> add <ip>
+
+
+# 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
+#
+# note -r option used to remove matching rule
+actionunban = /sbin/npfctl table <tablename> rem <ip>
+
+[Init]
+# Option: tablename
+# Notes.: The pf table name.
+# Values: [ STRING ]
+#
+tablename = fail2ban
# OpenBSD pf ban/unban
#
# Author: Nick Hilliard <nick@foobar.org>
+# Modified by: Alexander Koeppe making PF work seamless and with IPv4 and IPv6
#
#
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
-# we don't enable PF automatically, as it will be enabled elsewhere
-actionstart =
+# we don't enable PF automatically; to enable run pfctl -e
+# or add `pf_enable="YES"` to /etc/rc.conf (tested on FreeBSD)
+# also, these rulesets are loaded into (nested) anchors
+# to enable them, add as wildcard:
+# anchor "f2b/*"
+# or using jail names:
+# anchor f2b {
+# anchor name1
+# anchor name2
+# ...
+# }
+# to your main pf ruleset, where "namei" are the names of the jails
+# which invoke this action
+actionstart = echo "table <<tablename>-<name>> persist counters" | <pfctl> -f-
+ port="<port>"; if [ "$port" != "" ] && case "$port" in \{*) false;; esac; then port="{$port}"; fi
+ echo "<block> proto <protocol> from <<tablename>-<name>> to <actiontype>" | <pfctl> -f-
+# Option: start_on_demand - to start action on demand
+# Example: `action=pf[actionstart_on_demand=true]`
+actionstart_on_demand = false
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
-# we don't disable PF automatically either
-actionstop =
+# we only disable PF rules we've installed prior
+actionstop = <pfctl> -sr 2>/dev/null | grep -v <tablename>-<name> | <pfctl> -f-
+ %(actionflush)s
+ <pfctl> -t <tablename>-<name> -T kill
+
+
+# Option: actionflush
+# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action)
+# Values: CMD
+#
+actionflush = <pfctl> -t <tablename>-<name> -T flush
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
-actioncheck =
+actioncheck = <pfctl> -sr | grep -q <tablename>-<name>
# Option: actionban
# <time> unix timestamp of the ban time
# Values: CMD
#
-actionban = /sbin/pfctl -t <tablename> -T add <ip>/32
+actionban = <pfctl> -t <tablename>-<name> -T add <ip>
# Option: actionunban
# Values: CMD
#
# note -r option used to remove matching rule
-actionunban = /sbin/pfctl -t <tablename> -T delete <ip>/32
+actionunban = <pfctl> -t <tablename>-<name> -T delete <ip>
+
+# Option: pfctl
+#
+# Use anchor as jailname to manipulate affected rulesets only.
+# If more parameter expected it can be extended with `pf[pfctl="<known/pfctl> ..."]`
+#
+pfctl = pfctl -a f2b/<name>
[Init]
# Option: tablename
# Notes.: The pf table name.
# Values: [ STRING ]
#
-tablename = fail2ban
+tablename = f2b
+
+# Option: block
+#
+# The action you want pf to take.
+# Probably, you want "block quick", but adjust as needed.
+block = block quick
+
+# Option: protocol
+# Notes.: internally used by config reader for interpolations.
+# Values: [ tcp | udp | icmp | ipv6-icmp ] Default: tcp
+#
+protocol = tcp
+
+# Option: actiontype
+# Notes.: defines additions to the blocking rule
+# Values: leave empty to block all attempts from the host
+# Default: Value of the multiport
+actiontype = <multiport>
+
+# Option: allports
+# Notes.: default addition to block all ports
+# Usage.: use in jail config: "banaction = pf[actiontype=<allports>]"
+allports = any
+
+# Option: multiport
+# Notes.: addition to block access only to specific ports
+# Usage.: use in jail config: "banaction = pf[actiontype=<multiport>]"
+multiport = any port $port
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
-actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on `uname -n`
+actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on <fq-hostname>
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
# Values: CMD
#
actionstop = if [ -f <tmpfile> ]; then
- printf %%b "Subject: [Fail2Ban] <name>: summary from `uname -n`
+ printf %%b "Subject: [Fail2Ban] <name>: summary from <fq-hostname>
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest>
rm <tmpfile>
fi
- printf %%b "Subject: [Fail2Ban] <name>: stopped on `uname -n`
+ printf %%b "Subject: [Fail2Ban] <name>: stopped on <fq-hostname>
From: Fail2Ban <<sender>>
To: <dest>\n
Hi,\n
actionban = printf %%b "`date`: <ip> (<failures> failures)\n" >> <tmpfile>
LINE=$( wc -l <tmpfile> | awk '{ print $1 }' )
if [ $LINE -ge <lines> ]; then
- printf %%b "Subject: [Fail2Ban] <name>: summary from `uname -n`
+ printf %%b "Subject: [Fail2Ban] <name>: summary from <fq-hostname>
From: <sendername> <<sender>>
To: <dest>\n
Hi,\n
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
-actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on `uname -n`
+actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
-actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped on `uname -n`
+actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped on <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
[INCLUDES]
before = sendmail-common.conf
+ helpers-common.conf
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# 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 "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
+actionban = ( printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
http://whois.domaintools.com/<ip>\n\n
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: `host -t A <ip> 2>&1`\n\n
- Lines containing IP:<ip> in <logpath>\n
- `grep -E <grepopts> '(^|[^0-9])<ip>([^0-9]|$)' <logpath>`\n\n
+ hostname: <ip-host>\n\n
+ Lines containing failures of <ip>\n";
+ %(_grep_logs)s;
+ printf %%b "\n
Regards,\n
- Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest>
+ Fail2Ban" ) | /usr/sbin/sendmail -f <sender> <dest>
[Init]
# Number of log lines to include in the email
#
-grepopts = -m 1000
+#grepmax = 1000
+#grepopts = -m <grepmax>
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# 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 "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
+actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# 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 "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
+actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
[INCLUDES]
before = sendmail-common.conf
+ helpers-common.conf
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# 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 "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
+actionban = ( printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
<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 IP:<ip> in <logpath>\n
- `grep -E <grepopts> '(^|[^0-9])<ip>([^0-9]|$)' <logpath>`\n\n
+ Lines containing failures of <ip>\n";
+ %(_grep_logs)s;
+ printf %%b "\n
Regards,\n
- Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest>
+ Fail2Ban" ) | /usr/sbin/sendmail -f <sender> <dest>
[Init]
# Number of log lines to include in the email
#
-grepopts = -m 1000
+#grepmax = 1000
+#grepopts = -m <grepmax>
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# 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 "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
+actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# 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 "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
+actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
# 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 "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
+actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from <fq-hostname>
Date: `LC_ALL=C date +"%%a, %%d %%h %%Y %%T %%z"`
From: <sendername> <<sender>>
To: <dest>\n
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionban = shorewall <blocktype> <ip>
+actionban = shorewall<family> <blocktype> <ip>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# Tags: See jail.conf(5) man page
# Values: CMD
#
-actionunban = shorewall allow <ip>
+actionunban = shorewall<family> allow <ip>
+
[Init]
+# Option: family
+# Note: Control which version of command is executed
+# Values: Empty or 6 in case of IPv6
+family =
+
# Option: blocktype
# Note: This is what the action does with rules.
# See man page of shorewall for options that include drop, logdrop, reject, or logreject
# Values: STRING
blocktype = reject
+
+[Init?family=inet6]
+
+# Option: family
+# Note: Control which version of command is executed
+# Values: Empty or 6 in case of IPv6
+family = 6
+
self.message_values = CallingMap(
jailname = self._jail.name,
hostname = socket.gethostname,
- bantime = self._jail.actions.getBanTime,
+ bantime = lambda: self._jail.actions.getBanTime(),
)
+ # bypass ban/unban for restored tickets
+ self.norestored = 1
+
def _sendMessage(self, subject, text):
"""Sends message based on arguments and instance's properties.
Dictionary which includes information in relation to
the ban.
"""
+ if aInfo.get('restored'):
+ return
aInfo.update(self.message_values)
message = "".join([
messages['ban']['head'],
# Login-Attack, Malware-Attack, Fraud (Phishing, etc.), Info DNSBL
#
# For details see:
-# https://github.com/abusix/xarf-specification
+# https://github.com/xarf/xarf-specification
# http://www.x-arf.org/schemata.html
#
# Author: Daniel Black
[Definition]
+# bypass ban/unban for restored tickets
+norestored = 1
+
actionstart =
actionstop =
FROM=<sender>
SERVICE=<service>
FAILURES=<failures>
- REPORTID=<time>@`uname -n`
+ REPORTID=<time>@<fq-hostname>
TLP=<tlp>
PORT=<port>
DATE=`LC_ALL=C date --date=@<time> +"%%a, %%d %%h %%Y %%T %%z"`
if [ ! -z "$ADDRESSES" ]; then
- (printf -- %%b "<header>\n<message>\n<report>\n";
+ (printf -- %%b "<header>\n<message>\n<report>\n\n";
date '+Note: Local timezone is %%z (%%Z)';
- printf -- %%b "<ipmatches>\n\n<footer>") | <mailcmd> <mailargs> ${ADDRESSES//,/\" \"}
+ printf -- %%b "\n<ipmatches>\n\n<footer>") | <mailcmd> <mailargs> ${ADDRESSES//,/\" \"}
fi
actionunban =
# Option: sender
# Notes.: This is the sender that is included in the XARF report
-sender = fail2ban@`uname -n`
+sender = fail2ban@<fq-hostname>
# Option: port
# Notes.: This is the port number that received the login-attack
# using logrotate -- also adjust or disable rotation in the
# corresponding configuration file
# (e.g. /etc/logrotate.d/fail2ban on Debian systems)
-# Values: [ STDOUT | STDERR | SYSLOG | FILE ] Default: STDERR
+# Values: [ STDOUT | STDERR | SYSLOG | SYSOUT | FILE ] Default: STDERR
#
logtarget = /var/log/fail2ban.log
# Options: dbpurgeage
# Notes.: Sets age at which bans should be purged from the database
# Values: [ SECONDS ] Default: 86400 (24hours)
-dbpurgeage = 86400
+dbpurgeage = 1d
ignoreregex =
+datepattern = {^LN-BEG}
+
# DEV Notes:
# http://www.3proxy.ru/howtoe.asp#ERRORS indicates that 01-09 are
# all authentication problems (%E field)
[Definition]
+prefregex = ^%(_apache_error_client)s (?:AH\d+: )?<F-CONTENT>.+</F-CONTENT>$
-failregex = ^%(_apache_error_client)s (AH(01797|01630): )?client denied by server configuration: (uri )?\S*(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH01617: )?user .*? authentication failure for "\S*": Password Mismatch(, referer: \S+)?$
- ^%(_apache_error_client)s (AH01618: )?user .*? not found(: )?\S*(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH01614: )?client used wrong authentication scheme: \S*(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH\d+: )?Authorization of user \S+ to access \S* failed, reason: .*$
- ^%(_apache_error_client)s (AH0179[24]: )?(Digest: )?user .*?: password mismatch: \S*(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH0179[01]: |Digest: )user `.*?' in realm `.+' (not found|denied by provider): \S*(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH01631: )?user .*?: authorization failure for "\S*":(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH01775: )?(Digest: )?invalid nonce .* received - length is not \S+(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH01788: )?(Digest: )?realm mismatch - got `.*?' but expected `.+'(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH01789: )?(Digest: )?unknown algorithm `.*?' received: \S*(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH01793: )?invalid qop `.*?' received: \S*(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH01777: )?(Digest: )?invalid nonce .*? received - user attempted time travel(, referer: \S+)?\s*$
+# auth_type = ((?:Digest|Basic): )?
+auth_type = ([A-Z]\w+: )?
+
+failregex = ^client (?:denied by server configuration|used wrong authentication scheme)\b
+ ^user <F-USER>(?:\S*|.*?)</F-USER> (?:auth(?:oriz|entic)ation failure|not found|denied by provider)\b
+ ^Authorization of user <F-USER>(?:\S*|.*?)</F-USER> to access .*? failed\b
+ ^%(auth_type)suser <F-USER>(?:\S*|.*?)</F-USER>: password mismatch\b
+ ^%(auth_type)suser `<F-USER>(?:[^']*|.*?)</F-USER>' in realm `.+' (not found|denied by provider)\b
+ ^%(auth_type)sinvalid nonce .* received - length is not\b
+ ^%(auth_type)srealm mismatch - got `(?:[^']*|.*?)' but expected\b
+ ^%(auth_type)sunknown algorithm `(?:[^']*|.*?)' received\b
+ ^invalid qop `(?:[^']*|.*?)' received\b
+ ^%(auth_type)sinvalid nonce .*? received - user attempted time travel\b
ignoreregex =
# all of these expressions. Lots of submodules like mod_authz_* return back to mod_authz_core
# to return the actual failure.
#
+# Note that URI can contain spaces.
+#
# See also: http://wiki.apache.org/httpd/ListOfErrors
# Expressions that don't have tests and aren't common.
# more be added with https://issues.apache.org/bugzilla/show_bug.cgi?id=55284
-# ^%(_apache_error_client)s (AH01778: )?user .*: nonce expired \([\d.]+ seconds old - max lifetime [\d.]+\) - sending new nonce\s*$
-# ^%(_apache_error_client)s (AH01779: )?user .*: one-time-nonce mismatch - sending new nonce\s*$
-# ^%(_apache_error_client)s (AH02486: )?realm mismatch - got `.*' but no realm specified\s*$
+# ^user .*: nonce expired \([\d.]+ seconds old - max lifetime [\d.]+\) - sending new nonce\s*$
+# ^user .*: one-time-nonce mismatch - sending new nonce\s*$
+# ^realm mismatch - got `(?:[^']*|.*?)' but no realm specified\s*$
#
-# referer is always in error log messages if it exists added as per the log_error_core function in server/log.c
+# Because url/referer are foreign input, short form of regex used if long enough to idetify failure.
#
# Author: Cyril Jaquier
-# Major edits by Daniel Black
+# Major edits by Daniel Black and Ben Rubson.
+# Rewritten for v.0.10 by Sergey Brester (sebres).
[Definition]
-badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider
+badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider|(?:Mozilla/\d+\.\d+ )?Jorgee
badbots = Atomic_Email_Hunter/4\.0|atSpider/1\.0|autoemailspider|bwh3_user_agent|China Local Browse 2\.6|ContactBot/0\.2|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailSpider|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Guestbook Auto Submitter|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 \+http\://letscrawl\.com/|Lincoln State Web Browser|LMQueueBot/0\.2|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|MVAClient|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/3\.0 \(compatible; scan4mail \(advanced version\) http\://www\.peterspages\.net/?scan4mail\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|NameOfAgent \(CMS Spider\)|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|ShablastBot 1\.0|snap\.com beta crawler v0|Snapbot/1\.0|Snapbot/1\.0 \(Snap Shots, \+http\://www\.snap\.com\)|sogou develop spider|Sogou Orion spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sogou spider|Sogou web spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|VadixBot|WebVulnCrawl\.unknown/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00
failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$
ignoreregex =
+datepattern = ^[^\[]*\[({DATE})
+ {^LN-BEG}
+
# DEV Notes:
# List of bad bots fetched from http://www.user-agents.org
# Generated on Thu Nov 7 14:23:35 PST 2013 by files/gen_badbots.
# This filter is aimed at blocking specific URLs that don't exist. This
# could be a set of URLs places in a Disallow: directive in robots.txt or
# just some web services that don't exist caused bots are searching for
-# exploitable content. This filter is designed to have a low false postitive
+# exploitable content. This filter is designed to have a low false positive
# rate due.
#
# An alternative to this is the apache-noscript filter which blocks all
[Definition]
-failregex = ^%(_apache_error_client)s ((AH001(28|30): )?File does not exist|(AH01264: )?script not found or unable to stat): <webroot><block>(, referer: \S+)?\s*$
- ^%(_apache_error_client)s script '<webroot><block>' not found or unable to stat(, referer: \S+)?\s*$
-
-ignoreregex =
+prefregex = ^%(_apache_error_client)s (?:AH\d+: )?<F-CONTENT>.+</F-CONTENT>$
+failregex = ^(?:File does not exist|script not found or unable to stat): <webroot><block>(, referer: \S+)?\s*$
+ ^script '<webroot><block>' not found or unable to stat(, referer: \S+)?\s*$
-[Init]
+ignoreregex =
# Webroot represents the webroot on which all other files are based
webroot = /var/www/
# DEV Notes:
#
-# Author: Daniel Black
\ No newline at end of file
+# Author: Daniel Black
[INCLUDES]
+before = common.conf
# Load customizations if any available
after = apache-common.local
[DEFAULT]
-_apache_error_client = \[\] \[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client <HOST>(:\d{1,5})?\]
+# Apache logging mode:
+# all - universal prefix (logfile, syslog)
+# logfile - logfile only
+# syslog - syslog only
+# Use `filter = apache-auth[logging=syslog]` to get more precise regex if apache logs into syslog (ErrorLog syslog).
+# Use `filter = apache-auth[logging=all]` to get universal regex matches both logging variants.
+logging = logfile
+
+# Apache logging prefixes (date-pattern prefix, server, process etc.):
+apache-prefix-syslog = %(__prefix_line)s
+apache-prefix-logfile = \[\]\s
+apache-prefix-all = (?:%(apache-prefix-logfile)s|%(apache-prefix-syslog)s)?
+
+# Setting for __prefix_line (only `logging=syslog`):
+_daemon = (?:apache\d*|httpd(?:/\w+)?)
+
+apache-prefix = <apache-prefix-<logging>>
+
+_apache_error_client = <apache-prefix>\[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client <HOST>(:\d{1,5})?\]
+
+datepattern = {^LN-BEG}
# Common prefix for [error] apache messages which also would include <HOST>
# Depending on the version it could be
ignoreregex =
+datepattern = ^[^\[]*\[({DATE})
+ {^LN-BEG}
# DEV Notes:
#
[Definition]
-failregex = ^%(_apache_error_client)s ModSecurity: (\[.*?\] )*Access denied with code [45]\d\d.*$
+failregex = ^%(_apache_error_client)s ModSecurity:\s+(?:\[(?:\w+ \"[^\"]*\"|[^\]]*)\]\s*)*Access denied with code [45]\d\d
ignoreregex =
# https://github.com/SpiderLabs/ModSecurity/wiki/ModSecurity-2-Data-Formats
# Author: Daniel Black
+# Sergey G. Brester aka sebres (review, optimization)
[Definition]
-failregex = ^%(_apache_error_client)s ((AH0013[456]: )?Invalid (method|URI) in request .*( - possible attempt to establish SSL connection on non-SSL port)?|(AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string: .*|AH00566: request failed: invalid characters in URI)(, referer: \S+)?$
+failregex = ^%(_apache_error_client)s (?:(?:AH0013[456]: )?Invalid (method|URI) in request\b|(?:AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string:|(?:AH00566: )?request failed: invalid characters in URI\b)
ignoreregex =
# DEV Notes:
+#
+# [sebres] Because this apache-log could contain very long URLs (and/or referrer),
+# the parsing of it anchored way may be very vulnerable (at least as regards
+# the system resources, see gh-1790). Thus rewritten without end-anchor ($).
#
# fgrep -r 'URI too long' httpd-2.*
# httpd-2.2.25/server/protocol.c: "request failed: URI too long (longer than %d)", r->server->limit_req_line);
#
# The knocking request must have a referer.
-[INCLUDES]
-
-before = apache-common.conf
-
[Definition]
failregex = ^<HOST> - \w+ \[\] "GET <knocking_url> HTTP/1\.[01]" 200 \d+ ".*" "[^-].*"$
ignoreregex =
+datepattern = ^[^\[]*\[({DATE})
+ {^LN-BEG}
+
[Init]
knocking_url = /knocking/
[Definition]
-failregex = ^%(_apache_error_client)s (AH01215: )?/bin/(ba)?sh: warning: HTTP_.*?: ignoring function definition attempt(, referer: \S+)?\s*$
- ^%(_apache_error_client)s (AH01215: )?/bin/(ba)?sh: error importing function definition for `HTTP_.*?'(, referer: \S+)?\s*$
+prefregex = ^%(_apache_error_client)s (AH01215: )?/bin/([bd]a)?sh: <F-CONTENT>.+</F-CONTENT>$
+
+failregex = ^warning: HTTP_[^:]+: ignoring function definition attempt(, referer: \S+)?\s*$
+ ^error importing function definition for `HTTP_[^']+'(, referer: \S+)?\s*$
ignoreregex =
# [Thu Sep 25 09:27:18.813902 2014] [cgi:error] [pid 16860] [client 89.207.132.76:59635] AH01215: /bin/bash: warning: HTTP_TEST: ignoring function definition attempt
# [Thu Sep 25 09:29:56.141832 2014] [cgi:error] [pid 16864] [client 162.247.73.206:41273] AH01215: /bin/bash: error importing function definition for `HTTP_TEST'
#
-# Author: Eugene Hopkinson (riot@riot.so)
+# Author: Eugene Hopkinson (e.hopkinson@gmail.com)
-# Fail2Ban filter for Anti-Spam SMTP Proxy Server also known as ASSP
-#
-# Honmepage: http://www.magicvillage.de/~Fritz_Borgstedt/assp/0003D91C-8000001C/
-# ProjektSite: http://sourceforge.net/projects/assp/?source=directory
+# Fail2Ban filter for Anti-Spam SMTP Proxy Server (ASSP)
+# Filter works in theory for both ASSP V1 and V2. Recommended ASSP is V2.5.1 or later.
+# Support for ASSP V1 ended in 2014 so if you are still running ASSP V1 an immediate upgrade is recommended.
+#
+# Homepage: http://sourceforge.net/projects/assp/
+# ProjectSite: http://sourceforge.net/projects/assp/?source=directory
#
#
[Definition]
+# Note: First three failregex matches below are for ASSP V1 with the remaining being designed for V2. Deleting the V1 regex is recommended but I left it in for compatibility reasons.
__assp_actions = (?:dropping|refusing)
failregex = ^(:? \[SSL-out\])? <HOST> max sender authentication errors \(\d{,3}\) exceeded -- %(__assp_actions)s connection - after reply: \d{3} \d{1}\.\d{1}.\d{1} Error: authentication failed: \w+;$
^(?: \[SSL-out\])? <HOST> SSL negotiation with client failed: SSL accept attempt failed with unknown error.*:unknown protocol;$
^ Blocking <HOST> - too much AUTH errors \(\d{,3}\);$
+ ^\s*(?:[\w\-]+\s+)*(?:\[\S+\]\s+)*<HOST> (?:\<\S+@\S+\.\S+\> )*(?:to: \S+@\S+\.\S+ )*relay attempt blocked for(?: \(parsing\))?: \S+$
+ ^\s*(?:[\w\-]+\s+)*(?:\[\S+\]\s+)*<HOST> \[SMTP Error\] 535 5\.7\.8 Error: authentication failed:\s+(?:\S+|Connection lost to authentication server|Invalid authentication mechanism|Invalid base64 data in continued response)?$
ignoreregex =
+datepattern = {^LN-BEG}%%b-%%d-%%Exy %%H:%%M:%%S
+ {^LN-BEG}
+
# DEV Notes:
+# V1 Examples matches:
+# Apr-27-13 02:33:09 Blocking 217.194.197.97 - too much AUTH errors (41);
+# Dec-29-12 17:10:31 [SSL-out] 200.247.87.82 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol;
+# Dec-30-12 04:01:47 [SSL-out] 81.82.232.66 max sender authentication errors (5) exceeded
#
-# Examples: Apr-27-13 02:33:09 Blocking 217.194.197.97 - too much AUTH errors (41);
-# Dec-29-12 17:10:31 [SSL-out] 200.247.87.82 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol;
-# Dec-30-12 04:01:47 [SSL-out] 81.82.232.66 max sender authentication errors (5) exceeded
+# V2 Examples matches:
+# Jul-29-16 16:49:52 m1-25391-06124 [Worker_1] [TLS-out] [RelayAttempt] 0.0.0.0 <user@example.com> to: user@example.org relay attempt blocked for: someone@example.org
+# Jul-30-16 16:59:42 [Worker_1] [TLS-out] 0.0.0.0 [SMTP Error] 535 5.7.8 Error: authentication failed: UGFzc3dvcmQ6
+# Jul-30-16 00:15:36 m1-52131-09651 [Worker_1] [TLS-out] 0.0.0.0 [SMTP Error] 535 5.7.8 Error: authentication failed: UGFzc3dvcmQ6
+# Jul-31-16 06:45:59 [Worker_1] [TLS-in] [TLS-out] 0.0.0.0 [SMTP Error] 535 5.7.8 Error: authentication failed:
+# Jan-05-16 08:38:49 m1-01129-09140 [Worker_1] [TLS-in] [TLS-out] [RelayAttempt] 0.0.0.0 <user@example.com> relay attempt blocked for (parsing): <user2@example>
+# Jun-12-16 16:43:37 m1-64217-12013 [Worker_1] [TLS-in] [TLS-out] [RelayAttempt] 0.0.0.0 <user@example.com> to: user2@example.com relay attempt blocked for (parsing): <a.notheruser69@example.c>
+# Jan-22-16 22:25:51 [Worker_1] [TLS-out] 0.0.0.0 [SMTP Error] 535 5.7.8 Error: authentication failed: Invalid authentication mechanism
+# Mar-19-16 13:42:20 [Worker_1] [TLS-out] 0.0.0.0 [SMTP Error] 535 5.7.8 Error: authentication failed: Invalid base64 data in continued response
+# Jul-18-16 16:54:21 [Worker_2] [TLS-out] 0.0.0.0 [SMTP Error] 535 5.7.8 Error: authentication failed: Connection lost to authentication server
+# Jul-18-16 17:14:23 m1-76453-02949 [Worker_1] [TLS-out] 0.0.0.0 [SMTP Error] 535 5.7.8 Error: authentication failed: Connection lost to authentication server
+
#
# Author: Enrico Labedzki (enrico.labedzki@deiwos.de)
+# V2 Filters: Robert Hardy (rhardy@webcon.ca)
_daemon = asterisk
-__pid_re = (?:\[\d+\])
+__pid_re = (?:\s*\[\d+\])
iso8601 = \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+[+-]\d{4}
# All Asterisk log messages begin like this:
-log_prefix= (?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[C-[\da-f]*\])? \S+:\d*( in \w+:)?
-
-failregex = ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - (Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$
- ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '[^']*' rejected because extension not found in context
- ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$
- ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$
- ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$
- ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$
- ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s hacking attempt detected '<HOST>'$
- ^(%(__prefix_line)s|\[\]\s*)%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="([\d-]+|%(iso8601)s)",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="(\d*|<unknown>)",SessionID=".+",LocalAddress="IPV[46]/(UDP|TCP|WS)/[\da-fA-F:.]+/\d+",RemoteAddress="IPV[46]/(UDP|TCP|WS)/<HOST>/\d+"(,Challenge="[\w/]+")?(,ReceivedChallenge="\w+")?(,Response="\w+",ExpectedResponse="\w*")?(,ReceivedHash="[\da-f]+")?(,ACLName="\w+")?$
- ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )Ext\. s: "Rejecting unknown SIP connection from <HOST>"$
+log_prefix= (?:NOTICE|SECURITY|WARNING)%(__pid_re)s:?(?:\[C-[\da-f]*\])? [^:]+:\d*(?:(?: in)? \w+:)?
+
+prefregex = ^%(__prefix_line)s%(log_prefix)s <F-CONTENT>.+</F-CONTENT>$
+
+failregex = ^Registration from '[^']*' failed for '<HOST>(:\d+)?' - (?:Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$
+ ^Call from '[^']*' \(<HOST>:\d+\) to extension '[^']*' rejected because extension not found in context
+ ^(?:Host )?<HOST> (?:failed (?:to authenticate\b|MD5 authentication\b)|tried to authenticate with nonexistent user\b)
+ ^No registration for peer '[^']*' \(from <HOST>\)$
+ ^hacking attempt detected '<HOST>'$
+ ^SecurityEvent="(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)"(?:(?:,(?!RemoteAddress=)\w+="[^"]*")*|.*?),RemoteAddress="IPV[46]/(UDP|TCP|WS)/<HOST>/\d+"(?:,(?!RemoteAddress=)\w+="[^"]*")*$
+ ^"Rejecting unknown SIP connection from <HOST>"$
+ ^Request (?:'[^']*' )?from '(?:[^']*|.*?)' failed for '<HOST>(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$
+
+# FreePBX (todo: make optional in v.0.10):
+# ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )[^:]+: Friendly Scanner from <HOST>$
ignoreregex =
+datepattern = {^LN-BEG}
# Author: Xavier Devlamynck / Daniel Black
#
# Block is the actual non-found directories to block
block = \/?(<webmail>|<phpmyadmin>|<wordpress>|cgi-bin|mysqladmin)[^,]*
-# These are just convient definitions that assist the blocking of stuff that
+# These are just convenient definitions that assist the blocking of stuff that
# isn't installed
webmail = roundcube|(ext)?mail|horde|(v-?)?webmail
# extra daemon info
# EXAMPLE: [ID 800047 auth.info]
-__daemon_extra_re = (?:\[ID \d+ \S+\])
+__daemon_extra_re = \[ID \d+ \S+\]
# Combinations of daemon name and PID
# EXAMPLES: sshd[31607], pop(pam_unix)[4920]
# bsdverbose is where syslogd is started with -v or -vv and results in <4.3> or
# <auth.info> appearing before the host as per testcases/files/logs/bsd/*.
-__bsd_syslog_verbose = (<[^.]+\.[^.]+>)
+__bsd_syslog_verbose = <[^.]+\.[^.]+>
+
+__vserver = @vserver_\S+
+
+__date_ambit = (?:\[\])
# Common line prefixes (beginnings) which could be used in filters
#
# [bsdverbose]? [hostname] [vserver tag] daemon_id spaces
#
# This can be optional (for instance if we match named native log files)
-__prefix_line = \s*%(__bsd_syslog_verbose)s?\s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s%(__daemon_extra_re)s?\s*
+__prefix_line = %(__date_ambit)s?\s*(?:%(__bsd_syslog_verbose)s\s+)?(?:%(__hostname)s\s+)?(?:%(__kernel_prefix)s\s+)?(?:%(__vserver)s\s+)?(?:%(__daemon_combs_re)s\s+)?(?:%(__daemon_extra_re)s\s+)?
# PAM authentication mechanism check for failures, e.g.: pam_unix, pam_sss,
# pam_ldap
__pam_auth = pam_unix
+# standardly all formats using prefix have line-begin anchored date:
+datepattern = {^LN-BEG}
+
# Author: Yaroslav Halchenko
ignoreregex =
-[Init]
-
datepattern = ^L %%d/%%m/%%Y - %%H:%%M:%%S
_daemon = (?:courier)?(?:imapd?|pop3d?)(?:login)?(?:-ssl)?
-failregex = ^%(__prefix_line)sLOGIN FAILED, user=.*, ip=\[<HOST>\]$
+failregex = ^%(__prefix_line)sLOGIN FAILED, (?:user|method)=.*, ip=\[<HOST>\]$
ignoreregex =
+datepattern = {^LN-BEG}
+
# Author: Christoph Haas
# Modified by: Cyril Jaquier
_daemon = courieresmtpd
-failregex = ^%(__prefix_line)serror,relay=<HOST>,.*: 550 User (<.*> )?unknown\.?$
- ^%(__prefix_line)serror,relay=<HOST>,msg="535 Authentication failed\.",cmd:( AUTH \S+)?( [0-9a-zA-Z\+/=]+)?$
+prefregex = ^%(__prefix_line)serror,relay=<HOST>,<F-CONTENT>.+</F-CONTENT>$
+
+failregex = ^[^:]*: 550 User (<.*> )?unknown\.?$
+ ^msg="535 Authentication failed\.",cmd:( AUTH \S+)?( [0-9a-zA-Z\+/=]+)?(?: \S+)$
ignoreregex =
_daemon = (?:cyrus/)?(?:imap(d|s)?|pop3(d|s)?)
-failregex = ^%(__prefix_line)sbadlogin: \S+ ?\[<HOST>\] \S+ .*?\[?SASL\(-13\): (authentication failure|user not found): .*\]?$
+failregex = ^%(__prefix_line)sbadlogin: [^\[]*\[<HOST>\] \S+ .*?\[?SASL\(-13\): (authentication failure|user not found): .*\]?$
ignoreregex =
ignoreregex =
-[Init]
datepattern = ^%%Y:%%m:%%d-%%H:%%M:%%S
#
--- /dev/null
+# Fail2Ban configuration file for IBM Domino SMTP Server TASK to detect failed login attempts
+#
+# Author: Christian Brandlehner
+#
+# $Revision: 003 $
+#
+# Configuration:
+# Set the following Domino Server parameters in notes.ini:
+# console_log_enabled=1
+# log_sessions=2
+# You also have to use a date and time format supported by fail2ban. Recommended notes.ini configuration is:
+# DateOrder=DMY
+# DateSeparator=-
+# ClockType=24_Hour
+# TimeSeparator=:
+#
+# Depending on your locale you might have to tweak the date and time format so fail2ban can read the log
+
+#[INCLUDES]
+# Read common prefixes. If any customizations available -- read them from
+# common.local
+#before = common.conf
+
+[Definition]
+# Option: failregex
+# Notes.: regex to match the password failure messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching and is only an alias for
+# (?:::f{4,6}:)?(?P<host>\S+)
+# Values: TEXT
+#
+# Sample log entries (used different time formats and an extra sample with process info in front of date)
+# 01-23-2009 19:54:51 SMTP Server: Authentication failed for user postmaster ; connecting host 1.2.3.4
+# [28325:00010-3735542592] 22-06-2014 09:56:12 smtp: postmaster [1.2.3.4] authentication failure using internet password
+# 08-09-2014 06:14:27 smtp: postmaster [1.2.3.4] authentication failure using internet password
+# 08-09-2014 06:14:27 SMTP Server: Authentication failed for user postmaster ; connecting host 1.2.3.4
+
+__prefix = (?:\[[^\]]+\])?\s+
+failregex = ^%(__prefix)sSMTP Server: Authentication failed for user .*? \; connecting host <HOST>$
+ ^%(__prefix)ssmtp: (?:[^\[]+ )*\[<HOST>\] authentication failure using internet password\s*$
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+
+ignoreregex =
+
[Definition]
-_daemon = (auth|dovecot(-auth)?|auth-worker)
+_auth_worker = (?:dovecot: )?auth(?:-worker)?
+_daemon = (?:dovecot(?:-auth)?|auth)
-failregex = ^%(__prefix_line)s(%(__pam_auth)s(\(dovecot:auth\))?:)?\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=<HOST>(\s+user=\S*)?\s*$
- ^%(__prefix_line)s(pop3|imap)-login: (Info: )?(Aborted login|Disconnected)(: Inactivity)? \(((auth failed, \d+ attempts)( in \d+ secs)?|tried to use (disabled|disallowed) \S+ auth)\):( user=<\S*>,)?( method=\S+,)? rip=<HOST>(, lip=(\d{1,3}\.){3}\d{1,3})?(, TLS( handshaking(: SSL_accept\(\) failed: error:[\dA-F]+:SSL routines:[TLS\d]+_GET_CLIENT_HELLO:unknown protocol)?)?(: Disconnected)?)?(, session=<\S+>)?\s*$
- ^%(__prefix_line)s(Info|dovecot: auth\(default\)|auth-worker\(\d+\)): pam\(\S+,<HOST>\): pam_authenticate\(\) failed: (User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\))\s*$
- ^%(__prefix_line)s(auth|auth-worker\(\d+\)): (pam|passwd-file)\(\S+,<HOST>\): unknown user\s*$
+prefregex = ^%(__prefix_line)s(?:%(_auth_worker)s(?:\([^\)]+\))?: )?(?:%(__pam_auth)s(?:\(dovecot:auth\))?: |(?:pop3|imap)-login: )?(?:Info: )?<F-CONTENT>.+</F-CONTENT>$
-ignoreregex =
+failregex = ^authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=<HOST>(?:\s+user=\S*)?\s*$
+ ^(?:Aborted login|Disconnected)(?::(?: [^ \(]+)+)? \((?:auth failed, \d+ attempts(?: in \d+ secs)?|tried to use (?:disabled|disallowed) \S+ auth)\):(?: user=<[^>]*>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
+ ^pam\(\S+,<HOST>(?:,\S*)?\): pam_authenticate\(\) failed: (?:User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\)|Permission denied)\s*$
+ ^[a-z\-]{3,15}\(\S*,<HOST>(?:,\S*)?\): (?:unknown user|invalid credentials)\s*$
+ <mdre-<mode>>
+
+mdre-aggressive = ^(?:Aborted login|Disconnected)(?::(?: [^ \(]+)+)? \((?:no auth attempts|disconnected before auth was ready,|client didn't finish \S+ auth,)(?: (?:in|waited) \d+ secs)?\):(?: user=<[^>]*>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
+
+mdre-normal =
-[Init]
+# Parameter `mode` - `normal` or `aggressive`.
+# Aggressive mode can be used to match log-entries like:
+# 'no auth attempts', 'disconnected before auth was ready', 'client didn't finish SASL auth'.
+# Note it may produce lots of false positives on misconfigured MTAs.
+# Ex.:
+# filter = dovecot[mode=aggressive]
+mode = normal
+
+ignoreregex =
journalmatch = _SYSTEMD_UNIT=dovecot.service
+datepattern = {^LN-BEG}TAI64N
+ {^LN-BEG}
+
# DEV Notes:
# * the first regex is essentially a copy of pam-generic.conf
-# * Probably doesn't do dovecot sql/ldap backends properly
-# * Removed the 'no auth attempts' log lines from the matches because produces
-# lots of false positives on misconfigured MTAs making regexp unusable
+# * Probably doesn't do dovecot sql/ldap backends properly (resolved in edit 21/03/2016)
#
# Author: Martin Waschbuesch
# Daniel Black (rewrote with begin and end anchors)
+# Martin O'Neal (added LDAP authentication failure regex)
+# Sergey G. Brester aka sebres (reviewed, optimized, IPv6-compatibility)
_daemon = dropbear
-failregex = ^%(__prefix_line)s[Ll]ogin attempt for nonexistent user ('.*' )?from <HOST>:\d+$
- ^%(__prefix_line)s[Bb]ad (PAM )?password attempt for .+ from <HOST>(:\d+)?$
- ^%(__prefix_line)s[Ee]xit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '.+' from <HOST>:\d+\s*$
+prefregex = ^%(__prefix_line)s<F-CONTENT>(?:[Ll]ogin|[Bb]ad|[Ee]xit).+</F-CONTENT>$
+
+failregex = ^[Ll]ogin attempt for nonexistent user ('.*' )?from <HOST>:\d+$
+ ^[Bb]ad (PAM )?password attempt for .+ from <HOST>(:\d+)?$
+ ^[Ee]xit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '.+' from <HOST>:\d+\s*$
ignoreregex =
# searched for other failures. This tag can be used multiple times.
# Values: TEXT
#
-failregex = ^=INFO REPORT==== ===\nI\(<0\.\d+\.0>:ejabberd_c2s:\d+\) : \([^)]+\) Failed authentication for .+ from IP <HOST> \({{(?:\d+,){3}\d+},\d+}\)$
- ^(?:\.\d+)? \[info\] <0\.\d+\.\d>@ejabberd_c2s:wait_for_feature_request:\d+ \([^\)]+\) Failed authentication for \S+ from IP <HOST>$
+failregex = ^=INFO REPORT==== ===\nI\(<0\.\d+\.0>:ejabberd_c2s:\d+\) : \([^)]+\) Failed authentication for \S+ from (?:IP )?<HOST>(?: \({{(?:\d+,){3}\d+},\d+}\))?$
+ ^(?:\.\d+)? \[info\] <0\.\d+\.\d>@ejabberd_c2s:\w+:\d+ \([^\)]+\) Failed (?:c2s \w+ )?authentication for \S+ from (?:IP )?(?:::FFFF:)?<HOST>(?:: |$)
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
#
ignoreregex =
-[Init]
-
# "maxlines" is number of log lines to buffer for multi-line regex searches
maxlines = 2
# Values: TEXT
#
journalmatch =
+
+#datepattern = ^(?:=[^=]+={3,} )?({DATE})
+# explicit time format using prefix =...==== and no date in second string begins with I(...)...
+datepattern = ^(?:=[^=]+={3,} )?(%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?)
+ ^I\(()**
[Definition]
-host_info = H=([\w.-]+ )?(\(\S+\) )?\[<HOST>\](:\d+)? (I=\[\S+\]:\d+ )?(U=\S+ )?(P=e?smtp )?
-pid = ( \[\d+\])?
+host_info_pre = (?:H=([\w.-]+ )?(?:\(\S+\) )?)?
+host_info_suf = (?::\d+)?(?: I=\[\S+\](:\d+)?)?(?: U=\S+)?(?: P=e?smtp)?(?: F=(?:<>|[^@]+@\S+))?\s
+host_info = %(host_info_pre)s\[<HOST>\]%(host_info_suf)s
+pid = (?: \[\d+\])?
# DEV Notes:
# From exim source code: ./src/receive.c:add_host_info_for_log
[Definition]
+# Fre-filter via "prefregex" is currently inactive because of too different failure syntax in exim-log (testing needed):
+#prefregex = ^%(pid)s <F-CONTENT>\b(?:\w+ authenticator failed|([\w\-]+ )?SMTP (?:(?:call|connection) from|protocol(?: synchronization)? error)|no MAIL in|(?:%(host_info_pre)s\[[^\]]+\]%(host_info_suf)s(?:sender verify fail|rejected RCPT|dropped|AUTH command))).+</F-CONTENT>$
+
failregex = ^%(pid)s %(host_info)ssender verify fail for <\S+>: (?:Unknown user|Unrouteable address|all relevant MX records point to non-existent hosts)\s*$
- ^%(pid)s \w+ authenticator failed for (\S+ )?\(\S+\) \[<HOST>\](:\d+)?( I=\[\S+\](:\d+)?)?: 535 Incorrect authentication data( \(set_id=.*\)|: \d+ Time\(s\))?\s*$
- ^%(pid)s %(host_info)sF=(<>|[^@]+@\S+) rejected RCPT [^@]+@\S+: (relay not permitted|Sender verify failed|Unknown user)\s*$
- ^%(pid)s SMTP protocol synchronization error \([^)]*\): rejected (connection from|"\S+") %(host_info)s(next )?input=".*"\s*$
- ^%(pid)s SMTP call from \S+ \[<HOST>\](:\d+)? (I=\[\S+\](:\d+)? )?dropped: too many nonmail commands \(last was "\S+"\)\s*$
+ ^%(pid)s \w+ authenticator failed for (?:[^\[\( ]* )?(?:\(\S*\) )?\[<HOST>\](?::\d+)?(?: I=\[\S+\](:\d+)?)?: 535 Incorrect authentication data( \(set_id=.*\)|: \d+ Time\(s\))?\s*$
+ ^%(pid)s %(host_info)srejected RCPT [^@]+@\S+: (?:relay not permitted|Sender verify failed|Unknown user|Unrouteable address)\s*$
+ ^%(pid)s SMTP protocol synchronization error \([^)]*\): rejected (?:connection from|"\S+") %(host_info)s(?:next )?input=".*"\s*$
+ ^%(pid)s SMTP call from \S+ %(host_info)sdropped: too many nonmail commands \(last was "\S+"\)\s*$
+ ^%(pid)s SMTP protocol error in "[^"]+(?:"+[^"]*(?="))*?" %(host_info)sAUTH command used when not advertised\s*$
+ ^%(pid)s no MAIL in SMTP connection from (?:[^\[\( ]* )?(?:\(\S*\) )?%(host_info)sD=\d\S*s(?: C=\S*)?\s*$
+ ^%(pid)s (?:[\w\-]+ )?SMTP connection from (?:[^\[\( ]* )?(?:\(\S*\) )?%(host_info)sclosed by DROP in ACL\s*$
+ <mdre-<mode>>
+
+mdre-aggressive = ^%(pid)s no host name found for IP address <HOST>$
+ ^%(pid)s no IP address found for host \S+ \(during SMTP connection from \[<HOST>\]\)$
+
+mdre-normal =
+
+# Parameter `mode` - `normal` or `aggressive`.
+# Aggressive mode can be used to match flood and ddos-similar log-entries like:
+# 'no host found for IP', 'no IP found for host'.
+# Note this is not an authentication failures, so it may produce lots of false
+# positives on misconfigured MTAs.
+# Ex.:
+# filter = exim[mode=aggressive]
+mode = normal
ignoreregex =
#
# Author: Cyril Jaquier
# Daniel Black (rewrote with strong regexs)
+# Martin O'Neal (added additional regexs to detect authentication failures, protocol errors, and drops)
# IP addresses on your LAN.
#
+[INCLUDES]
+
+# Read common prefixes. If any customizations available -- read them from
+# common.local
+before = common.conf
+
[Definition]
-failregex = ^\.\d+ \[WARNING\] sofia_reg\.c:\d+ SIP auth (failure|challenge) \((REGISTER|INVITE)\) on sofia profile \'[^']+\' for \[.*\] from ip <HOST>$
- ^\.\d+ \[WARNING\] sofia_reg\.c:\d+ Can't find user \[\d+@\d+\.\d+\.\d+\.\d+\] from <HOST>$
+_daemon = freeswitch
+
+# Prefix contains common prefix line (server, daemon, etc.) and 2 datetimes if used systemd backend
+_pref_line = ^%(__prefix_line)s(?:\d+-\d+-\d+ \d+:\d+:\d+\.\d+)?
+
+failregex = %(_pref_line)s \[WARNING\] sofia_reg\.c:\d+ SIP auth (failure|challenge) \((REGISTER|INVITE)\) on sofia profile \'[^']+\' for \[[^\]]*\] from ip <HOST>$
+ %(_pref_line)s \[WARNING\] sofia_reg\.c:\d+ Can't find user \[[^@]+@[^\]]+\] from <HOST>$
ignoreregex =
+datepattern = {^LN-BEG}
+
# Author: Rupa SChomaker, soapee01, Daniel Black
-# http://wiki.freeswitch.org/wiki/Fail2ban
+# https://freeswitch.org/confluence/display/FREESWITCH/Fail2Ban
# Thanks to Jim on mailing list of samples and guidance
#
# No need to match the following. Its a duplicate of the SIP auth regex.
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values: TEXT
#
-failregex = ^%(__prefix_line)s\[Login Action <HOST>\] Unknown user \S* tried to login.$
- ^%(__prefix_line)s\[Login Action <HOST>\] User \S* tried to login with wrong password.$
+
+prefregex = ^%(__prefix_line)s\[Login Action <HOST>\] <F-CONTENT>.+</F-CONTENT>$
+
+failregex = ^Unknown user \S* tried to login.$
+ ^User \S* tried to login with wrong password.$
# Option: ignoreregex
#
ignoreregex =
-[Init]
# "maxlines" is number of log lines to buffer for multi-line regex searches
maxlines = 2
+
+datepattern = ^%%b %%d, %%ExY %%I:%%M:%%S %%p
+ ^WARNING:()**
+ {^LN-BEG}
\ No newline at end of file
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values: TEXT
#
-failregex = ^%(__prefix_line)s<HOST>.*<NOSRV> -1/-1/-1/-1/\+*\d* 401
+failregex = ^%(__prefix_line)s<HOST>(?::\d+)?\s+.*<NOSRV> -1/-1/-1/-1/\+*\d* 401
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
-#!/usr/bin/python
+#!/usr/bin/env fail2ban-python
# Inspired by https://isc.sans.edu/forums/diary/When+Google+isnt+Google/15968/
#
# Written in Python to reuse built-in Python batteries and not depend on
# presence of host and cut commands
#
import sys
+from fail2ban.server.ipdns import DNSUtils, IPAddr
def process_args(argv):
if len(argv) != 2:
- sys.stderr.write("Please provide a single IP as an argument. Got: %s\n"
+ raise ValueError("Please provide a single IP as an argument. Got: %s\n"
% (argv[1:]))
- sys.exit(2)
-
ip = argv[1]
- from fail2ban.server.filter import DNSUtils
- if not DNSUtils.isValidIP(ip):
- sys.stderr.write("Argument must be a single valid IP. Got: %s\n"
+ if not IPAddr(ip).isValid:
+ raise ValueError("Argument must be a single valid IP. Got: %s\n"
% ip)
- sys.exit(3)
return ip
+google_ips = None
+
def is_googlebot(ip):
import re
- from fail2ban.server.filter import DNSUtils
host = DNSUtils.ipToName(ip)
if not host or not re.match('.*\.google(bot)?\.com$', host):
- sys.exit(1)
+ return False
host_ips = DNSUtils.dnsToIp(host)
- sys.exit(0 if ip in host_ips else 1)
+ return (ip in host_ips)
-if __name__ == '__main__':
- is_googlebot(process_args(sys.argv))
+if __name__ == '__main__': # pragma: no cover
+ try:
+ ret = is_googlebot(process_args(sys.argv))
+ except ValueError as e:
+ sys.stderr.write(str(e))
+ sys.exit(2)
+ sys.exit(0 if ret else 1)
[Definition]
failregex = ^ SMTP Spam attack detected from <HOST>,
- ^ IP address <HOST> found in DNS blacklist \S+, mail from \S+ to \S+$
+ ^ IP address <HOST> found in DNS blacklist
^ Relay attempt from IP address <HOST>
^ Attempt to deliver to unknown recipient \S+, from \S+, IP address <HOST>$
+ ^ Failed SMTP login from <HOST>
+ ^ SMTP: User \S+ doesn't exist. Attempt from IP address <HOST>
+ ^ Client with IP address <HOST> has no reverse DNS entry, connection rejected before SMTP greeting$
+ ^ Administration login into Web Administration from <HOST> failed: IP address not allowed$
+ ^ Message from IP address <HOST>, sender \S+ rejected: sender domain does not exist$
ignoreregex =
-[Init]
-
datepattern = ^\[%%d/%%b/%%Y %%H:%%M:%%S\]
# DEV NOTES:
#
# Author: A.P. Lawrence
+# Updated by: M. Bischoff <https://github.com/herrbischoff>
#
# Based off: http://aplawrence.com/Kerio/fail2ban.html
[Definition]
-failregex = ^: \(http_auth\.c\.\d+\) (password doesn\'t match .* username: .*|digest: auth failed for .*: wrong password|get_password failed), IP: <HOST>\s*$
+failregex = ^: \((?:http|mod)_auth\.c\.\d+\) (?:password doesn\'t match .* username: .*|digest: auth failed for .*: wrong password|get_password failed), IP: <HOST>\s*$
ignoreregex =
--- /dev/null
+# Fail2Ban filter for unsuccesfull MongoDB authentication attempts
+#
+# Logfile /var/log/mongodb/mongodb.log
+#
+# add setting in /etc/mongodb.conf
+# logpath=/var/log/mongodb/mongodb.log
+#
+# and use of the authentication
+# auth = true
+#
+
+[Definition]
+#failregex = ^\s+\[initandlisten\] connection accepted from <HOST>:\d+ \#(?P<__connid>\d+) \(1 connection now open\)<SKIPLINES>\s+\[conn(?P=__connid)\] Failed to authenticate\s+
+failregex = ^\s+\[conn(?P<__connid>\d+)\] Failed to authenticate [^\n]+<SKIPLINES>\s+\[conn(?P=__connid)\] end connection <HOST>
+
+ignoreregex =
+
+
+[Init]
+maxlines = 10
+
+# DEV Notes:
+#
+# Regarding the multiline regex:
+#
+# There can be a nunber of non-related lines between the first and second part
+# of this regex maxlines of 10 is quite generious.
+#
+# Note the capture __connid, includes the connection ID, used in second part of regex.
+#
+# The first regex is commented out (but will match also), because it is better to use
+# the host from "end connection" line (uncommented above):
+# - it has the same prefix, searching begins directly with failure message
+# (so faster, because ignores success connections at all)
+# - it is not so vulnerable in case of possible race condition
+#
+# Log example:
+# 2016-10-20T09:54:27.108+0200 [initandlisten] connection accepted from 127.0.0.1:53276 #1 (1 connection now open)
+# 2016-10-20T09:54:27.109+0200 [conn1] authenticate db: test { authenticate: 1, nonce: "xxx", user: "root", key: "xxx" }
+# 2016-10-20T09:54:27.110+0200 [conn1] Failed to authenticate root@test with mechanism MONGODB-CR: AuthenticationFailed UserNotFound Could not find user root@test
+# 2016-11-09T09:54:27.894+0100 [conn1] end connection 127.0.0.1:53276 (0 connections now open)
+# 2016-11-09T11:55:58.890+0100 [initandlisten] connection accepted from 127.0.0.1:54266 #1510 (1 connection now open)
+# 2016-11-09T11:55:58.892+0100 [conn1510] authenticate db: admin { authenticate: 1, nonce: "xxx", user: "root", key: "xxx" }
+# 2016-11-09T11:55:58.892+0100 [conn1510] Failed to authenticate root@admin with mechanism MONGODB-CR: AuthenticationFailed key mismatch
+# 2016-11-09T11:55:58.894+0100 [conn1510] end connection 127.0.0.1:54266 (0 connections now open)
+#
+# Authors: Alexander Finkhäuser
+# Sergey G. Brester (sebres)
+
#
#
+[INCLUDES]
+
+# Read common prefixes. If any customizations available -- read them from
+# common.local
+before = common.conf
+
[Definition]
-failregex = ^\[[A-Z]+\s+\]\s*error\s*:\s*Warning:\s+Client '<HOST>' supplied unknown user '\w+' accessing monit httpd$
- ^\[[A-Z]+\s+\]\s*error\s*:\s*Warning:\s+Client '<HOST>' supplied wrong password for user '\w+' accessing monit httpd$
+_daemon = monit
+
+# Regexp for previous (accessing monit httpd) and new (access denied) versions
+failregex = ^\[\s*\]\s*error\s*:\s*Warning:\s+Client '<HOST>' supplied (?:unknown user '[^']+'|wrong password for user '[^']*') accessing monit httpd$
+ ^%(__prefix_line)s\w+: access denied -- client <HOST>: (?:unknown user '[^']+'|wrong password for user '[^']*'|empty password)$
+# Ignore login with empty user (first connect, no user specified)
+# ignoreregex = %(__prefix_line)s\w+: access denied -- client <HOST>: (?:unknown user '')
ignoreregex =
# variable in your server config file (murmur.ini / mumble-server.ini).
_usernameregex = [^>]+
-_prefix = <W>[\n\s]*(\.\d{3})?\s+\d+ => <\d+:%(_usernameregex)s\(-1\)> Rejected connection from <HOST>:\d+:
+_prefix = \s+\d+ => <\d+:%(_usernameregex)s\(-1\)> Rejected connection from <HOST>:\d+:
-failregex = ^%(_prefix)s Invalid server password$
- ^%(_prefix)s Wrong certificate or password for existing user$
+prefregex = ^%(_prefix)s <F-CONTENT>.+</F-CONTENT>$
+
+failregex = ^Invalid server password$
+ ^Wrong certificate or password for existing user$
ignoreregex =
+datepattern = ^<W>{DATE}
# DEV Notes:
#
-# Fail2Ban filter for unsuccesfull MySQL authentication attempts
+# Fail2Ban filter for unsuccesful MySQL authentication attempts
#
#
# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld]:
# this can be optional (for instance if we match named native log files)
__line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)?
-failregex = ^%(__line_prefix)s( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: (view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$
- ^%(__line_prefix)s( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: zone transfer '\S+/AXFR/\w+' denied\s*$
- ^%(__line_prefix)s( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: bad zone transfer request: '\S+/IN': non-authoritative zone \(NOTAUTH\)\s*$
+prefregex = ^%(__line_prefix)s( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: <F-CONTENT>.+</F-CONTENT>$
+
+failregex = ^(view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$
+ ^zone transfer '\S+/AXFR/\w+' denied\s*$
+ ^bad zone transfer request: '\S+/IN': non-authoritative zone \(NOTAUTH\)\s*$
ignoreregex =
ignoreregex =
+datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
+ ^[^\[]*\[({DATE})
+ {^LN-BEG}
# DEV Notes:
# Based on apache-botsearch filter
[Definition]
-failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
+failregex = ^ \[error\] \d+#\d+: \*\d+ user "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\s*$
ignoreregex =
+datepattern = {^LN-BEG}
+
# DEV NOTES:
# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files
# Extensive search of all nginx auth failures not done yet.
# Use following full expression if you should range limit request to specified
# servers, requests, referrers etc. only :
#
-# failregex = ^\s*\[error\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
+# failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
# Shortly, much faster and stable version of regexp:
-failregex = ^\s*\[error\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>
+failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,
ignoreregex =
+datepattern = {^LN-BEG}
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values: TEXT
-failregex = ^\[\]%(__prefix_line)sinfo: ratelimit block .* query <HOST> TYPE255$
- ^\[\]%(__prefix_line)sinfo: .* <HOST> refused, no acl matches\.$
+failregex = ^%(__prefix_line)sinfo: ratelimit block .* query <HOST> TYPE255$
+ ^%(__prefix_line)sinfo: .* <HOST> refused, no acl matches\.$
ignoreregex =
+
+datepattern = {^LN-BEG}Epoch
+ {^LN-BEG}
\ No newline at end of file
[Definition]
failregex = ^<HOST>\s+-\s+-\s+\[\]\s+"[A-Z]+ .*" 401 \d+\s*$
-[Init]
datepattern = %%d/%%b[^/]*/%%Y:%%H:%%M:%%S %%z
# Note that you MUST have LOG_FORMAT=4 for this to work!
#
-failregex = ^.*tr="[A-Z]+\|[0-9.]+\|\d+\|<HOST>\|\d+" ap="[^"]*" mi="Bad password" us="[^"]*" di="535 5.7.8 Bad username or password( \(Authentication failed\))?\."/>$
+failregex = tr="[A-Z]+\|[0-9.]+\|\d+\|<HOST>\|\d+" ap="[^"]*" mi="Bad password" us="[^"]*" di="535 5.7.8 Bad username or password( \(Authentication failed\))?\."/>$
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =
+
+datepattern = ^<co ts="{DATE}"\s+
__pam_re=\(?%(__pam_auth)s(?:\(\S+\))?\)?:?
_daemon = \S+
-failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$
+prefregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s <F-CONTENT>.+</F-CONTENT>$
+
+failregex = ^ruser=<F-USER>\S*</F-USER> rhost=<HOST>\s*$
+ ^ruser= rhost=<HOST>\s+user=<F-USER>\S*</F-USER>\s*$
+ ^ruser= rhost=<HOST>\s+user=<F-USER>.*?</F-USER>\s*$
+ ^ruser=<F-USER>.*?</F-USER> rhost=<HOST>\s*$
ignoreregex =
# http://blogs.buanzo.com.ar/2009/04/fail2ban-filter-for-php-injection-attacks.html#comment-1489
#
# Author: Arturo 'Buanzo' Busleiman <buanzo@buanzo.com.ar>
+
+datepattern = ^[^\[]*\[({DATE})
+ {^LN-BEG}
--- /dev/null
+# Fail2Ban fitler for the phpMyAdmin-syslog
+#
+
+[INCLUDES]
+
+before = common.conf
+
+[Definition]
+
+_daemon = phpMyAdmin
+
+failregex = ^%(__prefix_line)suser denied: (?:\S+|.*?) \(mysql-denied\) from <HOST>\s*$
+
+ignoreregex =
+
+
+# Author: Pavel Mihadyuk
+# Regex fixes: Serg G. Brester
ignoreregex =
+datepattern = {^LN-BEG}Epoch
+ {^LN-BEG}
+
# Author: Pacop <pacoparu@gmail.com>
[Definition]
-_daemon = postfix(-\w+)?/(submission/)?smtp(d|s)
-
-failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 554 5\.7\.1 .*$
- ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.7\.1 Client host rejected: cannot find your hostname, (\[\S*\]); from=<\S*> to=<\S+> proto=ESMTP helo=<\S*>$
- ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.7\.1 : Helo command rejected: Host not found; from=<> to=<> proto=ESMTP helo= *$
- ^%(__prefix_line)sNOQUEUE: reject: EHLO from \S+\[<HOST>\]: 504 5\.5\.2 <\S+>: Helo command rejected: need fully-qualified hostname;
- ^%(__prefix_line)sNOQUEUE: reject: VRFY from \S+\[<HOST>\]: 550 5\.1\.1 .*$
- ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.1\.8 <\S*>: Sender address rejected: Domain not found; from=<\S*> to=<\S+> proto=ESMTP helo=<\S*>$
- ^%(__prefix_line)simproper command pipelining after \S+ from [^[]*\[<HOST>\]:?$
+_daemon = postfix(-\w+)?/\w+(?:/smtp[ds])?
+_port = (?::\d+)?
+
+prefregex = ^%(__prefix_line)s<mdpr-<mode>> <F-CONTENT>.+</F-CONTENT>$
+
+mdpr-normal = (?:NOQUEUE: reject:|improper command pipelining after \S+)
+mdre-normal=^RCPT from [^[]*\[<HOST>\]%(_port)s: 55[04] 5\.7\.1\s
+ ^RCPT from [^[]*\[<HOST>\]%(_port)s: 45[04] 4\.7\.1 (?:Service unavailable\b|Client host rejected: cannot find your (reverse )?hostname\b)
+ ^RCPT from [^[]*\[<HOST>\]%(_port)s: 450 4\.7\.1 (<[^>]*>)?: Helo command rejected: Host not found\b
+ ^EHLO from [^[]*\[<HOST>\]%(_port)s: 504 5\.5\.2 (<[^>]*>)?: Helo command rejected: need fully-qualified hostname\b
+ ^VRFY from [^[]*\[<HOST>\]%(_port)s: 550 5\.1\.1\s
+ ^RCPT from [^[]*\[<HOST>\]%(_port)s: 450 4\.1\.8 (<[^>]*>)?: Sender address rejected: Domain not found\b
+ ^from [^[]*\[<HOST>\]%(_port)s:?
+
+mdpr-auth = warning:
+mdre-auth = ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server| Invalid authentication mechanism)
+mdre-auth2= ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server)
+# todo: check/remove "Invalid authentication mechanism" from ignore list, if gh-1243 will get finished (see gh-1297).
+
+# Mode "rbl" currently included in mode "normal", but if needed for jail "postfix-rbl" only:
+mdpr-rbl = %(mdpr-normal)s
+mdre-rbl = ^RCPT from [^[]*\[<HOST>\]%(_port)s: [45]54 [45]\.7\.1 Service unavailable; Client host \[\S+\] blocked\b
+
+# Mode "rbl" currently included in mode "normal" (within 1st rule)
+mdpr-more = %(mdpr-normal)s
+mdre-more = %(mdre-normal)s
+
+mdpr-ddos = lost connection after(?! DATA) [A-Z]+
+mdre-ddos = ^from [^[]*\[<HOST>\]%(_port)s:?
+
+mdpr-extra = (?:%(mdpr-auth)s|%(mdpr-normal)s)
+mdre-extra = %(mdre-auth)s
+ %(mdre-normal)s
+
+mdpr-aggressive = (?:%(mdpr-auth)s|%(mdpr-normal)s|%(mdpr-ddos)s)
+mdre-aggressive = %(mdre-auth2)s
+ %(mdre-normal)s
+
+
+
+failregex = <mdre-<mode>>
+
+# Parameter "mode": more (default combines normal and rbl), auth, normal, rbl, ddos, extra or aggressive (combines all)
+# Usage example (for jail.local):
+# [postfix]
+# mode = aggressive
+# # or another jail (rewrite filter parameters of jail):
+# [postfix-rbl]
+# filter = postfix[mode=rbl]
+#
+mode = more
ignoreregex =
__suffix_failed_login = (User not authorized for login|No such user found|Incorrect password|Password expired|Account disabled|Invalid shell: '\S+'|User in \S+|Limit (access|configuration) denies login|Not a UserAlias|maximum login length exceeded).?
-failregex = ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ USER .*: no such user found from \S+ \[\S+\] to \S+:\S+ *$
- ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ USER .* \(Login failed\): %(__suffix_failed_login)s\s*$
- ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ SECURITY VIOLATION: .* login attempted\. *$
- ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ Maximum login attempts \(\d+\) exceeded *$
+
+prefregex = ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ <F-CONTENT>(?:USER|SECURITY|Maximum).+</F-CONTENT>$
+
+
+failregex = ^USER .*: no such user found from \S+ \[\S+\] to \S+:\S+ *$
+ ^USER .* \(Login failed\): %(__suffix_failed_login)s\s*$
+ ^SECURITY VIOLATION: .* login attempted\. *$
+ ^Maximum login attempts \(\d+\) exceeded *$
ignoreregex =
+[Init]
+journalmatch = _SYSTEMD_UNIT=proftpd.service
+
# Author: Yaroslav Halchenko
# Daniel Black - hardening of regex
ignoreregex =
+[Init]
+
+journalmatch = _SYSTEMD_UNIT=pure-ftpd.service + _COMM=pure-ftpd
+
# Author: Cyril Jaquier
# Modified: Yaroslav Halchenko for pure-ftpd
# Documentation thanks to Blake on http://www.fail2ban.org/wiki/index.php?title=Fail2ban:Community_Portal
[Definition]
-failregex = ^\s*(\[\])?(%(__hostname)s\s*(roundcube:)?\s*(<[\w]+>)? IMAP Error)?: (FAILED login|Login failed) for .*? from <HOST>(\. .* in .*?/rcube_imap\.php on line \d+ \(\S+ \S+\))?$
- ^\[\]:\s*(<[\w]+>)? Failed login for [\w\-\.\+]+(@[\w\-\.\+]+\.[a-zA-Z]{2,6})? from <HOST> in session \w+( \(error: \d\))?$
+prefregex = ^\s*(\[\])?(%(__hostname)s\s*(?:roundcube(?:\[(\d*)\])?:)?\s*(<[\w]+>)? IMAP Error)?: <F-CONTENT>.+</F-CONTENT>$
+
+failregex = ^(?:FAILED login|Login failed) for <F-USER>.*</F-USER> from <HOST>(?:(?:\([^\)]*\))?\. (?:(?! from ).)*(?: user=(?P=user))? in \S+\.php on line \d+ \(\S+ \S+\))?$
+ ^(?:<[\w]+> )?Failed login for <F-USER>.*</F-USER> from <HOST> in session \w+( \(error: \d\))?$
ignoreregex =
+
+journalmatch = SYSLOG_IDENTIFIER=roundcube
+
# DEV Notes:
#
# Source: https://github.com/roundcube/roundcubemail/blob/master/program/lib/Roundcube/rcube_imap.php#L180
ignoreregex =
+datepattern = EPOCH
+
# Author: Daniel Black
[Definition]
-_daemon = (?:sm-(mta|acceptingconnections))
+_daemon = (?:sendmail|sm-(?:mta|acceptingconnections))
failregex = ^%(__prefix_line)s\w{14}: (\S+ )?\[<HOST>\]( \(may be forged\))?: possible SMTP attack: command=AUTH, count=\d+$
ignoreregex =
+journalmatch = _SYSTEMD_UNIT=sendmail.service
+
# DEV Notes:
#
# Author: Daniel Black
_daemon = (?:(sm-(mta|acceptingconnections)|sendmail))
-failregex = ^%(__prefix_line)s\w{14}: ruleset=check_rcpt, arg1=(?P<email><\S+@\S+>), relay=(\S+ )?\[<HOST>\]( \(may be forged\))?, reject=(550 5\.7\.1 (?P=email)\.\.\. Relaying denied\. (IP name possibly forged \[(\d+\.){3}\d+\]|Proper authentication required\.|IP name lookup failed \[(\d+\.){3}\d+\])|553 5\.1\.8 (?P=email)\.\.\. Domain of sender address \S+ does not exist|550 5\.[71]\.1 (?P=email)\.\.\. (Rejected: .*|User unknown))$
- ^%(__prefix_line)sruleset=check_relay, arg1=(?P<dom>\S+), arg2=<HOST>, relay=((?P=dom) )?\[(\d+\.){3}\d+\]( \(may be forged\))?, reject=421 4\.3\.2 (Connection rate limit exceeded\.|Too many open connections\.)$
- ^%(__prefix_line)s\w{14}: rejecting commands from (\S+ )?\[<HOST>\] due to pre-greeting traffic after \d+ seconds$
- ^%(__prefix_line)s\w{14}: (\S+ )?\[<HOST>\]: ((?i)expn|vrfy) \S+ \[rejected\]$
- ^(?P<__prefix>%(__prefix_line)s\w+: )<[^@]+@[^>]+>\.\.\. No such user here<SKIPLINES>(?P=__prefix)from=<[^@]+@[^>]+>, size=\d+, class=\d+, nrcpts=\d+, bodytype=\w+, proto=E?SMTP, daemon=MTA, relay=\S+ \[<HOST>\]$
+prefregex = ^<F-MLFID>%(__prefix_line)s(?:\w{14}: )?</F-MLFID><F-CONTENT>.+</F-CONTENT>$
+cmnfailre = ^ruleset=check_rcpt, arg1=(?P<email><\S+@\S+>), relay=(\S+ )?\[<HOST>\](?: \(may be forged\))?, reject=(550 5\.7\.1 (?P=email)\.\.\. Relaying denied\. (IP name possibly forged \[(\d+\.){3}\d+\]|Proper authentication required\.|IP name lookup failed \[(\d+\.){3}\d+\])|553 5\.1\.8 (?P=email)\.\.\. Domain of sender address \S+ does not exist|550 5\.[71]\.1 (?P=email)\.\.\. (Rejected: .*|User unknown))$
+ ^ruleset=check_relay, arg1=(?P<dom>\S+), arg2=<HOST>, relay=((?P=dom) )?\[(\d+\.){3}\d+\](?: \(may be forged\))?, reject=421 4\.3\.2 (Connection rate limit exceeded\.|Too many open connections\.)$
+ ^rejecting commands from (\S* )?\[<HOST>\] due to pre-greeting traffic after \d+ seconds$
+ ^(?:\S+ )?\[<HOST>\]: (?:(?i)expn|vrfy) \S+ \[rejected\]$
+ ^<[^@]+@[^>]+>\.\.\. No such user here$
+ ^<F-NOFAIL>from=<[^@]+@[^>]+></F-NOFAIL>, size=\d+, class=\d+, nrcpts=\d+, bodytype=\w+, proto=E?SMTP, daemon=MTA, relay=\S+ \[<HOST>\]$
-ignoreregex =
+mdre-normal =
+mdre-extra = ^(?:\S+ )?\[<HOST>\](?: \(may be forged\))? did not issue (?:[A-Z]{4}[/ ]?)+during connection to M(?:TA|SP)(?:-\w+)?$
-[Init]
+mdre-aggressive = %(mdre-extra)s
-# "maxlines" is number of log lines to buffer for multi-line regex searches
-maxlines = 10
+failregex = %(cmnfailre)s
+ <mdre-<mode>>
+
+# Parameter "mode": normal (default), extra or aggressive
+# Usage example (for jail.local):
+# [sendmail-reject]
+# filter = sendmail-reject[mode=extra]
+#
+mode = normal
+
+ignoreregex =
+
+journalmatch = _SYSTEMD_UNIT=sendmail.service
# DEV NOTES:
#
-# Regarding the last multiline regex:
+# Regarding the multiline regex:
#
-# There can be a nunber of non-related lines between the first and second part
-# of this regex maxlines of 10 is quite generious. Only one of the
-# "No such user" lines needs to be matched before the line with the HOST.
+# "No such user" lines generate a failure and needs to be matched together with
+# another line with the HOST, therefore no-failure line was added as regex, that
+# contains HOST (see line with tag <F-NOFAIL>).
#
-# Note the capture __prefix, includes both the __prefix_lines (which includes
-# the sendmail PID), but also the \w+ which the the sendmail assigned mail ID.
+# Note the capture <F-MLFID>, includes both the __prefix_lines (which includes
+# the sendmail PID), but also the `\w{14}` which the the sendmail assigned
+# mail ID (todo: check this is necessary, possible obsolete).
#
-# Author: Daniel Black and Fabian Wenk
+# Author: Daniel Black, Fabian Wenk and Sergey Brester aka sebres.
+# Rewritten using prefregex by Serg G. Brester.
--- /dev/null
+# slapd (Stand-alone LDAP Daemon) openldap daemon filter
+#
+# Detecting invalid credentials: error code 49
+# http://www.openldap.org/doc/admin24/appendix-ldap-result-codes.html#invalidCredentials (49)
+
+[INCLUDES]
+
+# Read common prefixes. If any customizations available -- read them from
+# common.local
+before = common.conf
+
+[Definition]
+
+_daemon = slapd
+
+failregex = ^(?P<__prefix>%(__prefix_line)s)conn=(?P<_conn_>\d+) fd=\d+ ACCEPT from IP=<HOST>:\d{1,5} \(IP=\S+\)\s*<SKIPLINES>(?P=__prefix)conn=(?P=_conn_) op=\d+ RESULT(?:\s(?!err)\S+=\S*)* err=49 text=[\w\s]*$
+
+ignoreregex =
+
+[Init]
+
+# "maxlines" is number of log lines to buffer for multi-line regex searches
+maxlines = 20
+
+# Author: Andrii Melnyk
failregex = ^ sogod \[\d+\]: SOGoRootPage Login from '<HOST>' for user '.*' might not have worked( - password policy: \d* grace: -?\d* expire: -?\d* bound: -?\d*)?\s*$
-ignoreregex =
+ignoreregex = "^<ADDR>"
+
+datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
+ {^LN-BEG}(?:%%a )?%%b %%d %%H:%%M:%%S(?:\.%%f)?(?: %%ExY)?
+ ^[^\[]*\[({DATE})
+ {^LN-BEG}
#
# DEV Notes:
ignoreregex =
+datepattern = {^LN-BEG}Epoch
+ {^LN-BEG}
+
# Author: Daniel Black
ignoreregex =
-[Init]
-
datepattern = ^%%m/%%d/%%Y %%H:%%M:%%S
# DEV NOTES:
# common.local
before = common.conf
-[Definition]
+[DEFAULT]
_daemon = sshd
-failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
- ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
- ^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
- ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
- ^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
- ^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
- ^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
- ^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
- ^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
- ^%(__prefix_line)s(?:error: )?Received disconnect from <HOST>: 3: .*: Auth fail(?: \[preauth\])?$
- ^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
- ^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
- ^(?P<__prefix>%(__prefix_line)s)User .+ not allowed because account is locked<SKIPLINES>(?P=__prefix)(?:error: )?Received disconnect from <HOST>: 11: .+ \[preauth\]$
- ^(?P<__prefix>%(__prefix_line)s)Disconnecting: Too many authentication failures for .+? \[preauth\]<SKIPLINES>(?P=__prefix)(?:error: )?Connection closed by <HOST> \[preauth\]$
- ^(?P<__prefix>%(__prefix_line)s)Connection from <HOST> port \d+(?: on \S+ port \d+)?<SKIPLINES>(?P=__prefix)Disconnecting: Too many authentication failures for .+? \[preauth\]$
- ^%(__prefix_line)s(error: )?maximum authentication attempts exceeded for .* from <HOST>(?: port \d*)?(?: ssh\d*)? \[preauth\]$
- ^%(__prefix_line)spam_unix\(sshd:auth\):\s+authentication failure;\s*logname=\S*\s*uid=\d*\s*euid=\d*\s*tty=\S*\s*ruser=\S*\s*rhost=<HOST>\s.*$
+# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: "
+__pref = (?:(?:error|fatal): (?:PAM: )?)?
+# optional suffix (logged from several ssh versions) like " [preauth]"
+__suff = (?: \[preauth\])?\s*
+__on_port_opt = (?: port \d+)?(?: on \S+(?: port \d+)?)?
-ignoreregex =
+# for all possible (also future) forms of "no matching (cipher|mac|MAC|compression method|key exchange method|host key type) found",
+# see ssherr.c for all possible SSH_ERR_..._ALG_MATCH errors.
+__alg_match = (?:(?:\w+ (?!found\b)){0,2}\w+)
+
+[Definition]
+
+prefregex = ^<F-MLFID>%(__prefix_line)s</F-MLFID>%(__pref)s<F-CONTENT>.+</F-CONTENT>$
+
+cmnfailre = ^[aA]uthentication (?:failure|error|failed) for <F-USER>.*</F-USER> from <HOST>( via \S+)?\s*%(__suff)s$
+ ^User not known to the underlying authentication module for <F-USER>.*</F-USER> from <HOST>\s*%(__suff)s$
+ ^Failed \S+ for invalid user <F-USER>(?P<cond_user>\S+)|(?:(?! from ).)*?</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
+ ^Failed \b(?!publickey)\S+ for (?P<cond_inv>invalid user )?<F-USER>(?P<cond_user>\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
+ ^<F-USER>ROOT</F-USER> LOGIN REFUSED.* FROM <HOST>\s*%(__suff)s$
+ ^[iI](?:llegal|nvalid) user <F-USER>.*?</F-USER> from <HOST>%(__on_port_opt)s\s*$
+ ^User <F-USER>.+</F-USER> from <HOST> not allowed because not listed in AllowUsers\s*%(__suff)s$
+ ^User <F-USER>.+</F-USER> from <HOST> not allowed because listed in DenyUsers\s*%(__suff)s$
+ ^User <F-USER>.+</F-USER> from <HOST> not allowed because not in any group\s*%(__suff)s$
+ ^refused connect from \S+ \(<HOST>\)\s*%(__suff)s$
+ ^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>%(__on_port_opt)s:\s*3: .*: Auth fail%(__suff)s$
+ ^User <F-USER>.+</F-USER> from <HOST> not allowed because a group is listed in DenyGroups\s*%(__suff)s$
+ ^User <F-USER>.+</F-USER> from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*%(__suff)s$
+ ^pam_unix\(sshd:auth\):\s+authentication failure;\s*logname=\S*\s*uid=\d*\s*euid=\d*\s*tty=\S*\s*ruser=<F-USER>\S*</F-USER>\s*rhost=<HOST>\s.*%(__suff)s$
+ ^(error: )?maximum authentication attempts exceeded for <F-USER>.*</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?%(__suff)s$
+ ^User <F-USER>.+</F-USER> not allowed because account is locked%(__suff)s
+ ^<F-MLFFORGET>Disconnecting</F-MLFFORGET>: Too many authentication failures(?: for <F-USER>.+?</F-USER>)?%(__suff)s
+ ^<F-NOFAIL>Received <F-MLFFORGET>disconnect</F-MLFFORGET></F-NOFAIL> from <HOST>: 11:
+ ^<F-NOFAIL>Connection <F-MLFFORGET>closed</F-MLFFORGET></F-NOFAIL> by <HOST>%(__suff)s$
+ ^<F-MLFFORGET><F-NOFAIL>Accepted publickey</F-NOFAIL></F-MLFFORGET> for \S+ from <HOST>(?:\s|$)
+
+mdre-normal =
+
+mdre-ddos = ^Did not receive identification string from <HOST>%(__suff)s$
+ ^Connection <F-MLFFORGET>reset</F-MLFFORGET> by <HOST>%(__on_port_opt)s%(__suff)s
+ ^<F-NOFAIL>SSH: Server;Ltype:</F-NOFAIL> (?:Authname|Version|Kex);Remote: <HOST>-\d+;[A-Z]\w+:
+ ^Read from socket failed: Connection <F-MLFFORGET>reset</F-MLFFORGET> by peer%(__suff)s
+
+mdre-extra = ^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>%(__on_port_opt)s:\s*14: No supported authentication methods available%(__suff)s$
+ ^Unable to negotiate with <HOST>%(__on_port_opt)s: no matching <__alg_match> found.
+ ^Unable to negotiate a <__alg_match>%(__suff)s$
+ ^no matching <__alg_match> found:
-[Init]
+mdre-aggressive = %(mdre-ddos)s
+ %(mdre-extra)s
-# "maxlines" is number of log lines to buffer for multi-line regex searches
-maxlines = 10
+cfooterre = ^<F-NOFAIL>Connection from</F-NOFAIL> <HOST>
+
+failregex = %(cmnfailre)s
+ <mdre-<mode>>
+ %(cfooterre)s
+
+# Parameter "mode": normal (default), ddos, extra or aggressive (combines all)
+# Usage example (for jail.local):
+# [sshd]
+# mode = extra
+# # or another jail (rewrite filter parameters of jail):
+# [sshd-aggressive]
+# filter = sshd[mode=aggressive]
+#
+mode = normal
+
+#filter = sshd[mode=aggressive]
+
+ignoreregex =
+
+maxlines = 1
journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd
+datepattern = {^LN-BEG}
+
# DEV Notes:
#
# "Failed \S+ for .*? from <HOST>..." failregex uses non-greedy catch-all because
# and later catch-all's could contain user-provided input, which need to be greedily
# matched away first.
#
-# Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black
-
+# Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black and Sergey Brester aka sebres
+# Rewritten using prefregex (and introduced "mode" parameter) by Serg G. Brester.
_lighttpd_prefix = (?:\(mod_fastcgi\.c\.\d+\) FastCGI-stderr:\s)
-failregex = ^%(__prefix_line)s%(_lighttpd_prefix)s?ALERT - .* \(attacker '<HOST>', file '.*'(?:, line \d+)?\)$
+failregex = ^%(__prefix_line)s%(_lighttpd_prefix)s?ALERT - .*? \(attacker '<HOST>', file '[^']*'(?:, line \d+)?\)$
ignoreregex =
# Fail2Ban filter for Tine 2.0 authentication
#
# Enable logging with:
-# $config['info_log']='/home/tine20/log/tine20.log';
+# $config['info_log']='/var/log/tine20/tine20.log';
#
-[INCLUDES]
-
-before = common.conf
[Definition]
-#failregex = ^[\da-f]{5,} [\da-f]{5,} (-- none --|.*?)( \d+(\-|\:\d+)?(h|m|s|ms)){0,2} INFO \(\d+\): Tinebase_Controller::_loginFailed::\d+ Login with username .*? from <HOST> failed \(-[1]\)!$
-failregex = ^.* Tinebase_Controller::_loginFailed::\d+ Login with username .*? from <HOST> failed .*$
-ignoreregex =
+failregex = ^[\da-f]{5,} [\da-f]{5,} (-- none --|.*?)( \d+(\.\d+)?(h|m|s|ms)){0,2} - WARN \(\d+\): Tinebase_Controller::login::\d+ Login with username .*? from <HOST> failed \(-[13]\)!$
+
+ignoreregex =
+
+datepattern = ^[^-]+ -- [^-]+ -- - ({DATE})
+ {^LN-BEG}
+
# Author: Mika (mkl) from Tine20.org forum: https://www.tine20.org/forum/viewtopic.php?f=2&t=15688&p=54766
# Editor: Daniel Black
# Advisor: Lars Kneschke
_daemon = vsftpd
failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=(ftp)? ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$
- ^ \[pid \d+\] \[.+\] FAIL LOGIN: Client "<HOST>"\s*$
+ ^ \[pid \d+\] \[[^\]]+\] FAIL LOGIN: Client "<HOST>"(?:\s*$|,)
ignoreregex =
_daemon = xinetd
-failregex = ^%(__prefix_line)sFAIL: \S+ address from=<HOST>$
- ^%(__prefix_line)sFAIL: \S+ libwrap from=<HOST>$
+prefregex = ^%(__prefix_line)sFAIL: <F-CONTENT>.+</F-CONTENT>$
+
+failregex = ^\S+ address from=<HOST>$
+ ^\S+ libwrap from=<HOST>$
ignoreregex =
--- /dev/null
+# Fail2Ban filter for Zoneminder login failures
+
+[INCLUDES]
+before = apache-common.conf
+
+[Definition]
+
+# pattern: [Wed Apr 27 23:12:07.736196 2016] [:error] [pid 2460] [client 10.1.1.1:47296] WAR [Login denied for user "test"], referer: https://zoneminderurl/index.php
+#
+#
+# Option: failregex
+# Notes.: regex to match the password failure messages in the logfile.
+
+failregex = ^%(_apache_error_client)s WAR \[Login denied for user "[^"]*"\]
+
+ignoreregex =
+
+# Notes:
+# Tested on Zoneminder 1.29.0
+#
+# Author: John Marzella
# See man 5 jail.conf for details.
#
# [DEFAULT]
-# bantime = 3600
+# bantime = 1h
#
# [sshd]
# enabled = true
# MISCELLANEOUS OPTIONS
#
-# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
-# ban a host which matches an address in this list. Several addresses can be
-# defined using space (and/or comma) separator.
-ignoreip = 127.0.0.1/8
+# "ignorself" specifies whether the local resp. own IP addresses should be ignored
+# (default is true). Fail2ban will not ban a host which matches such addresses.
+#ignorself = true
+
+# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
+# will not ban a host which matches an address in this list. Several addresses
+# can be defined using space (and/or comma) separator.
+#ignoreip = 127.0.0.1/8 ::1
# External command that will take an tagged arguments to ignore, e.g. <ip>,
# and return true if the IP is to be ignored. False otherwise.
ignorecommand =
# "bantime" is the number of seconds that a host is banned.
-bantime = 600
+bantime = 10m
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
-findtime = 600
+findtime = 10m
# "maxretry" is the number of failures before a host get banned.
maxretry = 5
# but it will be logged as a warning.
# no: if a hostname is encountered, will not be used for banning,
# but it will be logged as info.
+# raw: use raw value (no hostname), allow use it for no-host filters/actions (example user)
usedns = warn
# "logencoding" specifies the encoding of the log files handled by the jail
enabled = false
+# "mode" defines the mode of the filter (see corresponding filter implementation for more info).
+mode = normal
+
# "filter" defines the filter to use by the jail.
# By default jails have names matching their filter name
#
-filter = %(__name__)s
+filter = %(__name__)s[mode=%(mode)s]
#
destemail = root@localhost
# Sender email address used solely for some actions
-sender = root@localhost
+sender = root@<fq-hostname>
# E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the
# mailing. Change mta configuration parameter to mail if you want to
# Default protocol
protocol = tcp
-# Specify chain where jumps would need to be added in iptables-* actions
-chain = INPUT
+# Specify chain where jumps would need to be added in ban-actions expecting parameter chain
+chain = <known/chain>
# Ports to be banned
# Usually should be overridden in a particular jail
# Report block via blocklist.de fail2ban reporting service API
#
-# See the IMPORTANT note in action.d/blocklist_de.conf for when to
-# use this action. Create a file jail.d/blocklist_de.local containing
-# [Init]
-# blocklist_de_apikey = {api key from registration]
+# See the IMPORTANT note in action.d/blocklist_de.conf for when to use this action.
+# Specify expected parameters in file action.d/blocklist_de.local or if the interpolation
+# `action_blocklist_de` used for the action, set value of `blocklist_de_apikey`
+# in your `jail.local` globally (section [DEFAULT]) or per specific jail section (resp. in
+# corresponding jail.d/my-jail.local file).
#
action_blocklist_de = blocklist_de[email="%(sender)s", service=%(filter)s, apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]
#
action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"]
+# Report ban via abuseipdb.com.
+#
+# See action.d/abuseipdb.conf for usage example and details.
+#
+action_abuseipdb = abuseipdb
+
# Choose default action. To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local
# globally (section [DEFAULT]) or per specific section
[sshd]
-port = ssh
-logpath = %(sshd_log)s
-backend = %(sshd_backend)s
-
-
-[sshd-ddos]
-# This jail corresponds to the standard configuration in Fail2ban.
-# The mail-whois action send a notification e-mail with a whois request
-# in the body.
+# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
+# normal (default), ddos, extra or aggressive (combines all).
+# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
+#mode = normal
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
# for email addresses. The mail outputs are buffered.
port = http,https
logpath = %(apache_access_log)s
-bantime = 172800
+bantime = 48h
maxretry = 1
port = http,https
logpath = %(roundcube_errors_log)s
+# Use following line in your jail.local if roundcube logs to journal.
+#backend = %(syslog_backend)s
[openwebmail]
[postfix]
-
-port = smtp,465,submission
-logpath = %(postfix_log)s
-backend = %(postfix_backend)s
+# To use another modes set filter parameter "mode" in jail.local:
+mode = more
+port = smtp,465,submission
+logpath = %(postfix_log)s
+backend = %(postfix_backend)s
[postfix-rbl]
+filter = postfix[mode=rbl]
port = smtp,465,submission
logpath = %(postfix_log)s
backend = %(postfix_backend)s
[sendmail-reject]
-
+# To use more aggressive modes set filter parameter "mode" in jail.local:
+# normal (default), extra or aggressive
+# See "tests/files/logs/sendmail-reject" or "filter.d/sendmail-reject.conf" for usage example and details.
+#mode = normal
port = smtp,465,submission
logpath = %(syslog_mail)s
backend = %(syslog_backend)s
[exim]
-
+# see filter.d/exim.conf for further modes supported from filter:
+#mode = normal
port = smtp,465,submission
logpath = %(exim_main_log)s
[courier-auth]
-port = smtp,465,submission,imap3,imaps,pop3,pop3s
+port = smtp,465,submission,imap,imaps,pop3,pop3s
logpath = %(syslog_mail)s
backend = %(syslog_backend)s
[postfix-sasl]
-port = smtp,465,submission,imap3,imaps,pop3,pop3s
+filter = postfix[mode=auth]
+port = smtp,465,submission,imap,imaps,pop3,pop3s
# You might consider monitoring /var/log/mail.warn instead if you are
# running postfix since it would provide the same log lines at the
# "warn" level but overall at the smaller filesize.
[perdition]
-port = imap3,imaps,pop3,pop3s
+port = imap,imaps,pop3,pop3s
logpath = %(syslog_mail)s
backend = %(syslog_backend)s
[squirrelmail]
-port = smtp,465,submission,imap2,imap3,imaps,pop3,pop3s,http,https,socks
+port = smtp,465,submission,imap,imap2,imaps,pop3,pop3s,http,https,socks
logpath = /var/lib/squirrelmail/prefs/squirrelmail_access_log
[cyrus-imap]
-port = imap3,imaps
+port = imap,imaps
logpath = %(syslog_mail)s
backend = %(syslog_backend)s
[uwimap-auth]
-port = imap3,imaps
+port = imap,imaps
logpath = %(syslog_mail)s
backend = %(syslog_backend)s
backend = %(mysql_backend)s
+# Log wrong MongoDB auth (for details see filter 'filter.d/mongodb-auth.conf')
+[mongodb-auth]
+# change port when running with "--shardsvr" or "--configsvr" runtime operation
+port = 27017
+logpath = /var/log/mongodb/mongodb.log
+
+
# Jail for more extended banning of persistent abusers
# !!! WARNINGS !!!
# 1. Make sure that your loglevel specified in fail2ban.conf/.local
logpath = /var/log/fail2ban.log
banaction = %(banaction_allports)s
-bantime = 604800 ; 1 week
-findtime = 86400 ; 1 day
+bantime = 1w
+findtime = 1d
# Generic filter for PAM. Has to be used with action which bans all
[pass2allow-ftp]
# this pass2allow example allows FTP traffic after successful HTTP authentication
port = ftp,ftp-data,ftps,ftps-data
-# knocking_url variable must be overridden to some secret value in filter.d/apache-pass.local
-filter = apache-pass
+# knocking_url variable must be overridden to some secret value in jail.local
+knocking_url = /knocking/
+filter = apache-pass[knocking_url="%(knocking_url)s"]
# access log of the website with HTTP auth
logpath = %(apache_access_log)s
blocktype = RETURN
returntype = DROP
-bantime = 3600
+action = %(action_)s[blocktype=%(blocktype)s, returntype=%(returntype)s]
+bantime = 1h
maxretry = 1
findtime = 1
# See "haproxy-http-auth" filter for a brief cautionary note when setting
# maxretry and findtime.
logpath = /var/log/haproxy.log
+
+[slapd]
+port = ldap,ldaps
+logpath = /var/log/slapd.log
+
+[domino-smtp]
+port = smtp,ssmtp
+logpath = /home/domino01/data/IBM_TECHNICAL_SUPPORT/console.log
+
+[phpmyadmin-syslog]
+port = http,https
+logpath = %(syslog_authpriv)s
+backend = %(syslog_backend)s
+
+
+[zoneminder]
+# Zoneminder HTTP/HTTPS web interface auth
+# Logs auth failures to apache2 error log
+port = http,https
+logpath = %(apache_error_log)s
+
--- /dev/null
+[sshd]
+enabled = true
--- /dev/null
+# Arch
+
+[INCLUDES]
+
+before = paths-common.conf
+
+after = paths-overrides.local
+
+
+[DEFAULT]
+
+apache_error_log = /var/log/httpd/*error_log
+
+apache_access_log = /var/log/httpd/*access_log
+
+exim_main_log = /var/log/exim/main.log
+
+mysql_log = /var/log/mariadb/mariadb.log
+ /var/log/mysqld.log
+
+roundcube_errors_log = /var/log/roundcubemail/errors
+
+# These services will log to the journal via syslog, so use the journal by
+# default.
+syslog_backend = systemd
+sshd_backend = systemd
+dropbear_backend = systemd
+proftpd_backend = systemd
+pureftpd_backend = systemd
+wuftpd_backend = systemd
+postfix_backend = systemd
+dovecot_backend = systemd
[DEFAULT]
-default_backend = auto
+default_backend = %(default/backend)s
+
+# Initial common values (to overwrite in path-<distribution>.conf)...
+# There is no sensible generic defaults for syslog log targets, thus
+# leaving them empty here (resp. set to mostly used variant) in order
+# to avoid errors while parsing/interpolating configs.
+#
+# Note systemd-backend does not need the logpath at all.
+#
+syslog_local0 = /var/log/messages
+
+syslog_authpriv = /var/log/auth.log
+syslog_daemon = %(syslog_local0)s
+syslog_ftp = %(syslog_local0)s
+syslog_mail =
+syslog_mail_warn =
+syslog_user = %(syslog_local0)s
+
+# Set the default syslog backend target to default_backend
+syslog_backend = %(default_backend)s
+
+# Default values for several jails:
sshd_log = %(syslog_authpriv)s
sshd_backend = %(default_backend)s
dropbear_log = %(syslog_authpriv)s
dropbear_backend = %(default_backend)s
-# There is no sensible generic defaults for syslog log targets, thus
-# leaving them empty here so that no errors while parsing/interpolating configs
-syslog_daemon =
-syslog_ftp =
-syslog_local0 =
-syslog_mail_warn =
-syslog_user =
-# Set the default syslog backend target to default_backend
-syslog_backend = %(default_backend)s
+apache_error_log = /var/log/apache2/*error.log
+
+apache_access_log = /var/log/apache2/*access.log
# from /etc/audit/auditd.conf
auditd_log = /var/log/audit/audit.log
# http://www.hardened-php.net/suhosin/configuration.html#suhosin.log.syslog.facility
# syslog_user is the default. Lighttpd also hooks errors into its log.
-suhosin_log = %(syslog_user)s %(lighttpd_error_log)s
+suhosin_log = %(syslog_user)s
+ %(lighttpd_error_log)s
# defaults to ftp or local2 if ftp doesn't exist
proftpd_log = %(syslog_ftp)s
syslog_mail = /var/log/mail.log
-syslog_mail_warn = /var/log/mail.warn
+# control the `mail.warn` setting, see `/etc/rsyslog.d/50-default.conf` (if commented `mail.*` wins).
+# syslog_mail_warn = /var/log/mail.warn
+syslog_mail_warn = %(syslog_mail)s
-syslog_authpriv = /var/log/auth.log
-
-# syslog_auth = /var/log/auth.log
-#
syslog_user = /var/log/user.log
syslog_ftp = /var/log/syslog
syslog_daemon = /var/log/daemon.log
-syslog_local0 = /var/log/messages
-
-
-apache_error_log = /var/log/apache2/*error.log
-
-apache_access_log = /var/log/apache2/*access.log
-
exim_main_log = /var/log/exim4/mainlog
# was in debian squeezy but not in wheezy
[DEFAULT]
-syslog_local0 = /var/log/messages
-
syslog_mail = /var/log/mail
syslog_mail_warn = %(syslog_mail)s
syslog_authpriv = %(syslog_local0)s
-syslog_user = %(syslog_local0)s
-
-syslog_ftp = %(syslog_local0)s
-
-syslog_daemon = %(syslog_local0)s
-
-apache_error_log = /var/log/apache2/*error_log
-
-apache_access_log = /var/log/apache2/*access_log
-
pureftpd_log = %(syslog_local0)s
exim_main_log = /var/log/exim/main.log
roundcube_errors_log = /srv/www/roundcubemail/logs/errors
solidpop3d_log = %(syslog_mail)s
+
+# These services will log to the journal via syslog, so use the journal by
+# default.
+syslog_backend = systemd
+sshd_backend = systemd
+dropbear_backend = systemd
+proftpd_backend = systemd
+pureftpd_backend = systemd
+wuftpd_backend = systemd
+postfix_backend = systemd
+dovecot_backend = systemd
+mysql_backend = systemd
# rename this file: (sudo) mv /etc/init.d/fail2ban.init /etc/init.d/fail2ban
# same with the logrotate file: (sudo) mv /etc/logrotate.d/fail2ban.logrotate /etc/logrotate.d/fail2ban
#
-PATH=/usr/sbin:/usr/bin:/sbin:/bin
+PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin
DESC="authentication failure monitor"
NAME=fail2ban
# fail2ban-client is not a daemon itself but starts a daemon and
# loads its with configuration
-DAEMON=/usr/local/bin/$NAME-client
+DAEMON=/usr/bin/$NAME-client
SCRIPTNAME=/etc/init.d/$NAME
# Ad-hoc way to parse out socket file name
--- /dev/null
+/var/log/fail2ban.log {
+
+ weekly
+ rotate 4
+ compress
+
+ delaycompress
+ missingok
+ postrotate
+ fail2ban-client flushlogs 1>/dev/null
+ endscript
+
+ # If fail2ban runs as non-root it still needs to have write access
+ # to logfiles.
+ # create 640 fail2ban adm
+ create 640 root adm
+}
--- /dev/null
+check process fail2ban with pidfile /var/run/fail2ban/fail2ban.pid
+ group services
+ start program = "/etc/init.d/fail2ban force-start"
+ stop program = "/etc/init.d/fail2ban stop"
+ if failed unixsocket /var/run/fail2ban/fail2ban.sock then restart
+ if 5 restarts within 5 cycles then timeout
+
+check file fail2ban_log with path /var/log/fail2ban.log
+ if match "ERROR|WARNING" then alert
--- /dev/null
+../init.d/fail2ban
\ No newline at end of file
--- /dev/null
+../init.d/fail2ban
\ No newline at end of file
--- /dev/null
+../init.d/fail2ban
\ No newline at end of file
--- /dev/null
+../init.d/fail2ban
\ No newline at end of file
--- /dev/null
+../init.d/fail2ban
\ No newline at end of file
--- /dev/null
+../init.d/fail2ban
\ No newline at end of file
--- /dev/null
+../init.d/fail2ban
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/fail2ban.service
\ No newline at end of file