diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..0cbdbf83 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +ChangeLog linguist-language=Markdown diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..543f316a --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: [sebres] +custom: [paypal.me/sebres] diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index cb4b4bc6..00000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,49 +0,0 @@ -_We will be very grateful, if your problem was described as completely as possible, -enclosing excerpts from logs (if possible within DEBUG mode, if no errors evident -within INFO mode), and configuration in particular of effected relevant settings -(e.g., with ` fail2ban-client -d | grep 'affected-jail-name' ` for a particular -jail troubleshooting). -Thank you in advance for the details, because such issues like "It does not work" -alone could not help to resolve anything! -Thanks! (remove this paragraph and other comments upon reading)_ - -### Environment: - -_Fill out and check (`[x]`) the boxes which apply. If your Fail2Ban version is outdated, -and you can't verify that the issue persists in the recent release, better seek support -from the distribution you obtained Fail2Ban from_ - -- Fail2Ban version (including any possible distribution suffixes): -- OS, including release name/version: -- [ ] Fail2Ban installed via OS/distribution mechanisms -- [ ] You have not applied any additional foreign patches to the codebase -- [ ] Some customizations were done to the configuration (provide details below is so) - -### The issue: - -_Summary here_ - -#### Steps to reproduce - -#### Expected behavior - -#### Observed behavior - -#### Any additional information - -### Configuration, dump and another helpful excerpts - -#### Any customizations done to /etc/fail2ban/ configuration -``` -``` - -#### Relevant parts of /var/log/fail2ban.log file: -_preferably obtained while running fail2ban with `loglevel = 4`_ - -``` -``` - -#### Relevant lines from monitored log files in question: - -``` -``` \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..33d94e10 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,70 @@ +--- +name: Bug report +about: Report a bug within the fail2ban engines (not filters or jails) +title: '[BR]: ' +labels: bug +assignees: '' + +--- + + + +### Environment: + + + +- Fail2Ban version : +- OS, including release name/version : +- [ ] Fail2Ban installed via OS/distribution mechanisms +- [ ] You have not applied any additional foreign patches to the codebase +- [ ] Some customizations were done to the configuration (provide details below is so) + +### The issue: + + + +#### Steps to reproduce + +#### Expected behavior + +#### Observed behavior + +#### Any additional information + + +### Configuration, dump and another helpful excerpts + +#### Any customizations done to /etc/fail2ban/ configuration + +``` +``` + +#### Relevant parts of /var/log/fail2ban.log file: + + +``` +``` + +#### Relevant lines from monitored log files: + +``` +``` diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..41812e82 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,35 @@ +--- +name: Feature request +about: Suggest an idea or an enhancement for this project +title: '[RFE]: ' +labels: enhancement +assignees: '' + +--- + + + +#### Feature request type + + +#### Description + + +#### Considered alternatives + + +#### Any additional information + diff --git a/.github/ISSUE_TEMPLATE/filter_request.md b/.github/ISSUE_TEMPLATE/filter_request.md new file mode 100644 index 00000000..caf02f90 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/filter_request.md @@ -0,0 +1,59 @@ +--- +name: Filter request +about: Request a new jail or filter to be supported or existing filter extended with new failregex +title: '[FR]: ' +labels: filter-request +assignees: '' + +--- + + + +### Environment: + + + +- Fail2Ban version : +- OS, including release name/version : + +#### Service, project or product which log or journal should be monitored + +- Name of filter or jail in Fail2Ban (if already exists) : +- Service, project or product name, including release name/version : +- Repository or URL (if known) : +- Service type : +- Ports and protocols the service is listening : + +#### Log or journal information + + + + +- Log file name(s) : + + + +- Journal identifier or unit name : + +#### Any additional information + + +### Relevant lines from monitored log files: + +#### failures in sense of fail2ban filter (fail2ban must match): + +``` +``` + +#### legitimate messages (fail2ban should not consider as failures): + +``` +``` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3a17ccc2..350d6ee2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,7 +1,8 @@ Before submitting your PR, please review the following checklist: - [ ] **CHOOSE CORRECT BRANCH**: if filing a bugfix/enhancement - against 0.9.x series, choose `master` branch + against certain release version, choose `0.9`, `0.10` or `0.11` branch, + for dev-edition use `master` branch - [ ] **CONSIDER adding a unit test** if your PR resolves an issue - [ ] **LIST ISSUES** this PR resolves - [ ] **MAKE SURE** this PR doesn't break existing tests diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..e681e417 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,100 @@ +name: CI + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + paths-ignore: + - 'doc/**' + - 'files/**' + - 'man/**' + pull_request: + paths-ignore: + - 'doc/**' + - 'files/**' + - 'man/**' + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-20.04 + strategy: + matrix: + python-version: [2.7, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11.0-beta.3', pypy2, pypy3] + fail-fast: false + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Grant systemd-journal access + run: sudo usermod -a -G systemd-journal "$USER" || echo 'no systemd-journal access' + + - name: Python version + run: | + F2B_PY=$(python -c "import sys; print(sys.version)") + echo "Python: ${{ matrix.python-version }} -- ${F2B_PY/$'\n'/ }" + F2B_PYV=$(echo "${F2B_PY}" | grep -oP '^\d+(?:\.\d+)') + F2B_PY=${F2B_PY:0:1} + echo "Set F2B_PY=$F2B_PY, F2B_PYV=$F2B_PYV" + echo "F2B_PY=$F2B_PY" >> $GITHUB_ENV + echo "F2B_PYV=$F2B_PYV" >> $GITHUB_ENV + # for GHA we need to monitor all journals, since it cannot be found using SYSTEM_ONLY(4): + echo "F2B_SYSTEMD_DEFAULT_FLAGS=0" >> $GITHUB_ENV + + - name: Install dependencies + run: | + if [[ "$F2B_PY" = 3 ]]; then python -m pip install --upgrade pip || echo "can't upgrade pip"; fi + if [[ "$F2B_PY" = 3 ]] && ! command -v 2to3x -v 2to3 > /dev/null; then + #pip install 2to3 + sudo apt-get -y install 2to3 + fi + #sudo apt-get -y install python${F2B_PY/2/}-pyinotify || echo 'inotify not available' + python -m pip install pyinotify || echo 'inotify not available' + #sudo apt-get -y install python${F2B_PY/2/}-systemd || echo 'systemd not available' + sudo apt-get -y install libsystemd-dev || echo 'systemd dependencies seems to be unavailable' + python -m pip install systemd-python || echo 'systemd not available' + #readline if available as module: + python -c 'import readline' 2> /dev/null || python -m pip install readline || echo 'readline not available' + + - name: Before scripts + run: | + cd "$GITHUB_WORKSPACE" + # Manually execute 2to3 for now + if [[ "$F2B_PY" = 3 ]]; then echo "2to3 ..." && ./fail2ban-2to3; fi + _debug() { echo -n "$1 "; err=$("${@:2}" 2>&1) && echo 'OK' || echo -e "FAIL\n$err"; } + # (debug) output current preferred encoding: + _debug 'Encodings:' python -c 'import locale, sys; from fail2ban.helpers import PREFER_ENC; print(PREFER_ENC, locale.getpreferredencoding(), (sys.stdout and sys.stdout.encoding))' + # (debug) backend availabilities: + echo 'Backends:' + _debug '- systemd:' python -c 'from fail2ban.server.filtersystemd import FilterSystemd' + #_debug '- systemd (root): ' sudo python -c 'from fail2ban.server.filtersystemd import FilterSystemd' + _debug '- pyinotify:' python -c 'from fail2ban.server.filterpyinotify import FilterPyinotify' + + - name: Test suite + run: | + if [[ "$F2B_PY" = 2 ]]; then + python setup.py test + elif dpkg --compare-versions "$F2B_PYV" lt 3.10; then + python bin/fail2ban-testcases --verbosity=2 + else + echo "Skip systemd backend since systemd-python module must be fixed for python >= v.3.10 in GHA ..." + python bin/fail2ban-testcases --verbosity=2 -i "[sS]ystemd|[jJ]ournal" + fi + + #- name: Test suite (debug some systemd tests only) + #run: python bin/fail2ban-testcases --verbosity=2 "[sS]ystemd|[jJ]ournal" + #run: python bin/fail2ban-testcases --verbosity=2 -l 5 "test_WrongChar" + + - name: Build + run: python setup.py build + + #- name: Test initd scripts + # run: shellcheck -s bash -e SC1090,SC1091 files/debian-initd diff --git a/.gitignore b/.gitignore index 780ecfb5..5f1b8924 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ htmlcov __pycache__ .vagrant/ .idea/ +.venv/ diff --git a/.travis.yml b/.travis.yml index 16a71249..502af5be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,24 @@ # vim ft=yaml # travis-ci.org definition for Fail2Ban build # https://travis-ci.org/fail2ban/fail2ban/ + +#os: linux + language: python -python: - - 2.6 - - 2.7 - - pypy - # disabled until coverage module fixes up compatibility issue - # - 3.2 - - 3.3 - - 3.4 - - 3.5 - - 3.6 - - 3.7-dev - # disabled since setuptools dropped support for Python 3.0 - 3.2 - # - pypy3 - - pypy3.3-5.5-alpha +dist: xenial + +matrix: + fast_finish: true + include: + - python: 2.7 + #- python: pypy + - python: 3.4 + - python: 3.5 + - python: 3.6 + - python: 3.7 + - python: 3.8 + - python: 3.9-dev + - python: pypy3.5 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; fi @@ -29,18 +32,29 @@ 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 + - F2B_COV=1 + - 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 || echo 'not installed'; fi + - if [[ "$F2B_PY" = 3 ]]; then travis_retry pip install dnspython3 || echo 'not installed'; fi + # python systemd bindings: + - if [[ "$F2B_PY" = 2 ]]; then travis_retry sudo apt-get install -qq python-systemd || echo 'not installed'; fi + - if [[ "$F2B_PY" = 3 ]]; then travis_retry sudo apt-get install -qq python3-systemd || echo 'not installed'; 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 + - 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/) || echo 'not installed'; fi # pyinotify - - travis_retry pip install pyinotify + - travis_retry pip install pyinotify || echo 'not installed' + # Install helper tools + - sudo apt-get install shellcheck before_script: # Manually execute 2to3 for now - if [[ "$F2B_PY" = 3 ]]; then ./fail2ban-2to3; fi + # (debug) output current preferred encoding: + - python -c 'import locale, sys; from fail2ban.helpers import PREFER_ENC; print(PREFER_ENC, locale.getpreferredencoding(), (sys.stdout and sys.stdout.encoding))' script: # Keep the legacy setup.py test approach of checking coverage for python2 - if [[ "$F2B_PY" = 2 ]]; then coverage run setup.py test; fi @@ -48,13 +62,14 @@ script: - 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 + # Doc files should get installed on Travis under Linux (some builds/python's seem to use another path segment) + - test -e /usr/share/doc/fail2ban/FILTERS && echo 'found' || echo 'not found' + # Test initd script + - shellcheck -s bash -e SC1090,SC1091 files/debian-initd after_success: - - coveralls + - if [[ "$F2B_COV" = 1 ]]; then coveralls; fi - codecov -matrix: - fast_finish: true + # Might be worth looking into #notifications: # email: true diff --git a/ChangeLog b/ChangeLog index 8714847e..0cc088eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + __ _ _ ___ _ / _|__ _(_) |_ ) |__ __ _ _ _ | _/ _` | | |/ /| '_ \/ _` | ' \ @@ -6,32 +7,296 @@ Fail2Ban: Changelog =================== -Incompatibility list (compared to v.0.9): +ver. 1.0.3-dev-1 (20??/??/??) - development nightly edition ----------- -* Filter (or `failregex`) internal capture-groups: +### Fixes +* circumvent SEGFAULT in a python's socket module by getaddrinfo with disabled IPv6 (gh-3438) +* `action.d/cloudflare-token.conf` - fixes gh-3479, url-encode args by unban - - If you've your own `failregex` or custom filters using conditional match `(?P=host)`, you should - rewrite the regex like in example below resp. using `(?:(?P=ip4)|(?P=ip6)` instead of `(?P=host)` - (or `(?:(?P=ip4)|(?P=ip6)|(?P=dns))` corresponding your `usedns` and `raw` settings). - - Of course you can always define your own capture-group (like below `_cond_ip_`) to do this. - ``` - testln="1500000000 failure from 192.0.2.1: bad host 192.0.2.1" - fail2ban-regex "$testln" "^\s*failure from (?P<_cond_ip_>): bad host (?P=_cond_ip_)$" - ``` - - New internal groups (currently reserved for internal usage): - `ip4`, `ip6`, `dns`, `fid`, `fport`, additionally `user` and another captures in lower case if - mapping from tag `` used in failregex (e. g. `user` by ``). - -* 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 IPv6 addresses, but not all ban actions are - IPv6-capable now. +### New Features and Enhancements +* better auto-detection for IPv6 support (`allowipv6 = auto` by default), trying to check sysctl net.ipv6.conf.all.disable_ipv6 + (value read from `/proc/sys/net/ipv6/conf/all/disable_ipv6`) if available, otherwise seeks over local IPv6 from network interfaces + if available for platform and uses DNS to find local IPv6 as a fallback only +* improve `ignoreself` by considering all local addresses from network interfaces additionally to IPs from hostnames (gh-3132) -ver. 0.11.0-dev-0 (20??/??/??) - development nightly edition +ver. 1.0.2 (2022/11/09) - finally-war-game-test-tape-not-a-nuclear-alarm +----------- + +### Fixes +* backend `systemd`: code review and several fixes: + - wait only if it is necessary, e. g. in operational mode and if no more entries retrieved (end of journal); + - ensure we give enough time after possible rotation, vacuuming or adding/removing journal files, + and move cursor back and forth to avoid entering dead space +* `filter.d/named-refused.conf`: + - support BIND named log categories, gh-3388 + - allow `info:` as possible error prefix too ("query (cache) denied" may occur as info) +* `filter.d/dovecot.conf`: + - fixes regression introduced in gh-3210: resolve extremely long search by repeated apply of non-greedy RE-part + with following branches (it may be extremely slow up to infinite search depending on message), gh-3370 + - fixes regression and matches new format in aggressive mode too (amend to gh-3210) + +### New Features and Enhancements + + +ver. 1.0.1 (2022/09/27) - energy-equals-mass-times-the-speed-of-light-squared +----------- + +### Compatibility +* the minimum supported python version is now 2.7, if you have previous python version + you can use the 0.11 version of fail2ban or upgrade python (or even build it from source). +* potential incompatibility by parsing of options of `backend`, `filter` and `action` parameters (if they + are partially incorrect), because fail2ban could throw an error now (doesn't silently bypass it anymore). +* due to fix for CVE-2021-32749 (GHSA-m985-3f3v-cwmm) the mailing action using mailutils may require extra configuration, + if it is not compatible or doesn't support `-E 'set escape'` (e. g. with `mailcmd` parameter), see gh-3059 +* automatic invocation of 2to3 is removed in setup now (gh-3098), there is also no option `--disable-2to3` anymore, + `./fail2ban-2to3` should be called outside before setup +* to v.0.11: + - due to change of `actioncheck` behavior (gh-488), some actions can be incompatible as regards + the invariant check, if `actionban` or `actionunban` would not throw an error (exit code + different from 0) in case of unsane environment. + - actions that have used tag `` (instead of `` or ``) to get failure-ID may become + incompatible, if filter uses IP-related tags (like `` or ``) additionally to `` + and the values are different (gh-3217) + +### Fixes +* theoretical RCE vulnerability in mailing action using mailutils (mail-whois), CVE-2021-32749, GHSA-m985-3f3v-cwmm +* readline fixed to consider interim new-line character as part of code point in multi-byte logs + (e. g. unicode encoding like utf-16be, utf-16le); +* [stability] solves race condition with uncontrolled growth of failure list (jail with too many matches, + that did not cause ban), behavior changed to ban ASAP, gh-2945 +* fixes search for the best datepattern - e. g. if line is too short, boundaries check for previously known + unprecise pattern may fail on incomplete lines (logging break-off, no flush, etc), gh-3020 +* [stability, performance] backend `systemd`: + - fixes error "local variable 'line' referenced before assignment", introduced in 55d7d9e2, gh-3097 + - don't update database too often (every 10 ticks or ~ 10 seconds in production) + - fixes wrong time point of "in operation" mode, gh-2882 + - better avoidance of landing in dead space by seeks over journals (improved seek to time) + - fixes missing space in message (tag ``) between timestamp and host if the message read from systemd journal, gh-3293 +* [stability] backend `pyinotify`: fixes sporadic runtime error "dictionary changed size during iteration" +* several backends optimizations (in file and journal filters): + - don't need to wait if we still had log-entries from last iteration (which got interrupted for servicing) + - rewritten update log/journal position, it is more stable and faster now (fewer DB access and surely up-to-date at end) +* `paths-debian.conf`: + - add debian path to roundcube error logs +* `action.d/firewallcmd-*.conf` (multiport only): fixed port range selector, replacing `:` with `-`;" + reverted the incompatibility gh-3047 introduced in a038fd5, gh-2821, because this depends now on firewalld backend + (e. g. `-` vs. `:` related to `iptables` vs. `nftables`) +* `action.d/nginx-block-map.conf`: reload nginx only if it is running (also avoid error in nginx-errorlog, gh-2949) +* `action.d/ufw.conf`: + - fixed handling on IPv6 (using prepend, gh-2331, gh-3018) + - application names containing spaces can be used now (gh-656, gh-1532, gh-3018) +* `filter.d/apache-fakegooglebot.conf`: + - better, more precise regex and datepattern (closes possible weakness like gh-3013) + - `filter.d/ignorecommands/apache-fakegooglebot` - added timeout parameter (default 55 seconds), avoid fail with timeout + (default 1 minute) by reverse lookup on some slow DNS services (googlebots must be resolved fast), gh-2951 +* `filter.d/apache-overflows.conf` - extended to match AH00126 error (Invalid URI ...), gh-2908 +* `filter.d/asterisk.conf` - add transport to asterisk RE: call rejection messages can have the transport prefixed to the IP address, gh-2913 +* `filter.d/courier-auth.conf`: + - consider optional port after IP, gh-3211 + - regex is rewritten without catch-all's and right anchor, so it is more stable against further modifications now +* `filter.d/dovecot.conf`: + - adjusted for updated dovecot log format with `read(size=...)` in message (gh-3210) + - parse everything in parenthesis by auth-worker info, e. g. can match (pid=...,uid=...) too (amend to gh-2553) + - extended to match prefix like `conn unix:auth-worker (uid=143): auth-worker<13247>:` + (authenticate from external service like exim), gh-2553 + - fixed "Authentication failure" regex, matches "Password mismatch" in title case (gh-2880) +* `filter.d/drupal-auth.conf` - more strict regex, extended to match "Login attempt failed from" (gh-2742) +* `filter.d/exim-common.conf` - pid-prefix extended to match `mx1 exim[...]:` (gh-2553) +* `filter.d/lighttpd-auth.conf` - adjusted to the current source code + avoiding catch-all's, etc (gh-3116) +* `filter.d/named-refused.conf`: + - added support for alternate names (suffix), FreeIPA renames the BIND9 named daemon to named-pkcs11, gh-2636 + - fixes prefix for messages from systemd journal (no mandatory space ahead, because don't have timestamp), gh-2899 +* `filter.d/nginx-*.conf` - added journalmatch to nginx filters, gh-2935 +* `filter.d/nsd.conf` - support for current log format, gh-2965 +* `filter.d/postfix.conf`: fixes and new vectors, review and combining several regex to single RE: + - mode `ddos` (and `aggressive`) extended: + * to consider abusive handling of clients hitting command limit, gh-3040 + * to handle postscreen's PREGREET and HANGUP messages, gh-2898 + - matches rejects with "undeliverable address" (sender/recipient verification) additionally to "Unknown user", gh-3039 + both are configurable now via extended parameter and can be disabled using `exre-user=` supplied in filter parameters + - reject: BDAT/DATA from, gh-2927 + - (since regex is more precise now) token selector changed to `[A-Z]{4}`, e. g. no matter what a command is supplied now + (RCPT, EHLO, VRFY, DATA, BDAT or something else) + - matches "Command rejected" and "Data command rejected" now + - matches RCPT from unknown, 504 5.5.2, need fully-qualified hostname, gh-2995 + - matches 550 5.7.25 Client host rejected, gh-2996 +* `filter.d/sendmail-auth.conf`: + - detect several "authentication failure" messages, sendmail 8.16.1, gh-2757 + - detect user not found, gh-3030 + - detect failures without user part, gh-3324 +* `filter.d/sendmail-reject.conf`: + - fix reverse DNS for ... (gh-3012) + - fixed regex to consider "Connection rate limit exceeded" with different combination of arguments +* `filter.d/sshd.conf`: + - mode `ddos` extended - recognizes messages "kex_exchange_identification: Connection closed / reset by pear", gh-3086 + (fixed possible regression of f77398c) + - mode `ddos` extended - recognizes new message "banner exchange: invalid format" generated by port scanner + (https payload on ssh port), gh-3169 +* `filter.d/zoneminder.conf` - support new log format (ERR instead of WAR), add detection of non-existent user login attempts, gh-2984 +* amend to gh-980 fixing several actions (correctly supporting new enhancements now) +* fixed typo by `--dump-pretty` option which did never work (only `--dp` was working) +* fixes start of fail2ban-client in docker: speedup daemonization process by huge open files limit, gh-3334 +* provides details of failed regex compilation in the error message we throw in Regex-constructor + (it's good to know what exactly is wrong) +* fixed failed update of database didn't signal with an error, gh-3352: + - client and server exit with error code by failure during start process (in foreground mode) + - added fallback to repair if database cannot be upgraded + +### New Features and Enhancements +* python 3.10 and 3.11 compatibility (and GHA-CI support) +* `actioncheck` behavior is changed now (gh-488), so invariant check as well as restore or repair + of sane environment (in case of recognized unsane state) would only occur on action errors (e. g. + if ban or unban operations are exiting with other code as 0) +* better recognition of log rotation, better performance by reopen: avoid unnecessary seek to begin of file + (and hash calculation) +* file filter reads only complete lines (ended with new-line) now, so waits for end of line (for its completion) +* datedetector: + - token `%Z` must recognize zone abbreviation `Z` (GMT/UTC) also (similar to `%z`) + - token `%Z` recognizes all known zone abbreviation besides Z, GMT, UTC correctly, if it is matching + (`%z` remains unchanged for backwards-compatibility, see comment in code) + - date patterns `%ExY` and `%Exy` accept every year from 19xx up to current century (+3 years) in `fail2ban-regex` + - better grouping algorithm for resulting century RE for `%ExY` and `%Exy` +* actions differentiate tags `` and `` (``), if IP-address deviates from ID then the value + of `` is not equal `` anymore (gh-3217) +* action info extended with new members for jail info (usable as tags in command actions), gh-10: + - ``, `` - current and total found failures + - ``, `` - current and total bans +* `filter.d/monitorix.conf` - added new filter and jail for Monitorix, gh-2679 +* `filter.d/mssql-auth.conf` - new filter and jail for Microsoft SQL Server, gh-2642 +* `filter.d/nginx-bad-request.conf` - added filter to find bad requests (400), gh-2750 +* `filter.d/nginx-http-auth.conf` - extended with parameter mode, so additionally to `auth` (or `normal`) + mode `fallback` (or combined as `aggressive`) can find SSL errors while SSL handshaking, gh-2881 +* `filter.d/scanlogd.conf` - new filter and jail, add support for filtering out detected port scans via scanlogd, gh-2950 +* `action.d/apprise.conf` - added Apprise support (50+ Notifications), gh-2565 +* `action.d/badips.*` - removed actions, badips.com is no longer active, gh-2889 +* `action.d/cloudflare.conf` - better IPv6 capability, gh-2891 +* `action.d/cloudflare-token.conf` - added support for Cloudflare Token APIs. This method is more restrictive and therefore safter than using API Keys. +* `action.d/ipthreat.conf` - new action for IPThreat integration, gh-3349 +* `action.d/ufw.conf` (gh-3018): + - new option `add` (default `prepend`), can be supplied as `insert 1` for ufw versions before v.0.36 (gh-2331, gh-3018) + - new options `kill-mode` and `kill` to drop established connections of intruder (see action for details, gh-3018) +* `iptables` and `iptables-ipset` actions extended to support multiple protocols with single action + for multiport or oneport type (back-ported from nftables action); +* `iptables` actions are more breakdown-safe: start wouldn't fail if chain or rule already exists + (e. g. created by previous instance and doesn't get purged properly); ultimately closes gh-980 +* `ipset` actions are more breakdown-safe: start wouldn't fail if set with this name already exists + (e. g. created by previous instance and don't deleted properly) +* replace internals of several `iptables` and `iptables-ipset` actions using internals of iptables include: + - better check mechanism (using `-C`, option `--check` is available long time); + - additionally iptables-ipset is a common action for `iptables-ipset-proto6-*` now (which become obsolete now); + - many features of different iptables actions are combinable as single chain/rule (can be supplied to action as parameters); + - iptables is a replacement for iptables-common now, several actions using this as include now become obsolete; +* new logtarget SYSTEMD-JOURNAL, gh-1403 +* fail2ban.conf: new fail2ban configuration option `allowipv6` (default `auto`), can be used to allow or disallow IPv6 + interface in fail2ban immediately by start (e. g. if fail2ban starts before network interfaces), gh-2804 +* invalidate IP/DNS caches by reload, so inter alia would allow to recognize IPv6IsAllowed immediately, previously + retarded up to cache max-time (5m), gh-2804 +* OpenRC (Gentoo, mainly) service script improvements, gh-2182 +* suppress unneeded info "Jail is not a JournalFilter instance" (moved to debug level), gh-3186 +* implements new interpolation variable `%(fail2ban_confpath)s` (automatically substituted from config-reader path, + default `/etc/fail2ban` or `/usr/local/etc/fail2ban` depending on distribution); `ignorecommands_dir` is unneeded anymore, + thus removed from `paths-common.conf`, fixes gh-3005 +* `fail2ban-regex`: accepts filter parameters containing new-line + + +ver. 0.11.2 (2020/11/23) - heal-the-world-with-security-tools +----------- + +### Compatibility +* to v.0.10: + - 0.11 is totally compatible to 0.10 (configuration- and API-related stuff), but the database + got some new tables and fields (auto-converted during the first start), so once updated to 0.11, you + have to remove the database /var/lib/fail2ban/fail2ban.sqlite3 (or its different to 0.10 schema) + if you would need to downgrade to 0.10 for some reason. +* to v.0.9: + - Filter (or `failregex`) internal capture-groups: + + * If you've your own `failregex` or custom filters using conditional match `(?P=host)`, you should + rewrite the regex like in example below resp. using `(?:(?P=ip4)|(?P=ip6)` instead of `(?P=host)` + (or `(?:(?P=ip4)|(?P=ip6)|(?P=dns))` corresponding your `usedns` and `raw` settings). + + Of course you can always define your own capture-group (like below `_cond_ip_`) to do this. + ``` + testln="1500000000 failure from 192.0.2.1: bad host 192.0.2.1" + fail2ban-regex "$testln" "^\s*failure from (?P<_cond_ip_>): bad host (?P=_cond_ip_)$" + ``` + * New internal groups (currently reserved for internal usage): + `ip4`, `ip6`, `dns`, `fid`, `fport`, additionally `user` and another captures in lower case if + mapping from tag `` used in failregex (e. g. `user` by ``). + + - v.0.10 and 0.11 use more precise date template handling, that can be theoretically incompatible to some + user configurations resp. `datepattern`. + + - Since v0.10 fail2ban supports the matching of IPv6 addresses, but not all ban actions are + IPv6-capable now. + +### Fixes +* [stability] prevent race condition - no ban if filter (backend) is continuously busy if + too many messages will be found in log, e. g. initial scan of large log-file or journal (gh-2660) +* pyinotify-backend sporadically avoided initial scanning of log-file by start +* python 3.9 compatibility (and Travis CI support) +* restoring a large number (500+ depending on files ulimit) of current bans when using PyPy fixed +* manual ban is written to database, so can be restored by restart (gh-2647) +* `jail.conf`: don't specify `action` directly in jails (use `action_` or `banaction` instead) +* no mails-action added per default anymore (e. g. to allow that `action = %(action_mw)s` should be specified + per jail or in default section in jail.local), closes gh-2357 +* ensure we've unique action name per jail (also if parameter `actname` is not set but name deviates from standard name, gh-2686) +* don't use `%(banaction)s` interpolation because it can be complex value (containing `[...]` and/or quotes), + so would bother the action interpolation +* fixed type conversion in config readers (take place after all interpolations get ready), that allows to + specify typed parameters variable (as substitutions) as well as to supply it in other sections or as init parameters. +* `action.d/*-ipset*.conf`: several ipset actions fixed (no timeout per default anymore), so no discrepancy + between ipset and fail2ban (removal from ipset will be managed by fail2ban only, gh-2703) +* `action.d/cloudflare.conf`: fixed `actionunban` (considering new-line chars and optionally real json-parsing + with `jq`, gh-2140, gh-2656) +* `action.d/nftables.conf` (type=multiport only): fixed port range selector, replacing `:` with `-` (gh-2763) +* `action.d/firewallcmd-*.conf` (multiport only): fixed port range selector, replacing `:` with `-` (gh-2821) +* `action.d/bsd-ipfw.conf`: fixed selection of rule-no by large list or initial `lowest_rule_num` (gh-2836) +* `filter.d/common.conf`: avoid substitute of default values in related `lt_*` section, `__prefix_line` + should be interpolated in definition section (inside the filter-config, gh-2650) +* `filter.d/dovecot.conf`: + - add managesieve and submission support (gh-2795); + - accept messages with more verbose logging (gh-2573); +* `filter.d/courier-smtp.conf`: prefregex extended to consider port in log-message (gh-2697) +* `filter.d/traefik-auth.conf`: filter extended with parameter mode (`normal`, `ddos`, `aggressive`) to handle + the match of username differently (gh-2693): + - `normal`: matches 401 with supplied username only + - `ddos`: matches 401 without supplied username only + - `aggressive`: matches 401 and any variant (with and without username) +* `filter.d/sshd.conf`: normalizing of user pattern in all RE's, allowing empty user (gh-2749) + +### New Features and Enhancements +* fail2ban-regex: + - speedup formatted output (bypass unneeded stats creation) + - extended with prefregex statistic + - more informative output for `datepattern` (e. g. set from filter) - pattern : description +* parsing of action in jail-configs considers space between action-names as separator also + (previously only new-line was allowed), for example `action = a b` would specify 2 actions `a` and `b` +* new filter and jail for GitLab recognizing failed application logins (gh-2689) +* new filter and jail for Grafana recognizing failed application logins (gh-2855) +* new filter and jail for SoftEtherVPN recognizing failed application logins (gh-2723) +* `filter.d/guacamole.conf` extended with `logging` parameter to follow webapp-logging if it's configured (gh-2631) +* `filter.d/bitwarden.conf` enhanced to support syslog (gh-2778) +* introduced new prefix `{UNB}` for `datepattern` to disable word boundaries in regex; +* datetemplate: improved anchor detection for capturing groups `(^...)`; +* datepattern: improved handling with wrong recognized timestamps (timezones, no datepattern, etc) + as well as some warnings signaling user about invalid pattern or zone (gh-2814): + - filter gets mode in-operation, which gets activated if filter starts processing of new messages; + in this mode a timestamp read from log-line that appeared recently (not an old line), deviating too much + from now (up too 24h), will be considered as now (assuming a timezone issue), so could avoid unexpected + bypass of failure (previously exceeding `findtime`); + - better interaction with non-matching optional datepattern or invalid timestamps; + - implements special datepattern `{NONE}` - allow to find failures totally without date-time in log messages, + whereas filter will use now as timestamp (gh-2802) +* performance optimization of `datepattern` (better search algorithm in datedetector, especially for single template); +* fail2ban-client: extended to unban IP range(s) by subnet (CIDR/mask) or hostname (DNS), gh-2791; +* extended capturing of alternate tags in filter, allowing combine of multiple groups to single tuple token with new tag + prefix `` with all value of `` tags (gh-2755) + + +ver. 0.11.1 (2020/01/11) - this-is-the-way ----------- ### Fixes @@ -55,9 +320,141 @@ ver. 0.11.0-dev-0 (20??/??/??) - development nightly edition * algorithm of restore current bans after restart changed: update the restored ban-time (and therefore end of ban) of the ticket with ban-time of jail (as maximum), for all tickets with ban-time greater (or persistent); not affected if ban-time of the jail is unchanged between stop/start. +* added new setup-option `--without-tests` to skip building and installing of tests files (gh-2287). +* added new command `fail2ban-client get banip ?sep-char|--with-time?` to get the banned ip addresses (gh-1916). -ver. 0.10.4-dev-1 (20??/??/??) - development edition +ver. 0.10.5 (2020/01/10) - deserve-more-respect-a-jedis-weapon-must +----------- + +Yes, Hrrrm... + +### Fixes +* [compatibility] systemd backend: default flags changed to SYSTEM_ONLY(4), fixed in gh-2444 in order to ignore + user session files per default, so could prevent "Too many open files" errors on a lot of user sessions (see gh-2392) +* [grave] fixed parsing of multi-line filters (`maxlines` > 1) together with systemd backend, + now systemd-filter replaces newlines in message from systemd journal with `\n` (otherwise + multi-line parsing may be broken, because removal of matched string from multi-line buffer window + is confused by such extra new-lines, so they are retained and got matched on every followed + message, see gh-2431) +* [stability] prevent race condition - no unban if the bans occur continuously (gh-2410); + now an unban-check will happen not later than 10 tickets get banned regardless there are + still active bans available (precedence of ban over unban-check is 10 now) +* fixed read of included config-files (`.local` overwrites options of `.conf` for config-files + included with before/after) +* `action.d/abuseipdb.conf`: switched to use AbuseIPDB API v2 (gh-2302) +* `action.d/badips.py`: fixed start of banaction on demand (which may be IP-family related), gh-2390 +* `action.d/helpers-common.conf`: rewritten grep arguments, now options `-wF` used to match only + whole words and fixed string (not as pattern), gh-2298 +* `filter.d/apache-auth.conf`: + - ignore errors from mod_evasive in `normal` mode (mode-controlled now) (gh-2548); + - extended with option `mode` - `normal` (default) and `aggressive` +* `filter.d/sshd.conf`: + - matches `Bad protocol version identification` in `ddos` and `aggressive` modes (gh-2404). + - captures `Disconnecting ...: Change of username or service not allowed` (gh-2239, gh-2279) + - captures `Disconnected from ... [preauth]`, preauth phase only, different handling by `extra` + (with supplied user only) and `ddos`/`aggressive` mode (gh-2115, 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) +* `filter.d/sendmail-reject.conf`: + - `mode=extra` now captures port IDs of `TLSMTA` and `MSA` (defaults for ports 465 and 587 on some distros) +* `files/fail2ban.service.in`: fixed systemd-unit template - missing nftables dependency (gh-2313) +* several `action.d/mail*`: fixed usage with multiple log files (ultimate fix for gh-976, gh-2341) +* `filter.d/sendmail-reject.conf`: fixed journal usage for some systems (e. g. CentOS): if only identifier + set to `sm-mta` (no unit `sendmail`) for some messages (gh-2385) +* `filter.d/asterisk.conf`: asterisk can log additional timestamp if logs into systemd-journal + (regex extended with optional part matching this, gh-2383) +* `filter.d/postfix.conf`: + - regexp's accept variable suffix code in status of postfix for precise messages (gh-2442) + - extended with new postfix filter mode `errors` to match "too many errors" (gh-2439), + also included within modes `normal`, `more` (`extra` and `aggressive`), since postfix + parameter `smtpd_hard_error_limit` is default 20 (additionally consider `maxretry`) +* `filter.d/named-refused.conf`: + - support BIND 9.11.0 log format (includes an additional field @0xXXX..., gh-2406); + - `prefregex` extended, more selective now (denied/NOTAUTH suffix moved from failregex, so no catch-all there anymore) +* `filter.d/sendmail-auth.conf`, `filter.d/sendmail-reject.conf` : + - ID in prefix can be longer as 14 characters (gh-2563); +* all filters would accept square brackets around IPv4 addresses also (e. g. monit-filter, gh-2494) +* avoids unhandled exception during flush (gh-2588) +* fixes pass2allow-ftp jail - due to inverted handling, action should prohibit access per default for any IP, + therefore reset start on demand parameter for this action (it will be started immediately by repair); +* auto-detection of IPv6 subsystem availability (important for not on-demand actions or jails, like pass2allow); + +### New Features +* new replacement tags for failregex to match subnets in form of IP-addresses with CIDR mask (gh-2559): + - `` - helper regex to match CIDR (simple integer form of net-mask); + - `` - regex to match sub-net addresses (in form of IP/CIDR, also single IP is matched, so part /CIDR is optional); +* grouped tags (``, ``, ``) recognize IP addresses enclosed in square brackets +* 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) +* filters: introduced new configuration parameter `logtype` (default `file` for file-backends, and + `journal` for journal-backends, gh-2387); can be also set to `rfc5424` to force filters (which include common.conf) + to use RFC 5424 conform prefix-line per default (gh-2467); +* for better performance and safety the option `logtype` can be also used to + select short prefix-line for file-backends too for all filters using `__prefix_line` (`common.conf`), + if message logged only with `hostname svc[nnnn]` prefix (often the case on several systems): +```ini +[jail] +backend = auto +filter = flt[logtype=short] +``` +* `filter.d/common.conf`: differentiate `__prefix_line` for file/journal logtype's (speedup and fix parsing + of systemd-journal); +* `filter.d/traefik-auth.conf`: used to ban hosts, that were failed through traefik +* `filter.d/znc-adminlog.conf`: new filter for ZNC (IRC bouncer); requires the adminlog module to be loaded + +### Enhancements +* introduced new options: `dbmaxmatches` (fail2ban.conf) and `maxmatches` (jail.conf) to contol + how many matches per ticket fail2ban can hold in memory and store in database (gh-2402, gh-2118); +* fail2ban.conf: introduced new section `[Thread]` and option `stacksize` to configure default size + of the stack for threads running in fail2ban (gh-2356), it could be set in `fail2ban.local` to + avoid runtime error "can't start new thread" (see gh-969); +* jail-reader extended (amend to gh-1622): actions support multi-line options now (interpolations + containing new-line); +* fail2ban-client: extended to ban/unban multiple tickets (see gh-2351, gh-2349); + Syntax: + - `fail2ban-client set banip ... ` + - `fail2ban-client set unbanip [--report-absent] ... ` +* fail2ban-client: extended with new feature which allows to inform fail2ban about single or multiple + attempts (failure) for IP (resp. failure-ID), see gh-2351; + Syntax: + - `fail2ban-client set attempt [ ... ]` +* `action.d/nftables.conf`: + - isolate fail2ban rules into a dedicated table and chain (gh-2254) + - `nftables-allports` supports multiple protocols in single rule now + - combined nftables actions to single action `nftables`: + * `nftables-common` is removed (replaced with single action `nftables` now) + * `nftables-allports` is obsolete, superseded by `nftables[type=allports]` + * `nftables-multiport` is obsolete, superseded by `nftables[type=multiport]` + - allowed multiple protocols in `nftables[type=multiport]` action (single set with multiple rules + in chain), following configuration in jail would replace 3 separate actions, see + https://github.com/fail2ban/fail2ban/pull/2254#issuecomment-534684675 +* `action.d/badips.py`: option `loglevel` extended with level of summary message, + following example configuration logging summary with NOTICE and rest with DEBUG log-levels: + `action = badips.py[loglevel="debug, notice"]` +* samplestestcase.py (testSampleRegexsFactory) extended: + - allow coverage of journal logtype; + - new option `fileOptions` to set common filter/test options for whole test-file; +* large enhancement: auto-reban, improved invariant check and conditional operations (gh-2588): + - improves invariant check and repair (avoid unhandled exception, consider family on conditional operations, etc), + prepared for bulk re-ban in repair case (if bulk-ban becomes implemented); + - automatic reban (repeat banning action) after repair/restore sane environment, if already logged ticket causes + new failures (via new action operation `actionreban` or `actionban` if still not defined in action); + * introduces banning epoch for actions and tickets (to distinguish or recognize removed set of the tickets); + * invariant check avoids repair by unban/stop (unless parameter `actionrepair_on_unban` set to `true`); + * better handling for all conditional operations (distinguish families for certain operations like + repair/flush/stop, prepared for other families, e. g. if different handling for subnets expected, etc); + * partially implements gh-980 (more breakdown safe handling); + * closes gh-1680 (better as large-scale banning implementation with on-demand reban by failure, + at least unless a bulk-ban gets implemented); +* fail2ban-regex - several enhancements and fixes: + - improved usage output (don't put a long help if an error occurs); + - new option `--no-check-all` to avoid check of all regex's (first matched only); + - new option `-o`, `--out` to set token only provided in output (disables check-all and outputs only expected data). + + +ver. 0.10.4 (2018/10/04) - ten-four-on-due-date-ten-four ----------- ### Fixes @@ -72,6 +469,9 @@ ver. 0.10.4-dev-1 (20??/??/??) - development edition - 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): 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/FILTERS b/FILTERS index e114973a..2ed6281d 100644 --- a/FILTERS +++ b/FILTERS @@ -278,6 +278,7 @@ to tune it. fail2ban-regex -D ... will present Debuggex URLs for the regexs and sample log files that you pass into it. In general use when using regex debuggers for generating fail2ban filters: + * use regex from the ./fail2ban-regex output (to ensure all substitutions are done) * replace with (?&.ipv4) diff --git a/MANIFEST b/MANIFEST index 3ea2816b..fec09dde 100644 --- a/MANIFEST +++ b/MANIFEST @@ -5,11 +5,11 @@ bin/fail2ban-testcases ChangeLog config/action.d/abuseipdb.conf config/action.d/apf.conf -config/action.d/badips.conf -config/action.d/badips.py +config/action.d/apprise.conf config/action.d/blocklist_de.conf config/action.d/bsd-ipfw.conf config/action.d/cloudflare.conf +config/action.d/cloudflare-token.conf config/action.d/complain.conf config/action.d/dshield.conf config/action.d/dummy.conf @@ -25,8 +25,8 @@ config/action.d/hostsdeny.conf config/action.d/ipfilter.conf config/action.d/ipfw.conf config/action.d/iptables-allports.conf -config/action.d/iptables-common.conf config/action.d/iptables.conf +config/action.d/iptables-ipset.conf config/action.d/iptables-ipset-proto4.conf config/action.d/iptables-ipset-proto6-allports.conf config/action.d/iptables-ipset-proto6.conf @@ -34,6 +34,7 @@ config/action.d/iptables-multiport.conf config/action.d/iptables-multiport-log.conf config/action.d/iptables-new.conf config/action.d/iptables-xt_recent-echo.conf +config/action.d/ipthreat.conf config/action.d/mail-buffered.conf config/action.d/mail.conf config/action.d/mail-whois-common.conf @@ -42,7 +43,7 @@ config/action.d/mail-whois-lines.conf config/action.d/mynetwatchman.conf config/action.d/netscaler.conf config/action.d/nftables-allports.conf -config/action.d/nftables-common.conf +config/action.d/nftables.conf config/action.d/nftables-multiport.conf config/action.d/nginx-block-map.conf config/action.d/npf.conf @@ -81,7 +82,9 @@ config/filter.d/apache-pass.conf config/filter.d/apache-shellshock.conf config/filter.d/assp.conf config/filter.d/asterisk.conf +config/filter.d/bitwarden.conf config/filter.d/botsearch-common.conf +config/filter.d/centreon.conf config/filter.d/common.conf config/filter.d/counter-strike.conf config/filter.d/courier-auth.conf @@ -98,6 +101,8 @@ config/filter.d/exim.conf config/filter.d/exim-spam.conf config/filter.d/freeswitch.conf config/filter.d/froxlor-auth.conf +config/filter.d/gitlab.conf +config/filter.d/grafana.conf config/filter.d/groupoffice.conf config/filter.d/gssftpd.conf config/filter.d/guacamole.conf @@ -108,10 +113,13 @@ config/filter.d/kerio.conf config/filter.d/lighttpd-auth.conf config/filter.d/mongodb-auth.conf config/filter.d/monit.conf +config/filter.d/monitorix.conf +config/filter.d/mssql-auth.conf config/filter.d/murmur.conf config/filter.d/mysqld-auth.conf config/filter.d/nagios.conf config/filter.d/named-refused.conf +config/filter.d/nginx-bad-request.conf config/filter.d/nginx-botsearch.conf config/filter.d/nginx-http-auth.conf config/filter.d/nginx-limit-req.conf @@ -130,6 +138,7 @@ config/filter.d/pure-ftpd.conf config/filter.d/qmail.conf config/filter.d/recidive.conf config/filter.d/roundcube-auth.conf +config/filter.d/scanlogd.conf config/filter.d/screensharingd.conf config/filter.d/selinux-common.conf config/filter.d/selinux-ssh.conf @@ -137,6 +146,7 @@ config/filter.d/sendmail-auth.conf config/filter.d/sendmail-reject.conf config/filter.d/sieve.conf config/filter.d/slapd.conf +config/filter.d/softethervpn.conf config/filter.d/sogo-auth.conf config/filter.d/solid-pop3d.conf config/filter.d/squid.conf @@ -145,11 +155,13 @@ config/filter.d/sshd.conf config/filter.d/stunnel.conf config/filter.d/suhosin.conf config/filter.d/tine20.conf +config/filter.d/traefik-auth.conf config/filter.d/uwimap-auth.conf config/filter.d/vsftpd.conf config/filter.d/webmin-auth.conf config/filter.d/wuftpd.conf config/filter.d/xinetd-fail.conf +config/filter.d/znc-adminlog.conf config/filter.d/zoneminder.conf config/jail.conf config/paths-arch.conf @@ -213,15 +225,17 @@ fail2ban/setup.py fail2ban-testcases-all fail2ban-testcases-all-python3 fail2ban/tests/action_d/__init__.py -fail2ban/tests/action_d/test_badips.py fail2ban/tests/action_d/test_smtp.py fail2ban/tests/actionstestcase.py fail2ban/tests/actiontestcase.py fail2ban/tests/banmanagertestcase.py fail2ban/tests/clientbeautifiertestcase.py fail2ban/tests/clientreadertestcase.py +fail2ban/tests/config/action.d/action.conf fail2ban/tests/config/action.d/brokenaction.conf fail2ban/tests/config/fail2ban.conf +fail2ban/tests/config/filter.d/checklogtype.conf +fail2ban/tests/config/filter.d/checklogtype_test.conf fail2ban/tests/config/filter.d/simple.conf fail2ban/tests/config/filter.d/test.conf fail2ban/tests/config/filter.d/test.local @@ -260,6 +274,8 @@ fail2ban/tests/files/database_v1.db fail2ban/tests/files/database_v2.db fail2ban/tests/files/filter.d/substition.conf fail2ban/tests/files/filter.d/testcase01.conf +fail2ban/tests/files/filter.d/testcase02.conf +fail2ban/tests/files/filter.d/testcase02.local fail2ban/tests/files/filter.d/testcase-common.conf fail2ban/tests/files/ignorecommand.py fail2ban/tests/files/logs/3proxy @@ -275,9 +291,11 @@ fail2ban/tests/files/logs/apache-pass fail2ban/tests/files/logs/apache-shellshock fail2ban/tests/files/logs/assp fail2ban/tests/files/logs/asterisk +fail2ban/tests/files/logs/bitwarden fail2ban/tests/files/logs/bsd/syslog-plain.txt fail2ban/tests/files/logs/bsd/syslog-v.txt fail2ban/tests/files/logs/bsd/syslog-vv.txt +fail2ban/tests/files/logs/centreon fail2ban/tests/files/logs/counter-strike fail2ban/tests/files/logs/courier-auth fail2ban/tests/files/logs/courier-smtp @@ -292,6 +310,8 @@ fail2ban/tests/files/logs/exim fail2ban/tests/files/logs/exim-spam fail2ban/tests/files/logs/freeswitch fail2ban/tests/files/logs/froxlor-auth +fail2ban/tests/files/logs/gitlab +fail2ban/tests/files/logs/grafana fail2ban/tests/files/logs/groupoffice fail2ban/tests/files/logs/gssftpd fail2ban/tests/files/logs/guacamole @@ -301,10 +321,13 @@ fail2ban/tests/files/logs/kerio fail2ban/tests/files/logs/lighttpd-auth fail2ban/tests/files/logs/mongodb-auth fail2ban/tests/files/logs/monit +fail2ban/tests/files/logs/monitorix +fail2ban/tests/files/logs/mssql-auth fail2ban/tests/files/logs/murmur fail2ban/tests/files/logs/mysqld-auth fail2ban/tests/files/logs/nagios fail2ban/tests/files/logs/named-refused +fail2ban/tests/files/logs/nginx-bad-request fail2ban/tests/files/logs/nginx-botsearch fail2ban/tests/files/logs/nginx-http-auth fail2ban/tests/files/logs/nginx-limit-req @@ -323,25 +346,30 @@ fail2ban/tests/files/logs/pure-ftpd fail2ban/tests/files/logs/qmail fail2ban/tests/files/logs/recidive fail2ban/tests/files/logs/roundcube-auth +fail2ban/tests/files/logs/scanlogd fail2ban/tests/files/logs/screensharingd fail2ban/tests/files/logs/selinux-ssh fail2ban/tests/files/logs/sendmail-auth fail2ban/tests/files/logs/sendmail-reject fail2ban/tests/files/logs/sieve fail2ban/tests/files/logs/slapd +fail2ban/tests/files/logs/softethervpn fail2ban/tests/files/logs/sogo-auth fail2ban/tests/files/logs/solid-pop3d fail2ban/tests/files/logs/squid fail2ban/tests/files/logs/squirrelmail fail2ban/tests/files/logs/sshd +fail2ban/tests/files/logs/sshd-journal fail2ban/tests/files/logs/stunnel fail2ban/tests/files/logs/suhosin fail2ban/tests/files/logs/tine20 +fail2ban/tests/files/logs/traefik-auth fail2ban/tests/files/logs/uwimap-auth fail2ban/tests/files/logs/vsftpd fail2ban/tests/files/logs/webmin-auth fail2ban/tests/files/logs/wuftpd fail2ban/tests/files/logs/xinetd-fail +fail2ban/tests/files/logs/znc-adminlog fail2ban/tests/files/logs/zoneminder fail2ban/tests/files/logs/zzz-generic-example fail2ban/tests/files/logs/zzz-sshd-obsolete-multiline @@ -371,12 +399,12 @@ files/cacti/fail2ban_stats.sh files/cacti/README files/debian-initd files/fail2ban-logrotate +files/fail2ban-openrc.conf +files/fail2ban-openrc.init.in files/fail2ban.service.in files/fail2ban-tmpfiles.conf files/fail2ban.upstart files/gen_badbots -files/gentoo-confd -files/gentoo-initd files/ipmasq-ZZZzzz_fail2ban.rul files/logwatch/fail2ban files/logwatch/fail2ban-0.8.log diff --git a/README.md b/README.md index aa3203c1..4d417586 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ / _|__ _(_) |_ ) |__ __ _ _ _ | _/ _` | | |/ /| '_ \/ _` | ' \ |_| \__,_|_|_/___|_.__/\__,_|_||_| - v0.11.0.dev1 20??/??/?? + v1.0.3.dev1 20??/??/?? ## Fail2Ban: ban hosts that cause multiple authentication errors @@ -22,7 +22,8 @@ mechanisms if you really want to protect services. ------|------ 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) +to be found on fail2ban(1) manpage, [Wiki](https://github.com/fail2ban/fail2ban/wiki), +[Developers documentation](https://fail2ban.readthedocs.io/) and the website: https://www.fail2ban.org Installation: @@ -32,7 +33,8 @@ Installation: this case, you should use that instead.** Required: -- [Python2 >= 2.6 or Python >= 3.2](https://www.python.org) or [PyPy](https://pypy.org) +- [Python2 >= 2.7 or Python >= 3.2](https://www.python.org) or [PyPy](https://pypy.org) +- python-setuptools, python-distutils or python3-setuptools for installation from source Optional: - [pyinotify >= 0.8.3](https://github.com/seb-m/pyinotify), may require: @@ -45,11 +47,11 @@ Optional: To install: - tar xvfj fail2ban-0.11.0.tar.bz2 - cd fail2ban-0.11.0 + tar xvfj fail2ban-master.tar.bz2 + cd fail2ban-master sudo python setup.py install -Alternatively, you can clone the source from GitHub to a directory of Your choice, and do the install from there. Pick the correct branch, for example, 0.11 +Alternatively, you can clone the source from GitHub to a directory of Your choice, and do the install from there. Pick the correct branch, for example, master or 0.11 git clone https://github.com/fail2ban/fail2ban.git cd fail2ban @@ -88,11 +90,11 @@ fail2ban(1) and jail.conf(5) manpages for further references. Code status: ------------ -* travis-ci.org: [![tests status](https://secure.travis-ci.org/fail2ban/fail2ban.svg?branch=0.11)](https://travis-ci.org/fail2ban/fail2ban?branch=0.11) (0.11 branch) / [![tests status](https://secure.travis-ci.org/fail2ban/fail2ban.svg?branch=0.10)](https://travis-ci.org/fail2ban/fail2ban?branch=0.10) (0.10 branch) +* travis-ci.org: [![tests status](https://secure.travis-ci.org/fail2ban/fail2ban.svg?branch=master)](https://travis-ci.org/fail2ban/fail2ban?branch=master) / [![tests status](https://secure.travis-ci.org/fail2ban/fail2ban.svg?branch=0.11)](https://travis-ci.org/fail2ban/fail2ban?branch=0.11) (0.11 branch) / [![tests status](https://secure.travis-ci.org/fail2ban/fail2ban.svg?branch=0.10)](https://travis-ci.org/fail2ban/fail2ban?branch=0.10) (0.10 branch) -* coveralls.io: [![Coverage Status](https://coveralls.io/repos/fail2ban/fail2ban/badge.svg?branch=0.11)](https://coveralls.io/github/fail2ban/fail2ban?branch=0.11) (0.11 branch) / [![Coverage Status](https://coveralls.io/repos/fail2ban/fail2ban/badge.svg?branch=0.10)](https://coveralls.io/github/fail2ban/fail2ban?branch=0.10) / (0.10 branch) +* coveralls.io: [![Coverage Status](https://coveralls.io/repos/fail2ban/fail2ban/badge.svg?branch=master)](https://coveralls.io/github/fail2ban/fail2ban?branch=master) / [![Coverage Status](https://coveralls.io/repos/fail2ban/fail2ban/badge.svg?branch=0.11)](https://coveralls.io/github/fail2ban/fail2ban?branch=0.11) (0.11 branch) / [![Coverage Status](https://coveralls.io/repos/fail2ban/fail2ban/badge.svg?branch=0.10)](https://coveralls.io/github/fail2ban/fail2ban?branch=0.10) / (0.10 branch) -* codecov.io: [![codecov.io](https://codecov.io/gh/fail2ban/fail2ban/coverage.svg?branch=0.11)](https://codecov.io/gh/fail2ban/fail2ban/branch/0.11) (0.11 branch) / [![codecov.io](https://codecov.io/gh/fail2ban/fail2ban/coverage.svg?branch=0.10)](https://codecov.io/gh/fail2ban/fail2ban/branch/0.10) (0.10 branch) +* codecov.io: [![codecov.io](https://codecov.io/gh/fail2ban/fail2ban/coverage.svg?branch=master)](https://codecov.io/gh/fail2ban/fail2ban/branch/master) / [![codecov.io](https://codecov.io/gh/fail2ban/fail2ban/coverage.svg?branch=0.11)](https://codecov.io/gh/fail2ban/fail2ban/branch/0.11) (0.11 branch) / [![codecov.io](https://codecov.io/gh/fail2ban/fail2ban/coverage.svg?branch=0.10)](https://codecov.io/gh/fail2ban/fail2ban/branch/0.10) (0.10 branch) Contact: -------- diff --git a/THANKS b/THANKS index c363c76c..9dd2e47c 100644 --- a/THANKS +++ b/THANKS @@ -33,6 +33,7 @@ Christoph Haas Christos Psonis craneworks Cyril Jaquier +Daniel Aleksandersen Daniel B. Cid Daniel B. Daniel Black diff --git a/config/action.d/abuseipdb.conf b/config/action.d/abuseipdb.conf index c53ed489..ed958c86 100644 --- a/config/action.d/abuseipdb.conf +++ b/config/action.d/abuseipdb.conf @@ -21,14 +21,13 @@ # # Example, for ssh bruteforce (in section [sshd] of `jail.local`): # action = %(known/action)s -# %(action_abuseipdb)s[abuseipdb_apikey="my-api-key", abuseipdb_category="18,22"] +# abuseipdb[abuseipdb_apikey="my-api-key", abuseipdb_category="18,22"] # -# See below for catagories. +# See below for categories. # -# Original Ref: https://wiki.shaunc.com/wikka.php?wakka=ReportingToAbuseIPDBWithFail2Ban # Added to fail2ban by Andrew James Collett (ajcollett) -## abuseIPDB Catagories, `the abuseipdb_category` MUST be set in the jail.conf action call. +## abuseIPDB Categories, `the abuseipdb_category` MUST be set in the jail.conf action call. # Example, for ssh bruteforce: action = %(action_abuseipdb)s[abuseipdb_category="18,22"] # ID Title Description # 3 Fraud Orders @@ -47,6 +46,9 @@ [Definition] +# bypass action for restored tickets +norestored = 1 + # Option: actionstart # Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD @@ -80,13 +82,10 @@ actioncheck = # wherever you install the helper script. For the PHP helper script, see # # -# --ciphers ecdhe_ecdsa_aes_256_sha is used to workaround a -# "NSS error -12286" from curl as it attempts to connect using -# SSLv3. See https://www.centos.org/forums/viewtopic.php?t=52732 # Tags: See jail.conf(5) man page # Values: CMD # -actionban = lgm=$(printf '%%s\n...' ""); curl --fail --tlsv1.1 --data "key=" --data-urlencode "comment=$lgm" --data "ip=" --data "category=" "https://www.abuseipdb.com/report/json" +actionban = lgm=$(printf '%%.1000s\n...' ""); curl -sSf "https://api.abuseipdb.com/api/v2/report" -H "Accept: application/json" -H "Key: " --data-urlencode "comment=$lgm" --data-urlencode "ip=" --data "categories=" # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the @@ -101,5 +100,5 @@ actionunban = # Notes Your API key from abuseipdb.com # Values: STRING Default: None # Register for abuseipdb [https://www.abuseipdb.com], get api key and set below. -# You will need to set the catagory in the action call. +# You will need to set the category in the action call. abuseipdb_apikey = diff --git a/config/action.d/apprise.conf b/config/action.d/apprise.conf new file mode 100644 index 00000000..37c42ea2 --- /dev/null +++ b/config/action.d/apprise.conf @@ -0,0 +1,49 @@ +# Fail2Ban configuration file +# +# Author: Chris Caron +# +# + +[Definition] + +# Option: actionstart +# Notes.: command executed once at the start of Fail2Ban. +# Values: CMD +# +actionstart = printf %%b "The jail as been started successfully." | -t "[Fail2Ban] : started on `uname -n`" + +# Option: actionstop +# Notes.: command executed once at the end of Fail2Ban +# Values: CMD +# +actionstop = printf %%b "The jail has been stopped." | -t "[Fail2Ban] : stopped on `uname -n`" + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionban = printf %%b "The IP has just been banned by Fail2Ban after attempts against " | -n "warning" -t "[Fail2Ban] : banned from `uname -n`" + +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionunban = + +[Init] + +# Define location of the default apprise configuration file to use +# +config = /etc/fail2ban/apprise.conf +# +apprise = apprise -c "" diff --git a/config/action.d/badips.conf b/config/action.d/badips.conf deleted file mode 100644 index 6f9513f6..00000000 --- a/config/action.d/badips.conf +++ /dev/null @@ -1,19 +0,0 @@ -# Fail2ban reporting to badips.com -# -# Note: This reports an IP only and does not actually ban traffic. Use -# another action in the same jail if you want bans to occur. -# -# Set the category to the appropriate value before use. -# -# To get see register and optional key to get personalised graphs see: -# http://www.badips.com/blog/personalized-statistics-track-the-attackers-of-all-your-servers-with-one-key - -[Definition] - -actionban = curl --fail --user-agent "" http://www.badips.com/add// - -[Init] - -# Option: category -# Notes.: Values are from the list here: http://www.badips.com/get/categories -category = diff --git a/config/action.d/badips.py b/config/action.d/badips.py deleted file mode 100644 index 4e50890c..00000000 --- a/config/action.d/badips.py +++ /dev/null @@ -1,389 +0,0 @@ -# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*- -# vi: set ft=python sts=4 ts=4 sw=4 noet : - -# This file is part of Fail2Ban. -# -# Fail2Ban is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Fail2Ban is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Fail2Ban; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -import sys -if sys.version_info < (2, 7): # pragma: no cover - raise ImportError("badips.py action requires Python >= 2.7") -import json -import threading -import logging -if sys.version_info >= (3, ): # pragma: 2.x no cover - from urllib.request import Request, urlopen - from urllib.parse import urlencode - from urllib.error import HTTPError -else: # pragma: 3.x no cover - from urllib2 import Request, urlopen, HTTPError - from urllib import urlencode - -from fail2ban.server.actions import ActionBase - - -class BadIPsAction(ActionBase): # pragma: no cover - may be unavailable - """Fail2Ban action which reports bans to badips.com, and also - blacklist bad IPs listed on badips.com by using another action's - ban method. - - Parameters - ---------- - jail : Jail - The jail which the action belongs to. - name : str - Name assigned to the action. - category : str - Valid badips.com category for reporting failures. - score : int, optional - Minimum score for bad IPs. Default 3. - age : str, optional - Age of last report for bad IPs, per badips.com syntax. - Default "24h" (24 hours) - key : str, optional - Key issued by badips.com to report bans, for later retrieval - of personalised content. - banaction : str, optional - Name of banaction to use for blacklisting bad IPs. If `None`, - no blacklist of IPs will take place. - Default `None`. - bancategory : str, optional - Name of category to use for blacklisting, which can differ - from category used for reporting. e.g. may want to report - "postfix", but want to use whole "mail" category for blacklist. - Default `category`. - bankey : str, optional - Key issued by badips.com to blacklist IPs reported with the - associated key. - updateperiod : int, optional - Time in seconds between updating bad IPs blacklist. - Default 900 (15 minutes) - agent : str, optional - User agent transmitted to server. - Default `Fail2Ban/ver.` - - Raises - ------ - ValueError - If invalid `category`, `score`, `banaction` or `updateperiod`. - """ - - TIMEOUT = 10 - _badips = "https://www.badips.com" - def _Request(self, url, **argv): - return Request(url, headers={'User-Agent': self.agent}, **argv) - - def __init__(self, jail, name, category, score=3, age="24h", key=None, - banaction=None, bancategory=None, bankey=None, updateperiod=900, agent="Fail2Ban", - timeout=TIMEOUT): - super(BadIPsAction, self).__init__(jail, name) - - self.timeout = timeout - self.agent = agent - self.category = category - self.score = score - self.age = age - self.key = key - self.banaction = banaction - self.bancategory = bancategory or category - self.bankey = bankey - self.updateperiod = updateperiod - - self._bannedips = set() - # Used later for threading.Timer for updating badips - self._timer = None - - @staticmethod - def isAvailable(timeout=1): - try: - response = urlopen(Request("/".join([BadIPsAction._badips]), - headers={'User-Agent': "Fail2Ban"}), timeout=timeout) - return True, '' - except Exception as e: # pragma: no cover - return False, e - - def logError(self, response, what=''): # pragma: no cover - sporadical (502: Bad Gateway, etc) - messages = {} - try: - messages = json.loads(response.read().decode('utf-8')) - except: - pass - self._logSys.error( - "%s. badips.com response: '%s'", what, - messages.get('err', 'Unknown')) - - def getCategories(self, incParents=False): - """Get badips.com categories. - - Returns - ------- - set - Set of categories. - - Raises - ------ - HTTPError - Any issues with badips.com request. - ValueError - If badips.com response didn't contain necessary information - """ - try: - response = urlopen( - self._Request("/".join([self._badips, "get", "categories"])), timeout=self.timeout) - except HTTPError as response: # pragma: no cover - self.logError(response, "Failed to fetch categories") - raise - else: - response_json = json.loads(response.read().decode('utf-8')) - if not 'categories' in response_json: - err = "badips.com response lacked categories specification. Response was: %s" \ - % (response_json,) - self._logSys.error(err) - raise ValueError(err) - categories = response_json['categories'] - categories_names = set( - value['Name'] for value in categories) - if incParents: - categories_names.update(set( - value['Parent'] for value in categories - if "Parent" in value)) - return categories_names - - def getList(self, category, score, age, key=None): - """Get badips.com list of bad IPs. - - Parameters - ---------- - category : str - Valid badips.com category. - score : int - Minimum score for bad IPs. - age : str - Age of last report for bad IPs, per badips.com syntax. - key : str, optional - Key issued by badips.com to fetch IPs reported with the - associated key. - - Returns - ------- - set - Set of bad IPs. - - Raises - ------ - HTTPError - Any issues with badips.com request. - """ - try: - url = "?".join([ - "/".join([self._badips, "get", "list", category, str(score)]), - urlencode({'age': age})]) - if key: - url = "&".join([url, urlencode({'key': key})]) - self._logSys.debug('badips.com: get list, url: %r', url) - response = urlopen(self._Request(url), timeout=self.timeout) - except HTTPError as response: # pragma: no cover - self.logError(response, "Failed to fetch bad IP list") - raise - else: - return set(response.read().decode('utf-8').split()) - - @property - def category(self): - """badips.com category for reporting IPs. - """ - return self._category - - @category.setter - def category(self, category): - if category not in self.getCategories(): - self._logSys.error("Category name '%s' not valid. " - "see badips.com for list of valid categories", - category) - raise ValueError("Invalid category: %s" % category) - self._category = category - - @property - def bancategory(self): - """badips.com bancategory for fetching IPs. - """ - return self._bancategory - - @bancategory.setter - def bancategory(self, bancategory): - if bancategory != "any" and bancategory not in self.getCategories(incParents=True): - self._logSys.error("Category name '%s' not valid. " - "see badips.com for list of valid categories", - bancategory) - raise ValueError("Invalid bancategory: %s" % bancategory) - self._bancategory = bancategory - - @property - def score(self): - """badips.com minimum score for fetching IPs. - """ - return self._score - - @score.setter - def score(self, score): - score = int(score) - if 0 <= score <= 5: - self._score = score - else: - raise ValueError("Score must be 0-5") - - @property - def banaction(self): - """Jail action to use for banning/unbanning. - """ - return self._banaction - - @banaction.setter - def banaction(self, banaction): - if banaction is not None and banaction not in self._jail.actions: - self._logSys.error("Action name '%s' not in jail '%s'", - banaction, self._jail.name) - raise ValueError("Invalid banaction") - self._banaction = banaction - - @property - def updateperiod(self): - """Period in seconds between banned bad IPs will be updated. - """ - return self._updateperiod - - @updateperiod.setter - def updateperiod(self, updateperiod): - updateperiod = int(updateperiod) - if updateperiod > 0: - self._updateperiod = updateperiod - else: - raise ValueError("Update period must be integer greater than 0") - - def _banIPs(self, ips): - for ip in ips: - try: - self._jail.actions[self.banaction].ban({ - 'ip': ip, - 'failures': 0, - 'matches': "", - 'ipmatches': "", - 'ipjailmatches': "", - }) - except Exception as e: - self._logSys.error( - "Error banning IP %s for jail '%s' with action '%s': %s", - ip, self._jail.name, self.banaction, e, - exc_info=self._logSys.getEffectiveLevel()<=logging.DEBUG) - else: - self._bannedips.add(ip) - self._logSys.debug( - "Banned IP %s for jail '%s' with action '%s'", - ip, self._jail.name, self.banaction) - - def _unbanIPs(self, ips): - for ip in ips: - try: - self._jail.actions[self.banaction].unban({ - 'ip': ip, - 'failures': 0, - 'matches': "", - 'ipmatches': "", - 'ipjailmatches': "", - }) - except Exception as e: - self._logSys.info( - "Error unbanning IP %s for jail '%s' with action '%s': %s", - ip, self._jail.name, self.banaction, e, - exc_info=self._logSys.getEffectiveLevel()<=logging.DEBUG) - else: - self._logSys.debug( - "Unbanned IP %s for jail '%s' with action '%s'", - ip, self._jail.name, self.banaction) - finally: - self._bannedips.remove(ip) - - def start(self): - """If `banaction` set, blacklists bad IPs. - """ - if self.banaction is not None: - self.update() - - def update(self): - """If `banaction` set, updates blacklisted IPs. - - Queries badips.com for list of bad IPs, removing IPs from the - blacklist if no longer present, and adds new bad IPs to the - blacklist. - """ - if self.banaction is not None: - if self._timer: - self._timer.cancel() - self._timer = None - - try: - ips = self.getList( - self.bancategory, self.score, self.age, self.bankey) - # Remove old IPs no longer listed - self._unbanIPs(self._bannedips - ips) - # Add new IPs which are now listed - self._banIPs(ips - self._bannedips) - - self._logSys.debug( - "Updated IPs for jail '%s'. Update again in %i seconds", - self._jail.name, self.updateperiod) - finally: - self._timer = threading.Timer(self.updateperiod, self.update) - self._timer.start() - - def stop(self): - """If `banaction` set, clears blacklisted IPs. - """ - if self.banaction is not None: - if self._timer: - self._timer.cancel() - self._timer = None - self._unbanIPs(self._bannedips.copy()) - - def ban(self, aInfo): - """Reports banned IP to badips.com. - - Parameters - ---------- - aInfo : dict - Dictionary which includes information in relation to - the ban. - - Raises - ------ - HTTPError - Any issues with badips.com request. - """ - try: - url = "/".join([self._badips, "add", self.category, str(aInfo['ip'])]) - if self.key: - url = "?".join([url, urlencode({'key': self.key})]) - self._logSys.debug('badips.com: ban, url: %r', url) - response = urlopen(self._Request(url), timeout=self.timeout) - except HTTPError as response: # pragma: no cover - self.logError(response, "Failed to ban") - raise - else: - messages = json.loads(response.read().decode('utf-8')) - self._logSys.debug( - "Response from badips.com report: '%s'", - messages['suc']) - -Action = BadIPsAction diff --git a/config/action.d/bsd-ipfw.conf b/config/action.d/bsd-ipfw.conf index 5116b0d8..444192d3 100644 --- a/config/action.d/bsd-ipfw.conf +++ b/config/action.d/bsd-ipfw.conf @@ -14,7 +14,10 @@ # Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). # Values: CMD # -actionstart = ipfw show | fgrep -c -m 1 -s 'table()' > /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 > "" ) +actionstart = ipfw show | fgrep -c -m 1 -s 'table(
)' > /dev/null 2>&1 || ( + num=$(ipfw show | awk 'BEGIN { b = } { if ($1 == b) { b = $1 + 1 } } END { print b }'); + ipfw -q add "$num" from table\(
\) to me ; echo "$num" > "" + ) # Option: actionstop diff --git a/config/action.d/cloudflare-token.conf b/config/action.d/cloudflare-token.conf new file mode 100644 index 00000000..287621eb --- /dev/null +++ b/config/action.d/cloudflare-token.conf @@ -0,0 +1,93 @@ +# +# Author: Logic-32 +# +# IMPORTANT +# +# Please set jail.local's permission to 640 because it contains your CF API token. +# +# This action depends on curl. +# +# To get your Cloudflare API token: https://developers.cloudflare.com/api/tokens/create/ +# +# Cloudflare Firewall API: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/endpoints/ + +[Definition] + +# Option: actionstart +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). +# Values: CMD +# +actionstart = + +# Option: actionstop +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) +# Values: CMD +# +actionstop = + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: IP address +# number of failures +#
+_nft_get_handle_id = grep -oP '@\s+.*\s+\Khandle\s+(\d+)$' + +_nft_add_set = add set
\{ type \; \} + <_nft_for_proto--iter> + add rule
%(rule_stat)s + <_nft_for_proto--done> +_nft_del_set = { %(_nft_list)s | %(_nft_get_handle_id)s; } | while read -r hdl; do + delete rule
$hdl; done + delete set
+ +# Option: _nft_shutdown_table +# Notes.: command executed after the stop in order to delete table (it checks that no sets are available): +# Values: CMD +# +_nft_shutdown_table = { list table
| grep -qP '^\s+set\s+'; } || { + delete table
+ } + +# Option: actionstart +# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false). +# Values: CMD +# +actionstart = add table
+ -- add chain
\{ type hook priority \; \} + %(_nft_add_set)s + +# Option: actionflush +# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action); +# uses `nft flush set ...` and as fallback (e. g. unsupported) recreates the set (with references) +# Values: CMD +# +actionflush = { flush set
2> /dev/null; } || { + %(_nft_del_set)s + %(_nft_add_set)s + } + +# Option: actionstop +# Notes.: command executed at the stop of jail (or at the end of Fail2Ban) +# Values: CMD +# +actionstop = %(_nft_del_set)s + <_nft_shutdown_table> + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = list chain
| grep -q '@[ \t]' + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionban = add element
\{ \} + +# 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 = delete element
\{ \} + +[Init] + +# Option: table +# Notes.: main table to store chain and sets (automatically created on demand) +# Values: STRING Default: f2b-table +table = f2b-table + +# Option: table_family +# Notes.: address family to work in +# Values: [ip | ip6 | inet] Default: inet +table_family = inet + +# Option: chain +# Notes.: main chain to store rules +# Values: STRING Default: f2b-chain +chain = f2b-chain + +# Option: chain_type +# Notes.: refers to the kind of chain to be created +# Values: [filter | route | nat] Default: filter +# +chain_type = filter + +# Option: chain_hook +# Notes.: refers to the kind of chain to be created +# Values: [ prerouting | input | forward | output | postrouting ] Default: input +# +chain_hook = input + +# Option: chain_priority +# Notes.: priority in the chain. +# Values: NUMBER Default: -1 +# +chain_priority = -1 + +# Option: addr_type +# Notes.: address type to work with +# Values: [ipv4_addr | ipv6_addr] Default: ipv4_addr +# +addr_type = ipv4_addr + +# Default name of the filtering set +# +name = default + +# Option: port +# Notes.: specifies port to monitor +# Values: [ NUM | STRING ] Default: +# +port = ssh + +# Option: protocol +# Notes.: internally used by config reader for interpolations. +# Values: [ tcp | udp ] Default: tcp +# +protocol = tcp + +# Option: blocktype +# Note: This is what the action does with rules. This can be any jump target +# as per the nftables man page (section 8). Common values are drop, +# reject, reject with icmpx type host-unreachable, redirect to 2222 +# Values: STRING +blocktype = reject + +# Option: nftables +# Notes.: Actual command to be executed, including common to all calls options +# Values: STRING +nftables = nft + +# Option: addr_set +# Notes.: The name of the nft set used to store banned addresses +# Values: STRING +addr_set = addr-set- + +# Option: addr_family +# Notes.: The family of the banned addresses +# Values: [ ip | ip6 ] +addr_family = ip + +[Init?family=inet6] +addr_family = ip6 +addr_type = ipv6_addr +addr_set = addr6-set- diff --git a/config/action.d/nginx-block-map.conf b/config/action.d/nginx-block-map.conf index 33c15f9c..0de382bd 100644 --- a/config/action.d/nginx-block-map.conf +++ b/config/action.d/nginx-block-map.conf @@ -84,8 +84,15 @@ srv_cfg_path = /etc/nginx/ #srv_cmd = nginx -c %(srv_cfg_path)s/nginx.conf srv_cmd = nginx -# first test configuration is correct, hereafter send reload signal: -blck_lst_reload = %(srv_cmd)s -qt; if [ $? -eq 0 ]; then +# pid file (used to check nginx is running): +srv_pid = /run/nginx.pid + +# command used to check whether nginx is running and configuration is valid: +srv_is_running = [ -f "%(srv_pid)s" ] +srv_check_cmd = %(srv_is_running)s && %(srv_cmd)s -qt + +# first test nginx is running and configuration is correct, hereafter send reload signal: +blck_lst_reload = %(srv_check_cmd)s; if [ $? -eq 0 ]; then %(srv_cmd)s -s reload; if [ $? -ne 0 ]; then echo 'reload failed.'; fi; fi; @@ -103,6 +110,8 @@ actionstop = %(actionflush)s actioncheck = -actionban = echo "\\\\ 1;" >> '%(blck_lst_file)s'; %(blck_lst_reload)s +_echo_blck_row = printf '\%%s 1;\n' "" -actionunban = id=$(echo "" | sed -e 's/[]\/$*.^|[]/\\&/g'); sed -i "/$id 1;/d" %(blck_lst_file)s; %(blck_lst_reload)s +actionban = %(_echo_blck_row)s >> '%(blck_lst_file)s'; %(blck_lst_reload)s + +actionunban = id=$(%(_echo_blck_row)s | sed -e 's/[]\/$*.^|[]/\\&/g'); sed -i "/^$id$/d" %(blck_lst_file)s; %(blck_lst_reload)s diff --git a/config/action.d/sendmail-buffered.conf b/config/action.d/sendmail-buffered.conf index 199c6ce5..13803f8b 100644 --- a/config/action.d/sendmail-buffered.conf +++ b/config/action.d/sendmail-buffered.conf @@ -24,7 +24,7 @@ actionstart = printf %%b "Subject: [Fail2Ban] : started on The jail has been started successfully.\n Output will be buffered until lines are available.\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | # Option: actionstop # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) @@ -38,7 +38,7 @@ actionstop = if [ -f ]; then These hosts have been banned by Fail2Ban.\n `cat ` Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | rm fi printf %%b "Subject: [Fail2Ban] : stopped on @@ -47,7 +47,7 @@ actionstop = if [ -f ]; then Hi,\n The jail has been stopped.\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | # Option: actioncheck # Notes.: command executed once before each actionban command @@ -71,7 +71,7 @@ actionban = printf %%b "`date`: ( failures)\n" >> These hosts have been banned by Fail2Ban.\n `cat ` Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | rm fi diff --git a/config/action.d/sendmail-common.conf b/config/action.d/sendmail-common.conf index 9bf15054..1e31fadf 100644 --- a/config/action.d/sendmail-common.conf +++ b/config/action.d/sendmail-common.conf @@ -21,7 +21,7 @@ actionstart = printf %%b "Subject: [Fail2Ban] : started on Hi,\n The jail has been started successfully.\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | # Option: actionstop # Notes.: command executed at the stop of jail (or at the end of Fail2Ban) @@ -34,7 +34,7 @@ actionstop = printf %%b "Subject: [Fail2Ban] : stopped on Hi,\n The jail has been stopped.\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | # Option: actioncheck # Notes.: command executed once before each actionban command @@ -60,6 +60,10 @@ actionunban = [Init] +# Your system mail command +# +mailcmd = /usr/sbin/sendmail -f "" "" + # Recipient mail address # dest = root diff --git a/config/action.d/sendmail-geoip-lines.conf b/config/action.d/sendmail-geoip-lines.conf index b7c1bf36..b36e49a7 100644 --- a/config/action.d/sendmail-geoip-lines.conf +++ b/config/action.d/sendmail-geoip-lines.conf @@ -37,11 +37,11 @@ actionban = ( printf %%b "Subject: [Fail2Ban] : banned from " | cut -d':' -f2-` AS:`geoiplookup -f /usr/share/GeoIP/GeoIPASNum.dat "" | cut -d':' -f2-` hostname: \n\n - Lines containing failures of \n"; + Lines containing failures of (max )\n"; %(_grep_logs)s; printf %%b "\n Regards,\n - Fail2Ban" ) | /usr/sbin/sendmail -f + Fail2Ban" ) | [Init] diff --git a/config/action.d/sendmail-whois-ipjailmatches.conf b/config/action.d/sendmail-whois-ipjailmatches.conf index 06ea3a3e..7790ec53 100644 --- a/config/action.d/sendmail-whois-ipjailmatches.conf +++ b/config/action.d/sendmail-whois-ipjailmatches.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf [Definition] @@ -27,11 +28,11 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from has just been banned by Fail2Ban after attempts against .\n\n Here is more information about :\n - `/usr/bin/whois `\n\n + `%(_whois_command)s`\n\n Matches for with failures IP:\n \n\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | [Init] diff --git a/config/action.d/sendmail-whois-ipmatches.conf b/config/action.d/sendmail-whois-ipmatches.conf index 83bff1b4..e4717ca1 100644 --- a/config/action.d/sendmail-whois-ipmatches.conf +++ b/config/action.d/sendmail-whois-ipmatches.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf [Definition] @@ -27,11 +28,11 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from has just been banned by Fail2Ban after attempts against .\n\n Here is more information about :\n - `/usr/bin/whois `\n\n + `%(_whois_command)s`\n\n Matches with failures IP:\n \n\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | [Init] diff --git a/config/action.d/sendmail-whois-lines.conf b/config/action.d/sendmail-whois-lines.conf index 4b947cb2..47ec6ed5 100644 --- a/config/action.d/sendmail-whois-lines.conf +++ b/config/action.d/sendmail-whois-lines.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf helpers-common.conf [Definition] @@ -27,13 +28,13 @@ actionban = ( printf %%b "Subject: [Fail2Ban] : banned from has just been banned by Fail2Ban after attempts against .\n\n - Here is more information about :\n - `/usr/bin/whois || echo missing whois program`\n\n - Lines containing failures of \n"; + Here is more information about :\n" + %(_whois_command)s; + printf %%b "\nLines containing failures of (max )\n"; %(_grep_logs)s; printf %%b "\n Regards,\n - Fail2Ban" ) | /usr/sbin/sendmail -f + Fail2Ban" ) | [Init] diff --git a/config/action.d/sendmail-whois-matches.conf b/config/action.d/sendmail-whois-matches.conf index 01520135..08215ea7 100644 --- a/config/action.d/sendmail-whois-matches.conf +++ b/config/action.d/sendmail-whois-matches.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf [Definition] @@ -27,11 +28,11 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from has just been banned by Fail2Ban after attempts against .\n\n Here is more information about :\n - `/usr/bin/whois `\n\n + `%(_whois_command)s`\n\n Matches:\n \n\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | [Init] diff --git a/config/action.d/sendmail-whois.conf b/config/action.d/sendmail-whois.conf index 2fb01ed3..9e93cd32 100644 --- a/config/action.d/sendmail-whois.conf +++ b/config/action.d/sendmail-whois.conf @@ -7,6 +7,7 @@ [INCLUDES] before = sendmail-common.conf + mail-whois-common.conf [Definition] @@ -27,9 +28,9 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from has just been banned by Fail2Ban after attempts against .\n\n Here is more information about :\n - `/usr/bin/whois || echo missing whois program`\n + `%(_whois_command)s`\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | [Init] diff --git a/config/action.d/sendmail.conf b/config/action.d/sendmail.conf index cf420915..ad9e8d79 100644 --- a/config/action.d/sendmail.conf +++ b/config/action.d/sendmail.conf @@ -27,7 +27,7 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from has just been banned by Fail2Ban after attempts against .\n Regards,\n - Fail2Ban" | /usr/sbin/sendmail -f + Fail2Ban" | [Init] diff --git a/config/action.d/shorewall-ipset-proto6.conf b/config/action.d/shorewall-ipset-proto6.conf index 45be0c0a..eacb53d9 100644 --- a/config/action.d/shorewall-ipset-proto6.conf +++ b/config/action.d/shorewall-ipset-proto6.conf @@ -51,7 +51,7 @@ # Values: CMD # actionstart = if ! ipset -quiet -name list f2b- >/dev/null; - then ipset -quiet -exist create f2b- hash:ip timeout ; + then ipset -quiet -exist create f2b- hash:ip timeout ; fi # Option: actionstop @@ -66,9 +66,9 @@ actionstop = ipset flush f2b- # Tags: See jail.conf(5) man page # Values: CMD # -actionban = ipset add f2b- timeout -exist +actionban = ipset add f2b- timeout -exist -actionprolong = %(actionban)s +# actionprolong = %(actionban)s # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the @@ -78,8 +78,16 @@ actionprolong = %(actionban)s # actionunban = ipset del f2b- -exist -# Option: default-timeout +# Option: default-ipsettime # Notes: specifies default timeout in seconds (handled default ipset timeout only) -# Values: [ NUM ] Default: 600 +# Values: [ NUM ] Default: 0 (no timeout, managed by fail2ban by unban) +default-ipsettime = 0 -default-timeout = 600 +# Option: ipsettime +# Notes: specifies ticket timeout (handled ipset timeout only) +# Values: [ NUM ] Default: 0 (managed by fail2ban by unban) +ipsettime = 0 + +# expresion to caclulate timeout from bantime, example: +# banaction = %(known/banaction)s[ipsettime=''] +timeout-bantime = $([ "" -le 2147483 ] && echo "" || echo 0) diff --git a/config/action.d/shorewall.conf b/config/action.d/shorewall.conf index dcef8829..83d08d99 100644 --- a/config/action.d/shorewall.conf +++ b/config/action.d/shorewall.conf @@ -9,7 +9,7 @@ # connections. So if the attempter goes on trying using the same connection # he could even log in. In order to get the same behavior of the iptable # action (so that the ban is immediate) the /etc/shorewall/shorewall.conf -# file should me modified with "BLACKLISTNEWONLY=No". Note that as of +# file should be modified with "BLACKLISTNEWONLY=No". Note that as of # Shorewall 4.5.13 BLACKLISTNEWONLY is deprecated; however the equivalent # of BLACKLISTNEWONLY=No can now be achieved by setting BLACKLIST="ALL". # diff --git a/config/action.d/smtp.py b/config/action.d/smtp.py index 9cdfe327..5c27d0ff 100644 --- a/config/action.d/smtp.py +++ b/config/action.d/smtp.py @@ -159,25 +159,25 @@ class SMTPAction(ActionBase): try: self._logSys.debug("Connected to SMTP '%s', response: %i: %s", self.host, *smtp.connect(self.host)) - if self.user and self.password: + if self.user and self.password: # pragma: no cover (ATM no tests covering that) smtp.login(self.user, self.password) failed_recipients = smtp.sendmail( self.fromaddr, self.toaddr.split(", "), msg.as_string()) - except smtplib.SMTPConnectError: + except smtplib.SMTPConnectError: # pragma: no cover self._logSys.error("Error connecting to host '%s'", self.host) raise - except smtplib.SMTPAuthenticationError: + except smtplib.SMTPAuthenticationError: # pragma: no cover self._logSys.error( "Failed to authenticate with host '%s' user '%s'", self.host, self.user) raise - except smtplib.SMTPException: + except smtplib.SMTPException: # pragma: no cover self._logSys.error( "Error sending mail to host '%s' from '%s' to '%s'", self.host, self.fromaddr, self.toaddr) raise else: - if failed_recipients: + if failed_recipients: # pragma: no cover self._logSys.warning( "Email to '%s' failed to following recipients: %r", self.toaddr, failed_recipients) @@ -186,7 +186,7 @@ class SMTPAction(ActionBase): try: self._logSys.debug("Disconnected from '%s', response %i: %s", self.host, *smtp.quit()) - except smtplib.SMTPServerDisconnected: + except smtplib.SMTPServerDisconnected: # pragma: no cover pass # Not connected def start(self): diff --git a/config/action.d/symbiosis-blacklist-allports.conf b/config/action.d/symbiosis-blacklist-allports.conf index 6fb7d0af..7208b293 100644 --- a/config/action.d/symbiosis-blacklist-allports.conf +++ b/config/action.d/symbiosis-blacklist-allports.conf @@ -5,7 +5,7 @@ [INCLUDES] -before = iptables-common.conf +before = iptables.conf [Definition] @@ -41,6 +41,11 @@ actionban = echo 'all' >| /etc/symbiosis/firewall/blacklist.d/.auto actionunban = rm -f /etc/symbiosis/firewall/blacklist.d/.auto -D -s -j || : +# [TODO] Flushing is currently not implemented for symbiosis blacklist.d +# +actionflush = + + [Init] # Option: chain diff --git a/config/action.d/ufw.conf b/config/action.d/ufw.conf index d2f731f2..c9ff7f37 100644 --- a/config/action.d/ufw.conf +++ b/config/action.d/ufw.conf @@ -13,16 +13,45 @@ actionstop = actioncheck = -actionban = [ -n "" ] && app="app " - ufw insert from to $app +# ufw does "quickly process packets for which we already have a connection" in before.rules, +# therefore all related sockets should be closed +# actionban is using `ss` to do so, this only handles IPv4 and IPv6. -actionunban = [ -n "" ] && app="app " - ufw delete from to $app +actionban = if [ -n "" ] && ufw app info "" + then + ufw from to app "" comment "" + else + ufw from to comment "" + fi + + +actionunban = if [ -n "" ] && ufw app info "" + then + ufw delete from to app "" + else + ufw delete from to + fi + +# Option: kill-mode +# Notes.: can be set to ss or conntrack (may be extended later with other modes) to immediately drop all connections from banned IP, default empty (no kill) +# Example: banaction = ufw[kill-mode=ss] +kill-mode = + +# intern conditional parameter used to provide killing mode after ban: +_kill_ = +_kill_ss = ss -K dst "[]" +_kill_conntrack = conntrack -D -s "" + +# Option: kill +# Notes.: can be used to specify custom killing feature, by default depending on option kill-mode +# Examples: banaction = ufw[kill='ss -K "( sport = :http || sport = :https )" dst "[]"'] +# banaction = ufw[kill='cutter ""'] +kill = <_kill_> [Init] -# Option: insertpos -# Notes.: The position number in the firewall list to insert the block rule -insertpos = 1 +# Option: add +# Notes.: can be set to "insert 1" to insert a rule at certain position (here 1): +add = prepend # Option: blocktype # Notes.: reject or deny @@ -36,6 +65,10 @@ destination = any # Notes.: application from sudo ufw app list application = +# Option: comment +# Notes.: comment for rule added by fail2ban +comment = by Fail2Ban after attempts against + # DEV NOTES: # # Author: Guilhem Lettron diff --git a/config/action.d/xarf-login-attack.conf b/config/action.d/xarf-login-attack.conf index 2b135c43..f348b2c4 100644 --- a/config/action.d/xarf-login-attack.conf +++ b/config/action.d/xarf-login-attack.conf @@ -41,7 +41,12 @@ actionstop = actioncheck = -actionban = oifs=${IFS}; IFS=.;SEP_IP=( ); set -- ${SEP_IP}; ADDRESSES=$(dig +short -t txt -q $4.$3.$2.$1.abuse-contacts.abusix.org); IFS=${oifs} +actionban = oifs=${IFS}; + RESOLVER_ADDR="%(addr_resolver)s" + if [ "" -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= FROM= SERVICE= @@ -51,26 +56,37 @@ actionban = oifs=${IFS}; IFS=.;SEP_IP=( ); set -- ${SEP_IP}; ADDRESSES=$(di PORT= DATE=`LC_ALL=C date --date=@