Compare commits

...

499 commits

Author SHA1 Message Date
sebres
8be17b0981 Merge branch 'gh-4142--nginx-ssl-aggressive': extends filter.d/nginx-http-auth.conf - modes fallback and aggressive match more SSL failures by SSL_do_handshake or SSL_read (gh-4142, gh-2881)
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13) (push) Has been cancelled
CI / build (3.14) (push) Has been cancelled
CI / build (3.15.0-alpha.5) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.11) (push) Has been cancelled
2026-02-12 14:04:55 +01:00
sebres
c03a6204c1 ChangeLog update 2026-02-12 14:03:07 +01:00
sebres
eb7ed973ef filter.d/nginx-http-auth.conf: modes fallback and aggressive extended to match more SSL failures, see gh-4142 (amend to gh-2881) 2026-02-12 13:53:57 +01:00
Sergey G. Brester
3b8033b337
Merge pull request #2537 from viiru-/improve-systemd-service
Some checks are pending
Codespell / Check for spelling errors (push) Waiting to run
Improve systemd service
2026-02-11 15:08:35 +01:00
Sergey G. Brester
243876e60a
Merge pull request #4143 from caronc/apprise-tag-support-v2
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13) (push) Has been cancelled
CI / build (3.14) (push) Has been cancelled
CI / build (3.15.0-alpha.5) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.11) (push) Has been cancelled
Small amend to #4141, adjust Apprise URL doc source and action comments
2026-02-02 03:07:01 +01:00
Sergey G. Brester
3bead7c011
Update comments in action
jail.conf shall be unmodified (jails are ideally in jail.local or jail.d/*.conf)
2026-02-02 03:04:25 +01:00
Chris Caron
05f6ad4fcc small fix to url for Apprise doc source 2026-02-01 20:52:06 -05:00
Sergey G. Brester
81b906303c
Merge pull request #4141 from caronc/apprise-tag-support
Improved Apprise integration (support tagging)
2026-02-02 02:44:46 +01:00
Sergey G. Brester
025adbf485
fixes apprise action configuration examples 2026-02-02 02:37:26 +01:00
Sergey G. Brester
f457cf8131
ChangeLog adjusted
move from compat to enhancement section
2026-02-02 02:31:19 +01:00
Chris Caron
1a802bee93 further feedback from PR 2026-02-01 20:18:07 -05:00
Chris Caron
36e28359ed fixed spelling 2026-02-01 19:51:26 -05:00
Chris Caron
8a8afefd70 applied updates based on PR feedback 2026-02-01 19:45:44 -05:00
Chris Caron
8afd0c8956 updated ChangeLog to reflect Apprise updates 2026-01-28 21:55:04 -05:00
Chris Caron
6cdb5738ec improved apprise fail2ban integration (support tagging) 2026-01-28 21:49:42 -05:00
sebres
9887ee4412 CI: bump python version (3.15.0-alpha.5)
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13) (push) Has been cancelled
CI / build (3.14) (push) Has been cancelled
CI / build (3.15.0-alpha.5) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.11) (push) Has been cancelled
2026-01-23 21:28:52 +01:00
sebres
8506e4a41d action.d/nftables.conf - 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), closes gh-4137
2026-01-23 21:23:58 +01:00
sebres
948e923589 Merge fix for #4126 (branch 'gh-4126--py-3.15')
refactor module loading to use exec_module: deprecated load_module is removed in py-3.15;
closes gh-4126
2026-01-01 21:56:15 +01:00
Sergey G. Brester
247667c9c2
refactor loading of SMTP action module in tests (deprecated load_module removed in v.3.15) 2026-01-01 21:49:12 +01:00
Sergey G. Brester
7528fce11b
refactor module loading to use exec_module: load_module is deprecated;
closes gh-4126
2026-01-01 21:43:27 +01:00
Sergey G. Brester
edaf8ef19f
GHA-CI: update python 3.14 + added 3.15 2026-01-01 21:26:22 +01:00
Sergey G. Brester
74981e4c13
Merge pull request #3254 from evanlinde/master
New filter for XRDP
2025-12-07 01:19:01 +01:00
Sergey G. Brester
45453826a3
small amend with missing newline 2025-12-07 01:18:04 +01:00
Sergey G. Brester
2f0e05a0d7
Merge branch 'master' into master 2025-12-07 01:14:39 +01:00
sebres
ef65652671 filter.d/apache-badbots.conf, filter.d/apache-fakegooglebot.conf - regexs fixed to match lines with vhost in accesslog;
closes gh-1594
2025-11-28 22:27:06 +01:00
sebres
bfafd12c59 filter.d/apache-badbots.conf, filter.d/apache-fakegooglebot.conf - rewrite apache access-log REs more strict (remove catch-alls) 2025-11-28 22:16:23 +01:00
Sergey G. Brester
7c2bda4977
Fix image size for IPv6 logo in README
Updated image tag in README to use 'style' attribute.
2025-11-24 23:14:47 +01:00
sebres
3f78f1520b fixed typo in comparison by build of stream from filter options (see #4066) 2025-10-28 21:34:00 +01:00
Sergey G. Brester
7bac839603
Merge pull request #4069 from sebres/init-param-to-cond-section
Setting of blocktype="DROP" via jail doesn't apply for IPv6 chain
2025-09-24 18:23:44 +02:00
Sergey G. Brester
d0b94c147e
Update ChangeLog 2025-09-24 18:22:06 +02:00
Sergey G. Brester
070d49e09c
man/jail.conf.5 - update docu 2025-09-24 18:18:38 +02:00
Sergey G. Brester
dda4aa7d2d
Merge pull request #4075 from para-do-x/froxlor-auth
Froxlor auth update
2025-09-24 16:58:27 +02:00
para-do-x
ad9aba5871
Update ChangeLog gh4075 2025-09-24 18:43:39 +04:00
sebres
13563fd09b combine both REs to single RE, no prefregex needed here 2025-09-24 16:23:05 +02:00
sebres
a9401233dd code review, make it backwards compatible to logging type=1 (as suggested in https://github.com/fail2ban/fail2ban/issues/2926#issuecomment-774780120); use by default type=2 2025-09-24 16:09:42 +02:00
para-do-x
1379a262f6 Update froxlor-auth testfile 2025-09-24 15:59:19 +02:00
para-do-x
abdd0d4b25 Update jail.conf for froxlor-auth
Changed logpath to syslog_user for froxlor-auth
2025-09-24 15:59:18 +02:00
para-do-x
897b21a4c5 Update froxlor-auth.conf
updated the regex to the new logging situation for froxlor.
2025-09-24 15:59:17 +02:00
sebres
65668b8ed8 filter.d/postfix.conf - modes ddos and aggressive extended to match rate limit exceeded for connection or message delivery request rates;
closes gh-3265;
closes gh-4073;
2025-09-23 12:18:45 +02:00
sebres
2856092709 filter.d/postfix.conf - use common prefix instead of NOQUEUE for all modes, outside of mdpr-<mode> in prefregex (amend to gh-4072) 2025-09-18 15:01:05 +02:00
Sergey G. Brester
2ac7e1284f
Merge pull request #4072 from ulm/postfix-ddos
filter.d/postfix.conf: Add optional "NOQUEUE:" to mdpr-ddos
2025-09-18 14:35:35 +02:00
Ulrich Müller
0fee8dbe92 filter.d/postfix.conf: Add optional "NOQUEUE:" to mdpr-ddos
The current regex doesn't match the following log entry, seen with
Postfix 3.10.2:

Sep 17 18:19:20 mxhost postfix/smtpd[12345]: NOQUEUE: lost connection after CONNECT from unknown[192.0.2.25]
Sep 17 18:19:20 mxhost postfix/smtpd[12345]: disconnect from unknown[192.0.2.25] commands=0/0
2025-09-18 08:23:45 +02:00
Sergey G. Brester
6c47bf6461
Merge pull request #4068 from billfor/xarf
fix `dig` to filter out warnings and prevent them from being injected as emails
2025-09-15 17:23:32 +02:00
sebres
9534bdac37 filter.d/nginx-http-auth.conf: filter rewritten and extended:
- with `prefregex` to capture content of error only (bypass common prefix and suffix, like server, request, host, referrer);
  - to match PAM authentication failures (gh-4071)
2025-09-15 16:14:22 +02:00
Sergey G. Brester
a8875c36b8
Merge pull request #4070 from yizhao1/fix
clientreadertestcase.py: set correct config dir for testReadStockJailFilterComplete
2025-09-12 14:51:14 +02:00
Yi Zhao
9f26da3cf8 clientreadertestcase.py: set correct config dir for testReadStockJailFilterComplete
In test case testReadStockJailFilterComplete, set configuration
directory to CONFIG_DIR (/etc/fail2ban/filter.d on the target) instead
of the hardcoded "config" directory. Otherwise, the config files will
not be found during runtime testing.

Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
2025-09-12 12:53:45 +08:00
sebres
5beee494a3 allow to overwrite conditional parameters only direct from jail, for example
`banaction = iptables-ipset[blocktype="...", blocktype?family=inet6="..."]`
2025-09-11 23:11:45 +02:00
sebres
3fd3454146 if parameter supplied to the config, overwrite also conditional init options (from init?... section) 2025-09-11 19:39:06 +02:00
sebres
ce8cc5d261 test illustrating the issue with blocktype="DROP" for IPv6 chain (supplying init parameter to action doesn't overwrite the value in conditional section) 2025-09-11 16:44:06 +02:00
Sergey G. Brester
4539e6719c
Update ChangeLog 2025-09-10 20:19:34 +02:00
Sergey G. Brester
85cfb81782
lets see an error (with debug messages) in debug case 2025-09-10 20:04:10 +02:00
bill
3d23a44bb1 fix dig to filter out warnings from email address capture 2025-09-10 13:27:30 -04:00
Sergey G. Brester
77efe3b40c
Merge pull request #4020 from billfor/sendmail
Update sendmail-reject.conf
2025-09-02 19:46:57 +02:00
sebres
26b91862fc introduces a parameter mta_dname (default \S+) to allow more complex REs to match custom MTA daemon names (e.g. with spaces etc) 2025-09-02 19:41:40 +02:00
sebres
10b12e8c57 reorder 2 tests belonging together 2025-09-02 19:11:05 +02:00
sebres
13876e93ad fixes the inconsistency with F-MLFID ("ID" matched by (?:\w{14,20}: )? is optional in message); simplify PR 2025-09-02 19:11:04 +02:00
bill
70d7fd0fdd update the test for lost input channel with real ip 2025-09-02 12:54:42 -04:00
bill
9e72e78f34 filter.d/sendmail-reject.conf: support BSD log format. match user unknown messages. add aggressive mode for lost input channel and relaying denied messages 2025-09-01 22:34:53 -04:00
sebres
912e3c81a2 removes mistaken return in quiet case for set jail attempt command 2025-09-01 20:12:07 +02:00
sebres
c54d505dea small amend (info with date pattern before debug message with regex) 2025-09-01 18:10:43 +02:00
sebres
6ac181f559 improve logging of date pattern (count of default templates added, info if it's filtered or used pre-match) 2025-09-01 18:03:09 +02:00
sebres
52399e6ef1 amend to #2351: providing the attempt via fail2bans protocol (Pickle, client command, etc) must follow ignore facilities (shall be ignored if matches ignoreip, ignoreself, ignorecommand etc) 2025-08-26 18:03:46 +02:00
sebres
c9e1a1b087 silence warning "Unknown distribution option: 'test_suite'", seems not work anymore (2.x only?) - test suite shall be invoked using bin/fail2ban-testcases 2025-08-23 22:22:20 +02:00
sebres
a055568500 GHA: update python 3.14.0-rc.2 2025-08-23 22:10:55 +02:00
sebres
0265df854e silence skipping tests output for python versions that basically can not have the modules 2025-08-23 22:00:03 +02:00
sebres
a3d181c973 filter.d/dovecot.conf: new matches in aggressive mode:
- new variant for `no auth attempts in X secs` with `Login aborted` and `(no_auth_attempts)`;
- covered `disconnected during TLS handshake` with `no application protocol` and `no shared cipher`.
2025-08-23 20:22:08 +02:00
sebres
002719dca4 ChangeLog update 2025-08-23 20:18:59 +02:00
sebres
c26fda9dbb filter.d/dovecot.conf: new matches in aggressive mode:
- new variant for `no auth attempts in X secs` with `Login aborted` and `(no_auth_attempts)`;
- covered `disconnected during TLS handshake` with `no application protocol` and `no shared cipher`.
2025-08-23 20:16:40 +02:00
sebres
bdb5d99906 Log Repeal Ban instead of Unban on stop action, jail or fail2ban, because the tickets are "unbanned" temporary (till restart);
closes gh-4057
2025-08-19 11:37:01 +02:00
sebres
4e22c20559 fixes ignoreip prefix file:// - it shall resolve absolute file name (starting with /) unless it starts with ./;
relative paths are based relative the working dir;
to use it relative current config root (normally `/etc/fail2ban`), one can use interpolation `%(fail2ban_confpath)s`, e.g.:
  file://%(fail2ban_confpath)s/ignore-ipaddr-file
2025-08-12 23:46:10 +02:00
sebres
3ce6f344e3 fixes beautifier get ignoreip (explicit convert to string) 2025-08-12 23:26:42 +02:00
Sergey G. Brester
bf4903538d
update ChangeLog (enhancement from #3291) 2025-08-08 10:29:02 +02:00
Sergey G. Brester
77ba28bae1
Merge pull request #3291 from ttyS4/patch-1
nftables.conf - add support for cidr notation and address ranges
2025-08-08 10:23:08 +02:00
Sergey G. Brester
dc3268ce5d
servertestcase.py: adjust test coverage 2025-08-08 10:16:01 +02:00
Sergey G. Brester
eb80b895d1
provides flags interval as addr_options now 2025-08-08 10:10:40 +02:00
Bill
6120a731d9
update nginx limit-req filter again (#4048)
amend to #4047 - removes unused ngx_limit_con_zones parameter.
2025-08-04 21:16:26 +02:00
Sergey G. Brester
e16e982a45
Merge pull request #4047 from billfor/nginx
Update nginx-limit-req filter (extended to ban hosts failed by limit connection in ngx_http_limit_conn_module);
closes gh-3674
2025-08-04 11:34:35 +02:00
Sergey G. Brester
dd58d440bc
Update ChangeLog 2025-08-04 11:32:10 +02:00
Sergey G. Brester
e6516fd2b3
combine 2 REs to single regex
closes gh-3674
2025-08-04 11:24:51 +02:00
bill
0a91bf69a5 add filter for delayed requests and connection limiting 2025-08-04 00:27:45 -04:00
sebres
d86a7aecca amend to #3979: removed mistaken double pipes in group matches 2025-07-31 17:38:28 +02:00
sebres
ff3eca1d61 * Merge pull request #3527 from vafgoettlich/master
(partial merge, only postfix-backend)
2025-07-24 11:17:05 +02:00
sebres
0b255a8723 Merge pull request #3527 from vafgoettlich/master
(partial merge, only postfix-backend)
2025-07-24 11:14:03 +02:00
Sergey G. Brester
793d0c6555
Merge pull request #4037 from kusaka-0107/fix/asterisk-conf-regex
filter.d/asterisk: fix regex to match "No matching endpoint found" with retry info (like `after X tries in Y ms`)
2025-07-20 15:17:17 +02:00
Sergey G. Brester
7bb86822d0
Update ChangeLog 2025-07-20 15:15:38 +02:00
Sergey G. Brester
6d3bfa8781
revert RE back, but relive the end-anchor a bit (ignore any text without single quote, so also preventing false match by injection on foreign data) 2025-07-20 15:04:15 +02:00
177ac
b309cf6b3c Add test line 2025-07-20 18:06:33 +09:00
177ac
e97df4672a filter.d/asterisk: fix regex to match "No matching endpoint found" with retry info 2025-07-20 18:05:35 +09:00
sebres
1c2ace2958 GHA: update python 3.14.0-beta.4 2025-07-13 01:08:50 +02:00
sebres
b710d5b6c7 filter.d/sendmail-reject.conf - also recognize "Domain of sender address ... does not resolve";
closes gh-4035
2025-07-13 01:03:53 +02:00
sebres
dc899e438f avoid error "Unable to get failures" by stop (if file gets removed from filter, but filter already entered getFailures for the file);
closes gh-4032
2025-07-07 01:04:35 +02:00
sebres
86b9adb2f5 workflows/publish.yml: amend (allow manual trigger for publishing) 2025-06-16 22:09:46 +02:00
sebres
85faeab644 workflows/publish.yml: flow to publish package on pypi 2025-06-16 21:55:58 +02:00
Sergey G. Brester
9ef134c17d
Merge pull request #4016 from nabbi/dovecot-2.4
add Dovecot 2.4 support
2025-06-15 18:09:40 +02:00
Sergey G. Brester
8a4f373617
integrate new RE in already existing (combine new and old format) 2025-06-15 18:07:43 +02:00
Nic Boet
646832d5bd dovecot 2.4 into changelog
Signed-off-by: Nic Boet <nic@boet.cc>
2025-06-13 17:00:47 -05:00
Nic Boet
04ff4c060c Dovecot 2.4 filter support
Dovecot 2.4 release is a major upgrade
Logger event structure has changed, all messages are now
prefixed with:

        "Login aborted: " <reason> "auth failed"

Maintain 2.3 support as many folks have yet to migrate,
community edition is still receiving cretial security patches

Dovecot 2.4.1
Python 3.12.10

Signed-off-by: Nic Boet <nic@boet.cc>
2025-06-13 16:44:57 -05:00
Sergey G. Brester
cfa3356e0f
Merge pull request #4001 from sebres/f2b-regex--inverted-out
fail2ban-regex: new feature `-i` or `--invert` to output not-matched lines by `-o` or `--out`
2025-06-03 22:23:19 +02:00
sebres
4254d6bcd3 man and changelog 2025-06-03 22:19:54 +02:00
Sergey G. Brester
afe9bc08ec
Merge pull request #4006 from pzl/smtp-py-wrap
Line-wrap long messages in smtp.py
2025-06-02 12:40:45 +02:00
pzl
a5d7127109
construct smtp.py email wrap long lines
RFC 5322 2.1.1 requires <=998 chars per line.
If matches are included, and are very long lines,
the email will be rejected. Constructing the mail
as a message instead of a subpart (mimetext) fixes this
2025-05-20 14:55:03 -04:00
sebres
cca2de984f fail2ban-regex: implemented new feature -i or --invert - inverting the sense of matching, to output non-matching lines. 2025-05-06 18:15:05 +02:00
Sergey G. Brester
f7aaaf50b8
filter.d/exim.conf: colon must be outside of F-RCPT group 2025-04-27 23:00:09 +02:00
sebres
f0a083449a coverage for non zero journalflags 2025-04-24 00:12:26 +02:00
sebres
9ecf6150c8 increase max wait time a bit - some (systemd) tests may fail occasionally in fast mode 2025-04-24 00:11:45 +02:00
sebres
cbc3cb431c amend to a0093b557e (systemd-review): flags cannot be specified simultaneously with files too; 2025-04-24 00:04:37 +02:00
Sergey G. Brester
d731b385f9
Merge pull request #3909 from avcbvamorec/patch-1
Enhancement on iptables: allow bans to be effective on multiple chains at the same time
2025-04-17 12:46:51 +02:00
Sergey G. Brester
52d239483d
typo 2025-04-16 17:18:36 +02:00
sebres
0d4a926029 ChangeLog (enhancement and compat entries) 2025-04-16 17:13:58 +02:00
sebres
cbe14c70c5 iptables.conf rewritten to affect all derivative actions (multiple chains are also supported by iptables-ipset etc);
iptables-xt_recent-echo.conf adjusted to be compatible to new syntax of inherited iptables.conf;
test coverage fixed to new handling
2025-04-16 16:56:46 +02:00
Arnaud
37f72f88ef Reverting chains to chain in order to preserve backward compatibilityu
backing to the option named "chain", using "iteredchain" a new variable to iterate over.
2025-04-16 16:06:29 +02:00
Arnaud
139151ec81 Update iptables.conf - allow bans to be efective on multiple chains at the same time
This patch allows the ban to be applied on the INPUT and the FORWARD chain at the time. May be useful at least on routing devices and on docker hosting machines.
2025-04-16 16:06:28 +02:00
sebres
c76e90fbb1 * Merge pull request #3940 from exim-pr-mode-more
`filter.d/exim.conf` - fewer REs by default, introduces mode `more`
2025-04-02 15:11:38 +02:00
Sergey G. Brester
6538d43a8e
Update ChangeLog 2025-04-02 14:57:03 +02:00
Sergey G. Brester
bfd80ce522
Merge pull request #3979 from LearningSpot/vaultwarden
Added jail for Vaultwarden
2025-04-02 14:41:38 +02:00
Sergey G. Brester
70ce1cef08
Update ChangeLog 2025-04-02 14:40:04 +02:00
Sergey G. Brester
426eeca62a
fixed times in test-log (test suite working in TZ CET) 2025-04-02 13:52:58 +02:00
Sergey G. Brester
6104444bb4
improve regex (anchored from left, no catch-alls, <ADDR> for IP, etc) 2025-04-01 17:28:58 +02:00
Rajib Sharia
cf9135983c
Update jail.conf
Added jail for vaultwarden
2025-04-01 20:40:15 +08:00
Rajib Sharia
c7f7bc55bb
Create vaultwarden.conf
Filter for unsuccessful Vaultwarden authentication attempts
2025-04-01 20:36:53 +08:00
Rajib Sharia
6b57e46070
Create vaultwarden test log 2025-04-01 20:32:00 +08:00
sebres
fc3e8a5d37 remove help command from protocol (the command was never supported);
closes gh-3241
2025-03-31 02:29:51 +02:00
sebres
1d6ff06856 amend to a0093b557e: filter only readable journal files by retrieving non-rotated files (if user is not root) 2025-03-31 02:28:40 +02:00
sebres
767c89f863 satisfy spellcheck 2025-03-31 01:27:52 +02:00
sebres
a0093b557e Merge branch 'systemd-review'
Large set of fixes and enhancements for `systemd` and `auto` backends:
* fixes `systemd` bug with missing journal descriptor after rotation by reopening of journal if it is recognized as not alive (gh-3929)
* improve threaded clean-up of all filters, new thread functions `afterStop` (to force clean-up after stop) and `done`, invoking `afterStop` once
* ensure journal-reader is always closed (additional prevention against leaks and "too many open files"), thereby avoid sporadic segfault 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 amout of systemd jails (see new parameter `rotated` below, gh-3391);
* backend `systemd` extended with new parameter `rotated` (default `false`, as prevention against "too many open files"),
  that allows to monitor only actual journals and ignore now a lot of rotated files by default; so can drastically reduce
  amount of used file descriptors, normally to 1 or 2 descriptors per jail (gh-3391)
* implements automatic switch `backend = auto` to backend `systemd`, when the following is true (RFE gh-3768):
  - no files matching `logpath` found for this jail;
  - no `systemd_if_nologs = false` is specified for the jail (`true` by default);
  - option `journalmatch` is set for the jail or its filter (otherwise it'd be too heavy to allow all auto-jails,
    even if they have never been foreseen for journal monitoring);
  (option `skip_if_nologs` will be ignored if we could switch backend to `systemd`)
2025-03-31 01:18:53 +02:00
sebres
d5718503ad update changelog and documentation (new features and handling) 2025-03-31 01:13:02 +02:00
sebres
6b56259f9a amend, obtain argument namespace before we'll use it 2025-03-31 01:11:05 +02:00
sebres
b2352f113e implements the feature of automatic switch backend = auto to backend systemd, when:
- no files matching `logpath` found for this jail;
- no `systemd_if_nologs = false` (`true` by default) is specified for the jail;
- option `journalmatch` is set for the jail or its filter (otherwise it'd be too heavy to allow all auto-jails, even if they have never been foreseen for journal);
- option `skip_if_nologs` will be ignored if we could switch backend to `systemd`;
closes gh-3768
2025-03-30 22:31:44 +02:00
sebres
5a2fd9b31c split new test to 2 tests (allows to cover _globJournalFiles even if system-journal is not available) 2025-03-30 20:13:39 +02:00
sebres
4eef68b3d3 backend systemd extended with new parameter rotated (default false, as prevention against "too many open files"), that allows to monitor only actual journals and ignore a lot of rotated files by default; so can drastically reduce amount of used file descriptors (to 1 or 2 per jail);
closes #3391
2025-03-30 19:03:32 +02:00
sebres
7a4985178f amend 2025-03-30 18:59:18 +02:00
sebres
786d5b7e9e test-suite: increase wait-time for fast-mode for long waiting intervals (stability, avoid sporadic errors) 2025-03-30 06:07:17 +02:00
sebres
191d1e9533 improve threaded clean-up of filters, new functions afterStop (to force clean-up after stop) and done, invoking afterStop once; ensure journal-reader is always closed (prevention against "too many open files"), thereby avoid sporadic segfault in systemd module (https://github.com/systemd/python-systemd/issues/143) 2025-03-30 06:04:49 +02:00
sebres
9f0b6382bf idle must be before anything else in loop (to avoid endless errors if something continuously fails and filter will be placed to idle state after 100 unhandled errors) 2025-03-30 06:04:47 +02:00
sebres
f49d50b8fd ensure the reader is really closed before reopen (preventing leaks if some handles or whatever are still open) 2025-03-30 06:04:44 +02:00
sebres
994a0b69da fixes systemd bug with missing journal descriptor after rotation by reopening of journal if it is recognized (it is not alive);
closes gh-3929
2025-03-30 00:53:27 +01:00
Sergey G. Brester
16ae53e888
Update main.yml
GHA: update python, 3.14.0-alpha.6 and pypy3.11
2025-03-28 23:07:27 +01:00
sebres
ee421dfbd6 filter.d/apache-noscript.conf - consider new log-format with "AH02811: stderr from /...";
closes gh-3900
2025-03-28 22:52:51 +01:00
sebres
b0d4eb07e5 command-line: test config shall output error directly and not using logger 2025-03-19 02:44:32 +01:00
sebres
d02a613e89 configreaders: don't swallow return code by decoding error (whole jail or fail2ban config failed to read due to some error like encoding etc), so dump or test of config would get an error at end (and coverage for #3971) 2025-03-19 02:19:16 +01:00
sebres
8ae6eaf39a filter.d/postfix.conf - default _daemon in prefix-line is loosened - can match everything starting with word postfix, like postfix-example.com/smtpd;
closes gh-3297
2025-03-10 22:35:26 +01:00
Sergey G. Brester
505d51fd5d
Update PULL_REQUEST_TEMPLATE.md 2025-03-04 19:19:57 +01:00
sebres
4bb1fd519d test-suite: if failed, sample regexs factory would show responsible header line (failJSON) together with the error line 2025-03-04 14:39:24 +01:00
sebres
cf9c8f1e9b test-suite: fixed sample regexs factory counting of line number (if it errors, the line number showing in error line was incorrect, because of missing increment) 2025-03-04 14:27:21 +01:00
Sergey G. Brester
c035428535
Merge pull request #3954 from luckylittle/feature/systemd-journal-vsftpd
`filter.d/vsftpd.conf` - fixed regex (if failures generated by systemd-journal)
2025-03-04 14:20:01 +01:00
sebres
79346e4f2c updated ChangeLog 2025-03-04 14:15:14 +01:00
sebres
94fe9cf4a8 more fixes, capture user names, more tests...
since line 7 matches successfully now (it was disabled in gh-358 because of obsolete format), it is marked as match:true (line can be removed later if unneeded)
2025-03-04 14:13:07 +01:00
sebres
1e06ab68b4 fixed filter (new regex is unneeded), tests format of failures produced by system journal 2025-03-04 13:47:59 +01:00
Sergey G. Brester
e9a42847bc
Merge pull request #3955 from luckylittle/feature/systemd-journal-lighttpd
`filter.d/lighttpd-auth.conf` - fixed regex (if failures generated by systemd-journal), bypass several prefixes now
2025-03-04 13:21:43 +01:00
Sergey G. Brester
3e9a4b4a48
Update ChangeLog 2025-03-04 13:20:54 +01:00
Sergey G. Brester
95cdf553f5
fixes test in lighttpd-auth: added failJSON to match the line 2025-03-04 13:09:21 +01:00
Sergey G. Brester
13a74feaad
2nd RE unneeded, fix single RE - bypass everything before open parenthesis 2025-03-04 13:02:50 +01:00
Lucian Maly
6e3bfd800c
Added author 2025-03-04 12:26:14 +11:00
Lucian Maly
9d7646e6c0
Added author 2025-03-04 12:25:27 +11:00
Lucian Maly
f5ba525cd2
Added sample log line 2025-03-04 12:22:35 +11:00
Lucian Maly
fd1d0d25a8
Added regex for systemd-journal matches of lighttpd-auth 2025-03-04 12:20:24 +11:00
Lucian Maly
bd4cb606e5
Added sample log line 2025-03-04 11:47:49 +11:00
Lucian Maly
65d473fc8e
Added regex for systemd-journal matches of vsftpd 2025-03-04 11:43:38 +11:00
sebres
e3ab969047 increase interval for up-to-date check (to 1 minute) after error, to avoid continuous flood in log on further possible errors 2025-03-04 00:07:31 +01:00
sebres
9145db8de3 small code review of FileIPAddrSet: encapsulate check for changed logic to _isModified and slightly increase coverage for it (latency, changed, unchanged) 2025-03-03 23:59:36 +01:00
sebres
7233edd0bf amend ChangeLog updated: ignoreip extended with file:... syntax to ignore IPs from file-ip-set;
+ silence codespell
2025-03-03 20:07:05 +01:00
sebres
c54f1a4603 Merge branch 'ignore-file-ip-addr-set':
configuration `ignoreip` and fail2ban-client commands `addignoreip`/`delignoreip` extended with `file:...` syntax to ignore IPs from file-ip-set (containing IP, subnet, dns/fqdn or raw strings);
the file would be read lazy on demand, 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)
2025-03-03 20:00:32 +01:00
sebres
5bea1c87f1 add few comments to test-ign-ips-file for the sake of completeness and coverage 2025-03-03 19:52:23 +01:00
sebres
6efa3a3144 man extended (ignoreip supports file://path/file-with-ip-set) 2025-03-03 19:19:21 +01:00
sebres
fe37047061 test coverage for FileIPAddrSet and ignoreip for file://... 2025-03-03 19:06:08 +01:00
sebres
81a5b1596b filter and configuration ignoreip extended with file:... to ignore IPs from file-ip-set (containing IP, subnet, dns/fqdn or raw strings); the file would be read lazy on demand, by first ban (and automatically reloaded by update after small latency) 2025-03-03 19:03:48 +01:00
sebres
d684339edd allow comments in file with ip-set: text followed # or ; chars after space or newline would be ignored 2025-03-03 19:00:09 +01:00
sebres
bdae15b522 ipdns.py: implemented FileIPAddrSet supporting file with IP-set, what may contain IP, subnet, or dns, with lazy load and dynamically reloaded by changes (with small latency to avoid expensive stats check on every compare) 2025-03-03 18:40:15 +01:00
Sergey G. Brester
c9b5e845ba
action.d/cloudflare-token.conf: fixes actionunban retrieving of CF-ID from IP:
force adding parameters to URL as query string (add `-G` to curl);
closes gh-3952
2025-03-01 20:19:35 +01:00
Sergey G. Brester
e5199aee92
action.d/ufw.conf: update comment:
fix syntax in example, because `dst` as command parameter doesn't have precedence over or-expression, so second `sport` would ignore `dst` and kill any connection for https regardless the IP
2025-03-01 00:23:55 +01:00
sebres
1c61836169 main.yml: merge branch 'gha-try-new-runner':
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13) (push) Has been cancelled
CI / build (3.14.0-alpha.5) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.10) (push) Has been cancelled
- update runner image (20.04 gets end of date)
- update python versions (v.3.7 is unsupported for 24.04, bump v.3.14 to next alpha)
2025-02-25 18:38:19 +01:00
Sergey G. Brester
fdac34a3ee
main.yml: update python versions
v.3.7 is unsupported for 24.04, bump v.3.14 to next alpha
2025-02-25 18:29:26 +01:00
Sergey G. Brester
c340fb0ef4
main.yml: update runner image
(20.04 gets end of date)
2025-02-25 18:24:40 +01:00
Sergey G. Brester
6d4b487eb9
adjust exim-log in the test factory 2025-02-13 21:42:52 +01:00
Sergey G. Brester
c88967df2d
filter.d/exim.conf - introduces mode more (several rules moved from mode normal to more), because:
- they have basically nothing with authentication;
- they can cause false positives (e. g. someone sends several mails from google mailing server to wrong recipients and if they would cause "rejected RCPT - Unknown user", the google host gets banned;
- to avoid occasional ban of legitimate servers one'd need create large white-list for `ignoreip` or construct complex `ignorecommands` to exclude all legitimate servers of big players (like google, microsoft, GMX, etc);
2025-02-13 21:30:04 +01:00
sebres
882e6d5e00 filter.d/exim.conf - mode aggressive extended to catch dropped by ACL failures, e.g. "ACL: Country is banned"
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13) (push) Has been cancelled
CI / build (3.14.0-alpha.4) (push) Has been cancelled
CI / build (3.7) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.10) (push) Has been cancelled
2025-02-10 17:30:07 +01:00
Sergey G. Brester
2d736ad755 small amend
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13) (push) Has been cancelled
CI / build (3.14.0-alpha.4) (push) Has been cancelled
CI / build (3.7) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.10) (push) Has been cancelled
2025-01-31 19:54:24 +01:00
Sergey G. Brester
a44c8dc3ec
Update FILTERS: clarify and improve docu, update some urls, etc
(related #3934)
2025-01-31 19:51:29 +01:00
Sergey G. Brester
6fb3532c45
Merge pull request #3931 from brianjmurrell/patch-2
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13) (push) Has been cancelled
CI / build (3.14.0-alpha.4) (push) Has been cancelled
CI / build (3.7) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.10) (push) Has been cancelled
`from '[^']*'` is not always present …
2025-01-30 14:06:00 +01:00
sebres
a1268f37c3 amend (move ChangeLog entry) 2025-01-30 14:04:00 +01:00
sebres
b55c20594e paths-common.conf: changed default mysql_log path (default logpath of mysqld-auth jail without maintainer overrides); adjusted comments (log_error_verbosity = 3 instead of log-warnings = 2)
closes gh-3932
2025-01-30 14:00:43 +01:00
Sergey G. Brester
6d3308ecb4
Merge pull request #2702 from pburndorfer/master
New openvpn jail
2025-01-30 13:16:44 +01:00
Brian J. Murrell
b8ab346257
Merge branch 'fail2ban:master' into patch-2 2025-01-29 19:36:54 -05:00
sebres
d2c60a168f combine several regexes to single RE 2025-01-30 01:13:49 +01:00
sebres
e1fc569291 normalize jail (defaults, etc); added missing tests for all REs; common prefix for failregex, no catch-alls, etc 2025-01-30 01:13:48 +01:00
Philipp Burndorfer
95710e9dac Adapted changelog. 2025-01-30 01:13:47 +01:00
Philipp Burndorfer
88385eb6c1 New openvpn jail. 2025-01-30 01:13:46 +01:00
sebres
7a5e2c8419 Merge branch 'example-com-ips': fixed test-suite (adjusted fqdn/ips, codespell)
Some checks are pending
Codespell / Check for spelling errors (push) Waiting to run
CI / build (3.10) (push) Waiting to run
CI / build (3.11) (push) Waiting to run
CI / build (3.12) (push) Waiting to run
CI / build (3.13) (push) Waiting to run
CI / build (3.14.0-alpha.4) (push) Waiting to run
CI / build (3.7) (push) Waiting to run
CI / build (3.8) (push) Waiting to run
CI / build (3.9) (push) Waiting to run
CI / build (pypy3.10) (push) Waiting to run
2025-01-30 01:12:37 +01:00
sebres
8c6d7dc12f GHA main.yml: update python versions ('3.14.0-alpha.4') 2025-01-30 01:09:20 +01:00
sebres
5b6c13f0aa example.com changes the IPs, again... additionally it got more IPs, which look unstable now (depends on resolver), so replaced with fail2ban.org, that seems to resolve to single IPv4 and IPv6 (can be adjusted later for something more persistent) 2025-01-30 01:05:30 +01:00
sebres
155a0855f2 silence codespell 2025-01-29 21:59:35 +01:00
Brian J. Murrell
eb1fc5b261
Add test line
Signed-off-by: Brian J. Murrell <brian@interlinx.bc.ca>
2025-01-28 13:22:04 -05:00
Brian J. Murrell
325613a8f8
from '[^']*' is not always present …
In the message from asterisk.

Signed-off-by: Brian J. Murrell <brian@interlinx.bc.ca>
2025-01-28 13:09:29 -05:00
sebres
9dde3d019e typo, shall be negative lookbehind ignoring escaped open parenthesis, like \(?iu)
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13.0) (push) Has been cancelled
CI / build (3.14.0-alpha.1) (push) Has been cancelled
CI / build (3.7) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.10) (push) Has been cancelled
2024-12-29 20:27:03 +01:00
sebres
a796cc9b91 filter.d/dropbear.conf: failregex extended to match different format of "Exit before auth" message;
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13.0) (push) Has been cancelled
CI / build (3.14.0-alpha.1) (push) Has been cancelled
CI / build (3.7) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.10) (push) Has been cancelled
closes gh-3791
2024-12-27 16:43:33 +01:00
Sergey G. Brester
4b6f69a14a
Merge pull request #3597 from MichaIng/patch-1
Fix Dropbear filter when logging to STDOUT
2024-12-27 16:16:34 +01:00
MichaIng
eb8b44370a
Make Dropbear regex more compatible and simpler
Dropbear uses `strftime` `"%b %d %H:%M:%S` to print its timestamps, hence we know the day and time format, but the month could be localized. We hence allow any 3 word characters for it, and additionally simplify the day and time pattern into a single group.

Signed-off-by: MichaIng <micha@dietpi.com>
2024-12-27 14:00:36 +07:00
Sergey G. Brester
b7b1fff53c
Update ChangeLog 2024-12-27 14:00:35 +07:00
Sergey G. Brester
62aeb55b63
dropbear test: added description 2024-12-27 13:59:36 +07:00
MichaIng
dd9f359f5c
Fix Dropbear filter when logging to STDOUT
Since Debian Bookworm, the distribution ships Dropbear with a native systemd service instead of the default upstream init.d service, and accordingly uses the `-F` and `-E` flags, to run it in foreground and have it logging to STDOUT instead of syslog.

As usual, timestamps and also the PID are now included by the log message emitted by Dropbear, in addition to the systemd journal log prefix.

The Dropbear filter hence does not match anymore. This commit adds the PID and timestamp as optional pattern between prefix and fail log text, to support Dropbear on Debian Bookworm and newer (and likely new versions of other distros) without breaking the old pattern when running Dropbear without `-E` flag.

Additionally, for performance reasons, this commit adds a `journalmatch` entry, matching Debian's and Fedora's `dropbear.service` with `dropbear` executable/identifier, the most likely match for a Dropbear systemd service.

Signed-off-by: MichaIng <micha@dietpi.com>
2024-12-27 13:59:35 +07:00
sebres
89b5f3bb1e filter.d/sshd.conf: ddos and aggressive modes, regex extended for timeout before authentication (optional connection from part);
Some checks are pending
Codespell / Check for spelling errors (push) Waiting to run
CI / build (3.10) (push) Waiting to run
CI / build (3.11) (push) Waiting to run
CI / build (3.12) (push) Waiting to run
CI / build (3.13.0) (push) Waiting to run
CI / build (3.14.0-alpha.1) (push) Waiting to run
CI / build (3.7) (push) Waiting to run
CI / build (3.8) (push) Waiting to run
CI / build (3.9) (push) Waiting to run
CI / build (pypy3.10) (push) Waiting to run
closes gh-3907
2024-12-26 14:24:15 +01:00
Sergey G. Brester
51358e1587
Merge pull request #3636 from szepeviktor/typos
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13.0) (push) Has been cancelled
CI / build (3.14.0-alpha.1) (push) Has been cancelled
CI / build (3.7) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.10) (push) Has been cancelled
Fix more typos
2024-12-21 19:31:54 +01:00
Jesús Cea
d89ded39b0 Trivial typo in "jail.conf.5" 2024-12-21 19:28:55 +01:00
Sergey G. Brester
b6aebc333c
Merge pull request #3903 from pano9000/docs_status-flavor
Some checks are pending
Codespell / Check for spelling errors (push) Waiting to run
CI / build (3.10) (push) Waiting to run
CI / build (3.11) (push) Waiting to run
CI / build (3.12) (push) Waiting to run
CI / build (3.13.0) (push) Waiting to run
CI / build (3.14.0-alpha.1) (push) Waiting to run
CI / build (3.7) (push) Waiting to run
CI / build (3.8) (push) Waiting to run
CI / build (3.9) (push) Waiting to run
CI / build (pypy3.10) (push) Waiting to run
docs: explicitly list supported status flavors
2024-12-21 18:43:32 +01:00
Panagiotis Papadopoulos
d38f233e91 docs: explicitly list status flavors 2024-12-20 08:42:19 +01:00
Sergey G. Brester
a6ca6e2a26
Merge pull request #3897 from pano9000/master
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
CI / build (3.10) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.12) (push) Has been cancelled
CI / build (3.13.0) (push) Has been cancelled
CI / build (3.14.0-alpha.1) (push) Has been cancelled
CI / build (3.7) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled
CI / build (pypy3.10) (push) Has been cancelled
docs: Remove outdated link to sourcecodebrowser
2024-12-16 13:09:23 +01:00
Panagiotis Papadopoulos
a57a768cb8 docs: Remove outdated link to sourcecodebrowser 2024-12-14 02:04:15 +01:00
sebres
4151eeccfe fixes mistaken usage of ignoreregex from filter, if ignoreregex is supplied with command line;
also avoid after-effect with "IndexError: list index out of range" from onIgnoreRegex (the lists of REs are different in filter and fail2banregex);
closes gh-3895
2024-12-11 21:55:20 +01:00
sebres
91c27d0600 filter.d/freeswitch.conf: bypass some new info in prefix before [WARNING] (changed default _pref_line);
closes gh-3143
2024-12-04 16:56:23 +01:00
sebres
12ff98027f GHA main.yml: update python versions ('3.13.0', '3.14.0-alpha.1') 2024-11-07 19:32:31 +01:00
sebres
eb4731d8b1 action.d/*-ipset.conf: workaround sporadic failures by stop if destroying ipset too fast (sleep a bit in error case and repeat);
closes gh-3624
2024-11-07 19:28:53 +01:00
sebres
0bf1106d72 manually added attempts inform the observer module (take the known ban-count of bad IPs into account);
closes gh-3845
2024-10-08 13:34:19 +02:00
Sergey G. Brester
89970d2e3e
Merge pull request #1351 from AntagonistHQ/csf
add support for the CSF firewall
2024-09-29 10:01:58 +02:00
Sergey G. Brester
363c0d5fd0
nftables.conf: fixed comment (since 7f1b578af4, gh-488 actioncheck would be never invoked in regular case) 2024-09-07 13:15:45 +02:00
Sergey G. Brester
1ea8a6de58
Merge pull request #3826 from thomas-333/patch-1
Update apprise.conf: typo
2024-09-02 11:32:05 +02:00
thomas-333
44bd87951e
Update apprise.conf
Correct typo. "as" should read "has"
2024-09-02 10:17:10 +01:00
Sergey G. Brester
3361fb0805
Merge pull request #3823 from orlitzky/after-nftables
files/fail2ban-openrc.init.in: start after nftables
2024-08-25 00:28:25 +02:00
Michael Orlitzky
9e31cfc1f1 files/fail2ban-openrc.init.in: start after nftables
The "after iptables" clause in the OpenRC service script's depend()
function causes fail2ban to start after iptables, if iptables is
scheduled to start. Here we add "after nftables" as well: nftables is
the successor to iptables, and fail2ban supports it out-of-the-box.
If nftables is scheduled to start, we want to wait until it's done
before starting fail2ban.
2024-08-24 11:59:59 -04:00
Sergey G. Brester
be734991eb
main.yml: update python versions ('3.13.0-rc.1', '3.14.0-alpha.0') 2024-08-23 20:20:55 +02:00
Sergey G. Brester
fda37fac81
main.yml: update actions/setup-python to v5 2024-08-23 20:15:55 +02:00
sebres
47e995cb57 Merge branch 'gh-2756': new jail option skip_if_nologs to ignore jail if no logpath matches found, fail2ban continue to start with warnings/errors, thus other jails become running 2024-08-23 20:05:46 +02:00
sebres
2950e41186 man/jail.conf.5: docu for skip_if_nologs 2024-08-23 15:22:00 +02:00
sebres
78af48862f new jail option skip_if_nologs to ignore jail if no logpath matches found, fail2ban continue to start with warnings/errors, thus other jails become running;
closes gh-2756
2024-08-23 12:16:08 +02:00
sebres
54c0effceb filter.d/sshd.conf: amend to #3747/#3812 (new ssh version would log with _COMM=sshd-session) 2024-08-11 12:10:12 +02:00
sebres
c769046a1f Revert "filterd./sshd.conf: fixed journalmatch (sshd.service seems to be renamed to ssh.service)" - it'd patched in debian branch.
This reverts commit 6fce23e7ba.
2024-08-11 11:55:39 +02:00
Sergey G. Brester
a43f7ad63f
Merge pull request #3816 from Skamasle/patch-1
Fix roundcube login failregex for roundcube 1.4+
2024-08-10 13:26:54 +02:00
sebres
2749109f10 ChangeLog 2024-08-10 13:23:28 +02:00
sebres
8e0a2366f0 Fixes unmatched tag (caused unmatched brace); review: combined to single regex, simple case without injection attempts faster, <HOST> replaced with <ADDR> (faster and fewer vulnerable on complex cases, since doesn't match text as hostname) etc. 2024-08-10 13:20:18 +02:00
Maksim Usmanov | Maks
af119e0ae1
roundcube 1.4+ logs 2024-08-09 23:22:43 +02:00
Maksim Usmanov | Maks
35afe20ea0
Roundcube 1.4 change log format
From roundcube 1.4 log change format -> e92d8e31a3/program/lib/Roundcube/rcube_imap.php (L194)
2024-08-09 22:53:45 +02:00
sebres
d4663e8941 action.d/firewallcmd-rich-*.conf: fixed incorrect quoting, disabling port variable expansion by substitution of rich rule; closes gh-3815 2024-08-07 22:43:42 +02:00
sebres
216f0abb5e Merge pull request #2966 from Derecho-com/master
Add support to Proxmox Web GUI
2024-07-30 19:25:33 +02:00
sebres
4a87802c59 ChangeLog 2024-07-30 19:19:24 +02:00
sebres
9a558589d7 review (anchoring RE, etc) 2024-07-30 19:16:40 +02:00
Jose
db8c943a7b Add jail to jail.conf as requested by test-suite 'More filters exists than are referenced in stock jail.conf set(['proxmox']) 2024-07-30 19:11:02 +02:00
Jose
83f2d59eee match numbers 2024-07-30 19:05:56 +02:00
Jose
07a7da8d8e Remove greedy catch-all before HOST 2024-07-30 19:05:55 +02:00
Jose
4fb04842a2 add log file for tests 2024-07-30 19:05:54 +02:00
Jose
ca45671db2 Add support to Proxmox Web GUI 2024-07-30 19:04:00 +02:00
Sergey G. Brester
7fd097d73f
Merge pull request #3805 from nabbi/postfix-3.9
tests for Postfix 3.9 SASL reason unavailable
2024-07-28 20:39:29 +02:00
sebres
93810fff75 consider CONNECT and other rejected commands as a valid _pref;
closes gh-3800
2024-07-26 19:25:36 +02:00
Nic Boet
a4f1b0ce9f tests for Postfix 3.9 SASL reason unavailable
SASL auth failure message changed with Postfix 3.9
Include addtional test log

17dbfb9b8b

Signed-off-by: Nic Boet <nic@boet.cc>
2024-07-25 13:57:46 -05:00
Sergey G. Brester
766d2b8d74
Update FUNDING.yml: added my liberapay 2024-07-16 13:47:28 +02:00
sebres
8170e9fe75 suppress SetuptoolsDeprecationWarning in test suite 2024-07-04 19:06:36 +02:00
Sergey G. Brester
599ec5e01e
main.yml: bump version 3.13.0-beta.3 2024-07-04 18:53:01 +02:00
Sergey G. Brester
7004d175b7
Merge pull request #3782 from fdellwing/patch-1
Adjust sshd.conf filter for OpenSSH 9.8
2024-07-03 19:43:04 +02:00
Sergey G. Brester
216622adb2
Update ChangeLog 2024-07-03 19:42:19 +02:00
Sergey G. Brester
50ff131a0f
filter.d/sshd.conf: ungroup (unneeded for _daemon) 2024-07-03 19:35:28 +02:00
Sergey G. Brester
8360776ce1
zzz-sshd-obsolete-multiline.conf: adjusted to new sshd-session log format 2024-07-03 19:33:39 +02:00
Sergey G. Brester
7b335f47ea
sshd: add test coverage for new format, gh-3782 2024-07-03 19:09:28 +02:00
Fabian Dellwing
2fed408c05 Adjust sshd filter for OpenSSH 9.8 new daemon name 2024-07-02 08:51:51 +02:00
sebres
59c5e78ce9 filter.d/apache-overflows.conf - consider AH10244: invalid URI path;
closes gh-3778
2024-06-28 12:50:14 +02:00
sebres
a7f3a04b0e filter.d/recidive.conf - restore possibility to set jail name in the filter, _jailname is positive now (but by default it uses now negative lookahead to exclude recidive jail);
closes gh-3769
2024-06-21 13:24:46 +02:00
sebres
ab9d41e530 beautifier detect whether it can use unicode chars in stats table; asciified output of beautifier in test suite;
closes gh-3750
2024-06-14 15:17:53 +02:00
Sergey G. Brester
6fce23e7ba
filterd./sshd.conf: fixed journalmatch (sshd.service seems to be renamed to ssh.service)
closes gh-3747
2024-06-10 01:40:59 +02:00
sebres
8ae5e7e3e4 GHA: update python version in CI-flow (3.13 is beta now) 2024-06-10 00:10:25 +02:00
sebres
cd95c3a1fc Merge branch 'ipsettype-in-ipset-actions' 2024-06-09 23:41:56 +02:00
sebres
2533526827 extend ipset actions with new parameter ipsettype for the type of set (gh-3760), affected actions:
`action.d/firewallcmd-ipset.conf`, `action.d/iptables-ipset.conf`, `action.d/shorewall-ipset-proto6.conf`
2024-06-09 23:38:58 +02:00
sebres
17daf0ec78 action.d/firewallcmd-ipset.conf: rename ipsettype to ipsetbackend (ipsettype will be used now to the real set type);
amend to #2620
2024-06-09 23:32:03 +02:00
sebres
304c3cd566 improve fix with fallback to local async libraries - add path to compat folder (pyinotify module may have dependency to asyncore module, see https://github.com/fail2ban/fail2ban/issues/3487#issuecomment-2133529081);
amend to 054e1d89ca
2024-05-27 16:18:26 +02:00
sebres
7d2fffbe19 .codespellrc: silence codespell flow on assertIn 2024-05-27 15:38:32 +02:00
sebres
8bbdb7b5a7 GHA: output current preferred encoding of fail2ban 2024-05-27 15:32:17 +02:00
Sergey G. Brester
246a617cd6
Merge pull request #3749 from by/patch-1
abuseipdb.conf: update link
2024-05-21 13:24:32 +02:00
by
21bf636056
Update abuseipdb.conf
Corrected link for HP helper (see https://shaunc.com/blog/article/reporting-to-abuseipdb.com-with-fail2ban~kDoa-Hml95wW)
2024-05-20 15:34:24 +02:00
Sergey G. Brester
65e9c411ef
README.md: typos
closes gh-3746
2024-05-14 11:46:49 +02:00
sebres
ecb9771123 GHA: 3.13.0-alpha.6 2024-05-07 13:26:11 +02:00
Sergey G. Brester
4da56cf4bc
Update README.md
distutils support removed
2024-05-07 13:18:08 +02:00
Sergey G. Brester
ac62658c10
Merge pull request #3728 from branchvincent/distutils
distutils removal
2024-05-07 13:14:57 +02:00
sebres
0185e1c7d5 setup.py: no distutils anymore 2024-05-07 13:06:50 +02:00
sebres
ed20a9a5b9 there is no systemd < 204 and pyinotify < 0.8.3 for supported python3 versions anymore 2024-05-07 12:53:54 +02:00
sebres
c04e12dd8d Merge remote-tracking branch 'remotes/gh-upstream/0.11' 2024-04-29 11:03:33 +02:00
Sergey G. Brester
1434e3089c
Merge pull request #2455 from Thermi/improved-action-blocklist-de
Improved blocklist_de action to not resend bans that were already reported
2024-04-28 21:12:49 +02:00
Branch Vincent
a763fbbdfd
replace distutils for python 3.12 2024-04-27 10:24:01 -07:00
sebres
d0d0728523 cherry-pick from debian: debian default banactions are nftables, systemd backend for sshd
closes gh-3292
2024-04-26 02:26:55 +02:00
sebres
c14327565d version bump 2024-04-26 02:06:09 +02:00
sebres
61799e15e1 release 1.1.0 -- object-found--norad-59479-cospar-2024-069a--altitude-36267km 2024-04-25 23:08:13 +02:00
sebres
22ffe12abb preparing release 2024-04-25 22:43:51 +02:00
sebres
7b528a6da6 example.com seemed to switch its IPs, replace them everywhere (and use test IP-range instead where it is possible) 2024-04-24 19:30:48 +02:00
sebres
3ca3646472 implemented fail2ban-client stats (or alias fail2ban-client statistic[s]) for tabulated output of fail2ban stats
amend to #2975
2024-04-24 18:49:59 +02:00
sebres
bdba42edd9 implemented fail2ban-client status --all [flavor]
closes #2975
2024-04-24 16:29:49 +02:00
sebres
921d9a5a40 Merge branch 'gh-2655--f2b-regex-4-jail': implemented loading of jail settings in fail2ban-regex;
amend to RFE gh-2655
2024-04-02 18:04:52 +02:00
sebres
3b97182f62 amend to 781321d609: better regex to detect jail name (it could contain dot etc) 2024-04-02 18:02:07 +02:00
Sergey G. Brester
b59fd2e7b5
Merge pull request #3697 from remontti/patch-1
named-refused.conf: denied allows any reason in parenthesis as suffix
2024-03-25 16:41:11 +01:00
sebres
44f32d6132 changelog 2024-03-25 16:36:21 +01:00
sebres
2c13cba73d loosening for denied suffix (would match no matter which reason in parenthesis);
add coverage for denied with "(allow-query-cache did not match)"
2024-03-25 16:35:20 +01:00
Rudimar Remontti
fd7657f9a9 Update named-refused.conf 2024-03-25 16:35:16 +01:00
sebres
4550e3ad27 ChangeLog: reorder (filters after actions) 2024-03-25 16:34:12 +01:00
sebres
a4ca2e83bd Merge branch 'gh-3060': adjusted filter.d/exim.conf and filter.d/exim-spam.conf:
- messages are prefiltered by `prefregex` now
- filter can bypass additional timestamp or pid that may be logged via systemd-journal or syslog-ng (gh-3060)
closes #3060
2024-03-25 15:56:10 +01:00
sebres
1ec9237e53 bypass additional pid in prefix (may be logged by syslog-ng, gh-3060); matches protocol error with authentication mechanism not supported 2024-03-25 15:52:06 +01:00
sebres
c80908837f filter.d/exim.conf:
- messages are prefiltered by `prefregex` now
  - filter can bypass additional timestamp that may be logged via systemd-journal (gh-3060)
2024-03-25 15:31:23 +01:00
Sergey G. Brester
e0f1a1e02a
Merge pull request #3702 from bes-internal/exim
exim: final `<HOST>` to `<ADDR>` conversion
2024-03-22 22:52:11 +01:00
Vladimir Varlamov
8da0a99cde pid part may contain full hostname 2024-03-22 22:38:33 +03:00
Vladimir Varlamov
806a27cb4f final <HOST> to <ADDR> conversion 2024-03-22 22:38:33 +03:00
Sergey G. Brester
5ecc26d3ba
Merge pull request #3701 from bes-internal/exim
filter.d/exim.conf: rewrite host line regex for all varied exim's log_selector states
2024-03-22 16:52:33 +01:00
sebres
e605415f61 simplify fields-group a bit (everything up to 4 chars long but H), so it'll be faster (no multiple branches) as well as would theoretically accept future enhancements of logged fields. 2024-03-22 16:47:54 +01:00
sebres
c22a83933b let's use <ADDR> instead <HOST> - only IPs expected, since host-name bypassed before it (directly after H=) 2024-03-22 16:35:46 +01:00
Vladimir Varlamov
df94ec4c52 filter.d/exim.conf: rewrite host line regex for all varied exim's log_selector states
Depending on Exim's log_selector settings, log lines may contain additional information about the connection. And also the line itself with the address of the remote host can vary greatly. But fortunately, all states can be found in the Exim code itself and taken into account. Makes it easier to add new regexps.
Closes #3263
2024-03-22 00:16:41 +03:00
Anton Samets
0c125ec9c9
filter.d/postfix.conf: add Sender address rejected: Malformed DNS server reply (#3590)
* add Sender address rejected: Malformed DNS server reply
2024-03-19 20:30:45 +01:00
sebres
77b052fdea amend to df9584505aea0e8570fb53dd5a8e43f8b3af994a (for gh-3487): setup must install fail2ban.compat 2024-03-18 14:22:39 +01:00
sebres
5a59b0bae2 filter.d/apache-common.conf: accepts remote instead of client
(closes gh-3622)
2024-03-15 22:40:26 +01:00
Sergey G. Brester
f63868b3e8
filter.d/apache-common.conf: remote besides client, gh-3622 2024-03-15 22:36:40 +01:00
Sergey G. Brester
9ca137b42b
test for apache-auth with remote, gh-3622 2024-03-15 22:23:45 +01:00
Sergey G. Brester
529eb79ddb
Merge pull request #3692 from pingou2712/postfixSystemd
Change journalmatch postfix
2024-03-13 02:34:03 +01:00
Vincent Laffargue
d260ed31d2 Maintain backward compatibility Postfix SYSTEMD_UNIT 2024-03-12 04:42:36 +01:00
Sergey G. Brester
8be16f1c1c
Merge pull request #3693 from pingou2712/ModifRecidive
Change Regex Recidive and journalmatch For Systemd Match
2024-03-11 19:12:16 +01:00
Sergey G. Brester
f12917c491
recidive: test case for journal log-format 2024-03-11 17:50:09 +01:00
Sergey G. Brester
dd3c78ecab
filter.d/recidive.conf: conditional RE depending on logtype (for file or journal) 2024-03-11 17:49:06 +01:00
Vincent Laffargue
0b63fc312d Change Regex Recidive and journalmatch For Systemd Match 2024-03-10 10:56:35 +01:00
Vincent Laffargue
93082ead79 Change journalmatch postfix 2024-03-10 10:10:03 +01:00
Sergey G. Brester
383adec83c
Merge pull request #3690 from karolyi/master
Add to postfix accepted logs
2024-03-08 14:45:53 +01:00
Sergey G. Brester
45d7f3cb97
no space in any case 2024-03-08 11:43:46 +01:00
László Károlyi
ff701e94c3
Add to postfix syslog daemon format 2024-03-07 20:23:50 +01:00
sebres
3047572701 set restored mark on ticket before ignore invocation (it can be checked in ignorecommand, considered by ignorecache, etc) 2024-03-01 12:49:59 +01:00
sebres
dce2c608c1 Merge branch 'gh-3486'
filter.d/sshd.conf: ddos/aggressive mode extended to match new messages caused by port scanner, wrong payload on ssh port:
  - message authentication code incorrect [preauth]
  - connection corrupted [preauth]
  - timeout before authentication
2024-02-13 16:59:08 +01:00
sebres
4f679a56e0 filter.d/sshd.conf: ddos/aggressive mode extended to match new messages caused by port scanner, wrong payload on ssh port:
- message authentication code incorrect [preauth]
  - connection corrupted [preauth]
  - timeout before authentication
closes gh-3486
2024-02-13 16:53:21 +01:00
sebres
9bedc3c383 Merge branch 'gh-2655--f2b-regex-4-jail': implemented loading of jail settings in fail2ban-regex;
closes gh-2655
2024-01-03 13:43:44 +01:00
sebres
302252b25c ChangeLog, gh-2655 2024-01-03 13:38:14 +01:00
sebres
cab6f93364 fail2ban-regex: fixes forgotten basedir (-c "$basedir") of jailreader 2024-01-03 13:18:33 +01:00
sebres
b3178851fe test coverage (restore usage with filter and load setting from jail) 2023-12-31 17:03:38 +01:00
sebres
781321d609 fail2ban-regex: loading parsing settings from jail now (by simple name it'd prefer jail to the filter now), fallback:
- fail2ban-regex ... sshd
  + fail2ban-regex ... filter.d/sshd
closes gh-2655
2023-12-31 16:38:18 +01:00
sebres
7de1057f94 avoid DNS of local names in fast tests (small optimization) 2023-12-31 12:48:22 +01:00
sebres
dd4431cd63 remove remaining tweaks for obsolete python 2023-12-31 12:45:24 +01:00
Sergey G. Brester
e1b7720d43
Merge pull request #3268 from Logic-32/feature/smtp-ssl
`action.d/smtp.py` - add support for TLS SMTP connections.
2023-12-30 21:56:01 +01:00
sebres
0c2edfacb0 combine smtpd and aiosmtpd tests; encapsulate smtp facilities to setUpClass/tearDownClass (behaves like a singleton, doesn't start smtp server per test); don't generate cert every time (too slow by RSA:2048, use short ECC:256 instead);
drastically speedup all smtp-action tests
2023-12-30 21:27:35 +01:00
Logic-32
b161e55ca7 Adding STARTTLS test with the help of aiosmtp. Make sure SMTP specifies host/port in addition to connect() due to bug with starttls. 2023-12-30 16:42:31 +01:00
Sergey G. Brester
6fb3198a41 attempt to fix action for 2.x
self.host cannot be supplied to SMTP because it can contain port (but `connect` takes place few lines below)
2023-12-30 16:42:27 +01:00
Logic-32
6a1da5e164 Removing logging in favor of just throwing. Removing user from message as it doesn't add any value. 2023-12-30 16:42:23 +01:00
Logic-32
419e380870 Add support for TLS SMTP connections. 2023-12-30 16:42:18 +01:00
sebres
6fb89d1709 testIPToName: switch from google to one of the root-servers (8.8.4.4 seems not to have rDNS anymore) 2023-12-30 15:49:44 +01:00
sebres
3190febb27 IPv6 fix (second IP logged in form for IPv6); pam authentication failure (part of gh-3410) 2023-12-30 15:10:37 +01:00
sebres
c6244a8509 fail2ban-regex: don't error by output if stdout pipe gets closed (e. g. using together with head);
amend to gh-2758 (see gh-3653)
2023-12-22 14:08:39 +01:00
sebres
7523a777f0 amend for python 3.x switch: BrokenPipeError is a build-in exception since 3.3 2023-12-22 14:05:04 +01:00
sebres
093cd763ce filter.d/postfix.conf: "rejected" extended to match "Access denied" too;
closes gh-3474
2023-12-15 01:03:30 +01:00
sebres
ff4a2a12fc filter.d/postfix.conf: avoid double counting ('lost connection after AUTH' together with message 'disconnect ...');
closes gh-3505
2023-12-15 00:32:48 +01:00
sebres
cabcc9b3f4 fixes testRepairDb for sqlite >= 3.42;
closes gh-3586
2023-12-15 00:07:43 +01:00
sebres
f2d7f16d2f satisfy CI spelling (let's use original asyncore lib as long as possible) 2023-12-12 15:41:40 +01:00
sebres
1024452fe1 Merge fix-gh-3487: bundling async modules removed in python 3.12 into f2b (fallback to local libraries if import would miss them);
closes gh-3487
2023-12-12 15:35:39 +01:00
sebres
86cacca9e4 pyasyncore and pyasynchat optional for python 3.12+ (bundled-in within fail2ban) 2023-12-12 15:30:41 +01:00
sebres
1371c91512 don't install async* modules, we need to cover bundled-in libraries and their successful import 2023-12-12 15:23:10 +01:00
sebres
054e1d89ca bundling async modules removed in python 3.12 into f2b (fallback to local libraries if import would miss them);
closes gh-3487
2023-12-12 15:16:05 +01:00
sebres
8d6bfd89bf Merge test-3.13: python 3.13 support, see gh-3487 2023-12-12 14:40:46 +01:00
sebres
7e88c9be8d more compat issues (Logger.warn -> Logger.warning) 2023-12-12 14:27:24 +01:00
sebres
337a519cb2 python3.13 support - unittest.makeSuite is removed in 3.13 2023-12-12 14:21:11 +01:00
Sergey G. Brester
e3b36756c0
main.yml: test python 3.13 2023-12-12 14:13:39 +01:00
Sergey G. Brester
36c890f15b
main.yml: restore test systemd/journal for python >= 3.10 2023-12-12 13:45:11 +01:00
sebres
4e326cb5cb Merge python-3.12--asyncore: python 3.12 support, see gh-3487 2023-12-12 13:40:11 +01:00
sebres
340d45ca88 amend to 70aef2c3c6: py3.12: silence warnings "invalid escape sequence" 2023-12-12 13:37:56 +01:00
sebres
26597f625d revert heavydebug logging for 3.12 in GHA 2023-12-12 13:31:04 +01:00
sebres
f1efea6a4f py3.12: install setuptools (packaged now) 2023-12-12 12:54:55 +01:00
sebres
f966d88ce5 verbose output for 3.12 2023-12-11 21:50:56 +01:00
sebres
ef208e9149 py3.12: ignore smtpd based tests (if no smtpd module) 2023-12-11 21:45:34 +01:00
sebres
70aef2c3c6 py3.12: silence warnings "invalid escape sequence" 2023-12-11 21:26:55 +01:00
sebres
572582137c try to use pip-modules asyncore/asynchat 2023-12-11 19:51:49 +01:00
Sergey G. Brester
7076af637f
main.yml: bump pypy to latest stock version (3.10, because 3.9 seems to have sporadic timing issues anyway) 2023-12-10 16:24:02 +01:00
Sergey G. Brester
5277e91013
Merge pull request #3503 from repcsi/pf_allproto
BSD Pf allproto actiontype to block all communication from source on IP level
2023-12-10 16:11:05 +01:00
Sergey G. Brester
c03afd3ad4
servertestcase.py: adjusted, protocol is variable now 2023-12-10 16:09:32 +01:00
sebres
e03df4805f Merge branch 'fix-gh-3646': nginx error-log filters extended with support of journal format; closes gh-3646 2023-12-10 15:43:21 +01:00
sebres
7c83669700 update main CI flow to new version of GHA (silence deprecated warnings, etc) 2023-12-10 15:41:03 +01:00
Sergey G. Brester
b71ed9e472
GHA: pypy seems need exact version now 2023-12-10 15:36:44 +01:00
Sergey G. Brester
9554279129
CI/main.yml: try to silence warning about deprecated node usage (switch to newer actions version) 2023-12-10 15:30:38 +01:00
sebres
0abba5dc6e more filters for nginx error-log supporting journal format now, added generalized include and __prefix_line 2023-12-10 15:21:20 +01:00
sebres
b245225b13 filter.d/nginx-http-auth.conf: added optional prefix to support systemd-journal format and additional timestamp (optionally) in prefix 2023-12-10 14:39:21 +01:00
repcsi
199759f0ba added pf[protocol=all] options as recommended by sebres 2023-12-10 11:20:39 +01:00
Viktor Szépe
70e964c062
Exclude .typos.toml in codespellrc 2023-11-26 18:16:42 +01:00
sebres
44fa2959e7 fixes gh-3635: avoid sporadic error in pyinotify backend if pending file deleted in other thread; restore correct logging in tests 2023-11-22 20:16:53 +01:00
sebres
5d9817728d fixes multi-threaded issue on __pending dict (caused due to missing lock on __pending dict);
an entry can be deleted by `_delPending` with 1st thread, while 2nd thread in filter doing `_checkPending` where it still got this key in iterator, but later fails in the cycle because `__pending[path]` may be deleted by 1st thread in-between;
closes #3635
2023-11-22 20:05:02 +01:00
sebres
4d603f9726 added missing inherited tearDown invocation 2023-11-22 20:01:31 +01:00
sebres
cdb6607261 remove double call of inherited setup in test cases;
previously caused that after that no restore of log-handler takes place in `tearDown` later, so after that tests it remains by `LogCaptureTestCase._MemHandler`, so every future logged message disappear in nirvana;
partially fixes #3635
2023-11-22 20:00:50 +01:00
Viktor Szépe
6bfc23b868 Remove false positive in logs 2023-11-22 17:14:57 +00:00
Viktor Szépe
44bd1f09fa Add Typos configuration 2023-11-22 16:32:38 +00:00
Viktor Szépe
1427625528 Fix more typos 2023-11-22 16:32:05 +00:00
Yaroslav Halchenko
22ce0c0536
Merge pull request #3630 from yarikoptic/enh-codespell
Add codespell: workflow, config and fix typos it finds
2023-11-22 10:53:48 -05:00
Sergey G. Brester
9fc754ceea
Merge pull request #3633 from brunobell/patch-1
Update Arch Linux package URL in RELEASE
2023-11-22 12:57:55 +01:00
Dash Lu
0e27811818 Update Arch Linux package URL in RELEASE 2023-11-21 23:05:54 +08:00
Yaroslav Halchenko
8ef0d3c7a9 [DATALAD RUNCMD] run codespell throughout fixing typo automagically
=== Do not change lines below ===
{
 "chain": [],
 "cmd": "codespell -w",
 "exit": 0,
 "extra_inputs": [],
 "inputs": [],
 "outputs": [],
 "pwd": "."
}
^^^ Do not change lines above ^^^
2023-11-18 10:04:04 -05:00
Yaroslav Halchenko
81b2eb32d6 Add pragma to ignore a codespell-detected typoin postfix.conf 2023-11-18 10:03:50 -05:00
Yaroslav Halchenko
5e9060a613 Add skipping of codespell-ignore annotated lines 2023-11-18 09:56:18 -05:00
Yaroslav Halchenko
b3bcd0a0f2 Filter substition -> substitution
I think it is just a filter for testing so should be safe to rename
2023-11-18 09:55:24 -05:00
Yaroslav Halchenko
e2ede1a43e Further adjust regex since apparently \b would not match at the beginning of e.g. [Uu]ser 2023-11-18 09:55:24 -05:00
Yaroslav Halchenko
dcb0177d96 Ignore URLs and few other specific things, group better in regex 2023-11-16 11:07:47 -05:00
Yaroslav Halchenko
e96ecf78c1 [DATALAD RUNCMD] Do interactive fixing of some ambigous typos
=== Do not change lines below ===
{
 "chain": [],
 "cmd": "codespell -w -i 3 -C 2 ./files/fail2ban-openrc.conf ./fail2ban/tests/fail2banclienttestcase.py",
 "exit": 0,
 "extra_inputs": [],
 "inputs": [],
 "outputs": [],
 "pwd": "."
}
^^^ Do not change lines above ^^^
2023-11-16 10:59:16 -05:00
Yaroslav Halchenko
3b3fcde2e6 Some ignores for codespell 2023-11-16 10:58:39 -05:00
Yaroslav Halchenko
698cba5708 Remove .project for Eclipse added originally by Cyril but IMHO never used since never tuned 2023-11-16 10:55:20 -05:00
Yaroslav Halchenko
4b4c728558 Add rudimentary codespell config 2023-11-16 10:42:20 -05:00
Yaroslav Halchenko
e20bd9402b Add github action to codespell master on push and PRs 2023-11-16 10:42:20 -05:00
Sergey G. Brester
eed319e896
gh-3604: filter.d/slapd.conf - switched to single-line processing
closes gh-3604
2023-10-18 16:06:56 +02:00
Sergey G. Brester
132c719386
Merge pull request #3603 from alexdrupal/patch-1
mysqld-auth: no suffix in message (mariadb 10.3 log format)
2023-10-16 12:05:42 +02:00
Sergey G. Brester
183f805ae3
amend 2023-10-16 11:41:05 +02:00
Sergey G. Brester
7931b67325
mysqld-auth.conf: better RE, optional suffix, non-capturing groups 2023-10-16 11:35:53 +02:00
Aliaksandr Yurchyk
162f0c4b6c
Update mysqld-auth test file 2023-10-16 01:45:43 +03:00
Aliaksandr Yurchyk
c55e9949dc
Fix issue with Mariadb 10.3 failed message 2023-10-16 01:35:15 +03:00
Sergey G. Brester
8eac5f597a
Merge pull request #3579 from stweil/travis
Remove Travis CI (no longer working)
2023-09-25 12:43:56 +02:00
Stefan Weil
cd2ba0a3ba Remove Travis CI (no longer working)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
2023-09-24 20:12:19 +02:00
Sergey G. Brester
f8f8c046a2
Merge pull request #3469 from vitkabele/routeros-auth
New filter: routeros-auth.conf
2023-09-02 18:56:04 +02:00
sebres
35af8b6d5d fixes DNS resolve related tests on systems without IPv6 support (considering that --no-network simulate resolving example.com via cache) 2023-08-23 16:30:42 +02:00
sebres
f8622c6f92 fixes IPAddr.searchIP for IPv6 (IPv4 group scanning plain IPv6 is None) 2023-08-23 16:30:39 +02:00
Sergey G. Brester
db3b410a60
Merge pull request #3564 from nodiscc/ipset-maxelem-argument
action.d/*ipset*: make maxelem ipset option configurable through banaction arguments
2023-08-23 12:41:19 +02:00
Sergey G. Brester
f7ee023661
ChangeLog: gh-3564 2023-08-23 12:38:12 +02:00
nodiscc
77f80e8c3f
action.d/*ipset*: make maxelem ipset option configurable through banaction arguments
- previously there was no way to override this value and ipsets would stop being updated when full (Hash is full, cannot add more elements)
- preserve ipset's default value of 65536
- update tests
- Closes #3549
2023-08-23 12:19:07 +02:00
sebres
bbca81f34c splitwords (used by ignoreip etc) considers now any kind of space as valid separator (also tabs) besides comma;
closes gh-3562
2023-08-22 14:06:04 +02:00
Sergey G. Brester
bcaf1e714e
Merge pull request #3557 from neofright/neofright-patch-1
Update FILTERS
2023-08-15 12:18:08 +02:00
neofright
6afaf35263
Update FILTERS 2023-08-14 20:23:26 +00:00
Sergey G. Brester
3e6a60f940
Merge pull request #3539 from Strykar/patch-1
Make ignorecommand help clearer
2023-07-14 00:00:22 +02:00
Sergey G. Brester
76f6bc81bc
small amend restore groff format (\f escape sequence) 2023-07-13 23:59:28 +02:00
Avinash H. Duduskar
c38f6654f7
Make ignorecommand help clearer 2023-07-14 00:51:43 +05:30
Sergey G. Brester
48c91dfb6b
Merge pull request #3532 from lade-odoo/master-restore_bans_with_full_ticket_info-lade
Restore bans from the database with full ticket information
2023-06-22 13:38:53 +02:00
Sergey G. Brester
7bfa133208
small amend: lets use lower level API for restored tickets too 2023-06-22 13:36:18 +02:00
Laurent Desausoi
3546071aa5 Restore bans from the database with full ticket information
In the case where we use the `ignoreCommand` with information from the
ticket, we want these informations to also be included when restoring
the bans from the database (the ticket may no longer be required to be
banned).
2023-06-22 09:50:43 +02:00
sebres
226a59445a merge branch gh-2690--mig2to3 : fail2ban is python 3.x based now;
closes gh-2690
2023-06-16 17:02:27 +02:00
sebres
9c5f6eea76 version bump (master / 1.1 is python 3.x based now) 2023-06-16 16:59:22 +02:00
sebres
99ff701678 remove support of python 2.x 2023-06-16 16:29:08 +02:00
sebres
03d7c92ae8 2to3 2023-06-16 15:23:41 +02:00
sebres
e2c4982417 Merge branch 'fix-gh-3485', filter.d/sshd.conf:
- avoid double counting for "maximum authentication attempts exceeded" (gh-3502)
  - message "Disconnecting ... Too many authentication failures" is not a failure anymore
2023-06-13 18:58:47 +02:00
sebres
101d6923e3 ChangeLog (gh-3485) 2023-06-13 18:57:05 +02:00
sebres
eebef0089c avoid double counting for "maximum authentication attempts exceeded" ("Disconnecting ..." is no failure anymore, now it's helper only);
closes gh-3485
2023-06-13 18:49:26 +02:00
Ulrich Goettlich
7d6b1a4c3b Fixed startup on debian bookworm (using systemd as sshd_backend) 2023-06-13 09:00:38 +02:00
Sergey G. Brester
66e195b0f3
jail.conf: comment only (time abbr format), no function changes
closes gh-3522
2023-06-10 14:15:52 +02:00
Sergey G. Brester
8e97474586
Merge pull request #3517 from seaniedan/patch-1
Update README.md: added reference to wiki/How-to-install-fail2ban-packages
2023-06-01 16:58:58 +02:00
Sean Danischevsky
5cd4c5a29f
Update README.md
added link to wiki page install instructions
2023-06-01 09:47:53 +01:00
Sean Danischevsky
217f404b22
Update README.md
add install instructions for popular linux distributions
2023-05-31 23:13:48 +01:00
Sergey G. Brester
fb8a93b40f
Merge pull request #3514 from ulm/gentoo-url
Update URLs for Gentoo
2023-05-27 13:15:00 +02:00
Ulrich Müller
50cbc7e8dd
Update URLs for Gentoo
Gentoo moved from CVS to Git in 2015.

Drop the Gentoo URL from fail2ban-logrotate, because the distro
specific config file has been dropped in 2013.
2023-05-21 10:47:52 +02:00
Sergey G. Brester
5d9603c104
failregex.py: resolve deprecation warning for sre_constants
closes gh-3508
2023-05-03 12:00:24 +02:00
Sergey G. Brester
baf8330214
GHA: update python-versions, 3.11 is released 2023-05-03 11:55:00 +02:00
sebres
ca4af85cd7 avoid confusion of path as failure ID with IP/CIDR notation, improve IP/CIDR parsing;
wrong CIDR notation or invalid plen always causes a fallback to raw string now;
fixes recognition of `::` and `::/32`
2023-04-26 17:10:39 +02:00
Sergey G. Brester
de0ed85fb8
README.md: code status - switch from travis-ci to GHA 2023-04-24 23:10:47 +02:00
Sergey G. Brester
871101c3c1
Merge pull request #3502 from fail2ban/gh-3497
filter.d/exim.conf: fixes "dropped: too many ..." regex (also matches unrecognized commands)
2023-04-24 22:59:00 +02:00
Sergey G. Brester
3c8d5fd4ef
Update ChangeLog 2023-04-24 17:11:04 +02:00
Sergey G. Brester
809b904106
filter.d/exim.conf: fixes "dropped: too many ..." regex and also matches unrecognized commands new vector 2023-04-24 15:40:53 +02:00
Sergey G. Brester
7544e969d5
new test messages for exim (gh-3497) 2023-04-24 15:36:21 +02:00
Sergey G. Brester
2b98f461bb
Merge pull request #2860 from a16bitsysop/mikrotik
Add action for mikrotik routerOS
2023-04-13 19:10:30 +02:00
Sergey G. Brester
e73748c442
Merge branch 'master' into mikrotik 2023-04-13 19:09:00 +02:00
Sergey G. Brester
27294c4b9e
fail2banregextestcase: compatibility fix for testWrongRE 2023-04-04 13:30:12 +02:00
sebres
56485c8548 filtertestcase.py: byte related copy of lines in tests (locale independent); closes gh-2936 2023-04-04 12:48:12 +02:00
Sergey G. Brester
a9b30eb86e
Merge pull request #2226 from mbologna/nginx-forbidden
Feat: ban nginx forbidden accesses
2023-03-23 12:33:32 +01:00
Sergey G. Brester
9cbf59c827
anchored datepattern and added journalmatch (if monitoring systemd journal) 2023-03-23 12:16:13 +01:00
Sergey G. Brester
212a4c236a
update changeLog, nginx-forbidden, gh-2226 2023-03-23 12:12:55 +01:00
Sergey G. Brester
2c0360d178
Merge branch 'master' into nginx-forbidden 2023-03-23 12:01:50 +01:00
sebres
d1d1730de0 Merge fix #3479:
action.d/cloudflare-token.conf: url-encode args by unban
closes 'gh-3479'
2023-03-15 15:14:43 +01:00
Sergey G. Brester
3d4bed50c2
changelog entry (gh-3479) 2023-03-15 15:08:45 +01:00
Sergey G. Brester
c7f8b75e7e
action.d/cloudflare-token.conf: fixes #3479, url-encode args by unban 2023-03-15 15:03:48 +01:00
Duncan Bellamy
7dc32971f8 changed missed names 2023-03-08 12:16:35 +00:00
Duncan Bellamy
9b1417a169 apply suggestions 2023-03-08 09:29:03 +00:00
Duncan Bellamy
b892133d51 move new comment in changelog 2023-03-08 09:20:51 +00:00
Sergey G. Brester
d46ec3a555 add jail boundary to flush command for more precise targeting of jail (if some name may be equal to prefix of other name) 2023-03-08 09:17:13 +00:00
Duncan Bellamy
5781675a7d change startcomment and comment so correct rules are flushed 2023-03-08 09:17:13 +00:00
Duncan Bellamy
ac2076ef4f change unban back to find comment so correct entry always deleted 2023-03-08 09:17:13 +00:00
Duncan Bellamy
0e3e9b1d7f Add flushaction
Change unban to find by ip address not comment
2023-03-08 09:17:13 +00:00
Duncan Bellamy
9997807fb3 Add action for mikrotik routerOS 2023-03-08 09:17:13 +00:00
Vít Kabele
a2c77429b9 New filter: routeros-auth.conf (Closes #3469)
Add filter to detect failed login attempts in the log produced by
MikroTik RouterOS.

- Add the filter to jail.conf
- Add testcase for the filter

Signed-off-by: Vít Kabele <vit@kabele.me>
2023-03-02 09:25:24 +01:00
Sergey G. Brester
234660e94d
CI-workflow: remove 3.5 (seems to have a bug in GHA now) 2023-02-28 11:39:00 +01:00
Sergey G. Brester
17f060526e
readme: amend 2023-02-28 11:36:34 +01:00
Sergey G. Brester
92fae68071
readme: update version 2023-02-28 11:32:28 +01:00
Sergey G. Brester
06e3dea062
Merge pull request #3460 from Trotyl84/patch-1
.gitignore: ignore `.venv/`
2023-02-20 08:42:53 +01:00
Łukasz Turon
5dcbc0dd55
Update .gitignore
Please add this entry for virtual python interpreter. This directory name is needed in the PyCharm environment.
2023-02-18 23:49:28 +01:00
sebres
f93a538693 gh-3447: fix careless mistake arisen in b12a3acb06 by attempt to implement new reload capacity (rewritten latter): causing error "'noduplicates' is not defined" by double jail configuration 2023-01-17 12:53:39 +01:00
sebres
a3a3fffa54 Merge branch 'fix-gh-3438':
* circumvent SEGFAULT in a python's socket module by getaddrinfo with disabled IPv6 (gh-3438)
* improve auto-detection of IPv6 support (`allowipv6 = auto` by default)
* improve `ignoreself` by considering all local addresses from network interfaces additionally to IPs from hostnames (gh-3132)
2023-01-11 18:41:15 +01:00
sebres
ed135b6a93 changelog entries (gh-3438, gh-3132) 2023-01-11 18:30:37 +01:00
sebres
582436aadf don't add subnets to local addresses of ignoreself from network interfaces, use only IPs instead (subnets may be too heavy and not wanted, todo: make it configurable later) 2023-01-11 18:27:44 +01:00
sebres
cb8674e68a amend with few improvements, IPv6IsAllowed prefers IPs from network interfaces (if available for platform) and uses DNS (socket.getaddrinfo) as a fallback only 2023-01-10 12:20:48 +01:00
sebres
09c23fd5b8 try to obtain local addresses from network interfaces before DNS to IP lookup (closes gh-3132);
DNSUtils.getSelfIP returns IPAddrSet now (because own IPs may be the subnets now, so the check `ignoreself` must check whether any of subnets contains the IP)
2023-01-09 21:52:12 +01:00
sebres
d8a9812adc improve auto detection of IPv6 - try to check sysctl net.ipv6.conf.all.disable_ipv6 (prefer value read from /proc/sys/net/ipv6/conf/all/disable_ipv6) 2023-01-09 16:21:36 +01:00
sebres
58834b6734 better auto-detection for IPv6 support (allowipv6 = auto by default); circumvent SF in some python's socket module by getaddrinfo with disabled IPv6 (closes gh-3438) 2023-01-06 14:50:25 +01:00
Sergey G. Brester
432e7e1e93
no warning if no config value but default (debug message now)
closes #3420
2022-11-28 13:21:15 +01:00
Sergey G. Brester
bd6e7aeff0
Merge pull request #2112 from al42and/dante
Create filter for Dante SOCKS server
2022-11-18 12:43:44 +01:00
Sergey G. Brester
efbbcb41ea
non capturing group 2022-11-18 12:32:15 +01:00
Sergey G. Brester
996553f330
review, simplify regex and capture user name 2022-11-18 12:31:11 +01:00
Andrey Alekseenko
df91b047d2 Dante SOCKS server: handle "1 byte/second" case
Thanks to @Loriowar and @sebres for pointing it out
2022-11-17 23:22:56 +01:00
Andrey Alekseenko
05c162ef10 Create filter for Dante SOCKS server 2022-11-17 23:22:55 +01:00
Sergey G. Brester
ae5fe2e003
amend to #3405, eliminate catch-all 2022-11-15 14:29:59 +01:00
sebres
36af3f2502 Merge branch 'gh-3405' 2022-11-15 14:23:28 +01:00
sebres
a58fcb8786 fix cut out of match for pattern with {EPOCH} (similar to other datepatterns group capturing whole regex only added if no groups specified at all);
allows to specify more precise anchored patterns, for example `datepattern = ^type=\S+ msg=audit\(({EPOCH})` for selinux-filters
2022-11-14 19:28:18 +01:00
sebres
cbb097a2b3 small amend (non capturing group) 2022-11-14 18:56:01 +01:00
sebres
82506f0586 filter.d/selinux-ssh.conf, filter.d/selinux-common.conf: fixes #3405 (new format with GS and additional parameters, e. g. grantors) 2022-11-14 18:51:06 +01:00
sebres
eba33d6205 version bump 2022-11-14 18:13:01 +01:00
sebres
e1d3006b03 update 1.0.2 -- finally-war-game-test-tape-not-a-nuclear-alarm 2022-11-09 16:46:15 +01:00
sebres
fd3805b40a changelog: backend systemd: code review and several fixes 2022-11-08 19:26:23 +01:00
sebres
cd17906afe Merge branch '0.11' 2022-11-08 19:03:01 +01:00
sebres
d8e2b03a24 filter.d/named-refused.conf extended (closes gh-3388):
- support BIND named log categories
  - allow `info:` as possible error prefix too ("query (cache) denied" may occur as info)
2022-11-03 11:41:21 +01:00
sebres
6d19d2e800 Merge branch '0.10' into 0.11 2022-11-02 21:06:46 +01:00
sebres
04c252c34b filtersystemd: code review, wait only if it is necessary - in operational mode and if no more entries retrieved (end of journal);
attempt to fix gh-3396 - ensure we give enough time after journal.wait returns with INVALIDATE (due to rotation, vacuuming or journal files added/removed etc) and move cursor back and forth to avoid entering dead space
2022-11-02 21:05:18 +01:00
sebres
ca2b94c522 fixes gh-3370: resolve extremely long search by repeated apply of non-greedy RE (?:: (?:[^\(]+|\w+\([^\)]*\))+)? with following branches (it may be extremely slow up to infinite search depending on message); added new regression tests
amend to gh-3210: fixes regression and matches new format in aggressive mode too
2022-10-04 14:10:45 +02:00
sebres
fc7dbcc6a7 test-suite: avoid mistaken match that confuses output with working on line message by deep debugging of test (e. g. with -l 4) 2022-09-28 15:37:52 +02:00
sebres
f8fcaf943b version bump 2022-09-27 22:57:50 +02:00
Csillag Tamas
05575de1f1
nftables.conf - add support for cidr notation
Currently when trying to add an address like: 141.98.11.0/24 it fails with:

fail2ban.utils          [720]: ERROR   7fe8c36f6630 -- exec: nft add element inet f2b-table addr-set-custom \{ 141.98.11.0/24 \}
fail2ban.utils          [720]: ERROR   7fe8c36f6630 -- stderr: "Error: You must add 'flags interval' to your set declaration if you want to add prefix elements"

After adding 'flags interval' one can ban ranges now as expected.
2022-05-30 14:05:18 +02:00
evanlinde
5a0224ff0e
Use potentially faster regex for username match 2022-04-08 09:52:52 -05:00
evanlinde
64983ecc29
Make added date pattern specific to xrdp's format 2022-04-08 09:48:35 -05:00
Sergey G. Brester
6a2d2aa97a
capture user, add datepattern (anchored exact main format and fail2ban defaults) 2022-04-08 09:55:44 +02:00
Evan Linde
11768a97e9 add filter for xrdp 2022-04-07 21:34:33 -05:00
Evan Linde
2224b3db4a extend date regex to include xrdp's %Y%m%d-%H:%M:%S format 2022-04-07 20:51:20 -05:00
Arto Jantunen
f376da4bec Set StateDirectory
This automatically handles permissions for /var/lib/fail2ban when run as a
non-root user.
2020-10-02 16:18:24 +03:00
Arto Jantunen
60b136333e Use RuntimeDirectory to create /run/fail2ban
Instead of the duplicated tmpfiles + ExecStartPre. This way the lifetime of
that directory becomes fixed, and also User is automatically respected for
the ownership of the directory (making it easy to run fail2ban as a
non-root user, like it was with at least the Debian init script).
2020-10-02 16:18:22 +03:00
Arto Jantunen
3359845242 Stop setting PIDFile, useless when Type=simple
This has been unneeded since commit 528a7a5ab which converted this from
Type=forking to Type=simple.
2020-10-02 16:17:34 +03:00
Sergey G. Brester
846b3316db
amend, remove NL 2019-06-29 12:04:02 +02:00
Sergey G. Brester
4ae00485b0
revert acktionban back, use norestored option 2019-06-29 12:03:01 +02:00
Noel Kuntze
9327218843
Improved blocklist_de action to not resend bans that were already reported 2019-06-29 01:39:38 +02:00
Michele Bologna
7e88ae0ee6 Feat: add forbidden to jail.conf 2018-09-14 23:08:12 +02:00
Michele Bologna
1fb7ffe759 Feat: ban nginx forbidden accesses
If you have configured nginx to forbid some paths in your webserver, e.g.:

    location ~ /\. {
      deny all;
    }

if a client tries to access https://yoursite/.user.ini then you will see
in nginx error log:

    2018/09/14 19:03:05 [error] 2035#2035: *9134 access forbidden by rule, client: 10.20.30.40, server: www.example.net, request: "GET /.user.ini HTTP/1.1", host: "www.example.net", referrer: "https://www.example.net"

By carefully setting this filter we ban every IP that tries too many times to
access forbidden resources.

Author: Michele Bologna https://www.michelebologna.net/
2018-09-14 22:21:24 +02:00
Sander Hoentjen
38d3f01a51 add support for the CSF firewall 2016-03-08 13:58:03 +01:00
203 changed files with 5219 additions and 2019 deletions

12
.codespellrc Normal file
View file

@ -0,0 +1,12 @@
[codespell]
# THANKS - names
skip = .git,*.pdf,*.svg,venv,.codespellrc,.typos.toml,THANKS,*test*.log,logs
check-hidden = true
# Ignore all acronyms etc as plenty e.g. in fail2ban/server/strptime.py
# Try to identify incomplete words which are part of a regex, hence having [] at the beginning
# Ignore all urls as something with :// in it
# Ignore all lines with codespell-ignore in them for pragma annotation
ignore-regex = (\b([A-Z][A-Z][A-Z]+|gir\.st)\b)|\[[a-zA-Z]+\][a-z]+\b|[a-z]+://\S+|.*codespell-ignore.*
# some oddly named variables, some names, etc
# wee -- comes in regex etc for weeks
ignore-words-list = assertIn,theis,timere,alls,wee,wight,ans,re-use,pre-emptive

3
.github/FUNDING.yml vendored
View file

@ -1,4 +1,5 @@
# These are supported funding model platforms
github: [sebres]
custom: [paypal.me/sebres]
custom: [https://paypal.me/sebres]
liberapay: sebres

View file

@ -1,12 +1,10 @@
Before submitting your PR, please review the following checklist:
- [ ] **CHOOSE CORRECT BRANCH**: if filing a bugfix/enhancement
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
- [ ] **LIST ISSUES** this PR resolves or describe the approach in detail
- [ ] **MAKE SURE** this PR doesn't break existing tests
- [ ] **KEEP PR small** so it could be easily reviewed.
- [ ] **KEEP PR small** so it could be easily reviewed
- [ ] **AVOID** making unnecessary stylistic changes in unrelated code
- [ ] **ACCOMPANY** each new `failregex` for filter `X` with sample log lines
within `fail2ban/tests/files/logs/X` file
(and `# failJSON`) within `fail2ban/tests/files/logs/X` file
- [ ] **PROVIDE ChangeLog** entry describing the pull request

22
.github/workflows/codespell.yml vendored Normal file
View file

@ -0,0 +1,22 @@
---
name: Codespell
on:
push:
branches: [master]
pull_request:
branches: [master]
permissions:
contents: read
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Codespell
uses: codespell-project/actions-codespell@v2

View file

@ -19,18 +19,18 @@ 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
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11.0-beta.3', pypy2, pypy3]
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:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
@ -51,27 +51,35 @@ jobs:
- 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
#if [[ "$F2B_PY" = 3 ]]; then python -m pip install --upgrade pip || echo "can't upgrade pip"; 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 sqlite3 || echo 'sqlite3 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:
# readline if available as module:
python -c 'import readline' 2> /dev/null || python -m pip install readline || echo 'readline not available'
# asyncore/asynchat:
if dpkg --compare-versions "$F2B_PYV" ge 3.12; then
#sudo apt-get -y install python${F2B_PY/2/}-setuptools || echo 'setuptools not unavailable'
python -m pip install setuptools || echo "can't install setuptools"
# don't install async* modules, we need to cover bundled-in libraries:
#python -m pip install pyasynchat || echo "can't install pyasynchat";
#python -m pip install pyasyncore || echo "can't install pyasyncore";
fi
# aiosmtpd in test_smtp (for 3.10+, no need to test it everywhere):
if dpkg --compare-versions "$F2B_PYV" ge 3.10; then
#sudo apt-get -y install python${F2B_PY/2/}-aiosmtpd || echo 'aiosmtpd not available'
python -m pip install aiosmtpd || echo 'aiosmtpd not available'
fi
- 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))'
echo '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'
@ -80,14 +88,8 @@ jobs:
- 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
#python setup.py test
python bin/fail2ban-testcases --verbosity=2
#- name: Test suite (debug some systemd tests only)
#run: python bin/fail2ban-testcases --verbosity=2 "[sS]ystemd|[jJ]ournal"

32
.github/workflows/publish.yml vendored Normal file
View file

@ -0,0 +1,32 @@
name: Upload Package to PyPI
on:
workflow_dispatch:
release:
types: [created]
jobs:
pypi-publish:
name: Publish release to PyPI
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/fail2ban
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip || echo "can't upgrade pip"
pip install setuptools wheel || echo "can't install/update setuptools or wheel"
- name: Build package
run: |
# python -m build ...
python setup.py sdist bdist_wheel
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

1
.gitignore vendored
View file

@ -10,3 +10,4 @@ htmlcov
__pycache__
.vagrant/
.idea/
.venv/

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>fail2ban-unstable</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

View file

@ -1,82 +0,0 @@
# vim ft=yaml
# travis-ci.org definition for Fail2Ban build
# https://travis-ci.org/fail2ban/fail2ban/
#os: linux
language: python
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
- if [[ $TRAVIS_PYTHON_VERSION == 3* || $TRAVIS_PYTHON_VERSION == pypy3* ]]; then export F2B_PY=3; fi
- echo "Set F2B_PY=$F2B_PY"
- travis_retry sudo apt-get update -qq
# Set this so sudo executes the correct python binary
# Anything not using sudo will already have the correct environment
- export VENV_BIN="$VIRTUAL_ENV/bin" && echo "VENV_BIN set to $VENV_BIN"
install:
# Install Python packages / dependencies
# coverage
- travis_retry pip install coverage
# 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 || 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/) || echo 'not installed'; fi
# 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
# Coverage doesn't pick up setup.py test with python3, so run it directly (with same verbosity as from setup)
- if [[ "$F2B_PY" = 3 ]]; then coverage run bin/fail2ban-testcases --verbosity=2; fi
# 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 (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:
- if [[ "$F2B_COV" = 1 ]]; then coveralls; fi
- codecov
# Might be worth looking into
#notifications:
# email: true
# irc:
# channels: "irc.freenode.org#fail2ban"
# template:
# - "%{repository}@%{branch}: %{message} (%{build_url})"
# on_success: change
# on_failure: change
# skip_join: true

35
.typos.toml Normal file
View file

@ -0,0 +1,35 @@
[files]
extend-exclude = [
".git/",
".codespellrc",
"fail2ban/tests/files/logs/",
]
ignore-hidden = false
[default]
extend-ignore-re = [
"Christoph Theis",
"\\[[0-9a-f]{7,8}\\]",
"hash_[0-9a-f]{38}",
"\t[0-9.-]+[ A-Z]+",
"Erreur d'authentification",
"WebEMailExtrac",
"ssh2: RSA 14:ba:xx",
"\\[Cc\\]lient",
"\\[Gg\\]ot",
"\\[nN\\]ot",
"\\[Uu\\]nknown",
"\\[uU\\]ser",
"\\[Uu\\]\\(\\?:ser",
]
[default.extend-words]
"alls" = "alls"
"helo" = "helo"
[default.extend-identifiers]
"failManager2nd" = "failManager2nd"
"log2nd" = "log2nd"
"routeros" = "routeros"
"REFERERS" = "REFERERS"
"tre_search" = "tre_search"

228
ChangeLog
View file

@ -7,6 +7,208 @@
Fail2Ban: Changelog
===================
ver. 1.1.1-dev-1 (20??/??/??) - development nightly edition
-----------
### Compatibility
* `action.d/iptables.conf` rewritten due to support of multiple chains (gh-3909), therefore user-level derivations
(action including iptables-based action) may become incompatible, e. g. some tags if used need to be replaced,
e. g. `<chain>` with `$chain` or `<_ipt_for_proto-iter>` with `<_ipt-iter>`;
* `filter.d/exim.conf` - several rules of mode `normal` moved to new mode `more`, because of too risky handling (see [gh-3940](https://github.com/fail2ban/fail2ban/pull/3940)),
to use it as before set `mode = more` for exim jail, but be aware of the consequences.
### Fixes
* fixes `systemd` bug with missing journal descriptor after rotation by reopening of journal if it is recognized as not alive (gh-3929)
* improve threaded clean-up of all filters, new thread functions `afterStop` (to force clean-up after stop) and `done`, invoking `afterStop` once
* ensure journal-reader is always closed (additional prevention against leaks and "too many open files"), thereby avoid sporadic segfault
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`
(can be overwritten in `jail.local` by user)
* `paths-common.conf`:
- changed default `mysql_log` path (default `logpath` of `mysqld-auth` jail without maintainer overrides, gh-3932)
* `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;
- mode `aggressive` extended to catch dropped by ACL failures, e.g. "ACL: Country is banned"
* `filter.d/freeswitch.conf` - bypass some new info in prefix before [WARNING] (changed default `_pref_line`),
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`:
- 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 `<F-MLFID>` 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"),
that allows to monitor only actual journals and ignore now a lot of rotated files by default; so can drastically reduce
amount of used file descriptors, normally to 1 or 2 descriptors per jail (gh-3391)
* new jail option `skip_if_nologs` to ignore jail if no `logpath` matches found, fail2ban continue to start with warnings/errors,
thus other jails become running (gh-2756)
* implements automatic switch `backend = auto` to backend `systemd`, when the following is true (RFE gh-3768):
- no files matching `logpath` found for this jail;
- no `systemd_if_nologs = false` is specified for the jail (`true` by default);
- option `journalmatch` is set for the jail or its filter (otherwise it'd be too heavy to allow all auto-jails,
even if they have never been foreseen for journal monitoring);
(option `skip_if_nologs` will be ignored if we could switch backend to `systemd`)
* configuration `ignoreip` and fail2ban-client commands `addignoreip`/`delignoreip` extended with `file:...` syntax
to ignore IPs from file-ip-set (containing IP, subnet, dns/fqdn or raw strings); the file would be read lazy on demand,
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)
- 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)
ver. 1.1.0 (2024/04/25) - object-found--norad-59479-cospar-2024-069a--altitude-36267km
-----------
### Compatibility
* the minimum supported python version is now 3.5, if you have previous python version
you can use the 0.11 or 1.0 version of fail2ban or upgrade python (or even build it from source).
### Fixes
* circumvent SEGFAULT in a python's socket module by getaddrinfo with disabled IPv6 (gh-3438)
* avoid sporadic error in pyinotify backend if pending file deleted in other thread, e. g. by flushing logs (gh-3635)
* `action.d/cloudflare-token.conf` - fixes gh-3479, url-encode args by unban
* `action.d/*ipset*`: make `maxelem` ipset option configurable through banaction arguments (gh-3564)
* `filter.d/apache-common.conf` - accepts remote besides client (gh-3622)
* `filter.d/mysqld-auth.conf` - matches also if no suffix in message (mariadb 10.3 log format, gh-3603)
* `filter.d/nginx-*.conf` - nginx error-log filters extended with support of journal format (gh-3646)
* `filter.d/postfix.conf`:
- "rejected" rule extended to match "Access denied" too (gh-3474)
- avoid double counting ('lost connection after AUTH' together with message 'disconnect ...', gh-3505)
- add Sender address rejected: Malformed DNS server reply (gh-3590)
- add to postfix syslog daemon format (gh-3690)
- change journalmatch postfix, allow sub-units with postfix@-.service (gh-3692)
* `filter.d/recidive.conf`: support for systemd-journal, conditional RE depending on logtype (for file or journal, gh-3693)
* `filter.d/slapd.conf` - filter rewritten for single-line processing, matches errored result without `text=...` (gh-3604)
### New Features and Enhancements
* supports python 3.12 and 3.13 (gh-3487)
* bundling async modules removed in python 3.12+ (fallback to local libraries pyasyncore/pyasynchat if import would miss them, gh-3487)
* `fail2ban-client` extended (gh-2975):
- `fail2ban-client status --all [flavor]` - returns status of fail2ban and all jails in usual form
- `fail2ban-client stats` - returns statistic in form of table (jail, backend, found and banned counts)
- `fail2ban-client statistic` or `fail2ban-client statistics` - same as `fail2ban-client stats` (aliases for stats)
- `fail2ban-client status --all stats` - (undocumented, flavor "stats") returns statistic of all jails in form of python dict
* `fail2ban-regex` extended to load settings from jail (by simple name it'd prefer jail to the filter now, gh-2655);
to load the settings from filter one could use:
```diff
- fail2ban-regex ... sshd ; # jail
+ fail2ban-regex ... sshd.conf ; # filter
# or:
+ fail2ban-regex ... filter.d/sshd ; # filter
```
* 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)
* `action.d/mikrotik.conf` - new action for mikrotik routerOS, adds and removes entries from address lists on the router (gh-2860)
* `action.d/pf.conf` - pf action extended with support of `protocol=all` (gh-3503)
* `action.d/smtp.py` - added optional support for TLS connections via the `ssl` arg.
* `filter.d/dante.conf` - new filter for Dante SOCKS server (gh-2112)
* `filter.d/exim.conf`, `filter.d/exim-spam.conf`:
- messages are prefiltered by `prefregex` now
- filter can bypass additional timestamp or pid that may be logged via systemd-journal or syslog-ng (gh-3060)
- rewrite host line regex for all varied exim's log_selector states (gh-3263, gh-3701, gh-3702)
- fixed "dropped: too many ..." regex, also matching unrecognized commands now (gh-3502)
* `filter.d/named-refused.conf` - denied allows any reason in parenthesis as suffix (gh-3697)
* `filter.d/nginx-forbidden.conf` - new filter to ban forbidden locations, e. g. using `deny` directive (gh-2226)
* `filter.d/routeros-auth.conf` - new filter detecting failed login attempts in the log produced by MikroTik RouterOS
* `filter.d/sshd.conf`:
- avoid double counting for "maximum authentication attempts exceeded" (gh-3502)
- message "Disconnecting ... Too many authentication failures" is not a failure anymore
- mode `ddos`/`aggressive` extended to match new messages caused by port scanner, wrong payload on ssh port (gh-3486):
* message authentication code incorrect [preauth]
* connection corrupted [preauth]
* timeout before authentication
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
-----------
@ -34,7 +236,7 @@ ver. 1.0.1 (2022/09/27) - energy-equals-mass-times-the-speed-of-light-squared
* [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
imprecise 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)
@ -372,7 +574,7 @@ filter = flt[logtype=short]
* `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
* introduced new options: `dbmaxmatches` (fail2ban.conf) and `maxmatches` (jail.conf) to control
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
@ -482,7 +684,7 @@ ver. 0.10.3 (2018/04/04) - the-time-is-always-right-to-do-what-is-right
- fixed root login refused regex (optional port before preauth, gh-2080);
- avoid banning of legitimate users when pam_unix used in combination with other password method, so
bypass pam_unix failures if accepted available for this user gh-2070;
- amend to gh-1263 with better handling of multiple attempts (failures for different user-names recognized immediatelly);
- amend to gh-1263 with better handling of multiple attempts (failures for different user-names recognized immediately);
- mode `ddos` (and `aggressive`) extended to catch `Connection closed by ... [preauth]`, so in DDOS mode
it counts failure on closing connection within preauth-stage (gh-2085);
* `action.d/abuseipdb.conf`: fixed curl cypher errors and comment quote-issue (gh-2044, gh-2101);
@ -812,7 +1014,7 @@ ver. 0.10.0-alpha-1 (2016/07/14) - ipv6-support-etc
sane environment in error case of `actioncheck`.
* Reporting via abuseipdb.com:
- Bans can now be reported to abuseipdb
- Catagories must be set in the config
- Categories must be set in the config
- Relevant log lines included in report
### Enhancements
@ -949,7 +1151,7 @@ releases.
- Rewritten without end-anchor ($), because of potential vulnerability on very long URLs.
* filter.d/apache-badbots.conf - extended to recognize Jorgee Vulnerability Scanner (gh-1882)
* filter.d/asterisk.conf
- fixed failregex AMI Asterisk authentification failed (see gh-1302)
- fixed failregex AMI Asterisk authentication failed (see gh-1302)
- removed invalid (vulnerable) regex blocking IPs using forign data (from header "from")
thus not the IP-address that really originates the request (see gh-1927)
- fixed failregex for the SQL-injection attempts with single-quotes in connect-string (see gh-2011)
@ -1249,7 +1451,7 @@ ver. 0.9.3 (2015/08/01) - lets-all-stay-friends
* `filter.d/roundcube-auth.conf`
- Updated regex to work with 'errors' log (1.0.5 and 1.1.1)
- Added regex to work with 'userlogins' log
* `action.d/sendmail*.conf` - use LC_ALL (superseeding LC_TIME) to override
* `action.d/sendmail*.conf` - use LC_ALL (superseding LC_TIME) to override
locale on systems with customized LC_ALL
* performance fix: minimizes connection overhead, close socket only at
communication end (gh-1099)
@ -1419,7 +1621,7 @@ ver. 0.9.1 (2014/10/29) - better, faster, stronger
* Ignored IPs are no longer banned when being restored from persistent
database
* Manually unbanned IPs are now removed from persistent database, such they
wont be banned again when Fail2Ban is restarted
won't be banned again when Fail2Ban is restarted
* Pass "bantime" parameter to the actions in default jail's action
definition(s)
* `filters.d/sieve.conf` - fixed typo in _daemon. Thanks Jisoo Park
@ -1710,7 +1912,7 @@ those filters were used.
all platforms to ensure permissions are the same before and after a ban.
Closes gh-266. hostsdeny supports daemon_list now too.
* `action.d/bsd-ipfw` - action option unused. Change blocktype to port unreach
instead of deny for consistancy.
instead of deny for consistency.
* `filter.d/dovecot` - added to support different dovecot failure
"..disallowed plaintext auth". Closes Debian bug #709324
* `filter.d/roundcube-auth` - timezone offset can be positive or negative
@ -1900,7 +2102,7 @@ fail2ban-users mailing list and IRC.
### New Features
- Yaroslav Halchenko
* [9ba27353] Add support for `jail.d/{confilefile}` and `fail2ban.d/{configfile}`
to provide additional flexibility to system adminstrators. Thanks to
to provide additional flexibility to system administrators. Thanks to
beilber for the idea. Closes gh-114.
* [3ce53e87] Add exim filter.
- Erwan Ben Souiden
@ -2051,7 +2253,7 @@ ver. 0.8.7 (2012/07/31) - stable
* [47c03a2] files/nagios - spelling/grammar fixes
* [b083038] updated Free Software Foundation's address
* [9092a63] changed TLDs to invalid domains, in accordance with RFC 2606
* [642d9af,3282f86] reformated printing of jail's name to be consistent
* [642d9af,3282f86] reformatted printing of jail's name to be consistent
with init's info messages
* [3282f86] uniform use of capitalized Jail in the messages
- Leonardo Chiquitto
@ -2396,7 +2598,7 @@ ver. 0.6.1 (2006/03/16) - stable
- Fixed crash when time format does not match data
- Propagated patch from Debian to fix fail2ban search path addition to the path
search list: now it is added first. Thanks to Nick Craig-Wood
- Added SMTP authentification for mail notification. Thanks to Markus Hoffmann
- Added SMTP authentication for mail notification. Thanks to Markus Hoffmann
- Removed debug mode as it is confusing for people
- Added parsing of timestamp in TAI64N format (#1275325). Thanks to Mark
Edgington
@ -2429,7 +2631,7 @@ ver. 0.5.5 (2005/10/26) - beta
further adjusted by upstream author).
* Added -f command line parameter for [findtime].
* Added a cleanup of firewall rules on emergency shutdown when unknown
exception is catched.
exception is caught.
* Fail2ban should not crash now if a wrong file name is specified in config.
* reordered code a bit so that log targets are setup right after background
and then only loglevel (verbose, debug) is processed, so the warning could
@ -2518,7 +2720,7 @@ ver. 0.3.1 (2005/03/31) - beta
ver. 0.3.0 (2005/02/24) - beta
----------
- Re-writting of parts of the code in order to handle several log files with
- Re-writing of parts of the code in order to handle several log files with
different rules
- Removed `sshd.py` because it is no more needed
- Fixed a bug when exiting with IP in the ban list

30
FILTERS
View file

@ -129,7 +129,7 @@ Date/Time
---------
At the moment, Fail2Ban depends on log lines to have time stamps. That is why
before starting to develop failregex, check if your log line format known to
before starting to develop failregex, check if your log line format is known to
Fail2Ban. Copy the time component from the log line and append an IP address to
test with following command::
@ -232,16 +232,24 @@ the <> at the start so regex should be similar to '^<> error <HOST> is evil$' us
The following general rules apply to regular expressions:
* ensure regexes start with a ^ and are as restrictive as possible. E.g. do not
use .* if \d+ is sufficient;
* ensure regexes are anchored (e. g. start with a ^) and are as restrictive
as possible. E.g. do not use catch-alls .+ or .* if \d+ or [^"]* is sufficient.
Basically avoid the catch-alls where it is possible, especially non-greedy
catch-alls on RE with many branches or ambiguous matches;
* use functionality of Python regexes defined in the standard Python re library
http://docs.python.org/2/library/re.html;
* make regular expressions readable (as much as possible). E.g.
(?:...) represents a non-capturing regex but (...) is more readable, thus
preferred.
https://docs.python.org/library/re.html;
* try to write regular expressions as efficient as possible. E.g. do not write
several REs for almost the same messages, just with A or B or C, if they can
be matched by single RE using | operator like ...(?:A|B|C)... and order them
by their frequency, so A before B and C, if A is more frequent or will match
faster;
* make regular expressions readable (as much as possible), but only if it is
justified. E.g. (?:...) represents a non-capturing regex and (...) is more
readable, but capturing groups make the RE a bit slower, thus (?:...) may be
more preferable.
If you have only a basic knowledge of regular repressions we advise to read
http://docs.python.org/2/library/re.html first. It doesn't take long and would
https://docs.python.org/library/re.html first. It doesn't take long and would
remind you e.g. which characters you need to escape and which you don't.
Developing/testing a regex
@ -265,10 +273,6 @@ Take note of -l heavydebug / -l debug and -v as they might be very useful.
parts are constrained and different formats depending on configuration or
less common usages.
.. TIP::
For looking through source code - http://sourcecodebrowser.com/ . It has
call graphs and can browse different versions.
.. TIP::
Some applications log spaces at the end. If you are not sure add \s*$ as
the end part of the regex.
@ -309,6 +313,8 @@ So more specifically in the [filter] section in jail.conf:
Submit github pull request (See "Pull Requests" above) for
github.com/fail2ban/fail2ban containing your great work.
You may also consider https://github.com/fail2ban/fail2ban/wiki/Best-practice
Filter Security
===============

View file

@ -40,6 +40,7 @@ config/action.d/mail.conf
config/action.d/mail-whois-common.conf
config/action.d/mail-whois.conf
config/action.d/mail-whois-lines.conf
config/action.d/mikrotik.conf
config/action.d/mynetwatchman.conf
config/action.d/netscaler.conf
config/action.d/nftables-allports.conf
@ -90,6 +91,7 @@ config/filter.d/counter-strike.conf
config/filter.d/courier-auth.conf
config/filter.d/courier-smtp.conf
config/filter.d/cyrus-imap.conf
config/filter.d/dante.conf
config/filter.d/directadmin.conf
config/filter.d/domino-smtp.conf
config/filter.d/dovecot.conf
@ -121,6 +123,8 @@ 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-error-common.conf
config/filter.d/nginx-forbidden.conf
config/filter.d/nginx-http-auth.conf
config/filter.d/nginx-limit-req.conf
config/filter.d/nsd.conf
@ -138,6 +142,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/routeros-auth.conf
config/filter.d/scanlogd.conf
config/filter.d/screensharingd.conf
config/filter.d/selinux-common.conf
@ -175,7 +180,6 @@ CONTRIBUTING.md
COPYING
.coveragerc
DEVELOP
fail2ban-2to3
fail2ban/client/actionreader.py
fail2ban/client/beautifier.py
fail2ban/client/configparserinc.py
@ -191,6 +195,8 @@ fail2ban/client/filterreader.py
fail2ban/client/__init__.py
fail2ban/client/jailreader.py
fail2ban/client/jailsreader.py
fail2ban/compat/asynchat.py
fail2ban/compat/asyncore.py
fail2ban/exceptions.py
fail2ban/helpers.py
fail2ban/__init__.py
@ -204,7 +210,6 @@ fail2ban/server/datedetector.py
fail2ban/server/datetemplate.py
fail2ban/server/failmanager.py
fail2ban/server/failregex.py
fail2ban/server/filtergamin.py
fail2ban/server/filterpoll.py
fail2ban/server/filter.py
fail2ban/server/filterpyinotify.py
@ -272,7 +277,7 @@ fail2ban/tests/files/config/apache-auth/noentry/.htaccess
fail2ban/tests/files/config/apache-auth/README
fail2ban/tests/files/database_v1.db
fail2ban/tests/files/database_v2.db
fail2ban/tests/files/filter.d/substition.conf
fail2ban/tests/files/filter.d/substitution.conf
fail2ban/tests/files/filter.d/testcase01.conf
fail2ban/tests/files/filter.d/testcase02.conf
fail2ban/tests/files/filter.d/testcase02.local
@ -300,6 +305,7 @@ fail2ban/tests/files/logs/counter-strike
fail2ban/tests/files/logs/courier-auth
fail2ban/tests/files/logs/courier-smtp
fail2ban/tests/files/logs/cyrus-imap
fail2ban/tests/files/logs/dante
fail2ban/tests/files/logs/directadmin
fail2ban/tests/files/logs/domino-smtp
fail2ban/tests/files/logs/dovecot
@ -329,6 +335,7 @@ 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-forbidden
fail2ban/tests/files/logs/nginx-http-auth
fail2ban/tests/files/logs/nginx-limit-req
fail2ban/tests/files/logs/nsd
@ -346,6 +353,7 @@ 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/routeros-auth
fail2ban/tests/files/logs/scanlogd
fail2ban/tests/files/logs/screensharingd
fail2ban/tests/files/logs/selinux-ssh

View file

@ -2,7 +2,7 @@
/ _|__ _(_) |_ ) |__ __ _ _ _
| _/ _` | | |/ /| '_ \/ _` | ' \
|_| \__,_|_|_/___|_.__/\__,_|_||_|
v1.0.1.dev1 20??/??/??
v1.1.0.dev1 20??/??/??
## Fail2Ban: ban hosts that cause multiple authentication errors
@ -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.
<img src="http://www.worldipv6launch.org/wp-content/themes/ipv6/downloads/World_IPv6_launch_logo.svg" height="52pt"/> | Since v0.10 fail2ban supports the matching of IPv6 addresses.
<img src="http://www.worldipv6launch.org/wp-content/themes/ipv6/downloads/World_IPv6_launch_logo.svg" style="height:52pt;"/> | Since v0.10 fail2ban supports the matching of IPv6 addresses.
------|------
This README is a quick introduction to Fail2Ban. More documentation, FAQ, and HOWTOs
@ -29,29 +29,30 @@ and the website: https://www.fail2ban.org
Installation:
-------------
**It is possible that Fail2Ban is already packaged for your distribution. In
this case, you should use that instead.**
Fail2Ban is likely already packaged for your Linux distribution and [can be installed with a simple command](https://github.com/fail2ban/fail2ban/wiki/How-to-install-fail2ban-packages).
If your distribution is not listed, you can install from GitHub:
Required:
- [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
- [Python >= 3.5](https://www.python.org) or [PyPy3](https://pypy.org)
- python-setuptools (or python3-setuptools) for installation from source
Optional:
- [pyinotify >= 0.8.3](https://github.com/seb-m/pyinotify), may require:
* Linux >= 2.6.13
- [gamin >= 0.0.21](http://www.gnome.org/~veillard/gamin)
- [systemd >= 204](http://www.freedesktop.org/wiki/Software/systemd) and python bindings:
* [python-systemd package](https://www.freedesktop.org/software/systemd/python-systemd/index.html)
- [dnspython](http://www.dnspython.org/)
- [pyasyncore](https://pypi.org/project/pyasyncore/) and [pyasynchat](https://pypi.org/project/pyasynchat/) (normally bundled-in within fail2ban, for python 3.12+ only)
To install:
tar xvfj fail2ban-1.0.1.tar.bz2
cd fail2ban-1.0.1
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, master or 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
@ -90,11 +91,7 @@ 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=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=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=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)
* [![CI](https://github.com/fail2ban/fail2ban/actions/workflows/main.yml/badge.svg)](https://github.com/fail2ban/fail2ban/actions/workflows/main.yml)
Contact:
--------

View file

@ -13,7 +13,7 @@ Preparation
* Check distribution patches and see if they can be included
* https://apps.fedoraproject.org/packages/fail2ban/sources
* http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/
* https://gitweb.gentoo.org/repo/gentoo.git/tree/net-analyzer/fail2ban
* http://svnweb.freebsd.org/ports/head/security/py-fail2ban/
* https://build.opensuse.org/package/show?package=fail2ban&project=openSUSE%3AFactory
* http://sophie.zarb.org/sources/fail2ban (Mageia)
@ -49,7 +49,7 @@ Preparation
ad-hoc bash script to run in a clean clone:
find -type f | grep -v -e '\.git' -e '/doc/' -e '\.travis' -e MANIFEST | sed -e 's,^\./,,g' | while read f; do grep -ne "^$f\$" MANIFEST >/dev/null || echo "$f" ; done
find -type f | grep -v -e '\.git' -e '/doc/' -e MANIFEST | sed -e 's,^\./,,g' | while read f; do grep -ne "^$f\$" MANIFEST >/dev/null || echo "$f" ; done
or an alternative for comparison with previous release
@ -115,7 +115,7 @@ Pre Release
* Arch Linux:
* https://www.archlinux.org/packages/community/any/fail2ban/
* https://www.archlinux.org/packages/extra/any/fail2ban/
* Debian: Yaroslav Halchenko <debian@onerussian.com>
@ -134,7 +134,7 @@ Pre Release
* Gentoo: netmon@gentoo.org
* http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/metadata.xml?view=markup
* https://gitweb.gentoo.org/repo/gentoo.git/tree/net-analyzer/fail2ban/metadata.xml
* https://bugs.gentoo.org/buglist.cgi?quicksearch=fail2ban
* openSUSE: Stephan Kulow <coolo@suse.com>

1
THANKS
View file

@ -22,6 +22,7 @@ Andrey G. Grozin
Andy Fragen
Arturo 'Buanzo' Busleiman
Axel Thimm
Balazs Mateffy
Bas van den Dikkenberg
Beau Raines
Bill Heaton

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
# vi: set ft=python sts=4 ts=4 sw=4 noet :

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
# vi: set ft=python sts=4 ts=4 sw=4 noet :
#

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
# vi: set ft=python sts=4 ts=4 sw=4 noet :

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
# vi: set ft=python sts=4 ts=4 sw=4 noet :
"""Script to run Fail2Ban tests battery

View file

@ -80,7 +80,7 @@ actioncheck =
# use my (Shaun's) helper PHP script by commenting out the first #actionban
# line below, uncommenting the second one, and pointing the URL at
# wherever you install the helper script. For the PHP helper script, see
# <https://wiki.shaunc.com/wikka.php?wakka=ReportingToAbuseIPDBWithFail2Ban>
# <https://github.com/parseword/fail2ban-abuseipdb/>
#
# Tags: See jail.conf(5) man page
# Values: CMD

View file

@ -2,7 +2,61 @@
#
# Author: Chris Caron <lead2gold@gmail.com>
#
# 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]
@ -10,7 +64,7 @@
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = printf %%b "The jail <name> as been started successfully." | <apprise> -t "[Fail2Ban] <name>: started on `uname -n`"
actionstart = printf %%b "The jail <name> has been started successfully." | <apprise> -t "[Fail2Ban] <name>: started on `uname -n`"
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
@ -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 "<config>"
args =
#
apprise = apprise -c "<config>" <args>

View file

@ -30,6 +30,9 @@
[Definition]
# bypass reporting of restored (already reported) 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

View file

@ -80,7 +80,7 @@ block = ip
# Option: blocktype
# Notes.: How to block the traffic. Use a action from man 5 ipfw
# Common values: deny, unreach port, reset
# ACTION defination at the top of man ipfw for allowed values.
# ACTION definition at the top of man ipfw for allowed values.
# Values: STRING
#
blocktype = unreach port

View file

@ -50,11 +50,12 @@ actionban = curl -s -X POST "<_cf_api_url>" \
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = id=$(curl -s -X GET "<_cf_api_url>?mode=<cfmode>&notes=<notes>&configuration.target=<cftarget>&configuration.value=<ip>" \
<_cf_api_prms> \
| awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1)}}}' \
| tr -d ' "' \
| head -n 1)
actionunban = id=$(curl -s -G -X GET "<_cf_api_url>" \
--data-urlencode "mode=<cfmode>" --data-urlencode "notes=<notes>" --data-urlencode "configuration.target=<cftarget>" --data-urlencode "configuration.value=<ip>" \
<_cf_api_prms> \
| awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1)}}}' \
| tr -d ' "' \
| head -n 1)
if [ -z "$id" ]; then echo "<name>: id for <ip> cannot be found using target <cftarget>"; exit 0; fi; \
curl -s -X DELETE "<_cf_api_url>/$id" \
<_cf_api_prms> \
@ -67,7 +68,7 @@ _cf_api_prms = -H "Authorization: Bearer <cftoken>" -H "Content-Type: applicatio
# Declare your Cloudflare Authorization Bearer Token in the [DEFAULT] section of your jail.local file.
# The Cloudflare <ZONE_ID> of hte domain you want to manage.
# The Cloudflare <ZONE_ID> of the domain you want to manage.
#
# cfzone =

View file

@ -16,7 +16,7 @@
#
# Please do not use this action unless you are certain that fail2ban
# does not result in "false positives" for your deployment. False
# positive reports could serve a mis-favor to the original cause by
# positive reports could serve a misfavor to the original cause by
# flooding corresponding contact addresses, and complicating the work
# of administration personnel responsible for handling (verified) legit
# complains.

26
config/action.d/csf.conf Normal file
View file

@ -0,0 +1,26 @@
# Fail2Ban configuration file
# http://configserver.com/cp/csf.html
#
# Note: CSF doesn't play nicely with other actions. It has been observed to
# remove bans created by other iptables based actions. If you are going to use
# this action, use it for all of your jails.
#
# DON'T MIX CSF and other IPTABLES based actions
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = csf --deny <ip> "banned by Fail2Ban <name>"
actionunban = csf --denyrm <ip>
[Init]
# Name used in CSF configuration
#
name = default
# DEV NOTES:
#
# based on apf.conf by Mark McKinstry

View file

@ -18,36 +18,36 @@ before = firewallcmd-common.conf
[Definition]
actionstart = <ipstype_<ipsettype>/actionstart>
actionstart = <ipsbackend_<ipsetbackend>/actionstart>
firewall-cmd --direct --add-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
actionflush = <ipstype_<ipsettype>/actionflush>
actionflush = <ipsbackend_<ipsetbackend>/actionflush>
actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
<actionflush>
<ipstype_<ipsettype>/actionstop>
<ipsbackend_<ipsetbackend>/actionstop>
actionban = <ipstype_<ipsettype>/actionban>
actionban = <ipsbackend_<ipsetbackend>/actionban>
# actionprolong = %(actionban)s
actionunban = <ipstype_<ipsettype>/actionunban>
actionunban = <ipsbackend_<ipsetbackend>/actionunban>
[ipstype_ipset]
[ipsbackend_ipset]
actionstart = ipset -exist create <ipmset> hash:ip timeout <default-ipsettime> <familyopt>
actionstart = ipset -exist create <ipmset> <ipsettype> timeout <default-ipsettime> maxelem <maxelem> <familyopt>
actionflush = ipset flush <ipmset>
actionstop = ipset destroy <ipmset>
actionstop = ipset destroy <ipmset> 2>/dev/null || { sleep 1; ipset destroy <ipmset>; }
actionban = ipset -exist add <ipmset> <ip> timeout <ipsettime>
actionunban = ipset -exist del <ipmset> <ip>
[ipstype_firewalld]
[ipsbackend_firewalld]
actionstart = firewall-cmd --direct --new-ipset=<ipmset> --type=hash:ip --option=timeout=<default-ipsettime> <firewalld_familyopt>
actionstart = firewall-cmd --direct --new-ipset=<ipmset> --type=<ipsettype> --option=timeout=<default-ipsettime> --option=maxelem=<maxelem> <firewalld_familyopt>
# TODO: there doesn't seem to be an explicit way to invoke the ipset flush function using firewall-cmd
actionflush =
@ -60,6 +60,11 @@ actionunban = firewall-cmd --ipset=<ipmset> --remove-entry=<ip>
[Init]
# Option: ipsettype
# Notes: specifies type of set, see `man --pager='less -p "^SET TYPES"' ipset` for details
# Values: hash:ip, hash:net, etc... Default: hash:ip
ipsettype = hash:ip
# Option: chain
# Notes specifies the iptables chain to which the fail2ban rules should be
# added
@ -77,15 +82,21 @@ default-ipsettime = 0
# Values: [ NUM ] Default: 0 (managed by fail2ban by unban)
ipsettime = 0
# expresion to caclulate timeout from bantime, example:
# Option: maxelem
# Notes: maximal number of elements which can be stored in the ipset
# You may want to increase this for long-duration/high-volume jails
# Values: [ NUM ] Default: 65536
maxelem = 65536
# expression to calculate timeout from bantime, example:
# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>']
timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0)
# Option: ipsettype
# Notes.: defines type of ipset used for match-set (firewalld or ipset)
# Option: ipsetbackend
# Notes.: defines the backend of ipset used for match-set (firewalld or ipset)
# Values: firewalld or ipset
# Default: ipset
ipsettype = ipset
ipsetbackend = ipset
# Option: actiontype
# Notes.: defines additions to the blocking rule
@ -118,4 +129,4 @@ firewalld_familyopt = --option=family=inet6
# DEV NOTES:
#
# Author: Edgar Hoch, Daniel Black, Sergey Brester and Mihail Politaev
# firewallcmd-new / iptables-ipset-proto6 combined for maximium goodness
# firewallcmd-new / iptables-ipset-proto6 combined for maximum goodness

View file

@ -35,7 +35,7 @@ actioncheck =
#
# Because rich rules can only handle single or a range of ports we must split ports and execute the command for each port. Ports can be single and ranges separated by a comma or space for an example: http, https, 22-60, 18 smtp
fwcmd_rich_rule = rule family='<family>' source address='<ip>' port port='$p' protocol='<protocol>' %(rich-suffix)s
fwcmd_rich_rule = rule family=\"<family>\" source address=\"<ip>\" port port=\"$p\" protocol=\"<protocol>\" %(rich-suffix)s
actionban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="%(fwcmd_rich_rule)s"; done

View file

@ -27,7 +27,7 @@ before = iptables.conf
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = ipset --create f2b-<name> iphash
actionstart = ipset --create f2b-<name> maxelem <maxelem> iphash
<_ipt_add_rules>
@ -61,6 +61,14 @@ actionban = ipset --test f2b-<name> <ip> || ipset --add f2b-<name> <ip>
#
actionunban = ipset --test f2b-<name> <ip> && ipset --del f2b-<name> <ip>
# Several capabilities used internaly:
# Several capabilities used internally:
rule-jump = -m set --match-set f2b-<name> src -j <blocktype>
[Init]
# Option: maxelem
# Notes: maximal number of elements which can be stored in the ipset
# You may want to increase this for long-duration/high-volume jails
# Values: [ NUM ] Default: 65536
maxelem = 65536

View file

@ -24,7 +24,7 @@ before = iptables.conf
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
# Values: CMD
#
actionstart = ipset -exist create <ipmset> hash:ip timeout <default-ipsettime> <familyopt>
actionstart = ipset -exist create <ipmset> <ipsettype> timeout <default-ipsettime> maxelem <maxelem> <familyopt>
<_ipt_add_rules>
# Option: actionflush
@ -39,7 +39,7 @@ actionflush = ipset flush <ipmset>
#
actionstop = <_ipt_del_rules>
<actionflush>
ipset destroy <ipmset>
ipset destroy <ipmset> 2>/dev/null || { sleep 1; ipset destroy <ipmset>; }
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
@ -59,13 +59,18 @@ actionban = ipset -exist add <ipmset> <ip> timeout <ipsettime>
#
actionunban = ipset -exist del <ipmset> <ip>
# Several capabilities used internaly:
# Several capabilities used internally:
rule-jump = -m set --match-set <ipmset> src -j <blocktype>
[Init]
# Option: ipsettype
# Notes: specifies type of set, see `man --pager='less -p "^SET TYPES"' ipset` for details
# Values: hash:ip, hash:net, etc... Default: hash:ip
ipsettype = hash:ip
# Option: default-ipsettime
# Notes: specifies default timeout in seconds (handled default ipset timeout only)
# Values: [ NUM ] Default: 0 (no timeout, managed by fail2ban by unban)
@ -76,7 +81,13 @@ default-ipsettime = 0
# Values: [ NUM ] Default: 0 (managed by fail2ban by unban)
ipsettime = 0
# expresion to caclulate timeout from bantime, example:
# Option: maxelem
# Notes: maximal number of elements which can be stored in the ipset
# You may want to increase this for long-duration/high-volume jails
# Values: [ NUM ] Default: 65536
maxelem = 65536
# expression to calculate timeout from bantime, example:
# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>']
timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0)

View file

@ -12,8 +12,9 @@ before = iptables.conf
[Definition]
_ipt_chain_rule = -m recent --update --seconds 3600 --name <iptname> -j <blocktype>
_ipt_for_proto-iter =
_ipt_for_proto-done =
_ipt_check_rule = <iptables> -C <chain> %(_ipt_chain_rule)s
_ipt-iter =
_ipt-done =
# Option: actionstart
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
@ -60,7 +61,7 @@ actionstop = echo / > /proc/net/xt_recent/<iptname>
# Notes.: command executed as invariant check (error by ban)
# Values: CMD
#
actioncheck = { <iptables> -C <chain> %(_ipt_chain_rule)s; } && test -e /proc/net/xt_recent/<iptname>
actioncheck = { %(_ipt_check_rule)s >/dev/null 2>&1; } && test -e /proc/net/xt_recent/<iptname>
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the

View file

@ -62,25 +62,25 @@ pre-rule =
rule-jump = -j <_ipt_rule_target>
# Several capabilities used internaly:
# Several capabilities used internally:
_ipt_for_proto-iter = for proto in $(echo '<protocol>' | sed 's/,/ /g'); do
_ipt_for_proto-done = done
_ipt-iter = for chain in $(echo '<chain>' | sed 's/,/ /g'); do for proto in $(echo '<protocol>' | sed 's/,/ /g'); do
_ipt-done = done; done
_ipt_add_rules = <_ipt_for_proto-iter>
{ %(_ipt_check_rule)s >/dev/null 2>&1; } || { <iptables> -I <chain> %(_ipt_chain_rule)s; }
<_ipt_for_proto-done>
_ipt_add_rules = <_ipt-iter>
{ %(_ipt_check_rule)s >/dev/null 2>&1; } || { <iptables> -I $chain %(_ipt_chain_rule)s; }
<_ipt-done>
_ipt_del_rules = <_ipt_for_proto-iter>
<iptables> -D <chain> %(_ipt_chain_rule)s
<_ipt_for_proto-done>
_ipt_del_rules = <_ipt-iter>
<iptables> -D $chain %(_ipt_chain_rule)s
<_ipt-done>
_ipt_check_rules = <_ipt_for_proto-iter>
_ipt_check_rules = <_ipt-iter>
%(_ipt_check_rule)s
<_ipt_for_proto-done>
<_ipt-done>
_ipt_chain_rule = <pre-rule><ipt_<type>/_chain_rule>
_ipt_check_rule = <iptables> -C <chain> %(_ipt_chain_rule)s
_ipt_check_rule = <iptables> -C $chain %(_ipt_chain_rule)s
_ipt_rule_target = f2b-<name>
[ipt_oneport]
@ -99,8 +99,9 @@ _chain_rule = -p $proto <rule-jump>
[Init]
# Option: chain
# Notes specifies the iptables chain to which the Fail2Ban rules should be
# added
# Notes specifies the iptables chains to which the Fail2Ban rules should be
# added. May be a single chain (e.g. INPUT) or a comma separated list
# (e.g. INPUT, FORWARD)
# Values: STRING Default: INPUT
chain = INPUT
@ -135,7 +136,7 @@ returntype = RETURN
# Option: lockingopt
# Notes.: Option was introduced to iptables to prevent multiple instances from
# running concurrently and causing irratic behavior. -w was introduced
# running concurrently and causing erratic behavior. -w was introduced
# in iptables 1.4.20, so might be absent on older systems
# See https://github.com/fail2ban/fail2ban/issues/1122
# Values: STRING

View file

@ -15,7 +15,7 @@
# Reporting an IP is a serious action. Make sure that it is legit.
# Consider using this action only for:
# * IP that has been banned more than once
# * High max retry to avoid user mis-typing password
# * High max retry to avoid user mistyping password
# * Filters that are unlikely to be human error
#
# Example:
@ -47,7 +47,7 @@
# BadBot 256 Bad bot that is not honoring robots.txt or just flooding with too many requests, etc
# Compromised 512 The ip has been taken over by malware or botnet
# Phishing 1024 The ip is involved in phishing or spoofing
# Iot 2048 The ip has targetted an iot (Internet of Things) device
# Iot 2048 The ip has targeted an iot (Internet of Things) device
# PortScan 4096 Port scan
# See https://ipthreat.net/bulkreportformat for more information
# ```

View file

@ -0,0 +1,84 @@
# Fail2Ban configuration file
#
# Mikrotik routerOS action to add/remove address-list entries
#
# Author: Duncan Bellamy <dunk@denkimushi.com>
# based on forum.mikrotik.com post by pakjebakmeel
#
# in the instructions:
# (10.0.0.1 is ip of mikrotik router)
# (10.0.0.2 is ip of fail2ban machine)
#
# on fail2ban machine:
# sudo mkdir /var/lib/fail2ban/ssh
# sudo chmod 700 /var/lib/fail2ban/ssh
# sudo ssh-keygen -N "" -f /var/lib/fail2ban/ssh/fail2ban_id_rsa
# sudo scp /var/lib/fail2ban/ssh/fail2ban_id_rsa.pub admin@10.0.0.1:/
# ssh admin@10.0.0.1
#
# on mikrotik router:
# /user add name=miki-f2b group=write address=10.0.0.2 password=""
# /user ssh-keys import public-key-file=fail2ban_id_rsa.pub user=miki-f2b
# /quit
#
# on fail2ban machine:
# (check password login fails)
# ssh miki-f2b@10.0.0.1
# (check private key works)
# sudo ssh -i /var/lib/fail2ban/ssh/fail2ban_id_rsa miki-f2b@10.0.0.1
#
# Then create rules on mikrorik router that use address
# list(s) maintained by fail2ban eg in the forward chain
# drop from address list, or in the forward chain drop
# from address list to server
#
# example extract from jail.local overriding some defaults
# action = mikrotik[keyfile="%(mkeyfile)s", user="%(muser)s", host="%(mhost)s", list="%(mlist)s"]
#
# ignoreip = 127.0.0.1/8 192.168.0.0/24
# mkeyfile = /etc/fail2ban/ssh/mykey_id_rsa
# muser = myuser
# mhost = 192.168.0.1
# mlist = BAD LIST
[Definition]
actionstart =
actionstop = %(actionflush)s
actionflush = %(command)s "/ip firewall address-list remove [find list=\"%(list)s\" comment~\"%(startcomment)s-*\"]"
actioncheck =
actionban = %(command)s "/ip firewall address-list add list=\"%(list)s\" address=<ip> comment=%(comment)s"
actionunban = %(command)s "/ip firewall address-list remove [find list=\"%(list)s\" comment=%(comment)s]"
command = ssh -l %(user)s -p%(port)s -i %(keyfile)s %(host)s
# Option: user
# Notes.: username to use when connecting to routerOS
user =
# Option: port
# Notes.: port to use when connecting to routerOS
port = 22
# Option: keyfile
# Notes.: ssh private key to use for connecting to routerOS
keyfile =
# Option: host
# Notes.: hostname or ip of router
host =
# Option: list
# Notes.: name of "address-list" to use on router
list = Fail2Ban
# Option: startcomment
# Notes.: used as a prefix to all comments, and used to match for flushing rules
startcomment = f2b-<name>
# Option: comment
# Notes.: comment to use on routerOS (must be unique as used for ip address removal)
comment = %(startcomment)s-<ip>
[Init]
name="%(__name__)s"

View file

@ -5,7 +5,7 @@
# The script will add offender IPs to a dataset on netscaler, the dataset can then be used to block the IPs at a cs/vserver or global level
# This dataset is then used to block IPs using responder policies on the netscaler.
#
# The script assumes using HTTPS with unsecure certificate to access the netscaler,
# The script assumes using HTTPS with insecure certificate to access the netscaler,
# if you have a valid certificate installed remove the -k from the curl lines, or if you want http change it accordingly (and remove the -k)
#
# This action depends on curl

View file

@ -44,7 +44,7 @@ match = <rule_match-<type>>
#
rule_stat = %(match)s <addr_family> saddr @<addr_set> <blocktype>
# optional interator over protocol's:
# optional iterator over protocol's:
_nft_for_proto-custom-iter =
_nft_for_proto-custom-done =
_nft_for_proto-allports-iter =
@ -53,9 +53,9 @@ _nft_for_proto-multiport-iter = for proto in $(echo '<protocol>' | sed 's/,/ /g'
_nft_for_proto-multiport-done = done
_nft_list = <nftables> -a list chain <table_family> <table> <chain>
_nft_get_handle_id = grep -oP '@<addr_set>\s+.*\s+\Khandle\s+(\d+)$'
_nft_get_handle_id = sed -nE 's/.*@<addr_set>\s+.*\s+\#\s*(handle\s+[0-9]+)$/\1/p'
_nft_add_set = <nftables> add set <table_family> <table> <addr_set> \{ type <addr_type>\; \}
_nft_add_set = <nftables> add set <table_family> <table> <addr_set> \{ type <addr_type>\;<addr_options> \}
<_nft_for_proto-<type>-iter>
<nftables> add rule <table_family> <table> <chain> %(rule_stat)s
<_nft_for_proto-<type>-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 = { <nftables> list table <table_family> <table> | grep -qP '^\s+set\s+'; } || {
_nft_shutdown_table = { <nftables> list table <table_family> <table> | grep -qE '^\s+set\s+'; } || {
<nftables> delete table <table_family> <table>
}
@ -97,7 +97,7 @@ actionstop = %(_nft_del_set)s
<_nft_shutdown_table>
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Notes.: command executed once in error case by other command (during the check/restore sane environment process)
# Values: CMD
#
actioncheck = <nftables> list chain <table_family> <table> <chain> | grep -q '@<addr_set>[ \t]'
@ -197,6 +197,11 @@ addr_set = addr-set-<name>
# 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 = <sp>flags interval\;
[Init?family=inet6]
addr_family = ip6
addr_type = ipv6_addr

View file

@ -4,6 +4,7 @@
#
# Author: Nick Hilliard <nick@foobar.org>
# Modified by: Alexander Koeppe making PF work seamless and with IPv4 and IPv6
# Modified by: Balazs Mateffy adding allproto option so all traffic gets blocked from the malicious source
#
#
@ -26,9 +27,11 @@
# }
# to your main pf ruleset, where "namei" are the names of the jails
# which invoke this action
# to block all protocols use the pf[protocol=all] option
actionstart = echo "table <<tablename>-<name>> persist counters" | <pfctl> -f-
port="<port>"; if [ "$port" != "" ] && case "$port" in \{*) false;; esac; then port="{$port}"; fi
echo "<block> proto <protocol> from <<tablename>-<name>> to <actiontype>" | <pfctl> -f-
protocol="<protocol>"; if [ "$protocol" != "all" ]; then protocol="proto $protocol"; else protocol=all; fi
echo "<block> $protocol from <<tablename>-<name>> to <actiontype>" | <pfctl> -f-
# Option: start_on_demand - to start action on demand
# Example: `action=pf[actionstart_on_demand=true]`
@ -98,6 +101,7 @@ tablename = f2b
#
# The action you want pf to take.
# Probably, you want "block quick", but adjust as needed.
# If you want to log all blocked use "blog log quick"
block = block quick
# Option: protocol

View file

@ -51,7 +51,7 @@
# Values: CMD
#
actionstart = if ! ipset -quiet -name list f2b-<name> >/dev/null;
then ipset -quiet -exist create f2b-<name> hash:ip timeout <default-ipsettime>;
then ipset -quiet -exist create f2b-<name> <ipsettype> timeout <default-ipsettime> maxelem <maxelem>;
fi
# Option: actionstop
@ -88,6 +88,19 @@ default-ipsettime = 0
# Values: [ NUM ] Default: 0 (managed by fail2ban by unban)
ipsettime = 0
# expresion to caclulate timeout from bantime, example:
# expression to calculate timeout from bantime, example:
# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>']
timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0)
[Init]
# Option: ipsettype
# Notes: specifies type of set, see `man --pager='less -p "^SET TYPES"' ipset` for details
# Values: hash:ip, hash:net, etc... Default: hash:ip
ipsettype = hash:ip
# Option: maxelem
# Notes: maximal number of elements which can be stored in the ipset
# You may want to increase this for long-duration/high-volume jails
# Values: [ NUM ] Default: 65536
maxelem = 65536

View file

@ -19,7 +19,8 @@
import socket
import smtplib
from email.mime.text import MIMEText
import email.policy
from email.message import EmailMessage
from email.utils import formatdate, formataddr
from fail2ban.server.actions import ActionBase, CallingMap
@ -75,7 +76,7 @@ class SMTPAction(ActionBase):
"""
def __init__(
self, jail, name, host="localhost", user=None, password=None,
self, jail, name, host="localhost", ssl=False, user=None, password=None,
sendername="Fail2Ban", sender="fail2ban", dest="root", matches=None):
"""Initialise action.
@ -88,6 +89,8 @@ class SMTPAction(ActionBase):
host : str, optional
SMTP host, of host:port format. Default host "localhost" and
port "25"
ssl : bool, optional
Whether to use TLS for the SMTP connection or not. Default False.
user : str, optional
Username used for authentication with SMTP server.
password : str, optional
@ -109,7 +112,7 @@ class SMTPAction(ActionBase):
super(SMTPAction, self).__init__(jail, name)
self.host = host
#TODO: self.ssl = ssl
self.ssl = ssl
self.user = user
self.password =password
@ -149,16 +152,25 @@ class SMTPAction(ActionBase):
See Python `smtplib` for full list of other possible
exceptions.
"""
msg = MIMEText(text)
msg = EmailMessage(policy=email.policy.SMTP)
msg.set_content(text)
msg['Subject'] = subject
msg['From'] = formataddr((self.fromname, self.fromaddr))
msg['To'] = self.toaddr
msg['Date'] = formatdate()
smtp = smtplib.SMTP()
smtp_host, smtp_port = self.host.split(':')
smtp = smtplib.SMTP(host=smtp_host, port=smtp_port)
try:
r = smtp.connect(host=smtp_host, port=smtp_port)
self._logSys.debug("Connected to SMTP '%s', response: %i: %s",
self.host, *smtp.connect(self.host))
self.host, *r)
if self.ssl: # pragma: no cover
r = smtp.starttls()[0];
if r != 220: # pragma: no cover
raise Exception("Failed to starttls() on '%s': %s" % (self.host, r))
if self.user and self.password: # pragma: no cover (ATM no tests covering that)
smtp.login(self.user, self.password)
failed_recipients = smtp.sendmail(

View file

@ -44,7 +44,7 @@ _kill_conntrack = conntrack -D -s "<ip>"
# Option: kill
# Notes.: can be used to specify custom killing feature, by default depending on option kill-mode
# Examples: banaction = ufw[kill='ss -K "( sport = :http || sport = :https )" dst "[<ip>]"']
# Examples: banaction = ufw[kill='ss -K "dst = [<ip>] && ( sport = :http || sport = :https )"']
# banaction = ufw[kill='cutter "<ip>"']
kill = <_kill_<kill-mode>>

View file

@ -44,7 +44,13 @@ actioncheck =
actionban = oifs=${IFS};
RESOLVER_ADDR="%(addr_resolver)s"
if [ "<debug>" -gt 0 ]; then echo "try to resolve $RESOLVER_ADDR"; fi
ADDRESSES=$(dig +short -t txt -q $RESOLVER_ADDR | tr -d '"')
ADDRESSES=$(dig +short -t txt -q $RESOLVER_ADDR | grep -v ';;' | tr -d '"')
if [ "<debug>" -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 [ "<debug>" -gt 0 ]; then exit 1; fi
exit 0
fi
IFS=,; ADDRESSES=$(echo $ADDRESSES)
IFS=${oifs}
IP=<ip>
@ -55,13 +61,11 @@ actionban = oifs=${IFS};
TLP=<tlp>
PORT=<port>
DATE=`LC_ALL=C date --date=@<time> +"%%a, %%d %%h %%Y %%T %%z"`
if [ ! -z "$ADDRESSES" ]; then
oifs=${IFS}; IFS=,; ADDRESSES=$(echo $ADDRESSES)
IFS=${oifs}
(printf -- %%b "<header>\n<message>\n<report>\n\n";
date '+Note: Local timezone is %%z (%%Z)';
printf -- %%b "\n<ipmatches>\n\n<footer>") | <mailcmd> <mailargs> $ADDRESSES
fi
oifs=${IFS}; IFS=,; ADDRESSES=$(echo $ADDRESSES)
IFS=${oifs}
(printf -- %%b "<header>\n<message>\n<report>\n\n";
date '+Note: Local timezone is %%z (%%Z)';
printf -- %%b "\n<ipmatches>\n\n<footer>") | <mailcmd> <mailargs> $ADDRESSES
actionunban =

View file

@ -64,7 +64,7 @@ ignoreregex =
# ^user .*: one-time-nonce mismatch - sending new nonce\s*$
# ^realm mismatch - got `(?:[^']*|.*?)' but no realm specified\s*$
#
# Because url/referer are foreign input, short form of regex used if long enough to idetify failure.
# Because url/referer are foreign input, short form of regex used if long enough to identify failure.
#
# Author: Cyril Jaquier
# Major edits by Daniel Black and Ben Rubson.

View file

@ -10,7 +10,8 @@
badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider|(?:Mozilla/\d+\.\d+ )?Jorgee
badbots = Atomic_Email_Hunter/4\.0|atSpider/1\.0|autoemailspider|bwh3_user_agent|China Local Browse 2\.6|ContactBot/0\.2|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailSpider|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Guestbook Auto Submitter|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 \+http\://letscrawl\.com/|Lincoln State Web Browser|LMQueueBot/0\.2|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|MVAClient|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/3\.0 \(compatible; scan4mail \(advanced version\) http\://www\.peterspages\.net/?scan4mail\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|NameOfAgent \(CMS Spider\)|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|ShablastBot 1\.0|snap\.com beta crawler v0|Snapbot/1\.0|Snapbot/1\.0 \(Snap Shots&#44; \+http\://www\.snap\.com\)|sogou develop spider|Sogou Orion spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sogou spider|Sogou web spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|VadixBot|WebVulnCrawl\.unknown/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00
failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$
vhostpref = (?:[\w]+[\w\-\.]*\s+)?
failregex = ^\s*%(vhostpref)s<ADDR> [^"]*"[A-Z]{3,10} [^"]+" \d+ \d+ "[^"]+" "[^"]*(?:%(badbots)s|%(badbotscustom)s)"$
ignoreregex =

View file

@ -29,7 +29,7 @@ apache-prefix = <apache-prefix-<logging>>
apache-pref-ignore =
_apache_error_client = <apache-prefix>\[(:?error|<apache-pref-ignore>\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client <HOST>(:\d{1,5})?\]
_apache_error_client = <apache-prefix>\[(:?error|<apache-pref-ignore>\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[(?:client|remote) <HOST>(:\d{1,5})?\]
datepattern = {^LN-BEG}

View file

@ -2,7 +2,8 @@
[Definition]
failregex = ^\s*<HOST> \S+ \S+(?: \S+)?\s+\S+ "[A-Z]+ /\S* [^"]*" \d+ \d+ \"[^"]*\" "[^"]*\bGooglebot/[^"]*"
vhostpref = (?:[\w]+[\w\-\.]*\s+)?
failregex = ^\s*%(vhostpref)s<ADDR> [^"]*"[A-Z]{3,10} /\S* [^"]*" \d+ \d+ "[^"]*" "[^"]*\bGooglebot/[^"]*"
ignoreregex =

View file

@ -19,11 +19,10 @@ before = apache-common.conf
script = /\S*(?:php(?:[45]|[.-]cgi)?|\.asp|\.exe|\.pl|\bcgi-bin/)
prefregex = ^%(_apache_error_client)s (?:AH0(?:01(?:28|30)|1(?:264|071)|2811): )?(?:(?:[Ff]ile|script|[Gg]ot) )<F-CONTENT>.+</F-CONTENT>$
prefregex = ^%(_apache_error_client)s (?:AH0(?:01(?:28|30)|1(?:264|071)|2811): )?(?=(?:[Ff]ile|[Ss]cript|[Gg]ot error|stderr from) )<F-CONTENT>.+</F-CONTENT>$
failregex = ^(?:does not exist|not found or unable to stat): <script>\b
^'<script>\S*' not found or unable to stat
^error '[Pp]rimary script unknown(?:\\n)?'
failregex = ^(?:(?:[Ff]ile does not exist|[Ss]cript not found or unable to stat): <script>\b|[Gg]ot error '[Pp]rimary script unknown\b)
^(?:stderr from |script (?P<_q>'))<script>\S*(?(_q)'|) (?:script )?(?:does not exist|not found or unable to stat)
ignoreregex =

View file

@ -8,7 +8,7 @@ before = apache-common.conf
[Definition]
failregex = ^%(_apache_error_client)s (?:(?:AH001[23][456]: )?Invalid (method|URI) in request\b|(?:AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string:|(?:AH00566: )?request failed: invalid characters in URI\b)
failregex = ^%(_apache_error_client)s (?:(?:AH(?:001[23][456]|10244): )?[Ii]nvalid (method|URI)\b|(?:AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string:|(?:AH00566: )?request failed: invalid characters in URI\b)
ignoreregex =

View file

@ -21,13 +21,13 @@ log_prefix= (?:NOTICE|SECURITY|WARNING)%(__pid_re)s:?(?:\[C-[\da-f]*\])?:? [^:]+
prefregex = ^%(__prefix_line)s%(log_prefix)s <F-CONTENT>.+</F-CONTENT>$
failregex = ^Registration from '[^']*' failed for '<HOST>(:\d+)?' - (?:Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$
^Call from '[^']*' \((?:(?:TCP|UDP):)?<HOST>:\d+\) to extension '[^']*' rejected because extension not found in context
^Call (?:from '[^']*' )?\((?:(?:TCP|UDP):)?<HOST>:\d+\) to extension '[^']*' rejected because extension not found in context
^(?:Host )?<HOST> (?:failed (?:to authenticate\b|MD5 authentication\b)|tried to authenticate with nonexistent user\b)
^No registration for peer '[^']*' \(from <HOST>\)$
^hacking attempt detected '<HOST>'$
^SecurityEvent="(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)"(?:(?:,(?!RemoteAddress=)\w+="[^"]*")*|.*?),RemoteAddress="IPV[46]/[^/"]+/<HOST>/\d+"(?:,(?!RemoteAddress=)\w+="[^"]*")*$
^"Rejecting unknown SIP connection from <HOST>(?::\d+)?"$
^Request (?:'[^']*' )?from '(?:[^']*|.*?)' failed for '<HOST>(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$
^Request (?:'[^']*' )?from '(?:[^']*|.*?)' failed for '<HOST>(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\b[^']*$
# FreePBX (todo: make optional in v.0.10):
# ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )[^:]+: Friendly Scanner from <HOST>$

View file

@ -0,0 +1,16 @@
# Fail2Ban filter for dante
#
# Make sure you have "log: error" set in your "client pass" directive
#
[INCLUDES]
before = common.conf
[Definition]
_daemon = danted
failregex = ^%(__prefix_line)sinfo: block\(\d\): tcp/accept \]: <ADDR>\.\d+ \S+: error after reading \d+ bytes? in \d+ seconds?: (?:could not access|system password authentication failed for|pam_authenticate\(\) for) user "<F-USER>[^"]+</F-USER>"
[Init]
journalmatch = _SYSTEMD_UNIT=danted.service

View file

@ -7,19 +7,21 @@ before = common.conf
[Definition]
_daemon = (?:dovecot(?:-auth)?|auth)
_auth_worker = (?:dovecot: )?auth(?:-worker)?
_auth_worker_info = (?:conn \w+:auth(?:-worker)? \([^\)]+\): auth(?:-worker)?<\d+>: )?
_daemon = (?:dovecot(?:-auth)?|auth)
_bypass_reject_reason = (?:: (?:\w+\([^\):]*\) \w+|[^\(]+))*
prefregex = ^%(__prefix_line)s(?:%(_auth_worker)s(?:\([^\)]+\))?: )?(?:%(__pam_auth)s(?:\(dovecot:auth\))?: |(?:pop3|imap|managesieve|submission)-login: )?(?:Info: )?%(_auth_worker_info)s<F-CONTENT>.+</F-CONTENT>$
failregex = ^authentication failure; logname=<F-ALT_USER1>\S*</F-ALT_USER1> uid=\S* euid=\S* tty=dovecot ruser=<F-USER>\S*</F-USER> rhost=<HOST>(?:\s+user=<F-ALT_USER>\S*</F-ALT_USER>)?\s*$
^(?:Aborted login|Disconnected|Remote closed connection|Client has quit the connection)(?:: (?:[^\(]+|\w+\([^\)]*\))+)? \((?:auth failed, \d+ attempts(?: in \d+ secs)?|tried to use (?:disabled|disallowed) \S+ auth|proxy dest auth failed)\):(?: user=<<F-USER>[^>]*</F-USER>>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
^(?:Login aborted|Aborted login|Disconnected|Remote closed connection|Client has quit the connection)%(_bypass_reject_reason)s \((?:auth failed, \d+ attempts(?: in \d+ secs)?|tried to use (?:disabled|disallowed) \S+ auth|proxy dest auth failed)\)[^:]*:(?: user=<<F-USER>[^>]*</F-USER>>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
^pam\(\S+,<HOST>(?:,\S*)?\): pam_authenticate\(\) failed: (?:User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \([Pp]assword mismatch\?\)|Permission denied)\s*$
^[a-z\-]{3,15}\(\S*,<HOST>(?:,\S*)?\): (?:[Uu]nknown user|[Ii]nvalid credentials|[Pp]assword mismatch)
<mdre-<mode>>
mdre-aggressive = ^(?:Aborted login|Disconnected|Remote closed connection|Client has quit the connection)(?::(?: [^ \(]+)+)? \((?:no auth attempts|disconnected before auth was ready,|client didn't finish \S+ auth,)(?: (?:in|waited) \d+ secs)?\):(?: user=<[^>]*>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
mdre-aggressive = ^(?:Login aborted|Aborted login|Disconnected|Remote closed connection|Client has quit the connection)%(_bypass_reject_reason)s \((?:no auth attempts|disconnected before auth was ready,|client didn't finish \S+ auth,|disconnected during TLS handshake)(?: (?:in|waited) \d+ secs)?\)[^:]*:(?: user=<[^>]*>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
mdre-normal =
@ -41,6 +43,7 @@ datepattern = {^LN-BEG}TAI64N
# DEV Notes:
# * the first regex is essentially a copy of pam-generic.conf
# * Probably doesn't do dovecot sql/ldap backends properly (resolved in edit 21/03/2016)
# * Dovecot version 2.4 changed event log structure, line prior needed to maintain 2.3 support
#
# Author: Martin Waschbuesch
# Daniel Black (rewrote with begin and end anchors)

View file

@ -23,14 +23,17 @@ before = common.conf
_daemon = dropbear
prefregex = ^%(__prefix_line)s<F-CONTENT>(?:[Ll]ogin|[Bb]ad|[Ee]xit).+</F-CONTENT>$
prefregex = ^%(__prefix_line)s(?:\[\d+\] \w{2,3} [\d:\s]+)?<F-CONTENT>(?:[Ll]ogin|[Bb]ad|[Ee]xit).+</F-CONTENT>$
failregex = ^[Ll]ogin attempt for nonexistent user ('.*' )?from <HOST>:\d+$
^[Bb]ad (PAM )?password attempt for .+ from <HOST>(:\d+)?$
^[Ee]xit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '.+' from <HOST>:\d+\s*$
failregex = ^[Ll]ogin attempt for nonexistent user (?:'<F-USER>.*</F-USER>' )?from <HOST>:\d+$
^[Bb]ad (?:PAM )?password attempt for '<F-USER>.+</F-USER>' from <HOST>(?::\d+)?$
^[Ee]xit before auth from \<?<ADDR>:\d+\>?: (?:\([^\)]*\): )?Max auth tries reached - user '<F-USER>.+</F-USER>'\s*$
^[Ee]xit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '<F-USER>.+</F-USER>' from <HOST>:\d+\s*$
ignoreregex =
journalmatch = _SYSTEMD_UNIT=dropbear.service + _COMM=dropbear
# DEV Notes:
#
# The first two regexs here match the unmodified dropbear messages. It isn't

View file

@ -9,12 +9,43 @@ after = exim-common.local
[Definition]
host_info_pre = (?:H=([\w.-]+ )?(?:\(\S+\) )?)?
host_info_suf = (?::\d+)?(?: I=\[\S+\](:\d+)?)?(?: U=\S+)?(?: P=e?smtp)?(?: F=(?:<>|[^@]+@\S+))?\s
host_info = %(host_info_pre)s\[<HOST>\]%(host_info_suf)s
pid = (?: \[\d+\]| \w+ exim\[\d+\]:)?
_fields_grp = (?: (?!H=)[A-Za-z]{1,4}(?:=\S+)?)*
host_info = %(_fields_grp)s (?:H=)?(?:[\w.-]+)? ?(?:\(\S+\))? ?\[<ADDR>\](?::\d+)?%(_fields_grp)s
pid = (?:\s?\[\d+\]|\s?[\w\.-]+ exim\[\d+\]:){0,2}
# DEV Notes:
# From exim source code: ./src/receive.c:add_host_info_for_log
#
# Author: Daniel Black
logtype = file
_add_pref = <lt_<logtype>/_add_pref>
__prefix_line = %(pid)s%(_add_pref)s
[lt_journal]
_add_pref = (?: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})?
[lt_file]
_add_pref =
# DEV Notes
# ------------
# Host string happens:
# H=[ip address]
# H=(helo_name) [ip address]
# H=host_name [ip address]
# H=host_name (helo_name) [ip address]
# flags H=host_name (helo_name) [ip address] flags
# where only [ip address] always visible, ignore ident
# From exim source code:
# src/src/host.c:host_and_ident()
# src/receive.c:add_host_info_for_log()
# Substitution of `_fields_grp` bypasses all flags but H
# Summary of Fields in Log Lines depending on log_selector
# https://www.exim.org/exim-html-current/doc/html/spec_html/ch-log_files.html
# at version exim-4.97.1
# ---
# Authors:
# Cyril Jaquier
# Daniel Black (rewrote with strong regexs)
# Sergey G. Brester aka sebres (optimization, rewrite to prefregex, reviews)
# Martin O'Neal (added additional regexs to detect authentication failures, protocol errors, and drops)
# Vladimir Varlamov (host line definition)

View file

@ -26,11 +26,13 @@ before = exim-common.conf
[Definition]
failregex = ^%(pid)s \S+ F=(<>|\S+@\S+) %(host_info)srejected by local_scan\(\): .{0,256}$
^%(pid)s %(host_info)sF=(<>|[^@]+@\S+) rejected RCPT [^@]+@\S+: .*dnsbl.*\s*$
^%(pid)s \S+ %(host_info)sF=(<>|[^@]+@\S+) rejected after DATA: This message contains a virus \(\S+\)\.\s*$
^%(pid)s \S+ SA: Action: flagged as Spam but accepted: score=\d+\.\d+ required=\d+\.\d+ \(scanned in \d+/\d+ secs \| Message-Id: \S+\)\. From \S+ \(host=\S+ \[<HOST>\]\) for <honeypot>$
^%(pid)s \S+ SA: Action: silently tossed message: score=\d+\.\d+ required=\d+\.\d+ trigger=\d+\.\d+ \(scanned in \d+/\d+ secs \| Message-Id: \S+\)\. From \S+ \(host=(\S+ )?\[<HOST>\]\) for \S+$
prefregex = ^%(__prefix_line)s<F-CONTENT>.+</F-CONTENT>$
failregex = ^\s?\S+%(host_info)s rejected by local_scan\(\): .{0,256}$
^%(host_info)s rejected RCPT [^@]+@\S+: .*dnsbl.*\s*$
^\s?\S+%(host_info)s rejected after DATA: This message contains a virus \(\S+\)\.\s*$
^\s?\S+ SA: Action: flagged as Spam but accepted: score=\d+\.\d+ required=\d+\.\d+ \(scanned in \d+/\d+ secs \| Message-Id: \S+\)\. From \S+ \(host=\S+ \[<HOST>\]\) for <honeypot>$
^\s?\S+ SA: Action: silently tossed message: score=\d+\.\d+ required=\d+\.\d+ trigger=\d+\.\d+ \(scanned in \d+/\d+ secs \| Message-Id: \S+\)\. From \S+ \(host=(\S+ )?\[<HOST>\]\) for \S+$
ignoreregex =
@ -43,8 +45,6 @@ ignoreregex =
honeypot = trap@example.com
# DEV Notes:
# The %(host_info) defination contains a <HOST> match
#
# Author: Cyril Jaquier
# Daniel Black (rewrote with strong regexs)
# DEV Notes
# -----------
# The %(host_info) definition contains a <ADDR> match. No space before. See exim-common.conf

View file

@ -13,21 +13,23 @@ before = exim-common.conf
[Definition]
# Fre-filter via "prefregex" is currently inactive because of too different failure syntax in exim-log (testing needed):
#prefregex = ^%(pid)s <F-CONTENT>\b(?:\w+ authenticator failed|([\w\-]+ )?SMTP (?:(?:call|connection) from|protocol(?: synchronization)? error)|no MAIL in|(?:%(host_info_pre)s\[[^\]]+\]%(host_info_suf)s(?:sender verify fail|rejected RCPT|dropped|AUTH command))).+</F-CONTENT>$
prefregex = ^%(__prefix_line)s<F-CONTENT>.+</F-CONTENT>$
failregex = ^%(pid)s %(host_info)ssender verify fail for <\S+>: (?:Unknown user|Unrouteable address|all relevant MX records point to non-existent hosts)\s*$
^%(pid)s \w+ authenticator failed for (?:[^\[\( ]* )?(?:\(\S*\) )?\[<HOST>\](?::\d+)?(?: I=\[\S+\](:\d+)?)?: 535 Incorrect authentication data( \(set_id=.*\)|: \d+ Time\(s\))?\s*$
^%(pid)s %(host_info)srejected RCPT [^@]+@\S+: (?:relay not permitted|Sender verify failed|Unknown user|Unrouteable address)\s*$
^%(pid)s SMTP protocol synchronization error \([^)]*\): rejected (?:connection from|"\S+") %(host_info)s(?:next )?input=".*"\s*$
^%(pid)s SMTP call from (?:[^\[\( ]* )?%(host_info)sdropped: too many (?:nonmail commands|syntax or protocol errors) \(last (?:command )?was "[^"]*"\)\s*$
^%(pid)s SMTP protocol error in "[^"]+(?:"+[^"]*(?="))*?" %(host_info)sAUTH command used when not advertised\s*$
^%(pid)s no MAIL in SMTP connection from (?:[^\[\( ]* )?(?:\(\S*\) )?%(host_info)sD=\d\S*s(?: C=\S*)?\s*$
^%(pid)s (?:[\w\-]+ )?SMTP connection from (?:[^\[\( ]* )?(?:\(\S*\) )?%(host_info)sclosed by DROP in ACL\s*$
failregex = ^\s?\w+ authenticator failed for%(host_info)s: 535 Incorrect authentication data(?: \(set_id=.*\)|: \d+ Time\(s\))?\s*$
<mdre-<mode>>
mdre-aggressive = ^%(pid)s no host name found for IP address <HOST>$
^%(pid)s no IP address found for host \S+ \(during SMTP connection from \[<HOST>\]\)$
mdre-more = ^%(host_info)s sender verify fail for <\S+>: (?:Unknown user|Unrouteable address|all relevant MX records point to non-existent hosts)\s*$
^%(host_info)s rejected RCPT (?:<F-RCPT>[^@]+@\S+</F-RCPT>:)?
^\s?SMTP protocol synchronization error \([^)]*\): rejected (?:connection from|"\S+")%(host_info)s (?:next )?input=".*"\s*$
^\s?SMTP call from%(host_info)s dropped: too many (?:(?:nonmail|unrecognized) commands|syntax or protocol errors)
^\s?SMTP protocol error in "[^"]+(?:"+[^"]*(?="))*?"%(host_info)s [A-Z]+ (?:command used when not advertised|authentication mechanism not supported)\s*$
^\s?no MAIL in SMTP connection from%(host_info)s
^\s?(?:[\w\-]+ )?SMTP connection from%(host_info)s closed by DROP in ACL\s*$
mdre-aggressive = %(mdre-more)s
^\s?no host name found for IP address <ADDR>$
^\s?no IP address found for host \S+ \(during SMTP connection from%(host_info)s\)$
^%(host_info)s dropped by '[^']+' ACL:
mdre-normal =
@ -42,13 +44,10 @@ mode = normal
ignoreregex =
# DEV Notes:
# The %(host_info) defination contains a <HOST> match
# DEV Notes
# -----------
# The %(host_info) definition contains a <ADDR> match. No space before. See exim-common.conf
#
# SMTP protocol synchronization error \([^)]*\) <- This needs to be non-greedy
# to void capture beyond ")" to avoid a DoS Injection vulnerabilty as input= is
# to void capture beyond ")" to avoid a DoS Injection vulnerability as input= is
# user injectable data.
#
# Author: Cyril Jaquier
# Daniel Black (rewrote with strong regexs)
# Martin O'Neal (added additional regexs to detect authentication failures, protocol errors, and drops)

View file

@ -29,9 +29,9 @@ _daemon = freeswitch
mode = extra
# Prefix contains common prefix line (server, daemon, etc.) and 2 datetimes if used systemd backend
_pref_line = ^%(__prefix_line)s(?:(?:\d+-)?\d+-\d+ \d+:\d+:\d+\.\d+)?
_pref_line = ^%(__prefix_line)s[^\[]*
prefregex = ^%(_pref_line)s \[WARN(?:ING)?\](?: \[SOFIA\])? \[?sofia_reg\.c:\d+\]? <F-CONTENT>.+</F-CONTENT>$
prefregex = ^%(_pref_line)s\s*\[WARN(?:ING)?\](?: \[SOFIA\])? \[?sofia_reg\.c:\d+\]? <F-CONTENT>.+</F-CONTENT>$
cmnfailre = ^Can't find user \[[^@]+@[^\]]+\] from <HOST>$

View file

@ -1,11 +1,15 @@
# Fail2Ban configuration file to block repeated failed login attempts to Frolor installation(s)
#
# Froxlor needs to log to Syslog User (e.g. /var/log/user.log) with one of the following messages
# <syslog prefix> Froxlor: [Login Action <HOST>] Unknown user '<USER>' tried to login.
# <syslog prefix> Froxlor: [Login Action <HOST>] User '<USER>' tried to login with wrong password.
# - for type=2
# <syslog prefix> froxlor[1-6]: froxlor.WARNING: Unknown user tried to login. {"source":"login","action":"50","user":"<ADDR>"} []
# <syslog prefix> froxlor[1-6]: froxlor.WARNING: User tried to login with wrong password. {"source":"login","action":"50","user":"<ADDR>"} []
# - for type=1:
# <syslog prefix> Froxlor: [Login Action <ADDR>] Unknown user '<USER>' tried to login.
# <syslog prefix> Froxlor: [Login Action <ADDR>] User '<USER>' tried to login with wrong password.
#
# Author: Joern Muehlencord
#
# Modified: Para-do-x™ - Andreas Duennwald
[INCLUDES]
@ -13,28 +17,18 @@
# common.local
before = common.conf
[DEFAULT]
_daemon = [Ff]roxlor
_re = (?:Unknown )?[uU]ser(?: '<F-USER>(?:\S*|[^']*)</F-USER>')? tried to login(?: with wrong password)?\.
[type1]
failregex = ^%(__prefix_line)s\[Login Action <ADDR>\] %(_re)s$
[type2]
failregex = ^%(__prefix_line)sfroxlor\.WARNING: %(_re)s \{(?:"[^"]+":"[^"]*",\s*){,5}"user":"<ADDR>"\} \[\]$
[Definition]
_daemon = Froxlor
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching and is only an alias for
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values: TEXT
#
prefregex = ^%(__prefix_line)s\[Login Action <HOST>\] <F-CONTENT>.+</F-CONTENT>$
failregex = ^Unknown user \S* tried to login.$
^User \S* tried to login with wrong password.$
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
type = 2
failregex = <type<type>/failregex>
ignoreregex =

View file

@ -3,8 +3,8 @@
[Definition]
failregex = ^\s*(?:: )?\(?(?:http|mod)_auth\.c\.\d+\) (?:password doesn\'t match for (?:\S+|.*?) username:\s+<F-USER>(?:\S+|.*?)</F-USER>\s*|digest: auth failed(?: for\s+<F-ALT_USER>(?:\S+|.*?)</F-ALT_USER>\s*)?: (?:wrong password|uri mismatch \([^\)]*\))|get_password failed),? IP: <HOST>\s*$
failregex = ^[^\)]*\(?(?:http|mod)_auth\.c\.\d+\) (?:password doesn\'t match for (?:\S+|.*?) username:\s+<F-USER>(?:\S+|.*?)</F-USER>\s*|digest: auth failed(?: for\s+<F-ALT_USER>(?:\S+|.*?)</F-ALT_USER>\s*)?: (?:wrong password|uri mismatch \([^\)]*\))|get_password failed),? IP: <HOST>\s*$
ignoreregex =
ignoreregex =
# Author: Francois Boulogne <fboulogne@april.org>
# Authors: Francois Boulogne <fboulogne@april.org>, Lucian Maly <lmaly@redhat.com>

View file

@ -1,4 +1,4 @@
# Fail2Ban filter for unsuccesfull MongoDB authentication attempts
# Fail2Ban filter for unsuccessful MongoDB authentication attempts
#
# Logfile /var/log/mongodb/mongodb.log
#
@ -23,7 +23,7 @@ maxlines = 10
#
# Regarding the multiline regex:
#
# There can be a nunber of non-related lines between the first and second part
# There can be a number of non-related lines between the first and second part
# of this regex maxlines of 10 is quite generious.
#
# Note the capture __connid, includes the connection ID, used in second part of regex.

View file

@ -1,9 +1,10 @@
# Fail2Ban filter for unsuccesful MySQL authentication attempts
# Fail2Ban filter for unsuccessful MySQL authentication attempts
#
#
# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld]:
# log-error=/var/log/mysqld.log
# log-warnings = 2
# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld],
# `log_error_verbosity` system variable set to 3 (`log-warnings = 2` for older versions),
# and check whether `log_error` (or `log-error`) system variable would match the `logpath` of fail2ban
# (see https://dev.mysql.com/doc/refman/en/communication-errors.html)
#
# If using mysql syslog [mysql_safe] has syslog in /etc/my.cnf
@ -17,7 +18,7 @@ before = common.conf
_daemon = mysqld
failregex = ^%(__prefix_line)s(?:(?:\d{6}|\d{4}-\d{2}-\d{2})[ T]\s?\d{1,2}:\d{2}:\d{2} )?(?:\d+ )?\[\w+\] (?:\[[^\]]+\] )*Access denied for user '<F-USER>[^']+</F-USER>'@'<HOST>' (to database '[^']*'|\(using password: (YES|NO)\))*\s*$
failregex = ^%(__prefix_line)s(?:(?:\d{6}|\d{4}-\d{2}-\d{2})[ T]\s?\d{1,2}:\d{2}:\d{2} )?(?:\d+ )?\[\w+\] (?:\[[^\]]+\] )*Access denied for user '<F-USER>[^']+</F-USER>'@'<HOST>'(?:\s+(?:to database '[^']*'|\(using password: (?:YES|NO)\)){1,2})?\s*$
ignoreregex =

View file

@ -30,11 +30,14 @@ __pid_re=(?:\[\d+\])
__daemon_re=\(?%(_daemon)s(?:\(\S+\))?\)?:?
__daemon_combs_re=(?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:)
_category = (?!error|info)[\w-]+
_category_re = (?:%(_category)s: )?
# hostname daemon_id spaces
# this can be optional (for instance if we match named native log files)
__line_prefix=(?:\s*\S+ %(__daemon_combs_re)s\s+)?
__line_prefix=\s*(?:\S+ %(__daemon_combs_re)s\s+)?%(_category_re)s
prefregex = ^%(__line_prefix)s(?: error:)?\s*client(?: @\S*)? <HOST>#\S+(?: \([\S.]+\))?: <F-CONTENT>.+</F-CONTENT>\s(?:denied|\(NOTAUTH\))\s*$
prefregex = ^%(__line_prefix)s(?:(?:error|info):\s*)?client(?: @\S*)? <HOST>#\S+(?: \([\S.]+\))?: <F-CONTENT>.+</F-CONTENT>\s(?:denied(?: \([^\)]*\))?|\(NOTAUTH\))\s*$
failregex = ^(?:view (?:internal|external): )?query(?: \(cache\))?
^zone transfer

View file

@ -0,0 +1,32 @@
# Generic nginx error_log configuration items (to be used as interpolations) in other
# filters monitoring nginx error-logs
#
[DEFAULT]
# Type of log-file resp. log-format (file, short, journal):
logtype = file
# Daemon definition is to be specialized (if needed) in .conf file
_daemon = nginx
# Common line prefixes (beginnings) which could be used in filters
#
# [bsdverbose]? [hostname] [vserver tag] daemon_id spaces
#
# This can be optional (for instance if we match named native log files)
__prefix = <lt_<logtype>/__prefix>
__err_type = error
__prefix_line = %(__prefix)s\[%(__err_type)s\] \d+#\d+: \*\d+\s+
[lt_file]
__prefix = \s*
[lt_short]
__prefix = \s*(?:(?!\[)\S+ %(_daemon)s\[\d+\]: [^\[]*)?
[lt_journal]
__prefix = %(lt_short/__prefix)s

View file

@ -0,0 +1,29 @@
# fail2ban filter configuration for nginx forbidden accesses
#
# If you have configured nginx to forbid some paths in your webserver, e.g.:
#
# location ~ /\. {
# deny all;
# }
#
# if a client tries to access https://yoursite/.user.ini then you will see
# in nginx error log:
#
# 2018/09/14 19:03:05 [error] 2035#2035: *9134 access forbidden by rule, client: 10.20.30.40, server: www.example.net, request: "GET /.user.ini HTTP/1.1", host: "www.example.net", referrer: "https://www.example.net"
#
# By carefully setting this filter we ban every IP that tries too many times to
# access forbidden resources.
#
# Author: Michele Bologna https://www.michelebologna.net/
[INCLUDES]
before = nginx-error-common.conf
[Definition]
failregex = ^%(__prefix_line)saccess forbidden by rule, client: <HOST>
ignoreregex =
datepattern = {^LN-BEG}
journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx

View file

@ -1,14 +1,25 @@
# fail2ban filter configuration for nginx
[INCLUDES]
before = nginx-error-common.conf
[Definition]
mode = normal
mdre-auth = ^\s*\[error\] \d+#\d+: \*\d+ user "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\s*$
mdre-fallback = ^\s*\[crit\] \d+#\d+: \*\d+ SSL_do_handshake\(\) failed \(SSL: error:\S+(?: \S+){1,3} too (?:long|short)\)[^,]*, client: <HOST>
__err_type = (?:error|crit)
__suffix_line = , client: <ADDR>(?:, (?:server|request|host|referrer): (?:"[^"]*"|\S*)){0,4}
prefregex = ^%(__prefix_line)s<F-CONTENT>.*</F-CONTENT>%(__suffix_line)s\s*$
mdre-auth = ^user "<F-USER>(?:[^"]+|.*?)</F-USER>":? (?:password mismatch|was not found in "[^\"]*")$
^(?:PAM: )?user '<F-USER>(?:[^']+|.*?)</F-USER>' - not authenticated: Authentication failure$
mdre-fallback = ^SSL_(?:do_handshake|read)\(\) failed \(SSL: error:\S+(?: \S+){1,3}[^\)]*\)[^,]*
mdre-normal = %(mdre-auth)s
mdre-aggressive = %(mdre-auth)s
%(mdre-fallback)s

View file

@ -23,6 +23,10 @@
# ...
#
[INCLUDES]
before = nginx-error-common.conf
[Definition]
# Specify following expression to define exact zones, if you want to ban IPs limited
@ -33,13 +37,16 @@
#
ngx_limit_req_zones = [^"]+
# Depending on limit_req_log_level directive (may be: info | notice | warn | error):
__err_type = [a-z]+
# Use following full expression if you should range limit request to specified
# servers, requests, referrers etc. only :
#
# failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
# failregex = ^%(__prefix_line)slimiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
# Shortly, much faster and stable version of regexp:
failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ limiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,
failregex = ^%(__prefix_line)s(?:limiting|delaying) (?:request|connection)s?(?:, excess: [\d\.]+,?)? by zone "(?:%(ngx_limit_req_zones)s)", client: <ADDR>,
ignoreregex =

View file

@ -0,0 +1,13 @@
# Fail2Ban filter for openvpn server
# Detecting wrong TLS handshakes
# typically logged in /var/log/syslog
# Author: Philipp Burndorfer
[INCLUDES]
before = common.conf
[Definition]
_daemon = ovpn-server\d*
failregex = ^%(__prefix_line)s<HOST>:\d{4,5} (?:TLS Auth Error:|VERIFY ERROR:|TLS Error: TLS handshake failed\b|SIGUSR1\[soft,connection-reset\] received\b)
^%(__prefix_line)sTLS Error: cannot locate HMAC in incoming packet from \[AF_INET\]\s*<HOST>:\d{4,5}

View file

@ -10,50 +10,63 @@ before = common.conf
[Definition]
_daemon = postfix(-\w+)?/\w+(?:/smtp[ds])?
_daemon = postfix\b([^\[\s]+)?
# optional port:
_port = (?::\d+)?
_pref = [A-Z]{4}
# optional prefix like `NOQUEUE: ` or `00ADB3C0899: ` etc...
_pref = (?:\w+: )?
# SMTP commands like RCPT etc
_cmd = [A-Z]{4,}
prefregex = ^%(__prefix_line)s<mdpr-<mode>> <F-CONTENT>.+</F-CONTENT>$
prefregex = ^%(__prefix_line)s%(_pref)s<mdpr-<mode>> <F-CONTENT>.+</F-CONTENT>$
# Extended RE for normal mode to match reject by unknown users or undeliverable address, can be set to empty to avoid this:
exre-user = |[Uu](?:ser unknown|ndeliverable address)
exre-user = |[Uu](?:ser unknown|ndeliverable address) ; pragma: codespell-ignore
mdpr-normal = (?:\w+: (?:milter-)?reject:|(?:improper command pipelining|too many errors) after \S+)
mdre-normal=^%(_pref)s from [^[]*\[<HOST>\]%(_port)s: [45][50][04] [45]\.\d\.\d+ (?:(?:<[^>]*>)?: )?(?:(?:Helo command|(?:Sender|Recipient) address) rejected: )?(?:Service unavailable|(?:Client host|Command|Data command) rejected|Relay access denied|(?:Host|Domain) not found|need fully-qualified hostname|match%(exre-user)s)\b
mdpr-normal = (?:(?:milter-)?reject:|(?:improper command pipelining|too many errors) after \S+)
mdre-normal=^%(_cmd)s from [^[]*\[<HOST>\]%(_port)s: [45][50][04] [45]\.\d\.\d+ (?:(?:<[^>]*>)?: )?(?:(?:Helo command|(?:Sender|Recipient) address) rejected: )?(?:Service unavailable|Access denied|(?:Client host|Command|Data command) rejected|Relay access denied|Malformed DNS server reply|(?:Host|Domain) not found|need fully-qualified hostname|match%(exre-user)s)\b
^from [^[]*\[<HOST>\]%(_port)s:?
mdad-normal =
mdpr-auth = warning:
mdre-auth = ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server| Invalid authentication mechanism)
mdre-auth2= ^[^[]*\[<HOST>\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server)
# todo: check/remove "Invalid authentication mechanism" from ignore list, if gh-1243 will get finished (see gh-1297).
mdad-auth =
mdad-auth2 =
# Mode "rbl" currently included in mode "normal", but if needed for jail "postfix-rbl" only:
mdpr-rbl = %(mdpr-normal)s
mdre-rbl = ^%(_pref)s from [^[]*\[<HOST>\]%(_port)s: [45]54 [45]\.7\.1 Service unavailable; Client host \[\S+\] blocked\b
mdre-rbl = ^%(_cmd)s from [^[]*\[<HOST>\]%(_port)s: [45]54 [45]\.7\.1 Service unavailable; Client host \[\S+\] blocked\b
mdad-rbl =
# Mode "rbl" currently included in mode "normal" (within 1st rule)
mdpr-more = %(mdpr-normal)s
mdre-more = %(mdre-normal)s
mdad-more =
# Includes some of the log messages described in
# <http://www.postfix.org/POSTSCREEN_README.html>.
mdpr-ddos = (?:lost connection after(?! DATA) [A-Z]+|disconnect(?= from \S+(?: \S+=\d+)* auth=0/(?:[1-9]|\d\d+))|(?:PREGREET \d+|HANGUP) after \S+|COMMAND (?:TIME|COUNT|LENGTH) LIMIT)
mdpr-ddos = (?:lost connection after (?!(?:DATA|AUTH)\b)[A-Z]+|disconnect(?= from \S+(?: \S+=\d+)* auth=0/(?:[1-9]|\d\d+))|(?:PREGREET \d+|HANGUP) after \S+|COMMAND (?:TIME|COUNT|LENGTH) LIMIT|warning:)
mdre-ddos = ^from [^[]*\[<HOST>\]%(_port)s:?
mdad-ddos = ^(?:Message delivery request|Connection) rate limit exceeded: \d+ from [^[]*\[<ADDR>\]
mdpr-extra = (?:%(mdpr-auth)s|%(mdpr-normal)s)
mdre-extra = %(mdre-auth)s
%(mdre-normal)s
mdad-extra =
mdpr-aggressive = (?:%(mdpr-auth)s|%(mdpr-normal)s|%(mdpr-ddos)s)
mdre-aggressive = %(mdre-auth2)s
%(mdre-normal)s
mdad-aggressive = %(mdad-ddos)s
mdpr-errors = too many errors after \S+
mdre-errors = ^from [^[]*\[<HOST>\]%(_port)s$
mdad-errors =
failregex = <mdre-<mode>>
<mdad-<mode>>
# Parameter "mode": more (default combines normal and rbl), auth, normal, rbl, ddos, extra or aggressive (combines all)
# Usage example (for jail.local):
@ -76,6 +89,6 @@ ignoreregex =
[Init]
journalmatch = _SYSTEMD_UNIT=postfix.service
journalmatch = _SYSTEMD_UNIT=postfix.service _SYSTEMD_UNIT=postfix@-.service
# Author: Cyril Jaquier

View file

@ -0,0 +1,20 @@
# Fail2Ban filter for Proxmox Web GUI
#
# Jail example:
# [proxmox]
# enabled = true
# port = https,http,8006
# filter = proxmox
# logpath = /var/log/daemon.log
# maxretry = 3
# # 1 hour
# bantime = 3600
[Definition]
_daemon = pvedaemon
failregex = ^\s*\S+ %(_daemon)s\[\d+\]: authentication failure; rhost=<ADDR> user=<F-USER>\S+</F-USER>
ignoreregex =

View file

@ -19,20 +19,34 @@
# common.local
before = common.conf
[Definition]
[DEFAULT]
_daemon = (?:fail2ban(?:-server|\.actions)\s*)
# The name of the jail that this filter is used for. In jail.conf, name the jail using
# this filter 'recidive', or supply another name with `filter = recidive[_jailname="jail"]`
_jailname = recidive
# this filter 'recidive', or supply another name with `filter = recidive[_jailname="jail"]`,
# default all jails excepting recidive
_jailname = (?!recidive\])[^\]]*
failregex = ^%(__prefix_line)s(?:\s*fail2ban\.actions\s*%(__pid_re)s?:\s+)?NOTICE\s+\[(?!%(_jailname)s\])(?:.*)\]\s+Ban\s+<HOST>\s*$
failregex = ^%(__prefix_line)s(?:\s*fail2ban\.actions\s*%(__pid_re)s?:\s+)?NOTICE\s+\[<_jailname>\]\s+Ban\s+<HOST>
[lt_short]
_daemon = (?:fail2ban(?:-server|\.actions)?\s*)
failregex = ^%(__prefix_line)s(?:\s*fail2ban(?:\.actions)?\s*%(__pid_re)s?:\s+)?(?:NOTICE\s+)?\[<_jailname>\]\s+Ban\s+<HOST>
[lt_journal]
_daemon = <lt_short/_daemon>
failregex = <lt_short/failregex>
[Definition]
_daemon = <lt_<logtype>/_daemon>
failregex = <lt_<logtype>/failregex>
datepattern = ^{DATE}
ignoreregex =
journalmatch = _SYSTEMD_UNIT=fail2ban.service PRIORITY=5
journalmatch = _SYSTEMD_UNIT=fail2ban.service
# Author: Tom Hendrikx, modifications by Amir Caspi

View file

@ -13,10 +13,9 @@ before = common.conf
[Definition]
prefregex = ^\s*(\[\])?(%(__hostname)s\s*(?:roundcube(?:\[(\d*)\])?:)?\s*(<[\w]+>)? IMAP Error)?: <F-CONTENT>.+</F-CONTENT>$
prefregex = ^\s*(\[\])?(%(__hostname)s\s*(?:roundcube(?:\[(\d*)\])?:)?\s*(<[\w]+>)? IMAP Error)?: (?:<[\w]+> )?<F-CONTENT>.+</F-CONTENT>$
failregex = ^(?:FAILED login|Login failed) for <F-USER>.*</F-USER> from <HOST>(?:(?:\([^\)]*\))?\. (?:(?! from ).)*(?: user=(?P=user))? in \S+\.php on line \d+ \(\S+ \S+\))?$
^(?:<[\w]+> )?Failed login for <F-USER>.*</F-USER> from <HOST> in session \w+( \(error: \d\))?$
failregex = ^(?:Login failed|(?i:Failed) login) for <F-USER>(?:(?P<simple>\S+)|.*)</F-USER> (?:against \S+ )?from <ADDR>(?:(?:\([^\)]*\))?\.(?! from ) (?(simple)(?:\S+(?! from ) )*|(?:(?! from ).)*(?: user=(?P=user))? )in \S+\.php on line \d+| in session \w+)?(?: \([^\)]*\))?$
ignoreregex =

View file

@ -0,0 +1,10 @@
# Fail2Ban filter for failure attempts in MikroTik RouterOS
#
#
[Definition]
failregex = ^\s*\S+ system,error,critical login failure for user <F-USER>.*?</F-USER> from <ADDR> via \S+$
# Author: Vit Kabele <vit@kabele.me>

View file

@ -14,7 +14,7 @@
[Definition]
failregex = ^type=%(_type)s msg=audit\(:\d+\): (user )?pid=\d+ uid=%(_uid)s auid=%(_auid)s ses=\d+ subj=%(_subj)s msg='%(_msg)s'$
failregex = ^type=%(_type)s msg=audit\(:\d+\): (?:user )?pid=\d+ uid=%(_uid)s auid=%(_auid)s ses=\d+ subj=%(_subj)s msg='%(_msg)s'(?:\x1D|$)
ignoreregex =

View file

@ -15,11 +15,13 @@ _subj = (?:unconfined_u|system_u):system_r:sshd_t:s0-s0:c0\.c1023
_exe =/usr/sbin/sshd
_terminal = ssh
_msg = op=\S+ acct=(?P<_quote_acct>"?)\S+(?P=_quote_acct) exe="%(_exe)s" hostname=(\?|(\d+\.){3}\d+) addr=<HOST> terminal=%(_terminal)s res=failed
_anygrp = (?!acct=|exe=|addr=|terminal=|res=)\w+=(?:"[^"]+"|\S*)
_msg = (?:%(_anygrp)s )*acct=(?:"<F-USER>[^"]+</F-USER>"|<F-ALT_USER>\S+</F-ALT_USER>) exe="%(_exe)s" (?:%(_anygrp)s )*addr=<ADDR> terminal=%(_terminal)s res=failed
# DEV Notes:
#
# Note: USER_LOGIN is ignored as this is the duplicate messsage
# Note: USER_LOGIN is ignored as this is the duplicate message
# ssh logs after 3 USER_AUTH failures.
#
# Author: Daniel Black

View file

@ -22,21 +22,28 @@ before = common.conf
_daemon = (?:(sm-(mta|acceptingconnections)|sendmail))
__prefix_line = %(known/__prefix_line)s(?:\w{14,20}: )?
addr = (?:(?:IPv6:)?<IP6>|<IP4>)
# mta_dname -- matches name of MTA daemon (typically specified in DAEMON_OPTIONS),
# normally something without spaces like MTA-v4 or Deamon0, etc. If it'd contain spaces, one can
# rewrite it in jail using `filter = %(known/filter)s[mta_dname="[^,]+"]` or in .local overwrite
# of the filter. (we would not use catch-alls here to satisfy obscure artificial case).
mta_dname = \S+
prefregex = ^<F-MLFID>%(__prefix_line)s</F-MLFID><F-CONTENT>.+</F-CONTENT>$
prefregex = ^\s*(?:<mail\.[^\>]+> )?<F-MLFID>%(__prefix_line)s</F-MLFID><F-CONTENT>.+</F-CONTENT>$
cmnfailre = ^ruleset=check_rcpt, arg1=(?P<email><\S+@\S+>), relay=(\S+ )?\[%(addr)s\](?: \(may be forged\))?, reject=(?:550 5\.7\.1(?: (?P=email)\.\.\.)?(?: Relaying denied\.)? (?:IP name possibly forged \[(\d+\.){3}\d+\]|Proper authentication required\.|IP name lookup failed \[(\d+\.){3}\d+\]|Fix reverse DNS for \S+)|553 5\.1\.8(?: (?P=email)\.\.\.)? Domain of sender address \S+ does not exist|550 5\.[71]\.1 (?P=email)\.\.\. (Rejected: .*|User unknown))$
cmnfailre = ^ruleset=check_rcpt, arg1=(?P<email><\S+@\S+>), relay=(\S+ )?\[%(addr)s\](?: \(may be forged\))?, reject=(?:550 5\.7\.1(?: (?P=email)\.\.\.)?(?: Relaying denied\.)? (?:IP name possibly forged \[(\d+\.){3}\d+\]|Proper authentication required\.|IP name lookup failed \[(\d+\.){3}\d+\]|Fix reverse DNS for \S+)|[45]5[13] [45]\.1\.8(?: (?P=email)\.\.\.)? Domain of sender address \S+ does not (?:exist|resolve)|550 5\.[71]\.1 (?P=email)\.\.\. (Rejected: .*|User unknown))$
^ruleset=check_relay(?:, arg\d+=\S*)*, relay=(\S+ )?\[%(addr)s\](?: \(may be forged\))?, reject=421 4\.3\.2 (Connection rate limit exceeded\.|Too many open connections\.)$
^rejecting commands from (\S* )?\[%(addr)s\] due to pre-greeting traffic after \d+ seconds$
^(?:\S+ )?\[%(addr)s\]: (?:(?i)expn|vrfy) \S+ \[rejected\]$
^<[^@]+@[^>]+>\.\.\. No such user here$
^<F-NOFAIL>from=<[^@]+@[^>]+></F-NOFAIL>, size=\d+, class=\d+, nrcpts=\d+, bodytype=\w+, proto=E?SMTP, daemon=MTA, relay=\S+ \[%(addr)s\]$
^<[^@]+@[^>]+>\.\.\. (?:No such user here|User unknown)$
^<F-NOFAIL>from=<[^@]+@[^>]+></F-NOFAIL>, size=\d+, class=\d+, nrcpts=\d+,(?: bodytype=\w+,)? proto=E?SMTP, daemon=%(mta_dname)s, relay=(?:\S+ )?\[%(addr)s\]$
mdre-normal =
mdre-extra = ^(?:\S+ )?\[%(addr)s\](?: \(may be forged\))? did not issue \S+ during connection
mdre-aggressive = %(mdre-extra)s
^lost input channel from (?:\S+ )?\[%(addr)s\] to %(mta_dname)s after rcpt$
^ruleset=check_rcpt, arg1=(?P<email><\S+@\S+>), relay=(?:\S+ )?\[%(addr)s\](?: \(may be forged\))?, reject=(?:450 4\.4\.0(?: (?P=email)\.\.\.)?(?: Relaying temporarily denied\.)?(?: Cannot resolve PTR record for (\d+\.){3}\d+))$
failregex = %(cmnfailre)s
<mdre-<mode>>
@ -63,6 +70,8 @@ journalmatch = SYSLOG_IDENTIFIER=sm-mta + _SYSTEMD_UNIT=sendmail.service
# Note the capture <F-MLFID>, includes both the __prefix_lines (which includes
# the sendmail PID), but also the `\w{14}` which the the sendmail assigned
# mail ID (todo: check this is necessary, possible obsolete).
# Avoid moving <F-MLFID> into the entire prefregex because the grouped messages we
# need have different syslog levels (info vs notice) that break the group if BSD verbose format is set
#
# Author: Daniel Black, Fabian Wenk and Sergey Brester aka sebres.
# Rewritten using prefregex by Serg G. Brester.

View file

@ -13,13 +13,11 @@ before = common.conf
_daemon = slapd
failregex = ^(?P<__prefix>%(__prefix_line)s)conn=(?P<_conn_>\d+) fd=\d+ ACCEPT from IP=<HOST>:\d{1,5} \(IP=\S+\)\s*<SKIPLINES>(?P=__prefix)conn=(?P=_conn_) op=\d+ RESULT(?:\s(?!err)\S+=\S*)* err=49 text=[\w\s]*$
prefregex = ^%(__prefix_line)sconn=<F-MLFID>\d+</F-MLFID>(?: (?:fd|op)=\d+){0,2} (?=ACCEPT|RESULT)<F-CONTENT>.+</F-CONTENT>$
failregex = ^<F-NOFAIL>ACCEPT</F-NOFAIL> from IP=<ADDR>:\d{1,5}\s+
^RESULT(?:\s(?!err)\S+=\S*)* err=49\b
ignoreregex =
[Init]
# "maxlines" is number of log lines to buffer for multi-line regex searches
maxlines = 20
# Author: Andrii Melnyk
# Author: Andrii Melnyk, Sergey G. Brester

View file

@ -1,4 +1,4 @@
# Fail2ban filter for SOGo authentcation
# Fail2ban filter for SOGo authentication
#
# Log file usually in /var/log/sogo/sogo.log

View file

@ -16,7 +16,7 @@ before = common.conf
[DEFAULT]
_daemon = sshd
_daemon = sshd(?:-session)?
# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: "
__pref = (?:(?:error|fatal): (?:PAM: )?)?
@ -24,8 +24,8 @@ __pref = (?:(?:error|fatal): (?:PAM: )?)?
#__suff = (?: port \d+)?(?: \[preauth\])?\s*
__suff = (?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*
__on_port_opt = (?: (?:port \d+|on \S+)){0,2}
# close by authenticating user:
__authng_user = (?: (?:invalid|authenticating) user <F-USER>\S+|.*?</F-USER>)?
# close by authenticating user (don't use <HOST> after %(__authng_user)s because of catch-all `.*?`):
__authng_user = (?: (?:by|from))?(?: (?:invalid|authenticating) user <F-USER>\S+|.*?</F-USER>)?(?: from)?
# for all possible (also future) forms of "no matching (cipher|mac|MAC|compression method|key exchange method|host key type) found",
# see ssherr.c for all possible SSH_ERR_..._ALG_MATCH errors.
@ -38,21 +38,21 @@ __pam_auth = pam_[a-z]+
prefregex = ^<F-MLFID>%(__prefix_line)s</F-MLFID>%(__pref)s<F-CONTENT>.+</F-CONTENT>$
cmnfailre = ^[aA]uthentication (?:failure|error|failed) for <F-USER>.*</F-USER> from <HOST>( via \S+)?%(__suff)s$
^User not known to the underlying authentication module for <F-USER>.*</F-USER> from <HOST>%(__suff)s$
cmnfailre = ^[aA]uthentication (?:failure|error|failed) for <F-USER>.*?</F-USER> (?:from )?<HOST>( via \S+)?%(__suff)s$
^User not known to the underlying authentication module for <F-USER>.*?</F-USER> (?:from )?<HOST>%(__suff)s$
<cmnfailre-failed-pub-<publickey>>
^Failed <cmnfailed> for (?P<cond_inv>invalid user )?<F-USER>(?P<cond_user>\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
^<F-USER>ROOT</F-USER> LOGIN REFUSED FROM <HOST>
^[iI](?:llegal|nvalid) user <F-USER>.*?</F-USER> from <HOST>%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> from <HOST> not allowed because not listed in AllowUsers%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> from <HOST> not allowed because listed in DenyUsers%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> from <HOST> not allowed because not in any group%(__suff)s$
^[iI](?:llegal|nvalid) user <F-USER>.*?</F-USER> (?:from )?<HOST>%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> (?:from )?<HOST> not allowed because not listed in AllowUsers%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> (?:from )?<HOST> not allowed because listed in DenyUsers%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> (?:from )?<HOST> not allowed because not in any group%(__suff)s$
^refused connect from \S+ \(<HOST>\)
^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>%(__on_port_opt)s:\s*3: .*: Auth fail%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> from <HOST> not allowed because a group is listed in DenyGroups%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> from <HOST> not allowed because none of user's groups are listed in AllowGroups%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> (?:from )?<HOST> not allowed because a group is listed in DenyGroups%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> (?:from )?<HOST> not allowed because none of user's groups are listed in AllowGroups%(__suff)s$
^<F-NOFAIL>%(__pam_auth)s\(sshd:auth\):\s+authentication failure;</F-NOFAIL>(?:\s+(?:(?:logname|e?uid|tty)=\S*)){0,4}\s+ruser=<F-ALT_USER>\S*</F-ALT_USER>\s+rhost=<HOST>(?:\s+user=<F-USER>\S*</F-USER>)?%(__suff)s$
^maximum authentication attempts exceeded for <F-USER>.*</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?%(__suff)s$
^maximum authentication attempts exceeded for (?:invalid user )?<F-USER>.*?</F-USER> (?:from )?<HOST>%(__on_port_opt)s(?: ssh\d*)?%(__suff)s$
^User <F-USER>\S+|.*?</F-USER> not allowed because account is locked%(__suff)s
^<F-MLFFORGET>Disconnecting</F-MLFFORGET>(?: from)?(?: (?:invalid|authenticating)) user <F-USER>\S+</F-USER> <HOST>%(__on_port_opt)s:\s*Change of username or service not allowed:\s*.*\[preauth\]\s*$
^Disconnecting: Too many authentication failures(?: for <F-USER>\S+|.*?</F-USER>)?%(__suff)s$
@ -68,24 +68,25 @@ cmnfailed = <cmnfailed-<publickey>>
mdre-normal =
# used to differentiate "connection closed" with and without `[preauth]` (fail/nofail cases in ddos mode)
mdre-normal-other = ^<F-NOFAIL><F-MLFFORGET>(Connection (?:closed|reset)|Disconnected)</F-MLFFORGET></F-NOFAIL> (?:by|from)%(__authng_user)s <HOST>(?:%(__suff)s|\s*)$
mdre-normal-other = ^<F-NOFAIL><F-MLFFORGET>(?:Connection (?:closed|reset)|Disconnect(?:ed|ing))</F-MLFFORGET></F-NOFAIL>%(__authng_user)s <ADDR>%(__on_port_opt)s(?:: (?!Too many authentication failures)[^\[]+)?(?: \[preauth\])?\s*$
mdre-ddos = ^Did not receive identification string from <HOST>
mdre-ddos = ^(?:Did not receive identification string from|Timeout before authentication for(?: connection from)?) <HOST>
^kex_exchange_identification: (?:read: )?(?:[Cc]lient sent invalid protocol identifier|[Cc]onnection (?:closed by remote host|reset by peer))
^Bad protocol version identification '.*' from <HOST>
^Bad protocol version identification '(?:[^']|.*?)' (?:from )?<HOST>%(__suff)s$
^<F-NOFAIL>SSH: Server;Ltype:</F-NOFAIL> (?:Authname|Version|Kex);Remote: <HOST>-\d+;[A-Z]\w+:
^Read from socket failed: Connection <F-MLFFORGET>reset</F-MLFFORGET> by peer
^banner exchange: Connection from <HOST><__on_port_opt>: invalid format
^(?:banner exchange|ssh_dispatch_run_fatal): Connection from <HOST><__on_port_opt>: (?:invalid format|(?:message authentication code incorrect|[Cc]onnection corrupted) \[preauth\])
# same as mdre-normal-other, but as failure (without <F-NOFAIL> with [preauth] and with <F-NOFAIL> on no preauth phase as helper to identify address):
mdre-ddos-other = ^<F-MLFFORGET>(Connection (?:closed|reset)|Disconnected)</F-MLFFORGET> (?:by|from)%(__authng_user)s <HOST>%(__on_port_opt)s\s+\[preauth\]\s*$
^<F-NOFAIL><F-MLFFORGET>(Connection (?:closed|reset)|Disconnected)</F-MLFFORGET></F-NOFAIL> (?:by|from)%(__authng_user)s <HOST>(?:%(__on_port_opt)s|\s*)$
mdre-ddos-other = ^<F-MLFFORGET>(?:Connection (?:closed|reset)|Disconnect(?:ed|ing))</F-MLFFORGET>%(__authng_user)s <ADDR>%(__on_port_opt)s(?:: (?!Too many authentication failures)[^\[]+)?\s+\[preauth\]\s*$
^<F-NOFAIL><F-MLFFORGET>(?:Connection (?:closed|reset)|Disconnect(?:ed|ing))</F-MLFFORGET></F-NOFAIL>%(__authng_user)s <ADDR>(?:%(__on_port_opt)s(?:: (?!Too many authentication failures)[^\[]+)?|\s*)$
mdre-extra = ^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>%(__on_port_opt)s:\s*14: No(?: supported)? authentication methods available
^Unable to negotiate with <HOST>%(__on_port_opt)s: no matching <__alg_match> found.
^Unable to negotiate a <__alg_match>
^no matching <__alg_match> found:
# part of mdre-ddos-other, but user name is supplied (invalid/authenticating) on [preauth] phase only:
mdre-extra-other = ^<F-MLFFORGET>Disconnected</F-MLFFORGET>(?: from)?(?: (?:invalid|authenticating)) user <F-USER>\S+|.*?</F-USER> <HOST>%(__on_port_opt)s \[preauth\]\s*$
mdre-extra-other = ^<F-MLFFORGET>Disconnected</F-MLFFORGET>(?: from)?(?: (?:invalid|authenticating)) user <F-USER>\S+|.*?</F-USER> (?:from )?<HOST>%(__on_port_opt)s \[preauth\]\s*$
mdre-aggressive = %(mdre-ddos)s
%(mdre-extra)s
@ -125,7 +126,7 @@ ignoreregex =
maxlines = 1
journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd
journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd + _COMM=sshd-session
# DEV Notes:
#

View file

@ -5,7 +5,7 @@
#
# To use 'traefik-auth' filter you have to configure your Traefik instance to write
# the access logs as describe in https://docs.traefik.io/configuration/logs/#access-logs
# into a log file on host and specifiy users for Basic Authentication
# into a log file on host and specify users for Basic Authentication
# https://docs.traefik.io/configuration/entrypoints/#basic-authentication
#
# Example:
@ -51,7 +51,7 @@
[Definition]
# Parameter "method" can be used to specifiy request method
# Parameter "method" can be used to specify request method
req-method = \S+
# Usage example (for jail.local):
# filter = traefik-auth[req-method="GET|POST|HEAD"]

View file

@ -0,0 +1,8 @@
# Fail2Ban filter for unsuccessful Vaultwarden authentication attempts
# Logged in /var/log/vaultwarden.log
# Author: LearningSpot
[Definition]
failregex = ^\s*(?:\[\]\s*)?\[vaultwarden::api::(?:identity|admin|core::two_factor::authenticator)?\]\[ERROR\] (?:Invalid admin token|Invalid TOTP code|Username or password is incorrect)[\.!](?:\s+(?!IP:)\S+)* IP: <ADDR>(?:\. Username: <F-USER>\S+</F-USER>)?
ignoreregex =

View file

@ -10,13 +10,13 @@ before = common.conf
[Definition]
__pam_re=\(?%(__pam_auth)s(?:\(\S+\))?\)?:?
__pam_re=(?:\(?%(__pam_auth)s(?:\(\S+\))?\)?:?\s+)?
_daemon = vsftpd
failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=(ftp)? ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$
^ \[pid \d+\] \[[^\]]+\] FAIL LOGIN: Client "<HOST>"(?:\s*$|,)
failregex = ^%(__prefix_line)s%(__pam_re)sauthentication failure; logname=<F-ALT_USER1>\S*</F-ALT_USER1> uid=\S* euid=\S* tty=(?:ftp)? ruser=<F-USER>\S*</F-USER> rhost=<HOST>(?:\s+user=<F-ALT_USER>\S*</F-ALT_USER>)?\s*$
^(?:\s*\[pid \d+\] |%(__prefix_line)s)\[<F-USER>[^\]]+</F-USER>\] FAIL LOGIN: Client "<HOST>"(?:\s*$|,)
ignoreregex =
ignoreregex =
# Author: Cyril Jaquier
# Authors: Cyril Jaquier, Lucian Maly <lmaly@redhat.com>
# Documentation from fail2ban wiki

35
config/filter.d/xrdp.conf Normal file
View file

@ -0,0 +1,35 @@
#
# Fail2Ban filter for XRDP
#
# Detects login attempts with invalid credentials
#
# Requirements:
# - xrdp >= 0.9.19
# - The log level in sesman.ini should be set to `INFO` or higher
# to emit the log messages needed for this filter.
#
# Author: Evan Linde
#
[INCLUDES]
# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf
[DEFAULT]
_daemon = xrdp-sesman
[Definition]
authfail_re = \[INFO \] AUTHFAIL: user=<F-USER>(?:\S+|.+)</F-USER> ip=<ADDR> time=\d+
failregex = ^%(__prefix_line)s%(authfail_re)s$
ignoreregex =
datepattern = ^\[?%%ExY%%Exm%%Exd-%%ExH:%%ExM:%%ExS\]?
^{DATE}

View file

@ -97,7 +97,9 @@ before = paths-debian.conf
# ignorecommand = /path/to/command <ip>
ignorecommand =
# "bantime" is the number of seconds that a host is banned.
# "bantime" is the amount of time that a host is banned, integer in seconds or
# time abbreviation format (m - minutes, h - hours, d - days, w - weeks, mo - months, y - years).
# This is to consider as an initial time if bantime.increment gets enabled.
bantime = 10m
# A host is banned if it has generated "maxretry" during the last "findtime"
@ -111,19 +113,17 @@ maxretry = 5
maxmatches = %(maxretry)s
# "backend" specifies the backend used to get files modification.
# Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".
# Available options are "pyinotify", "polling", "systemd" and "auto".
# This option can be overridden in each jail as well.
#
# pyinotify: requires pyinotify (a file alteration monitor) to be installed.
# If pyinotify is not installed, Fail2ban will use auto.
# gamin: requires Gamin (a file alteration monitor) to be installed.
# If Gamin is not installed, Fail2ban will use auto.
# polling: uses a polling algorithm which does not require external libraries.
# systemd: uses systemd python library to access the systemd journal.
# Specifying "logpath" is not valid for this backend.
# See "journalmatch" in the jails associated filter config
# auto: will try to use the following backends, in order:
# pyinotify, gamin, polling.
# pyinotify, polling.
#
# Note: if systemd backend is chosen as the default but you enable a jail
# for which logs are present only in its own log files, specify some other
@ -205,8 +205,8 @@ fail2ban_agent = Fail2Ban/%(fail2ban_version)s
# iptables-multiport, shorewall, etc) It is used to define
# action_* variables. Can be overridden globally or per
# section within jail.local file
banaction = iptables-multiport
banaction_allports = iptables-allports
#banaction = iptables-multiport
#banaction_allports = iptables-allports
# The simplest action to take: ban only
action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
@ -227,14 +227,11 @@ action_mwl = %(action_)s
action_xarf = %(action_)s
xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
# ban & send a notification to one or more of the 50+ services supported by Apprise.
# See https://github.com/caronc/apprise/wiki for details on what is supported.
#
# You may optionally over-ride the default configuration line (containing the Apprise URLs)
# by using 'apprise[config="/alternate/path/to/apprise.cfg"]' otherwise
# /etc/fail2ban/apprise.conf is sourced for your supported notification configuration.
# ban & send a notification to one or more of the 120+ services supported by Apprise.
# action = %(action_)s
# apprise
# apprise[config="/alternate/path/to/apprise.yaml", args='--tag fail2ban']
# See https://appriseit.com/services/ for details on what is supported.
# Or action.d/apprise.conf for more details how to configure or customize it.
# ban IP on CloudFlare & send an e-mail with whois report and relevant log lines
# to the destemail.
@ -395,6 +392,10 @@ logpath = %(nginx_error_log)s
port = http,https
logpath = %(nginx_access_log)s
[nginx-forbidden]
port = http,https
logpath = %(nginx_error_log)s
# Ban attackers that try to use PHP's URL-fopen() functionality
# through GET/POST variables. - Experimental, with more than a year
# of usage in production environments.
@ -497,7 +498,7 @@ backend = %(syslog_backend)s
[froxlor-auth]
port = http,https
logpath = %(syslog_authpriv)s
logpath = %(syslog_user)s
backend = %(syslog_backend)s
@ -781,17 +782,11 @@ logpath = /var/lib/znc/moddata/adminlog/znc.log
# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld] or
# equivalent section:
# log-warnings = 2
#
# for syslog (daemon facility)
# [mysqld_safe]
# syslog
#
# for own logfile
# [mysqld]
# log-error=/var/log/mysqld.log
# log_error_verbosity = 3
# for older versions:
# log-warnings = 2
# Also check whether `log_error` (or `log-error`) system variable match the `logpath`.
[mysqld-auth]
port = 3306
logpath = %(mysql_log)s
backend = %(mysql_backend)s
@ -958,6 +953,9 @@ port = http,https
logpath = %(syslog_authpriv)s
backend = %(syslog_backend)s
[routeros-auth]
port = ssh,http,https
logpath = /var/log/MikroTik/router.log
[zoneminder]
# Zoneminder HTTP/HTTPS web interface auth
@ -971,6 +969,10 @@ logpath = %(apache_error_log)s
port = http,https
logpath = /var/log/traefik/access.log
[openvpn]
port = 443
logpath = /var/log/syslog
[scanlogd]
logpath = %(syslog_local0)s
banaction = %(banaction_allports)s
@ -978,3 +980,19 @@ banaction = %(banaction_allports)s
[monitorix]
port = 8080
logpath = /var/log/monitorix-httpd
[dante]
port = 1080
logpath = %(syslog_daemon)s
[proxmox]
port = https,http,8006
logpath = /var/log/daemon.log
[vaultwarden]
port = http,https
logpath = /var/log/vaultwarden.log
[xrdp]
port = 3389
logpath = /var/log/xrdp-sesman.log

View file

@ -67,7 +67,7 @@ proftpd_backend = %(default_backend)s
pureftpd_log = %(syslog_ftp)s
pureftpd_backend = %(default_backend)s
# ftp, daemon and then local7 are tried at configure time however it is overwriteable at configure time
# ftp, daemon and then local7 are tried at configure time however it is overwritable at configure time
#
wuftpd_log = %(syslog_ftp)s
wuftpd_backend = %(default_backend)s
@ -87,7 +87,12 @@ dovecot_backend = %(default_backend)s
# Seems to be set at compile time only to LOG_LOCAL0 (src/const.h) at Notice level
solidpop3d_log = %(syslog_local0)s
mysql_log = %(syslog_daemon)s
mysql_log = /var/log/mariadb/mariadb.log
/var/log/mariadb/error.log
/var/log/mysql/mysqld.log
/var/log/mysql/error.log
/var/log/mysqld.log
mysql_backend = %(default_backend)s
roundcube_errors_log = /var/log/roundcube/errors

View file

@ -9,6 +9,12 @@ after = paths-overrides.local
[DEFAULT]
banaction = nftables
banaction_allports = nftables[type=allports]
sshd_backend = systemd
postfix_backend = systemd
syslog_mail = /var/log/mail.log
# control the `mail.warn` setting, see `/etc/rsyslog.d/50-default.conf` (if commented `mail.*` wins).

View file

@ -47,12 +47,9 @@ copyright = u'2014'
#
from fail2ban.version import version as fail2ban_version
from distutils.version import LooseVersion
fail2ban_loose_version = LooseVersion(fail2ban_version)
# The short X.Y version.
version = ".".join(str(_) for _ in fail2ban_loose_version.version[:2])
version = ".".join(str(_) for _ in fail2ban_version.split(".")[:2])
# The full version, including alpha/beta/rc tags.
release = fail2ban_version

View file

@ -1,7 +0,0 @@
fail2ban.server.filtergamin module
==================================
.. automodule:: fail2ban.server.filtergamin
:members:
:undoc-members:
:show-inheritance:

View file

@ -13,7 +13,6 @@ fail2ban.server package
fail2ban.server.failmanager
fail2ban.server.failregex
fail2ban.server.filter
fail2ban.server.filtergamin
fail2ban.server.filterpoll
fail2ban.server.filterpyinotify
fail2ban.server.filtersystemd

View file

@ -1,14 +0,0 @@
#!/bin/bash
# This script carries out conversion of fail2ban to python3
# A backup of any converted files are created with ".bak"
# extension
set -eu
if 2to3 -w --no-diffs bin/* fail2ban;then
echo "Success!" >&2
exit 0
else
echo "Fail!" >&2
exit 1
fi

View file

@ -89,11 +89,11 @@ class ActionReader(DefinitionInitConfigReader):
stream = list()
stream.append(head + ["addaction", self._name])
multi = []
for opt, optval in opts.iteritems():
for opt, optval in opts.items():
if opt in self._configOpts and not opt.startswith('known/'):
multi.append([opt, optval])
if self._initOpts:
for opt, optval in self._initOpts.iteritems():
for opt, optval in self._initOpts.items():
if opt not in self._configOpts and not opt.startswith('known/'):
multi.append([opt, optval])
if len(multi) > 1:

View file

@ -21,8 +21,10 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2013- Yaroslav Halchenko"
__license__ = "GPL"
import sys
from ..exceptions import UnknownJailException, DuplicateJailException
from ..helpers import getLogger, logging
from ..helpers import getLogger, logging, PREFER_ENC
# Gets the instance of the logger.
logSys = getLogger(__name__)
@ -36,6 +38,11 @@ logSys = getLogger(__name__)
class Beautifier:
stdoutEnc = PREFER_ENC
if sys.stdout and sys.stdout.encoding is not None:
stdoutEnc = sys.stdout.encoding
encUtf = 1 if stdoutEnc.lower() == 'utf-8' else 0
def __init__(self, cmd = None):
self.__inputCmd = cmd
@ -71,24 +78,84 @@ class Beautifier:
elif inC[0] == "echo":
msg = ' '.join(msg)
elif inC[0:1] == ['status']:
if len(inC) > 1:
# Display information
msg = ["Status for the jail: %s" % inC[1]]
def jail_stat(response, pref=""):
# Display jail information
for n, res1 in enumerate(response):
prefix1 = "`-" if n == len(response) - 1 else "|-"
prefix1 = pref + ("`-" if n == len(response) - 1 else "|-")
msg.append("%s %s" % (prefix1, res1[0]))
prefix1 = " " if n == len(response) - 1 else "| "
prefix1 = pref + (" " if n == len(response) - 1 else "| ")
for m, res2 in enumerate(res1[1]):
prefix2 = prefix1 + ("`-" if m == len(res1[1]) - 1 else "|-")
val = " ".join(map(str, res2[1])) if isinstance(res2[1], list) else res2[1]
msg.append("%s %s:\t%s" % (prefix2, res2[0], val))
if len(inC) > 1 and inC[1] != "--all":
msg = ["Status for the jail: %s" % inC[1]]
jail_stat(response)
else:
jstat = None
if len(inC) > 1: # --all
jstat = response[-1]
response = response[:-1]
msg = ["Status"]
for n, res1 in enumerate(response):
prefix1 = "`-" if n == len(response) - 1 else "|-"
prefix1 = "`-" if not jstat and n == len(response) - 1 else "|-"
val = " ".join(map(str, res1[1])) if isinstance(res1[1], list) else res1[1]
msg.append("%s %s:\t%s" % (prefix1, res1[0], val))
if jstat:
msg.append("`- Status for the jails:")
i = 0
for n, j in jstat.items():
i += 1
prefix1 = "`-" if i == len(jstat) else "|-"
msg.append(" %s Jail: %s" % (prefix1, n))
jail_stat(j, " " if i == len(jstat) else " | ")
msg = "\n".join(msg)
elif inC[0:1] == ['stats'] or inC[0:1] == ['statistics']:
chrTable = [
['|', '-', '|', 'x', 'x', '-', '|', '-'], ## ascii
["\u2551", "\u2550", "\u255F", "\u256B", "\u256C", "\u2569", "\u2502", "\u2500"] ## utf-8
];
def _statstable(response, ct):
tophead = ["Jail", "Backend", "Filter", "Actions"]
headers = ["", "", "cur", "tot", "cur", "tot"]
minlens = [8, 8, 3, 3, 3, 3]
ralign = [0, 0, 1, 1, 1, 1]
rows = [[n, r[0], *r[1], *r[2]] for n, r in response.items()]
lens = []
for i in range(len(rows[0])):
col = (len(str(s[i])) for s in rows)
lens.append(max(minlens[i], max(col)))
rfmt = []
hfmt = []
for i in range(len(rows[0])):
f = "%%%ds" if ralign[i] else "%%-%ds"
rfmt.append(f % lens[i])
hfmt.append(f % lens[i])
rfmt = [rfmt[0], rfmt[1], "%s %s %s" % (rfmt[2], ct[6], rfmt[3]), "%s %s %s" % (rfmt[4], ct[6], rfmt[5])]
hfmt = [hfmt[0], hfmt[1], "%s %s %s" % (hfmt[2], ct[6], hfmt[3]), "%s %s %s" % (hfmt[4], ct[6], hfmt[5])]
tlens = [lens[0], lens[1], 3 + lens[2] + lens[3], 3 + lens[4] + lens[5]]
tfmt = [hfmt[0], hfmt[1], "%%-%ds" % (tlens[2],), "%%-%ds" % (tlens[3],)]
tsep = tfmt[0:2]
rfmt = (" "+ct[0]+" ").join(rfmt)
hfmt = (" "+ct[0]+" ").join(hfmt)
tfmt = (" "+ct[0]+" ").join(tfmt)
tsep = (" "+ct[0]+" ").join(tsep)
separator = ((tsep % tuple(tophead[0:2])) + " "+ct[2]+ct[7] +
((ct[7]+ct[3]+ct[7]).join([ct[7] * n for n in tlens[2:]])) + ct[7])
ret = []
ret.append(" "+tfmt % tuple(["", ""]+tophead[2:]))
ret.append(" "+separator)
ret.append(" "+hfmt % tuple(headers))
separator = (ct[1]+ct[4]+ct[1]).join([ct[1] * n for n in tlens]) + ct[1]
ret.append(ct[1]+separator)
for row in rows:
ret.append(" "+rfmt % tuple(row))
separator = (ct[1]+ct[5]+ct[1]).join([ct[1] * n for n in tlens]) + ct[1]
ret.append(ct[1]+separator)
return ret
if not response:
return "No jails found."
msg = "\n".join(_statstable(response, chrTable[self.encUtf]))
elif len(inC) < 2:
pass # to few cmd args for below
elif inC[1] == "syslogsocket":
@ -145,8 +212,8 @@ class Beautifier:
else:
msg = "These IP addresses/networks are ignored:\n"
for ip in response[:-1]:
msg += "|- " + ip + "\n"
msg += "`- " + response[-1]
msg += "|- " + str(ip) + "\n"
msg += "`- " + str(response[-1])
elif inC[2] in ("failregex", "addfailregex", "delfailregex",
"ignoreregex", "addignoreregex", "delignoreregex"):
if len(response) == 0:

View file

@ -29,49 +29,36 @@ import re
import sys
from ..helpers import getLogger
if sys.version_info >= (3,): # pragma: 2.x no cover
# SafeConfigParser deprecated from Python 3.2 (renamed to ConfigParser)
from configparser import ConfigParser as SafeConfigParser, BasicInterpolation, \
InterpolationMissingOptionError, NoOptionError, NoSectionError
# SafeConfigParser deprecated from Python 3.2 (renamed to ConfigParser)
from configparser import ConfigParser as SafeConfigParser, BasicInterpolation, \
InterpolationMissingOptionError, NoOptionError, NoSectionError
# And interpolation of __name__ was simply removed, thus we need to
# decorate default interpolator to handle it
class BasicInterpolationWithName(BasicInterpolation):
"""Decorator to bring __name__ interpolation back.
# And interpolation of __name__ was simply removed, thus we need to
# decorate default interpolator to handle it
class BasicInterpolationWithName(BasicInterpolation):
"""Decorator to bring __name__ interpolation back.
Original handling of __name__ was removed because of
functional deficiencies: http://bugs.python.org/issue10489
Original handling of __name__ was removed because of
functional deficiencies: http://bugs.python.org/issue10489
commit v3.2a4-105-g61f2761
Author: Lukasz Langa <lukasz@langa.pl>
Date: Sun Nov 21 13:41:35 2010 +0000
commit v3.2a4-105-g61f2761
Author: Lukasz Langa <lukasz@langa.pl>
Date: Sun Nov 21 13:41:35 2010 +0000
Issue #10489: removed broken `__name__` support from configparser
Issue #10489: removed broken `__name__` support from configparser
But should be fine to reincarnate for our use case
"""
def _interpolate_some(self, parser, option, accum, rest, section, map,
*args, **kwargs):
if section and not (__name__ in map):
map = map.copy() # just to be safe
map['__name__'] = section
# try to wrap section options like %(section/option)s:
parser._map_section_options(section, option, rest, map)
return super(BasicInterpolationWithName, self)._interpolate_some(
parser, option, accum, rest, section, map, *args, **kwargs)
But should be fine to reincarnate for our use case
"""
def _interpolate_some(self, parser, option, accum, rest, section, map,
*args, **kwargs):
if section and not (__name__ in map):
map = map.copy() # just to be safe
map['__name__'] = section
# try to wrap section options like %(section/option)s:
parser._map_section_options(section, option, rest, map)
return super(BasicInterpolationWithName, self)._interpolate_some(
parser, option, accum, rest, section, map, *args, **kwargs)
else: # pragma: 3.x no cover
from ConfigParser import SafeConfigParser, \
InterpolationMissingOptionError, NoOptionError, NoSectionError
# Interpolate missing known/option as option from default section
SafeConfigParser._cp_interpolate_some = SafeConfigParser._interpolate_some
def _interpolate_some(self, option, accum, rest, section, map, *args, **kwargs):
# try to wrap section options like %(section/option)s:
self._map_section_options(section, option, rest, map)
return self._cp_interpolate_some(option, accum, rest, section, map, *args, **kwargs)
SafeConfigParser._interpolate_some = _interpolate_some
def _expandConfFilesWithLocal(filenames):
"""Expands config files with local extension.
@ -129,20 +116,14 @@ after = 1.conf
CONDITIONAL_RE = re.compile(r"^(\w+)(\?.+)$")
if sys.version_info >= (3,2):
# overload constructor only for fancy new Python3's
def __init__(self, share_config=None, *args, **kwargs):
kwargs = kwargs.copy()
kwargs['interpolation'] = BasicInterpolationWithName()
kwargs['inline_comment_prefixes'] = ";"
super(SafeConfigParserWithIncludes, self).__init__(
*args, **kwargs)
self._cfg_share = share_config
else:
def __init__(self, share_config=None, *args, **kwargs):
SafeConfigParser.__init__(self, *args, **kwargs)
self._cfg_share = share_config
# overload constructor only for fancy new Python3's
def __init__(self, share_config=None, *args, **kwargs):
kwargs = kwargs.copy()
kwargs['interpolation'] = BasicInterpolationWithName()
kwargs['inline_comment_prefixes'] = ";"
super(SafeConfigParserWithIncludes, self).__init__(
*args, **kwargs)
self._cfg_share = share_config
def get_ex(self, section, option, raw=False, vars={}):
"""Get an option value for a given section.
@ -327,7 +308,7 @@ after = 1.conf
# mix it with defaults:
return set(opts.keys()) | set(self._defaults)
# only own option names:
return opts.keys()
return list(opts.keys())
def read(self, filenames, get_includes=True):
if not isinstance(filenames, list):
@ -356,7 +337,7 @@ after = 1.conf
ret += i
# merge defaults and all sections to self:
alld.update(cfg.get_defaults())
for n, s in cfg.get_sections().iteritems():
for n, s in cfg.get_sections().items():
# conditional sections
cond = SafeConfigParserWithIncludes.CONDITIONAL_RE.match(n)
if cond:
@ -366,14 +347,14 @@ after = 1.conf
del(s['__name__'])
except KeyError:
pass
for k in s.keys():
for k in list(s.keys()):
v = s.pop(k)
s[k + cond] = v
s2 = alls.get(n)
if isinstance(s2, dict):
# save previous known values, for possible using in local interpolations later:
self.merge_section('KNOWN/'+n,
dict(filter(lambda i: i[0] in s, s2.iteritems())), '')
dict([i for i in iter(s2.items()) if i[0] in s]), '')
# merge section
s2.update(s)
else:
@ -385,10 +366,7 @@ after = 1.conf
if logSys.getEffectiveLevel() <= logLevel:
logSys.log(logLevel, " Reading file: %s", fileNamesFull[0])
# read file(s) :
if sys.version_info >= (3,2): # pragma: no cover
return SafeConfigParser.read(self, fileNamesFull, encoding='utf-8')
else:
return SafeConfigParser.read(self, fileNamesFull)
return SafeConfigParser.read(self, fileNamesFull, encoding='utf-8')
def merge_section(self, section, options, pref=None):
alls = self.get_sections()
@ -400,7 +378,7 @@ after = 1.conf
sec.update(options)
return
sk = {}
for k, v in options.iteritems():
for k, v in options.items():
if not k.startswith(pref) and k != '__name__':
sk[pref+k] = v
sec.update(sk)

View file

@ -26,7 +26,7 @@ __license__ = "GPL"
import glob
import os
from ConfigParser import NoOptionError, NoSectionError
from configparser import NoOptionError, NoSectionError
from .configparserinc import sys, SafeConfigParserWithIncludes, logLevel
from ..helpers import getLogger, _as_bool, _merge_dicts, substituteRecursiveTags
@ -98,7 +98,7 @@ class ConfigReader():
def read(self, name, once=True):
""" Overloads a default (not shared) read of config reader.
To prevent mutiple reads of config files with it includes, reads into
To prevent multiple reads of config files with it includes, reads into
the config reader, if it was not yet cached/shared by 'name'.
"""
# already shared ?
@ -183,7 +183,7 @@ class ConfigReader():
class ConfigReaderUnshared(SafeConfigParserWithIncludes):
"""Unshared config reader (previously ConfigReader).
Do not use this class (internal not shared/cached represenation).
Do not use this class (internal not shared/cached representation).
Use ConfigReader instead.
"""
@ -221,7 +221,7 @@ class ConfigReaderUnshared(SafeConfigParserWithIncludes):
config_files += sorted(glob.glob('%s/*.local' % config_dir))
# choose only existing ones
config_files = filter(os.path.exists, config_files)
config_files = list(filter(os.path.exists, config_files))
if len(config_files):
# at least one config exists and accessible
@ -230,6 +230,7 @@ class ConfigReaderUnshared(SafeConfigParserWithIncludes):
missed = [ cf for cf in config_files if cf not in config_files_read ]
if missed:
logSys.error("Could not read config files: %s", ', '.join(missed))
return False
if config_files_read:
return True
logSys.error("Found no accessible config files for %r under %s",
@ -277,7 +278,7 @@ class ConfigReaderUnshared(SafeConfigParserWithIncludes):
# TODO: validate error handling here.
except NoOptionError:
if not optvalue is None:
logSys.warning("'%s' not defined in '%s'. Using default one: %r"
logSys.debug("'%s' not defined in '%s'. Using default one: %r"
% (optname, sec, optvalue))
values[optname] = optvalue
# elif logSys.getEffectiveLevel() <= logLevel:
@ -353,6 +354,11 @@ class DefinitionInitConfigReader(ConfigReader):
if v is None: v = getopt(opt)
self._initOpts['known/'+opt] = v
if opt not in self._initOpts:
# overwrite also conditional init options (from init?... section):
cond = SafeConfigParserWithIncludes.CONDITIONAL_RE.match(opt)
if cond:
optc, cond = cond.groups()
v = pOpts.get(optc, v)
if v is None: v = getopt(opt)
self._initOpts[opt] = v
if all and self.has_section("Definition"):
@ -406,7 +412,7 @@ class DefinitionInitConfigReader(ConfigReader):
if cond:
n, cond = cond.groups()
ignore.add(n)
# substiture options already specified direct:
# substitute options already specified direct:
opts = substituteRecursiveTags(combinedopts,
ignore=ignore, addrepl=self.getCombOption)
if not opts:

View file

@ -63,11 +63,13 @@ class Configurator:
return fail2ban_basedir
def readEarly(self):
self.__fail2ban.read()
if not self.__fail2ban.read():
raise LookupError("Read fail2ban configuration failed.")
def readAll(self):
self.readEarly()
self.__jails.read()
if not self.__jails.read():
raise LookupError("Read jails configuration failed.")
def getEarlyOptions(self):
return self.__fail2ban.getEarlyOptions()

View file

@ -47,7 +47,7 @@ class CSocket:
def send(self, msg, nonblocking=False, timeout=None):
# Convert every list member to string
obj = dumps(map(CSocket.convert, msg), HIGHEST_PROTOCOL)
obj = dumps(list(map(CSocket.convert, msg)), HIGHEST_PROTOCOL)
self.__csock.send(obj)
self.__csock.send(CSPROTO.END)
return self.receive(self.__csock, nonblocking, timeout)
@ -72,7 +72,7 @@ class CSocket:
@staticmethod
def convert(m):
"""Convert every "unexpected" member of message to string"""
if isinstance(m, (basestring, bool, int, float, list, dict, set)):
if isinstance(m, (str, bool, int, float, list, dict, set)):
return m
else: # pragma: no cover
return str(m)

View file

@ -45,7 +45,7 @@ def _thread_name():
return threading.current_thread().__class__.__name__
def input_command(): # pragma: no cover
return raw_input(PROMPT)
return input(PROMPT)
##
#
@ -406,6 +406,8 @@ class Fail2banClient(Fail2banCmdLine, Thread):
if ret is not None:
if ret:
return True
if self._conf.get("test", False) and not self._args: # test only
return False
raise ServerExecutionException("Init of command line failed")
# Commands
@ -456,7 +458,7 @@ class Fail2banClient(Fail2banCmdLine, Thread):
return False
finally:
self._alive = False
for s, sh in _prev_signals.iteritems():
for s, sh in _prev_signals.items():
signal.signal(s, sh)

View file

@ -27,7 +27,7 @@ import sys
from ..version import version, normVersion
from ..protocol import printFormatted
from ..helpers import getLogger, str2LogLevel, getVerbosityFormat, BrokenPipeError
from ..helpers import getLogger, str2LogLevel, getVerbosityFormat
# Gets the instance of the logger.
logSys = getLogger("fail2ban")
@ -260,12 +260,15 @@ class Fail2banCmdLine():
if readcfg:
readcfg = False
ret, stream = self.readConfig()
if not ret:
raise ServerExecutionException("ERROR: test configuration failed")
# exit after test if no commands specified (test only):
if not len(self._args):
output("OK: configuration test is successful")
if ret:
output("OK: configuration test is successful")
else:
output("ERROR: test configuration failed")
return ret
if not ret:
raise ServerExecutionException("ERROR: test configuration failed")
# Nothing to do here, process in client/server
return None

View file

@ -37,7 +37,7 @@ class Fail2banReader(ConfigReader):
ConfigReader.__init__(self, **kwargs)
def read(self):
ConfigReader.read(self, "fail2ban")
return ConfigReader.read(self, "fail2ban")
def getEarlyOptions(self):
opts = [

View file

@ -40,10 +40,10 @@ import os
import shlex
import sys
import time
import urllib
import urllib.request, urllib.parse, urllib.error
from optparse import OptionParser, Option
from ConfigParser import NoOptionError, NoSectionError, MissingSectionHeaderError
from configparser import NoOptionError, NoSectionError, MissingSectionHeaderError
try: # pragma: no cover
from ..server.filtersystemd import FilterSystemd
@ -51,7 +51,7 @@ except ImportError:
FilterSystemd = None
from ..version import version, normVersion
from .filterreader import FilterReader
from .jailreader import FilterReader, JailReader, NoJailError
from ..server.filter import Filter, FileContainer, MyTime
from ..server.failregex import Regex, RegexException
@ -67,9 +67,9 @@ def debuggexURL(sample, regex, multiline=False, useDns="yes"):
'flavor': 'python'
}
if multiline: args['flags'] = 'm'
return 'https://www.debuggex.com/?' + urllib.urlencode(args)
return 'https://www.debuggex.com/?' + urllib.parse.urlencode(args)
def output(args): # pragma: no cover (overriden in test-cases)
def output(args): # pragma: no cover (overridden in test-cases)
print(args)
def shortstr(s, l=53):
@ -106,7 +106,7 @@ usage = lambda: "%s [OPTIONS] <LOG> <REGEX> [IGNOREREGEX]" % sys.argv[0]
class _f2bOptParser(OptionParser):
def format_help(self, *args, **kwargs):
""" Overwritten format helper with full ussage."""
""" Overwritten format helper with full usage."""
self.usage = ''
return "Usage: " + usage() + "\n" + __doc__ + """
LOG:
@ -118,12 +118,11 @@ LOG:
REGEX:
string a string representing a 'failregex'
filter name of filter, optionally with options (sshd[mode=aggressive])
filter name of jail or filter, optionally with options (sshd[mode=aggressive])
filename path to a filter file (filter.d/sshd.conf)
IGNOREREGEX:
string a string representing an 'ignoreregex'
filename path to a filter file (filter.d/sshd.conf)
\n""" + OptionParser.format_help(self, *args, **kwargs) + """\n
Report bugs to https://github.com/fail2ban/fail2ban/issues\n
""" + __copyright__ + "\n"
@ -173,6 +172,8 @@ def get_opt_parser():
help="Disable check for all regex's"),
Option("-o", "--out", action="store", dest="out", default=None,
help="Set token to print failure information only (row, id, ip, msg, host, ip4, ip6, dns, matches, ...)"),
Option("-i", "--invert", action="store_true", dest="invert",
help="Invert the sense of matching, to output non-matching lines."),
Option("--print-no-missed", action='store_true',
help="Do not print any missed lines"),
Option("--print-no-ignored", action='store_true',
@ -246,7 +247,7 @@ class Fail2banRegex(object):
def __init__(self, opts):
# set local protected members from given options:
self.__dict__.update(dict(('_'+o,v) for o,v in opts.__dict__.iteritems()))
self.__dict__.update(dict(('_'+o,v) for o,v in opts.__dict__.items()))
self._opts = opts
self._maxlines_set = False # so we allow to override maxlines in cmdline
self._datepattern_set = False
@ -280,7 +281,7 @@ class Fail2banRegex(object):
self._filter.setUseDns(opts.usedns)
self._filter.returnRawHost = opts.raw
self._filter.checkAllRegex = opts.checkAllRegex and not opts.out
# ignore pending (without ID/IP), added to matches if it hits later (if ID/IP can be retreved)
# ignore pending (without ID/IP), added to matches if it hits later (if ID/IP can be retrieved)
self._filter.ignorePending = bool(opts.out)
# callback to increment ignored RE's by index (during process):
self._filter.onIgnoreRegex = self._onIgnoreRegex
@ -312,12 +313,18 @@ class Fail2banRegex(object):
def _dumpRealOptions(self, reader, fltOpt):
realopts = {}
combopts = reader.getCombined()
if isinstance(reader, FilterReader):
_get_opt = lambda k: reader.get('Definition', k)
elif reader.filter: # JailReader for jail with filter:
_get_opt = lambda k: reader.filter.get('Definition', k)
else: # JailReader for jail without filter:
_get_opt = lambda k: None
# output all options that are specified in filter-argument as well as some special (mostly interested):
for k in ['logtype', 'datepattern'] + fltOpt.keys():
for k in ['logtype', 'datepattern'] + list(fltOpt.keys()):
# combined options win, but they contain only a sub-set in filter expected keys,
# so get the rest from definition section:
try:
realopts[k] = combopts[k] if k in combopts else reader.get('Definition', k)
realopts[k] = combopts[k] if k in combopts else _get_opt(k)
except NoOptionError: # pragma: no cover
pass
self.output("Real filter options : %r" % realopts)
@ -330,16 +337,26 @@ class Fail2banRegex(object):
fltName = value
fltFile = None
fltOpt = {}
jail = None
if regextype == 'fail':
if re.search(r'(?ms)^/{0,3}[\w/_\-.]+(?:\[.*\])?$', value):
try:
fltName, fltOpt = extractOptions(value)
if not re.search(r'(?ms)(?:/|\.(?:conf|local)$)', fltName): # name of jail?
try:
jail = JailReader(fltName, force_enable=True,
share_config=self.share_config, basedir=basedir)
jail.read()
except NoJailError:
jail = None
if "." in fltName[~5:]:
tryNames = (fltName,)
else:
tryNames = (fltName, fltName + '.conf', fltName + '.local')
for fltFile in tryNames:
if not "/" in fltFile:
if os.path.dirname(fltFile) == 'filter.d':
fltFile = os.path.join(basedir, fltFile)
elif not "/" in fltFile:
if os.path.basename(basedir) == 'filter.d':
fltFile = os.path.join(basedir, fltFile)
else:
@ -354,8 +371,28 @@ class Fail2banRegex(object):
output(" while parsing: %s" % (value,))
if self._verbose: raise(e)
return False
elif self._ignoreregex:
# clear ignoreregex that could be previously loaded from filter:
self._filter.delIgnoreRegex()
readercommands = None
# if it is jail:
if jail:
self.output( "Use %11s jail : %s" % ('', fltName) )
if fltOpt:
self.output( "Use jail/flt options : %r" % fltOpt )
if not fltOpt: fltOpt = {}
fltOpt['backend'] = self._backend
ret = jail.getOptions(addOpts=fltOpt)
if not ret:
output('ERROR: Failed to get jail for %r' % (value,))
return False
# show real options if expected:
if self._verbose > 1 or logSys.getEffectiveLevel()<=logging.DEBUG:
self._dumpRealOptions(jail, fltOpt)
readercommands = jail.convert(allow_no_files=True)
# if it is filter file:
if fltFile is not None:
elif fltFile is not None:
if (basedir == self._opts.config
or os.path.basename(basedir) == 'filter.d'
or ("." not in fltName[~5:] and "/" not in fltName)
@ -364,16 +401,17 @@ class Fail2banRegex(object):
if os.path.basename(basedir) == 'filter.d':
basedir = os.path.dirname(basedir)
fltName = os.path.splitext(os.path.basename(fltName))[0]
self.output( "Use %11s filter file : %s, basedir: %s" % (regex, fltName, basedir) )
self.output( "Use %11s file : %s, basedir: %s" % ('filter', fltName, basedir) )
else:
## foreign file - readexplicit this file and includes if possible:
self.output( "Use %11s file : %s" % (regex, fltName) )
self.output( "Use %11s file : %s" % ('filter', fltName) )
basedir = None
if not os.path.isabs(fltName): # avoid join with "filter.d" inside FilterReader
fltName = os.path.abspath(fltName)
if fltOpt:
self.output( "Use filter options : %r" % fltOpt )
reader = FilterReader(fltName, 'fail2ban-regex-jail', fltOpt, share_config=self.share_config, basedir=basedir)
reader = FilterReader(fltName, 'fail2ban-regex-jail', fltOpt,
share_config=self.share_config, basedir=basedir)
ret = None
try:
if basedir is not None:
@ -398,7 +436,8 @@ class Fail2banRegex(object):
# to stream:
readercommands = reader.convert()
regex_values = {}
regex_values = {}
if readercommands:
for opt in readercommands:
if opt[0] == 'multi-set':
optval = opt[3]
@ -438,9 +477,9 @@ class Fail2banRegex(object):
else:
self.output( "Use %11s line : %s" % (regex, shortstr(value)) )
regex_values = {regextype: [RegexStat(value)]}
regex_values[regextype] = [RegexStat(value)]
for regextype, regex_values in regex_values.iteritems():
for regextype, regex_values in regex_values.items():
regex = regextype + 'regex'
setattr(self, "_" + regex, regex_values)
for regex in regex_values:
@ -476,7 +515,7 @@ class Fail2banRegex(object):
ret.append(match)
else:
is_ignored = True
if self._opts.out: # (formated) output - don't need stats:
if self._opts.out: # (formatted) output - don't need stats:
return None, ret, None
# prefregex stats:
if self._filter.prefRegex:
@ -492,7 +531,7 @@ class Fail2banRegex(object):
except RegexException as e: # pragma: no cover
output( 'ERROR: %s' % e )
return None, 0, None
if self._filter.getMaxLines() > 1:
if self._filter.getMaxLines() > 1 and not self._opts.out:
for bufLine in orgLineBuffer[int(fullBuffer):]:
if bufLine not in self._filter._Filter__lineBuffer:
try:
@ -532,13 +571,13 @@ class Fail2banRegex(object):
def _out(ret):
for r in ret:
for r in r[3].get('matches'):
if not isinstance(r, basestring):
if not isinstance(r, str):
r = ''.join(r for r in r)
output(r)
elif ofmt == 'row':
def _out(ret):
for r in ret:
output('[%r,\t%r,\t%r],' % (r[1],r[2],dict((k,v) for k, v in r[3].iteritems() if k != 'matches')))
output('[%r,\t%r,\t%r],' % (r[1],r[2],dict((k,v) for k, v in r[3].items() if k != 'matches')))
elif '<' not in ofmt:
def _out(ret):
for r in ret:
@ -573,7 +612,7 @@ class Fail2banRegex(object):
# wrap multiline tag (msg) interpolations to single line:
for r, v in rows:
for r in r[3].get('matches'):
if not isinstance(r, basestring):
if not isinstance(r, str):
r = ''.join(r for r in r)
r = v.replace("\x00msg\x00", r)
output(r)
@ -582,8 +621,10 @@ class Fail2banRegex(object):
def process(self, test_lines):
t0 = time.time()
out = None
if self._opts.out: # get out function
out = self._prepaireOutput()
outinv = self._opts.invert
for line in test_lines:
if isinstance(line, tuple):
line_datetimestripped, ret, is_ignored = self.testRegex(line[0], line[1])
@ -595,8 +636,13 @@ class Fail2banRegex(object):
continue
line_datetimestripped, ret, is_ignored = self.testRegex(line)
if self._opts.out: # (formated) output:
if len(ret) > 0 and not is_ignored: out(ret)
if out: # (formatted) output:
if len(ret) > 0 and not is_ignored:
if not outinv: out(ret)
elif outinv: # inverted output (currently only time and message as matches):
if not len(ret): # [failRegexIndex, fid, date, fail]
ret = [[-1, "", self._filter._Filter__lastDate, {"fid":"", "matches":[line]}]]
out(ret)
continue
if is_ignored:
@ -639,9 +685,9 @@ class Fail2banRegex(object):
ans = [[]]
for arg in [l, regexlist]:
ans = [ x + [y] for x in ans for y in arg ]
b = map(lambda a: a[0] + ' | ' + a[1].getFailRegex() + ' | ' +
b = [a[0] + ' | ' + a[1].getFailRegex() + ' | ' +
debuggexURL(self.encode_line(a[0]), a[1].getFailRegex(),
multiline, self._opts.usedns), ans)
multiline, self._opts.usedns) for a in ans]
pprint_list([x.rstrip() for x in b], header)
else:
output( "%s too many to print. Use --print-all-%s " \
@ -789,7 +835,15 @@ class Fail2banRegex(object):
return True
def _loc_except_hook(exctype, value, traceback):
if (exctype != BrokenPipeError and exctype != IOError or value.errno != 32):
return sys.__excepthook__(exctype, value, traceback)
# pipe seems to be closed (head / tail / etc), thus simply exit:
sys.exit(0)
def exec_command_line(*args):
sys.excepthook = _loc_except_hook; # stop on closed/broken pipe
logging.exitOnIOError = True
parser = get_opt_parser()
(opts, args) = parser.parse_args(*args)

View file

@ -45,7 +45,7 @@ class Fail2banServer(Fail2banCmdLine):
@staticmethod
def startServerDirect(conf, daemon=True, setServer=None):
logSys.debug(" direct starting of server in %s, deamon: %s", os.getpid(), daemon)
logSys.debug(" direct starting of server in %s, daemon: %s", os.getpid(), daemon)
from ..server.server import Server
server = None
try:
@ -120,7 +120,7 @@ class Fail2banServer(Fail2banCmdLine):
if frk: # pragma: no cover
os.execv(exe, args)
else:
# use P_WAIT instead of P_NOWAIT (to prevent defunct-zomby process), it startet as daemon, so parent exit fast after fork):
# use P_WAIT instead of P_NOWAIT (to prevent defunct-zomby process), it started as daemon, so parent exit fast after fork):
ret = os.spawnv(os.P_WAIT, exe, args)
if ret != 0: # pragma: no cover
raise OSError(ret, "Unknown error by executing server %r with %r" % (args[1], exe))

View file

@ -71,7 +71,7 @@ class FilterReader(DefinitionInitConfigReader):
@staticmethod
def _fillStream(stream, opts, jailName):
prio0idx = 0
for opt, value in opts.iteritems():
for opt, value in opts.items():
# Do not send a command if the value is not set (empty).
if value is None: continue
if opt in ("failregex", "ignoreregex"):
@ -89,7 +89,7 @@ class FilterReader(DefinitionInitConfigReader):
stream.insert(0 if opt == 'usedns' else prio0idx,
["set", jailName, opt, value])
prio0idx += 1
elif opt in ('datepattern'):
elif opt == 'datepattern':
stream.append(["set", jailName, opt, value])
elif opt == 'journalmatch':
for match in value.split("\n"):

Some files were not shown because too many files have changed in this diff Show more