diff --git a/.coveragerc b/.coveragerc index 19bc3db4..442ddb82 100644 --- a/.coveragerc +++ b/.coveragerc @@ -7,5 +7,6 @@ source = [report] exclude_lines = - pragma: no cover - pragma: systemd no cover + pragma: ?no ?cover + pragma: ?${F2B_PY}.x no ?cover + pragma: ?systemd no ?cover diff --git a/.travis.yml b/.travis.yml index 0c611a95..ebfcd68e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,9 @@ python: - pypy3.3-5.5-alpha before_install: - echo "running under $TRAVIS_PYTHON_VERSION" - - if [[ $TRAVIS_PYTHON_VERSION == 2* || $TRAVIS_PYTHON_VERSION == pypy* && $TRAVIS_PYTHON_VERSION != pypy3* ]]; then export F2B_PY_2=true && echo "Set F2B_PY_2"; fi - - if [[ $TRAVIS_PYTHON_VERSION == 3* || $TRAVIS_PYTHON_VERSION == pypy3* ]]; then export F2B_PY_3=true && echo "Set F2B_PY_3"; fi + - if [[ $TRAVIS_PYTHON_VERSION == 2* || $TRAVIS_PYTHON_VERSION == pypy* && $TRAVIS_PYTHON_VERSION != pypy3* ]]; then export F2B_PY=2; fi + - if [[ $TRAVIS_PYTHON_VERSION == 3* || $TRAVIS_PYTHON_VERSION == pypy3* ]]; then export F2B_PY=3; fi + - echo "Set F2B_PY=$F2B_PY" - travis_retry sudo apt-get update -qq # Set this so sudo executes the correct python binary # Anything not using sudo will already have the correct environment @@ -28,29 +29,32 @@ install: # Install Python packages / dependencies # coverage - travis_retry pip install coverage - # coveralls - - travis_retry pip install coveralls codecov + # coveralls (note coveralls doesn't support 2.6 now): + - if [[ $TRAVIS_PYTHON_VERSION != 2.6* ]]; then F2B_COV=1; else F2B_COV=0; fi + - if [[ "$F2B_COV" = 1 ]]; then travis_retry pip install coveralls; fi + # codecov: + - travis_retry pip install codecov # dnspython or dnspython3 - - if [[ "$F2B_PY_2" ]]; then travis_retry pip install dnspython; fi - - if [[ "$F2B_PY_3" ]]; then travis_retry pip install dnspython3; fi + - if [[ "$F2B_PY" = 2 ]]; then travis_retry pip install dnspython; fi + - if [[ "$F2B_PY" = 3 ]]; then travis_retry pip install dnspython3; fi # gamin - install manually (not in PyPI) - travis-ci system Python is 2.7 - if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then travis_retry sudo apt-get install -qq python-gamin && cp /usr/share/pyshared/gamin.py /usr/lib/pyshared/python2.7/_gamin.so $VIRTUAL_ENV/lib/python2.7/site-packages/; fi # pyinotify - travis_retry pip install pyinotify before_script: # Manually execute 2to3 for now - - if [[ "$F2B_PY_3" ]]; then ./fail2ban-2to3; fi + - if [[ "$F2B_PY" = 3 ]]; then ./fail2ban-2to3; fi script: # Keep the legacy setup.py test approach of checking coverage for python2 - - if [[ "$F2B_PY_2" ]]; then coverage run setup.py test; fi + - if [[ "$F2B_PY" = 2 ]]; then coverage run setup.py test; fi # Coverage doesn't pick up setup.py test with python3, so run it directly (with same verbosity as from setup) - - if [[ "$F2B_PY_3" ]]; then coverage run bin/fail2ban-testcases --verbosity=2; fi + - if [[ "$F2B_PY" = 3 ]]; then coverage run bin/fail2ban-testcases --verbosity=2; fi # Use $VENV_BIN (not python) or else sudo will always run the system's python (2.7) - sudo $VENV_BIN/pip install . # Doc files should get installed on Travis under Linux - test -e /usr/share/doc/fail2ban/FILTERS after_success: - - coveralls + - if [[ "$F2B_COV" = 1 ]]; then coveralls; fi - codecov matrix: fast_finish: true diff --git a/ChangeLog b/ChangeLog index 29b07973..f24c43ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,10 +27,117 @@ Incompatibility list (compared to v.0.9): * v.0.10 uses more precise date template handling, that can be theoretically incompatible to some user configurations resp. `datepattern`. -* Since v0.10 fail2ban supports the matching of the IPv6 addresses, but not all ban actions are +* Since v0.10 fail2ban supports the matching of IPv6 addresses, but not all ban actions are IPv6-capable now. +ver. 0.10.5-dev-1 (20??/??/??) - development edition +----------- + +### Fixes +* fixed read of included config-files (`.local` overwrites options of `.conf` for config-files + included with before/after) +* `filter.d/sshd.conf`: + - captures `Disconnecting ...: Change of username or service not allowed` (gh-2239, gh-2279) + - captures `Disconnected from ... [preauth]` (`extra`/`aggressive` mode and preauth phase only, gh-2239, gh-2279) +* `filter.d/mysqld-auth.conf`: + - MYSQL 8.0.13 compatibility (log-error-verbosity = 3), log-format contains few additional words + enclosed in brackets after "[Note]" (gh-2314) +* `files/fail2ban.service.in`: fixed systemd-unit template - missing nftables dependency (gh-2313) + +### New Features +* new failregex-flag tag `` for failregex, signaled that the access to service was gained + (ATM used similar to tag ``, but it does not add the log-line to matches, gh-2279) + +### Enhancements + + +ver. 0.10.4 (2018/10/04) - ten-four-on-due-date-ten-four +----------- + +### Fixes +* `filter.d/dovecot.conf`: + - failregex enhancement to catch sql password mismatch errors (gh-2153); + - disconnected with "proxy dest auth failed" (gh-2184); +* `filter.d/freeswitch.conf`: + - provide compatibility for log-format from gh-2193: + * extended with new default date-pattern `^(?:%%Y-)?%%m-%%d[ T]%%H:%%M:%%S(?:\.%%f)?` to cover + `YYYY-mm-dd HH:MM::SS.ms` as well as `mm-dd HH:MM::SS.ms` (so year is optional); + * more optional arguments in log-line (so accept [WARN] as well as [WARNING] and optional [SOFIA] hereafter); + - extended with mode parameter, allows to avoid matching of messages like `auth challenge (REGISTER)` + (see gh-2163) (currently `extra` as default to be backwards-compatible), see comments in filter + how to set it to mode `normal`. +* `filter.d/domino-smtp.conf`: + - recognizes failures logged using another format (something like session-id, IP enclosed in square brackets); + - failregex extended to catch connections rejected for policy reasons (gh-2228); +* `action.d/hostsdeny.conf`: fix parameter in config (dynamic parameters stating with '_' are protected + and don't allowed in command-actions), see gh-2114; +* decoding stability fix by wrong encoded characters like utf-8 surrogate pairs, etc (gh-2171): + - fail2ban running in the preferred encoding now (as default encoding also within python 2.x), mostly + `UTF-8` in opposite to `ascii` previously, so minimizes influence of implicit conversions errors; + - actions: avoid possible conversion errors on wrong-chars by replace tags; + - database: improve adapter/converter handlers working on invalid characters in sense of json and/or sqlite-database; + additionally both are exception-safe now, so avoid possible locking of database (closes gh-2137); + - logging in fail2ban is process-wide exception-safe now. +* repaired start-time of initial seek to time (as well as other log-parsing related data), + if parameter `logpath` specified before `findtime`, `backend`, `datepattern`, etc (gh-2173) +* systemd: fixed type error on option `journalflags`: an integer is required (gh-2125); + +### New Features +* new option `ignorecache` to improve performance of ignore failure check (using caching of `ignoreip`, + `ignoreself` and `ignorecommand`), see `man jail.conf` for syntax-example; +* `ignorecommand` extended to use actions-similar replacement (capable to interpolate + all possible tags like ``, ``, ``, `F-USER` etc.) + +### Enhancements +* `filter.d/dovecot.conf`: extended with tags F-USER (and alternatives) to collect user-logins (gh-2168) +* since v.0.10.4, fail2ban-client, fail2ban-server and fail2ban-regex will return version without logo info, + additionally option `-V` can be used to get version in normalized machine-readable short format. + + +ver. 0.10.3 (2018/04/04) - the-time-is-always-right-to-do-what-is-right +----------- + +### ver. 0.10.3.1: +* fixed JSON serialization for the set-object within dump into database (gh-2103). + +### Fixes +* `filter.d/asterisk.conf`: fixed failregex prefix by log over remote syslog server (gh-2060); +* `filter.d/exim.conf`: failregex extended - SMTP call dropped: too many syntax or protocol errors (gh-2048); +* `filter.d/recidive.conf`: fixed if logging into systemd-journal (SYSLOG) with daemon name in prefix, gh-2069; +* `filter.d/sendmail-auth.conf`, `filter.d/sendmail-reject.conf` : + - fixed failregex, sendmail uses prefix 'IPv6:' logging of IPv6 addresses (gh-2064); +* `filter.d/sshd.conf`: + - failregex got an optional space in order to match new log-format (see gh-2061); + - fixed ddos-mode regex to match refactored message (some versions can contain port now, see gh-2062); + - fixed root login refused regex (optional port before preauth, gh-2080); + - avoid banning of legitimate users when pam_unix used in combination with other password method, so + bypass pam_unix failures if accepted available for this user gh-2070; + - amend to gh-1263 with better handling of multiple attempts (failures for different user-names recognized immediatelly); + - mode `ddos` (and `aggressive`) extended to catch `Connection closed by ... [preauth]`, so in DDOS mode + it counts failure on closing connection within preauth-stage (gh-2085); +* `action.d/abuseipdb.conf`: fixed curl cypher errors and comment quote-issue (gh-2044, gh-2101); +* `action.d/badips.py`: implicit convert IPAddr to str, solves an issue "expected string, IPAddr found" (gh-2059); +* `action.d/hostsdeny.conf`: fixed IPv6 syntax (enclosed in square brackets, gh-2066); +* (Free)BSD ipfw actionban fixed to allow same rule added several times (gh-2054); + +### New Features +* several stability and performance optimizations, more effective filter parsing, etc; +* stable runnable within python versions 3.6 (as well as within 3.7-dev); + +### Enhancements +* `filter.d/apache-auth.conf`: detection of Apache SNI errors resp. misredirect attempts (gh-2017, gh-2097); +* `filter.d/apache-noscript.conf`: extend failregex to match "Primary script unknown", e. g. from php-fpm (gh-2073); +* date-detector extended with long epoch (`LEPOCH`) to parse milliseconds/microseconds posix-dates (gh-2029); +* possibility to specify own regex-pattern to match epoch date-time, e. g. `^\[{EPOCH}\]` or `^\[{LEPOCH}\]` (gh-2038); + the epoch-pattern similar to `{DATE}` patterns does the capture and cuts out the match of whole pattern from the log-line, + e. g. date-pattern `^\[{LEPOCH}\]\s+:` will match and cut out `[1516469849551000] :` from begin of the log-line. +* badips.py now uses https instead of plain http when requesting badips.com (gh-2057); +* add support for "any" badips.py bancategory, to be able to retrieve IPs from all categories with a desired score (gh-2056); +* Introduced new parameter `padding` for logging within fail2ban-server (default on, excepting SYSLOG): + Usage `logtarget = target[padding=on|off]` + + ver. 0.10.2 (2018/01/18) - nothing-burns-like-the-cold ----------- @@ -93,7 +200,7 @@ ver. 0.10.1 (2017/10/12) - succeeded-before-friday-the-13th * avoid using "ANSI_X3.4-1968" as preferred encoding (if missing environment variables 'LANGUAGE', 'LC_ALL', 'LC_CTYPE', and 'LANG', see gh-1587). * action.d/pf.conf: several fixes for pf-action like anchoring, etc. (see gh-1866, gh-1867); -* fixed ignorself issue "Retrieving own IPs of localhost failed: inet_pton() argument 2 must be string, not int" (see gh-1865); +* fixed ignoreself issue "Retrieving own IPs of localhost failed: inet_pton() argument 2 must be string, not int" (see gh-1865); * fixed tags `` and ``, could be used without ticket (a. g. in `actionstart` etc., gh-1859). * setup.py: fixed several setup facilities (gh-1874): diff --git a/DEVELOP b/DEVELOP index bb7de5c8..f3f9819a 100644 --- a/DEVELOP +++ b/DEVELOP @@ -262,12 +262,16 @@ FileContainer Keeps the position pointer -dnsutils.py -~~~~~~~~~~~ +ipdns.py +~~~~~~~~ DNSUtils - Utility class for DNS and IP handling + Utility class for DNS handling + +IPAddr + + Object-class for IP address handling filter*.py diff --git a/MANIFEST b/MANIFEST index bfdd77c0..144ae697 100644 --- a/MANIFEST +++ b/MANIFEST @@ -391,6 +391,8 @@ kill-server man/fail2ban.1 man/fail2ban-client.1 man/fail2ban-client.h2m +man/fail2ban-python.1 +man/fail2ban-python.h2m man/fail2ban-regex.1 man/fail2ban-regex.h2m man/fail2ban-server.1 diff --git a/README.md b/README.md index 94485adb..2b40d306 100644 --- a/README.md +++ b/README.md @@ -2,53 +2,55 @@ / _|__ _(_) |_ ) |__ __ _ _ _ | _/ _` | | |/ /| '_ \/ _` | ' \ |_| \__,_|_|_/___|_.__/\__,_|_||_| - v0.10.2 2018/01/18 + v0.10.3.dev1 20??/??/?? ## Fail2Ban: ban hosts that cause multiple authentication errors -Fail2Ban scans log files like `/var/log/auth.log` and bans IP addresses having +Fail2Ban scans log files like `/var/log/auth.log` and bans IP addresses conducting too many failed login attempts. It does this by updating system firewall rules to reject new connections from those IP addresses, for a configurable amount of time. Fail2Ban comes out-of-the-box ready to read many standard log files, -such as those for sshd and Apache, and is easy to configure to read any log -file you choose, for any error you choose. +such as those for sshd and Apache, and is easily configured to read any log +file of your choosing, for any error you wish. -Though Fail2Ban is able to reduce the rate of incorrect authentications -attempts, it cannot eliminate the risk that weak authentication presents. -Configure services to use only two factor or public/private authentication +Though Fail2Ban is able to reduce the rate of incorrect authentication +attempts, it cannot eliminate the risk presented by weak authentication. +Set up services to use only two factor, or public/private authentication mechanisms if you really want to protect services. | Since v0.10 fail2ban supports the matching of the IPv6 addresses. ------|------ -This README is a quick introduction to Fail2ban. More documentation, FAQ, HOWTOs -are available in fail2ban(1) manpage, [Wiki](https://github.com/fail2ban/fail2ban/wiki) -and on the website http://www.fail2ban.org +This README is a quick introduction to Fail2Ban. More documentation, FAQ, and HOWTOs +to be found on fail2ban(1) manpage, [Wiki](https://github.com/fail2ban/fail2ban/wiki) +and the website: https://www.fail2ban.org Installation: ------------- -**It is possible that Fail2ban is already packaged for your distribution. In -this case, you should use it instead.** +**It is possible that Fail2Ban is already packaged for your distribution. In +this case, you should use that instead.** Required: -- [Python2 >= 2.6 or Python >= 3.2](http://www.python.org) or [PyPy](http://pypy.org) +- [Python2 >= 2.6 or Python >= 3.2](https://www.python.org) or [PyPy](https://pypy.org) Optional: -- [pyinotify >= 0.8.3](https://github.com/seb-m/pyinotify) - - Linux >= 2.6.13 +- [pyinotify >= 0.8.3](https://github.com/seb-m/pyinotify), may require: + * Linux >= 2.6.13 - [gamin >= 0.0.21](http://www.gnome.org/~veillard/gamin) -- [systemd >= 204](http://www.freedesktop.org/wiki/Software/systemd) +- [systemd >= 204](http://www.freedesktop.org/wiki/Software/systemd) and python bindings: + * [python-systemd package](https://www.freedesktop.org/software/systemd/python-systemd/index.html) - [dnspython](http://www.dnspython.org/) -To install, just do: - tar xvfj fail2ban-0.10.2.tar.bz2 - cd fail2ban-0.10.2 +To install: + + tar xvfj fail2ban-0.10.3.tar.bz2 + cd fail2ban-0.10.3 python setup.py install This will install Fail2Ban into the python library directory. The executable -scripts are placed into `/usr/bin`, and configuration under `/etc/fail2ban`. +scripts are placed into `/usr/bin`, and configuration in `/etc/fail2ban`. Fail2Ban should be correctly installed now. Just type: @@ -90,7 +92,7 @@ Contact: See [CONTRIBUTING.md](https://github.com/fail2ban/fail2ban/blob/master/CONTRIBUTING.md) ### You just appreciate this program: -send kudos to the original author ([Cyril Jaquier](mailto:cyril.jaquier@fail2ban.org)) +Send kudos to the original author ([Cyril Jaquier](mailto:cyril.jaquier@fail2ban.org)) or *better* to the [mailing list](https://lists.sourceforge.net/lists/listinfo/fail2ban-users) since Fail2Ban is "community-driven" for years now. diff --git a/bin/fail2ban-server b/bin/fail2ban-server index 860a7607..03dc0fd3 100755 --- a/bin/fail2ban-server +++ b/bin/fail2ban-server @@ -22,7 +22,7 @@ Fail2Ban reads log file that contains password failure report and bans the corresponding IP addresses using firewall rules. -This tools starts/stops fail2ban server or does client/server communication, +This tool starts/stops fail2ban server or does client/server communication to change/read parameters of the server or jails. """ diff --git a/bin/fail2ban-testcases b/bin/fail2ban-testcases index 5539d4c6..ba3d90b9 100755 --- a/bin/fail2ban-testcases +++ b/bin/fail2ban-testcases @@ -31,7 +31,7 @@ import time import unittest # Check if local fail2ban module exists, and use if it exists by -# modifying the path. This is such that tests can be used in dev +# modifying the path. This is done so that tests can be used in dev # environment. if os.path.exists("fail2ban/__init__.py"): sys.path.insert(0, ".") diff --git a/config/action.d/abuseipdb.conf b/config/action.d/abuseipdb.conf index 15e41fbe..c53ed489 100644 --- a/config/action.d/abuseipdb.conf +++ b/config/action.d/abuseipdb.conf @@ -48,13 +48,13 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = @@ -86,7 +86,7 @@ actioncheck = # Tags: See jail.conf(5) man page # Values: CMD # -actionban = curl --fail --ciphers ecdhe_ecdsa_aes_256_sha --data 'key=' --data-urlencode 'comment=' --data 'ip=' --data 'category=' "https://www.abuseipdb.com/report/json" +actionban = lgm=$(printf '%%s\n...' ""); curl --fail --tlsv1.1 --data "key=" --data-urlencode "comment=$lgm" --data "ip=" --data "category=" "https://www.abuseipdb.com/report/json" # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the diff --git a/config/action.d/badips.py b/config/action.d/badips.py index 473fbf33..1ad711f4 100644 --- a/config/action.d/badips.py +++ b/config/action.d/badips.py @@ -18,20 +18,22 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import sys -if sys.version_info < (2, 7): +if sys.version_info < (2, 7): # pragma: no cover raise ImportError("badips.py action requires Python >= 2.7") import json import threading import logging -if sys.version_info >= (3, ): +if sys.version_info >= (3, ): # pragma: 2.x no cover from urllib.request import Request, urlopen from urllib.parse import urlencode from urllib.error import HTTPError -else: +else: # pragma: 3.x no cover from urllib2 import Request, urlopen, HTTPError from urllib import urlencode from fail2ban.server.actions import ActionBase +from fail2ban.helpers import str2LogLevel + class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable @@ -70,6 +72,9 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable updateperiod : int, optional Time in seconds between updating bad IPs blacklist. Default 900 (15 minutes) + loglevel : int/str, optional + Log level of the message when an IP is (un)banned. + Default `DEBUG`. agent : str, optional User agent transmitted to server. Default `Fail2Ban/ver.` @@ -81,12 +86,12 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable """ TIMEOUT = 10 - _badips = "http://www.badips.com" + _badips = "https://www.badips.com" def _Request(self, url, **argv): return Request(url, headers={'User-Agent': self.agent}, **argv) def __init__(self, jail, name, category, score=3, age="24h", key=None, - banaction=None, bancategory=None, bankey=None, updateperiod=900, agent="Fail2Ban", + banaction=None, bancategory=None, bankey=None, updateperiod=900, loglevel='DEBUG', agent="Fail2Ban", timeout=TIMEOUT): super(BadIPsAction, self).__init__(jail, name) @@ -99,6 +104,7 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable self.banaction = banaction self.bancategory = bancategory or category self.bankey = bankey + self.loglevel = str2LogLevel(loglevel) self.updateperiod = updateperiod self._bannedips = set() @@ -114,6 +120,15 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable except Exception as e: # pragma: no cover return False, e + def logError(self, response, what=''): # pragma: no cover - sporadical (502: Bad Gateway, etc) + messages = {} + try: + messages = json.loads(response.read().decode('utf-8')) + except: + pass + self._logSys.error( + "%s. badips.com response: '%s'", what, + messages.get('err', 'Unknown')) def getCategories(self, incParents=False): """Get badips.com categories. @@ -133,11 +148,8 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable try: response = urlopen( 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( - "Failed to fetch categories. badips.com response: '%s'", - messages['err']) + except HTTPError as response: # pragma: no cover + self.logError(response, "Failed to fetch categories") raise else: response_json = json.loads(response.read().decode('utf-8')) @@ -186,12 +198,10 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable urlencode({'age': age})]) if key: url = "&".join([url, urlencode({'key': key})]) + self._logSys.debug('badips.com: get list, url: %r', url) response = urlopen(self._Request(url), timeout=self.timeout) - except HTTPError as response: - messages = json.loads(response.read().decode('utf-8')) - self._logSys.error( - "Failed to fetch bad IP list. badips.com response: '%s'", - messages['err']) + except HTTPError as response: # pragma: no cover + self.logError(response, "Failed to fetch bad IP list") raise else: return set(response.read().decode('utf-8').split()) @@ -219,7 +229,7 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable @bancategory.setter def bancategory(self, bancategory): - if bancategory not in self.getCategories(incParents=True): + if bancategory != "any" and bancategory not in self.getCategories(incParents=True): self._logSys.error("Category name '%s' not valid. " "see badips.com for list of valid categories", bancategory) @@ -285,7 +295,7 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable exc_info=self._logSys.getEffectiveLevel()<=logging.DEBUG) else: self._bannedips.add(ip) - self._logSys.info( + self._logSys.log(self.loglevel, "Banned IP %s for jail '%s' with action '%s'", ip, self._jail.name, self.banaction) @@ -300,12 +310,12 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable 'ipjailmatches': "", }) except Exception as e: - self._logSys.info( + self._logSys.error( "Error unbanning IP %s for jail '%s' with action '%s': %s", ip, self._jail.name, self.banaction, e, exc_info=self._logSys.getEffectiveLevel()<=logging.DEBUG) else: - self._logSys.info( + self._logSys.log(self.loglevel, "Unbanned IP %s for jail '%s' with action '%s'", ip, self._jail.name, self.banaction) finally: @@ -333,13 +343,16 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable ips = self.getList( self.bancategory, self.score, self.age, self.bankey) # Remove old IPs no longer listed - self._unbanIPs(self._bannedips - ips) + s = self._bannedips - ips + m = len(s) + self._unbanIPs(s) # Add new IPs which are now listed - self._banIPs(ips - self._bannedips) - - self._logSys.info( - "Updated IPs for jail '%s'. Update again in %i seconds", - self._jail.name, self.updateperiod) + s = ips - self._bannedips + p = len(s) + self._banIPs(s) + self._logSys.log(self.loglevel, + "Updated IPs for jail '%s' (-%d/+%d). Update again in %i seconds", + self._jail.name, m, p, self.updateperiod) finally: self._timer = threading.Timer(self.updateperiod, self.update) self._timer.start() @@ -368,19 +381,17 @@ class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable Any issues with badips.com request. """ try: - url = "/".join([self._badips, "add", self.category, aInfo['ip']]) + url = "/".join([self._badips, "add", self.category, str(aInfo['ip'])]) if self.key: url = "?".join([url, urlencode({'key': self.key})]) + self._logSys.debug('badips.com: ban, url: %r', url) response = urlopen(self._Request(url), timeout=self.timeout) - except HTTPError as response: - messages = json.loads(response.read().decode('utf-8')) - self._logSys.error( - "Response from badips.com report: '%s'", - messages['err']) + except HTTPError as response: # pragma: no cover + self.logError(response, "Failed to ban") raise else: messages = json.loads(response.read().decode('utf-8')) - self._logSys.info( + self._logSys.debug( "Response from badips.com report: '%s'", messages['suc']) diff --git a/config/action.d/blocklist_de.conf b/config/action.d/blocklist_de.conf index 2f31d8b9..ba6d427b 100644 --- a/config/action.d/blocklist_de.conf +++ b/config/action.d/blocklist_de.conf @@ -31,13 +31,13 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = @@ -54,7 +54,7 @@ actioncheck = # Tags: See jail.conf(5) man page # Values: CMD # -actionban = curl --fail --data-urlencode 'server=' --data 'apikey=' --data 'service=' --data 'ip=' --data-urlencode 'logs=' --data 'format=text' --user-agent "" "https://www.blocklist.de/en/httpreports.html" +actionban = curl --fail --data-urlencode "server=" --data "apikey=" --data "service=" --data "ip=" --data-urlencode "logs=
" --data 'format=text' --user-agent "" "https://www.blocklist.de/en/httpreports.html" # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the @@ -64,10 +64,8 @@ actionban = curl --fail --data-urlencode 'server=' --data 'apikey=)' > /dev/null 2>&1 || ( ipfw show | awk 'BEGIN { b = } { if ($1 < b) {} else if ($1 == b) { b = $1 + 1 } else { e = b } } END { if (e) exit e
else exit b }'; num=$?; ipfw -q add $num from table\(\) to me ; echo $num > "" ) # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = [ ! -f ] || ( read num < ""
ipfw -q delete $num
rm "" ) @@ -38,7 +38,7 @@ actioncheck = # Values: CMD # # requires an ipfw rule like "deny ip from table(1) to me" -actionban = e=`ipfw table
add 2>&1`; x=$?; [ $x -eq 0 -o "$e" = 'ipfw: setsockopt(IP_FW_TABLE_XADD): File exists' ] || { echo "$e" 1>&2; exit $x; } +actionban = e=`ipfw table
add 2>&1`; x=$?; [ $x -eq 0 -o "$e" = 'ipfw: setsockopt(IP_FW_TABLE_XADD): File exists' ] || echo "$e" | grep -q "record already exists" || { echo "$e" 1>&2; exit $x; } # Option: actionunban @@ -47,7 +47,7 @@ actionban = e=`ipfw table
add 2>&1`; x=$?; [ $x -eq 0 -o "$e" = 'ip # Tags: See jail.conf(5) man page # Values: CMD # -actionunban = e=`ipfw table
delete 2>&1`; x=$?; [ $x -eq 0 -o "$e" = 'ipfw: setsockopt(IP_FW_TABLE_XDEL): No such process' ] || { echo "$e" 1>&2; exit $x; } +actionunban = e=`ipfw table
delete 2>&1`; x=$?; [ $x -eq 0 -o "$e" = 'ipfw: setsockopt(IP_FW_TABLE_XDEL): No such process' ] || echo "$e" | grep -q "record not found" || { echo "$e" 1>&2; exit $x; } [Init] # Option: table diff --git a/config/action.d/cloudflare.conf b/config/action.d/cloudflare.conf index 89df5b9e..1c48a37f 100644 --- a/config/action.d/cloudflare.conf +++ b/config/action.d/cloudflare.conf @@ -15,13 +15,13 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = diff --git a/config/action.d/complain.conf b/config/action.d/complain.conf index 1f74d635..3a5f882c 100644 --- a/config/action.d/complain.conf +++ b/config/action.d/complain.conf @@ -41,13 +41,13 @@ debug = 0 norestored = 1 # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = diff --git a/config/action.d/dshield.conf b/config/action.d/dshield.conf index 4f2e09ca..c128bef3 100644 --- a/config/action.d/dshield.conf +++ b/config/action.d/dshield.conf @@ -32,13 +32,13 @@ norestored = 1 # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = if [ -f .buffer ]; then diff --git a/config/action.d/dummy.conf b/config/action.d/dummy.conf index 41250c27..eb07e320 100644 --- a/config/action.d/dummy.conf +++ b/config/action.d/dummy.conf @@ -7,7 +7,7 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = if [ ! -z '' ]; then touch ; fi; @@ -22,7 +22,7 @@ actionflush = printf %%b "-*\n" echo "%(debug)s clear all" # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = if [ ! -z '' ]; then rm -f ; fi; diff --git a/config/action.d/helpers-common.conf b/config/action.d/helpers-common.conf index 5799d9d3..b036f68f 100644 --- a/config/action.d/helpers-common.conf +++ b/config/action.d/helpers-common.conf @@ -1,16 +1,16 @@ -[DEFAULT] - -# Usage: -# _grep_logs_args = 'test' -# (printf %%b "Log-excerpt contains 'test':\n"; %(_grep_logs)s; printf %%b "Log-excerpt contains 'test':\n") | mail ... -# -_grep_logs = logpath=""; grep -E %(_grep_logs_args)s $logpath | -_grep_logs_args = "(^|[^0-9a-fA-F:])$(echo '' | sed 's/\./\\./g')([^0-9a-fA-F:]|$)" - -# Used for actions, that should not by executed if ticket was restored: -_bypass_if_restored = if [ '' = '1' ]; then exit 0; fi; - -[Init] -greplimit = tail -n -grepmax = 1000 -grepopts = -m +[DEFAULT] + +# Usage: +# _grep_logs_args = 'test' +# (printf %%b "Log-excerpt contains 'test':\n"; %(_grep_logs)s; printf %%b "Log-excerpt contains 'test':\n") | mail ... +# +_grep_logs = logpath=""; grep -E %(_grep_logs_args)s $logpath | +_grep_logs_args = "(^|[^0-9a-fA-F:])$(echo '' | sed 's/\./\\./g')([^0-9a-fA-F:]|$)" + +# Used for actions, that should not by executed if ticket was restored: +_bypass_if_restored = if [ '' = '1' ]; then exit 0; fi; + +[Init] +greplimit = tail -n +grepmax = 1000 +grepopts = -m diff --git a/config/action.d/hostsdeny.conf b/config/action.d/hostsdeny.conf index 5cca6529..8eebbaff 100644 --- a/config/action.d/hostsdeny.conf +++ b/config/action.d/hostsdeny.conf @@ -8,13 +8,13 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = @@ -31,7 +31,7 @@ actioncheck = # Tags: See jail.conf(5) man page # Values: CMD # -actionban = IP= && printf %%b ": $IP\n" >> +actionban = printf %%b ": \n" >> # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the @@ -39,7 +39,7 @@ actionban = IP= && printf %%b ": $IP\n" >> # Tags: See jail.conf(5) man page # Values: CMD # -actionunban = IP=$(echo | sed 's/\./\\./g') && sed -i "/^: $IP$/d" +actionunban = IP=$(echo "" | sed 's/[][\.]/\\\0/g') && sed -i "/^: $IP$/d" [Init] @@ -54,3 +54,9 @@ file = /etc/hosts.deny # for hosts.deny/hosts_access. Default is all services. # Values: STR Default: ALL daemon_list = ALL + +# internal variable IP (to differentiate the IPv4 and IPv6 syntax, where it is enclosed in brackets): +ip_value = + +[Init?family=inet6] +ip_value = [] diff --git a/config/action.d/ipfilter.conf b/config/action.d/ipfilter.conf index 61420e38..02091d60 100644 --- a/config/action.d/ipfilter.conf +++ b/config/action.d/ipfilter.conf @@ -9,7 +9,7 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # # enable IPF if not already enabled @@ -17,7 +17,7 @@ actionstart = /sbin/ipf -E # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # # don't disable IPF with "/sbin/ipf -D", there may be other filters in use diff --git a/config/action.d/ipfw.conf b/config/action.d/ipfw.conf index 37625209..956b154b 100644 --- a/config/action.d/ipfw.conf +++ b/config/action.d/ipfw.conf @@ -8,14 +8,14 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = diff --git a/config/action.d/iptables-allports.conf b/config/action.d/iptables-allports.conf index dbea5984..caf9ab81 100644 --- a/config/action.d/iptables-allports.conf +++ b/config/action.d/iptables-allports.conf @@ -14,7 +14,7 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = -N f2b- @@ -22,7 +22,7 @@ actionstart = -N f2b- -I -p -j f2b- # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = -D -p -j f2b- diff --git a/config/action.d/iptables-ipset-proto4.conf b/config/action.d/iptables-ipset-proto4.conf index 30353f36..99ebbf8c 100644 --- a/config/action.d/iptables-ipset-proto4.conf +++ b/config/action.d/iptables-ipset-proto4.conf @@ -24,7 +24,7 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = ipset --create f2b- iphash @@ -38,7 +38,7 @@ actionstart = ipset --create f2b- iphash actionflush = ipset --flush f2b- # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = -D -p -m multiport --dports -m set --match-set f2b- src -j diff --git a/config/action.d/iptables-ipset-proto6-allports.conf b/config/action.d/iptables-ipset-proto6-allports.conf index b761ad8c..dc7d63a7 100644 --- a/config/action.d/iptables-ipset-proto6-allports.conf +++ b/config/action.d/iptables-ipset-proto6-allports.conf @@ -23,7 +23,7 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = ipset create hash:ip timeout @@ -36,7 +36,7 @@ actionstart = ipset create hash:ip timeout actionflush = ipset flush # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = -D -m set --match-set src -j diff --git a/config/action.d/iptables-ipset-proto6.conf b/config/action.d/iptables-ipset-proto6.conf index e337eedf..f88777b8 100644 --- a/config/action.d/iptables-ipset-proto6.conf +++ b/config/action.d/iptables-ipset-proto6.conf @@ -23,7 +23,7 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = ipset create hash:ip timeout @@ -36,7 +36,7 @@ actionstart = ipset create hash:ip timeout actionflush = ipset flush # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = -D -p -m multiport --dports -m set --match-set src -j diff --git a/config/action.d/iptables-multiport-log.conf b/config/action.d/iptables-multiport-log.conf index 62c2b4b1..df126dbf 100644 --- a/config/action.d/iptables-multiport-log.conf +++ b/config/action.d/iptables-multiport-log.conf @@ -16,7 +16,7 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = -N f2b- @@ -34,7 +34,7 @@ actionflush = -F f2b- -F f2b--log # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = -D -p -m multiport --dports -j f2b- diff --git a/config/action.d/iptables-multiport.conf b/config/action.d/iptables-multiport.conf index c05f6ffc..41b00c54 100644 --- a/config/action.d/iptables-multiport.conf +++ b/config/action.d/iptables-multiport.conf @@ -11,7 +11,7 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = -N f2b- @@ -19,7 +19,7 @@ actionstart = -N f2b- -I -p -m multiport --dports -j f2b- # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = -D -p -m multiport --dports -j f2b- diff --git a/config/action.d/iptables-new.conf b/config/action.d/iptables-new.conf index 5b316807..39a17099 100644 --- a/config/action.d/iptables-new.conf +++ b/config/action.d/iptables-new.conf @@ -13,7 +13,7 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = -N f2b- @@ -21,7 +21,7 @@ actionstart = -N f2b- -I -m state --state NEW -p --dport -j f2b- # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = -D -m state --state NEW -p --dport -j f2b- diff --git a/config/action.d/iptables-xt_recent-echo.conf b/config/action.d/iptables-xt_recent-echo.conf index 1970de14..97449222 100644 --- a/config/action.d/iptables-xt_recent-echo.conf +++ b/config/action.d/iptables-xt_recent-echo.conf @@ -12,7 +12,7 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # # Changing iptables rules requires root privileges. If fail2ban is @@ -42,7 +42,7 @@ actionstart = if [ `id -u` -eq 0 ];then -I -m recent --update actionflush = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = echo / > /proc/net/xt_recent/ diff --git a/config/action.d/iptables.conf b/config/action.d/iptables.conf index bf83e24a..8ed5fdad 100644 --- a/config/action.d/iptables.conf +++ b/config/action.d/iptables.conf @@ -11,7 +11,7 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = -N f2b- @@ -19,7 +19,7 @@ actionstart = -N f2b- -I -p --dport -j f2b- # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = -D -p --dport -j f2b- diff --git a/config/action.d/mail-buffered.conf b/config/action.d/mail-buffered.conf index 88cd623f..325f185b 100644 --- a/config/action.d/mail-buffered.conf +++ b/config/action.d/mail-buffered.conf @@ -10,7 +10,7 @@ norestored = 1 # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = printf %%b "Hi,\n @@ -20,7 +20,7 @@ actionstart = printf %%b "Hi,\n Fail2Ban"|mail -s "[Fail2Ban] : started on " # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = if [ -f ]; then diff --git a/config/action.d/mail-whois-lines.conf b/config/action.d/mail-whois-lines.conf index 37e2d9b0..3a3e56b2 100644 --- a/config/action.d/mail-whois-lines.conf +++ b/config/action.d/mail-whois-lines.conf @@ -15,7 +15,7 @@ before = mail-whois-common.conf norestored = 1 # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = printf %%b "Hi,\n @@ -24,7 +24,7 @@ actionstart = printf %%b "Hi,\n Fail2Ban" | "[Fail2Ban] : started on " # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = printf %%b "Hi,\n diff --git a/config/action.d/mail-whois.conf b/config/action.d/mail-whois.conf index 1f69f4c6..7fea34c4 100644 --- a/config/action.d/mail-whois.conf +++ b/config/action.d/mail-whois.conf @@ -14,7 +14,7 @@ before = mail-whois-common.conf norestored = 1 # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = printf %%b "Hi,\n @@ -23,7 +23,7 @@ actionstart = printf %%b "Hi,\n Fail2Ban"|mail -s "[Fail2Ban] : started on " # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = printf %%b "Hi,\n diff --git a/config/action.d/mail.conf b/config/action.d/mail.conf index cfc1cf65..5d8c0e15 100644 --- a/config/action.d/mail.conf +++ b/config/action.d/mail.conf @@ -10,7 +10,7 @@ norestored = 1 # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = printf %%b "Hi,\n @@ -19,7 +19,7 @@ actionstart = printf %%b "Hi,\n Fail2Ban"|mail -s "[Fail2Ban] : started on " # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = printf %%b "Hi,\n diff --git a/config/action.d/mynetwatchman.conf b/config/action.d/mynetwatchman.conf index 8f3edf9e..b0ab2cc3 100644 --- a/config/action.d/mynetwatchman.conf +++ b/config/action.d/mynetwatchman.conf @@ -28,13 +28,13 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = diff --git a/config/action.d/nftables-common.conf b/config/action.d/nftables-common.conf index 83311087..37045712 100644 --- a/config/action.d/nftables-common.conf +++ b/config/action.d/nftables-common.conf @@ -25,7 +25,7 @@ after = nftables-common.local nftables_mode = dport \{ \} # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = add set \{ type \; \} @@ -35,7 +35,7 @@ _nft_list = --handle --numeric list chain saddr @ # handle' | grep -oe ' handle [0-9]*' # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = HANDLE_ID=$(%(_nft_list)s | %(_nft_get_handle_id)s) diff --git a/config/action.d/npf.conf b/config/action.d/npf.conf index 8b00d177..3bbb2f51 100644 --- a/config/action.d/npf.conf +++ b/config/action.d/npf.conf @@ -9,7 +9,7 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # # we don't enable NPF automatically, as it will be enabled elsewhere @@ -17,7 +17,7 @@ actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # # we don't disable NPF automatically either diff --git a/config/action.d/nsupdate.conf b/config/action.d/nsupdate.conf index 7886825c..ef56c6bd 100644 --- a/config/action.d/nsupdate.conf +++ b/config/action.d/nsupdate.conf @@ -42,14 +42,14 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = diff --git a/config/action.d/osx-ipfw.conf b/config/action.d/osx-ipfw.conf index abe4009c..6ff6afdf 100644 --- a/config/action.d/osx-ipfw.conf +++ b/config/action.d/osx-ipfw.conf @@ -9,14 +9,14 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = diff --git a/config/action.d/pf.conf b/config/action.d/pf.conf index 905312c3..933b4de0 100644 --- a/config/action.d/pf.conf +++ b/config/action.d/pf.conf @@ -10,7 +10,7 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # # we don't enable PF automatically; to enable run pfctl -e @@ -35,7 +35,7 @@ actionstart = echo "table <-> persist counters" | -f- actionstart_on_demand = false # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # # we only disable PF rules we've installed prior diff --git a/config/action.d/sendmail-buffered.conf b/config/action.d/sendmail-buffered.conf index 37bc642d..199c6ce5 100644 --- a/config/action.d/sendmail-buffered.conf +++ b/config/action.d/sendmail-buffered.conf @@ -14,7 +14,7 @@ before = sendmail-common.conf norestored = 1 # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = printf %%b "Subject: [Fail2Ban] : started on @@ -27,7 +27,7 @@ actionstart = printf %%b "Subject: [Fail2Ban] : started on Fail2Ban" | /usr/sbin/sendmail -f # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = if [ -f ]; then diff --git a/config/action.d/sendmail-common.conf b/config/action.d/sendmail-common.conf index 46eca9ca..9bf15054 100644 --- a/config/action.d/sendmail-common.conf +++ b/config/action.d/sendmail-common.conf @@ -11,7 +11,7 @@ after = sendmail-common.local [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = printf %%b "Subject: [Fail2Ban] : started on @@ -24,7 +24,7 @@ actionstart = printf %%b "Subject: [Fail2Ban] : started on Fail2Ban" | /usr/sbin/sendmail -f # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = printf %%b "Subject: [Fail2Ban] : stopped on diff --git a/config/action.d/shorewall-ipset-proto6.conf b/config/action.d/shorewall-ipset-proto6.conf index 1ebcfb01..fc7dd24e 100644 --- a/config/action.d/shorewall-ipset-proto6.conf +++ b/config/action.d/shorewall-ipset-proto6.conf @@ -47,7 +47,7 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = if ! ipset -quiet -name list f2b- >/dev/null; @@ -55,7 +55,7 @@ actionstart = if ! ipset -quiet -name list f2b- >/dev/null; fi # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = ipset flush f2b- diff --git a/config/action.d/shorewall.conf b/config/action.d/shorewall.conf index 282b95af..83d08d99 100644 --- a/config/action.d/shorewall.conf +++ b/config/action.d/shorewall.conf @@ -9,7 +9,7 @@ # connections. So if the attempter goes on trying using the same connection # he could even log in. In order to get the same behavior of the iptable # action (so that the ban is immediate) the /etc/shorewall/shorewall.conf -# file should me modified with "BLACKLISTNEWONLY=No". Note that as of +# file should be modified with "BLACKLISTNEWONLY=No". Note that as of # Shorewall 4.5.13 BLACKLISTNEWONLY is deprecated; however the equivalent # of BLACKLISTNEWONLY=No can now be achieved by setting BLACKLIST="ALL". # @@ -17,13 +17,13 @@ [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = diff --git a/config/action.d/symbiosis-blacklist-allports.conf b/config/action.d/symbiosis-blacklist-allports.conf index c24a8e0a..6fb7d0af 100644 --- a/config/action.d/symbiosis-blacklist-allports.conf +++ b/config/action.d/symbiosis-blacklist-allports.conf @@ -10,13 +10,13 @@ before = iptables-common.conf [Definition] # Option: actionstart -# Notes.: command executed once at the start of Fail2Ban. +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # actionstart = # Option: actionstop -# Notes.: command executed once at the end of Fail2Ban +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) # Values: CMD # actionstop = diff --git a/config/filter.d/apache-auth.conf b/config/filter.d/apache-auth.conf index d9a6fa5e..91c89b26 100644 --- a/config/filter.d/apache-auth.conf +++ b/config/filter.d/apache-auth.conf @@ -15,15 +15,16 @@ prefregex = ^%(_apache_error_client)s (?:AH\d+: )?.+$ auth_type = ([A-Z]\w+: )? failregex = ^client (?:denied by server configuration|used wrong authentication scheme)\b - ^user (?:\S*|.*?) (?:auth(?:oriz|entic)ation failure|not found|denied by provider)\b + ^user (?!`)(?:\S*|.*?) (?:auth(?:oriz|entic)ation failure|not found|denied by provider)\b ^Authorization of user (?:\S*|.*?) to access .*? failed\b ^%(auth_type)suser (?:\S*|.*?): password mismatch\b - ^%(auth_type)suser `(?:[^']*|.*?)' in realm `.+' (not found|denied by provider)\b + ^%(auth_type)suser `(?:[^']*|.*?)' in realm `.+' (auth(?:oriz|entic)ation failure|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 + ^(?:No h|H)ostname \S+ provided via SNI(?:, but no hostname provided| and hostname \S+ provided| for a name based virtual host)\b ignoreregex = diff --git a/config/filter.d/apache-noscript.conf b/config/filter.d/apache-noscript.conf index fbc1af64..1963d1dd 100644 --- a/config/filter.d/apache-noscript.conf +++ b/config/filter.d/apache-noscript.conf @@ -17,8 +17,13 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s ((AH001(28|30): )?File does not exist|(AH01264: )?script not found or unable to stat): /\S*(php([45]|[.-]cgi)?|\.asp|\.exe|\.pl)(, referer: \S+)?\s*$ - ^%(_apache_error_client)s script '/\S*(php([45]|[.-]cgi)?|\.asp|\.exe|\.pl)\S*' not found or unable to stat(, referer: \S+)?\s*$ +script = /\S*(?:php(?:[45]|[.-]cgi)?|\.asp|\.exe|\.pl) + +prefregex = ^%(_apache_error_client)s (?:AH0(?:01(?:28|30)|1(?:264|071)): )?(?:(?:[Ff]ile|script|[Gg]ot) ).+$ + +failregex = ^(?:does not exist|not found or unable to stat):