diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2c0ae72f..ee6305c4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.8, 3.9, '3.10', '3.11', '3.12', '3.13', '3.14.0-alpha.6', pypy3.11] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12', '3.13', '3.14', '3.15.0-alpha.5', pypy3.11] fail-fast: false # Steps represent a sequence of tasks that will be executed as part of the job steps: diff --git a/ChangeLog b/ChangeLog index 4f06aaeb..216ffe88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,7 +7,7 @@ Fail2Ban: Changelog =================== -ver. 1.1.1-beta-0 (2025/06/16) - just-an-interim-beta +ver. 1.1.1-dev-1 (20??/??/??) - development nightly edition ----------- ### Compatibility @@ -24,6 +24,10 @@ ver. 1.1.1-beta-0 (2025/06/16) - just-an-interim-beta in systemd module (see https://github.com/systemd/python-systemd/issues/143) * fixes `systemd` causing "too many open files" error for a lot of journal files and large amount of systemd jails (see new parameter `rotated` below, gh-3391); +* passing of arguments from jails to action or filter will affect conditional section too (gh-4069), + e. g. setting `blocktype="DROP"` via jail for action would now apply for IPv4 and IPv6 chains, + to submit different `blocktype` for IPv4 and IPv6 from jail, one can pass them like in this example: + `banaction = iptables-ipset[blocktype="...", blocktype?family=inet6="..."]` * `jail.conf`: - default banactions need to be specified in `paths-*.conf` (maintainer level) now - since stock fail2ban includes `paths-debian.conf` by default, banactions are `nftables` @@ -33,10 +37,20 @@ ver. 1.1.1-beta-0 (2025/06/16) - just-an-interim-beta * `paths-debian.conf`: - default banactions are `nftables` - sshd backend switched to `systemd` (gh-3292) + - postfix backend switched to `systemd` (gh-3527) * `action.d/firewallcmd-ipset.conf`: - rename `ipsettype` to `ipsetbackend` (gh-2620), parameter `ipsettype` will be used now to the real set type (gh-3760) +* `action.d/nftables.conf`: + - action fixed for SELinux without execmem permission, rewrite capturing with `grep -P` using `grep -E` or `sed` + (PCRE-JIT by `grep -P` may cause SELinux denial for execmem, see gh-4137) +* `action.d/xarf-login-attack.conf` - ignore errors or warnings in output of `dig` provided as comment (gh-4068) +* `filter.d/apache-badbots.conf`, `filter.d/apache-fakegooglebot.conf`: + - regexs rewritten more strict (removed catch-alls, etc); + - regexs fixed to match lines with vhost in accesslog (gh-1594) * `filter.d/apache-noscript.conf` - consider new log-format with "AH02811: stderr from /..." (gh-3900) * `filter.d/apache-overflows.conf` - consider AH10244: invalid URI path (gh-3778, gh-3900) +* `filter.d/asterisk.conf` - fixed RE for "no matching endpoint" with retry info (like `after X tries in Y ms`) at end, + loosening of end anchor (ignore any simple text tokens at end if no single quote found), gh-4037 * `filter.d/exim.conf`: - several rules of mode `normal` moved to new mode `more`, because of too risky handling (gh-3940), thereby mode `aggressive` is not affected, because it fully includes mode `more` now; @@ -45,18 +59,28 @@ ver. 1.1.1-beta-0 (2025/06/16) - just-an-interim-beta FreeSWITCH log line prefix has changed in newer versions (gh-3143) * `filter.d/lighttpd-auth.conf` - fixed regex (if failures generated by systemd-journal), bypass several prefixes now (gh-3955) * `filter.d/postfix.conf`: + - extended `prefregex` to capture username in postfix SASL failures (gh-4165) - consider CONNECT and other rejected commands as a valid `_pref` (gh-3800) - default `_daemon` in prefix-line is loosened - can match everything starting with word postfix, like `postfix-example.com/smtpd` (gh-3297) + - add optional `NOQUEUE:` prefix to ddos regex (gh-4072) + - internal parameter `_pref` is renamed to `_cmd`, `_pref` matches now optional prefix like `NOQUEUE: ` etc + - modes `ddos` and `aggressive` extended to match `rate limit exceeded` for connection or message delivery request rates (gh-3265, gh-4073) * `filter.d/dropbear.conf`: - recognizes extra pid/timestamp if logged into stdout/journal, added `journalmatch` (gh-3597) - failregex extended to match different format of "Exit before auth" message (gh-3791) * `filter.d/recidive.conf` - restore possibility to set jail name in the filter, _jailname is positive now (gh-3769) * `filter.d/roundcube-auth.conf` - improved RE better matching log format of roundcube version 1.4+ (gh-3816) +* `filter.d/sendmail-reject.conf`: (gh-4020) + - support `` for BSD-style logfiles + - add match for `User unknown` to default + - the relay field may not always have a hostname before the ip address + - mode `aggressive` enables match for `lost input channel` and `Cannot resolve PTR record` * `filter.d/sshd.conf`: - adapted to conform possible new daemon name sshd-session, since OpenSSH 9.8 several log messages will be tagged with as originating from a process named "sshd-session" rather than "sshd" (gh-3782) - `ddos` and `aggressive` modes: regex extended for timeout before authentication (optional connection from part, gh-3907) * `filter.d/vsftpd.conf` - fixed regex (if failures generated by systemd-journal, gh-3954) +* `filter.d/froxlor-auth.conf` - updated the regex to the new logging situation for froxlor and changed logpath in jail.conf (gh-4075). ### New Features and Enhancements * backend `systemd` extended with new parameter `rotated` (default `false`, as prevention against "too many open files"), @@ -75,16 +99,30 @@ ver. 1.1.1-beta-0 (2025/06/16) - just-an-interim-beta by first ban (and automatically reloaded by update after small latency to avoid expensive stats check on every compare); the entries inside the file can be separated by comma, space or new line with optional comments (text following chars `#` or `;` after space or newline would be ignored up to next newline) +* `action.d/apprise.conf` - updated to support tagging and other command line args (gh-4141) * `action.d/*-ipset.conf`: - parameter `ipsettype` to set type of ipset, e. g. hash:ip, hash:net, etc (gh-3760) * `action.d/iptables.conf` - action and few derivatives of it extended to handle multiple chains, e. g. would also accept `chain = INPUT,FORWARD` (gh-3909) +* `action.d/nftables.conf` (gh-3291): + - new parameter `addr_options` for addr-set (default `flags interval\;`, allows to store CIDR or address ranges); + can be set to empty value to create simple addresses set (restore previous behavior). * `action.d/firewallcmd-rich-*.conf` - fixed incorrect quoting, disabling port variable expansion by substitution of rich rule (gh-3815) -* `filter.d/dovecot.conf` - add support for latest Dovecot 2.4 release (gh-4016) +* `filter.d/dovecot.conf`: + - add support for latest Dovecot 2.4 release (gh-4016) + - mode `aggressive` covered new variant for `no auth attempts in X secs` with `Login aborted` and `(no_auth_attempts)` + - mode `aggressive` extended to match `disconnected during TLS handshake` with `no application protocol` and `no shared cipher` +* `filter.d/nginx-http-auth.conf`: + - extended with `prefregex` to capture content of error only (bypass common prefix and suffix, like server, request, host, referrer); + - extended to match PAM authentication failures (gh-4071) + - modes `fallback` and `aggressive` extended to match more SSL failures by SSL_do_handshake or SSL_read (gh-4142, gh-2881) +* `filter.d/nginx-limit-req.conf` - extended to ban hosts failed by limit connection in ngx_http_limit_conn_module (gh-3674, gh-4047) * `filter.d/proxmox.conf` - add support to Proxmox Web GUI (gh-2966) * `filter.d/openvpn.conf` - new filter and jail for openvpn recognizing failed TLS handshakes (gh-2702) +* `filter.d/sendmail-reject.conf` - also recognize "Domain of sender address ... does not resolve" (gh-4035) * `filter.d/vaultwarden.conf` - new filter and jail for Vaultwarden (gh-3979) +* `filter.d/xrdp.conf` - new filter for XRDP, an open source RDP server (gh-3254) * `fail2ban-regex` extended with new option `-i` or `--invert` to output not-matched lines by `-o` or `--out` (gh-4001) diff --git a/MANIFEST b/MANIFEST index 1a1d38c6..972a2b48 100644 --- a/MANIFEST +++ b/MANIFEST @@ -11,7 +11,6 @@ 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/csf.conf config/action.d/dshield.conf config/action.d/dummy.conf config/action.d/firewallcmd-allports.conf @@ -130,7 +129,6 @@ config/filter.d/nginx-http-auth.conf config/filter.d/nginx-limit-req.conf config/filter.d/nsd.conf config/filter.d/openhab.conf -config/filter.d/openvpn.conf config/filter.d/openwebmail.conf config/filter.d/oracleims.conf config/filter.d/pam-generic.conf @@ -140,7 +138,6 @@ config/filter.d/php-url-fopen.conf config/filter.d/portsentry.conf config/filter.d/postfix.conf config/filter.d/proftpd.conf -config/filter.d/proxmox.conf config/filter.d/pure-ftpd.conf config/filter.d/qmail.conf config/filter.d/recidive.conf @@ -165,7 +162,6 @@ 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/vaultwarden.conf config/filter.d/vsftpd.conf config/filter.d/webmin-auth.conf config/filter.d/wuftpd.conf @@ -344,7 +340,6 @@ fail2ban/tests/files/logs/nginx-http-auth fail2ban/tests/files/logs/nginx-limit-req fail2ban/tests/files/logs/nsd fail2ban/tests/files/logs/openhab -fail2ban/tests/files/logs/openvpn fail2ban/tests/files/logs/openwebmail fail2ban/tests/files/logs/oracleims fail2ban/tests/files/logs/pam-generic @@ -354,7 +349,6 @@ fail2ban/tests/files/logs/php-url-fopen fail2ban/tests/files/logs/portsentry fail2ban/tests/files/logs/postfix fail2ban/tests/files/logs/proftpd -fail2ban/tests/files/logs/proxmox fail2ban/tests/files/logs/pure-ftpd fail2ban/tests/files/logs/qmail fail2ban/tests/files/logs/recidive @@ -379,7 +373,6 @@ 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/vaultwarden fail2ban/tests/files/logs/vsftpd fail2ban/tests/files/logs/webmin-auth fail2ban/tests/files/logs/wuftpd @@ -397,7 +390,6 @@ fail2ban/tests/files/testcase-journal.log fail2ban/tests/files/testcase-multiline.log fail2ban/tests/files/testcase-usedns.log fail2ban/tests/files/testcase-wrong-char.log -fail2ban/tests/files/test-ign-ips-file fail2ban/tests/files/zzz-sshd-obsolete-multiline.log fail2ban/tests/filtertestcase.py fail2ban/tests/__init__.py diff --git a/README.md b/README.md index a5aa646c..9d5a5959 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ attempts, it cannot eliminate the risk presented by weak authentication. Set up services to use only two factor, or public/private authentication mechanisms if you really want to protect services. - | Since v0.10 fail2ban supports the matching of IPv6 addresses. + | Since v0.10 fail2ban supports the matching of IPv6 addresses. ------|------ This README is a quick introduction to Fail2Ban. More documentation, FAQ, and HOWTOs diff --git a/config/action.d/apprise.conf b/config/action.d/apprise.conf index c6ce539a..899b1e5f 100644 --- a/config/action.d/apprise.conf +++ b/config/action.d/apprise.conf @@ -2,7 +2,61 @@ # # Author: Chris Caron # +# ban & send a notification to one or more of the 120+ services supported by +# Apprise. +# - See https://appriseit.com/services/ for details on what is supported. +# - See https://appriseit.com/getting-started/configuration/ for information +# on how to prepare an Apprise configuration file. # +# This plugin requires that Apprise is installed on your system: +# +# pip install apprise +# +# Breakdown: +# config provide a path to an Apprise Config file +# The default is /etc/fail2ban/apprise.conf if not provided. +# Both YAML and TEXT formats are supported. +# You can even point your configuration to an Apprise API +# endpoint. +# +# args Provide additional arguments to support the Apprise CLI. +# See https://appriseit.com/cli/usage/ for additional options. +# the --tag (-g) is incredibly useful for integrating with +# fail2ban as you can exclusively have it target specific +# notifications this way. +# +# Config Example #1: Simple +# 1. Create a /etc/fail2ban/apprise.conf +# ``` +# # /etc/fail2ban/apprise.conf +# fail2ban=mailto://user:pass@example.com +# ``` +# 2 In jail: +# ``` +# action = %(action_)s +# apprise[args='--tag fail2ban'] +# ``` +# +# Config Example #2: YAML an Custom path +# 1. Create a /etc/fail2ban/apprise.conf +# ``` +# # /etc/fail2ban/apprise.yaml +# urls: +# - mailto://user:pass@example.com: +# tags: f2b +# ``` +# 2. In jail: +# ``` +# action = %(action_)s +# apprise[config='/etc/fail2ban/apprise.yaml',args='--tag f2b'] +# ``` +# +# Config Example #3: Apprise API +# 1. In jail: +# ``` +# action = %(action_)s +# apprise[config='http://apprise.example.ca/get/mykey',args='-g f2b'] +# ``` [Definition] @@ -45,5 +99,9 @@ actionunban = # Define location of the default apprise configuration file to use # config = /etc/fail2ban/apprise.conf + +# Support passing in arguments for example: "-g fail2ban" # -apprise = apprise -c "" +args = +# +apprise = apprise -c "" diff --git a/config/action.d/nftables.conf b/config/action.d/nftables.conf index 53fbcfec..94ff9cdf 100644 --- a/config/action.d/nftables.conf +++ b/config/action.d/nftables.conf @@ -53,9 +53,9 @@ _nft_for_proto-multiport-iter = for proto in $(echo '' | sed 's/,/ /g' _nft_for_proto-multiport-done = done _nft_list = -a list chain -_nft_get_handle_id = grep -oP '@\s+.*\s+\Khandle\s+(\d+)$' +_nft_get_handle_id = sed -nE 's/.*@\s+.*\s+\#\s*(handle\s+[0-9]+)$/\1/p' -_nft_add_set = add set
\{ type \; \} +_nft_add_set = add set
\{ type \; \} <_nft_for_proto--iter> add rule
%(rule_stat)s <_nft_for_proto--done> @@ -67,7 +67,7 @@ _nft_del_set = { %(_nft_list)s | %(_nft_get_handle_id)s; } | while read -r hdl; # 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+'; } || { +_nft_shutdown_table = { list table
| grep -qE '^\s+set\s+'; } || { delete table
} @@ -197,6 +197,11 @@ addr_set = addr-set- # Values: [ ip | ip6 ] addr_family = ip +# Option: addr_options +# Notes: Additional options for the addr-set, by default allows to store CIDR or address ranges. +# Can be set to empty value to create simple addresses set. +addr_options = flags interval\; + [Init?family=inet6] addr_family = ip6 addr_type = ipv6_addr diff --git a/config/action.d/xarf-login-attack.conf b/config/action.d/xarf-login-attack.conf index f348b2c4..00da7f79 100644 --- a/config/action.d/xarf-login-attack.conf +++ b/config/action.d/xarf-login-attack.conf @@ -44,7 +44,13 @@ actioncheck = 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 '"') + ADDRESSES=$(dig +short -t txt -q $RESOLVER_ADDR | grep -v ';;' | tr -d '"') + if [ "" -gt 0 ]; then echo "returned address $ADDRESSES"; fi + if [ -z "$ADDRESSES" ]; then + echo "address for $RESOLVER_ADDR cannot be found or timeout from dig"; + if [ "" -gt 0 ]; then exit 1; fi + exit 0 + fi IFS=,; ADDRESSES=$(echo $ADDRESSES) IFS=${oifs} IP= @@ -55,13 +61,11 @@ actionban = oifs=${IFS}; TLP= PORT= DATE=`LC_ALL=C date --date=@