From 26e663d111e39ca96c63702ad27a05b6736607cf Mon Sep 17 00:00:00 2001 From: Lomain Date: Wed, 25 Mar 2026 05:08:35 +0100 Subject: [PATCH] add fail2ban handler (#1352) --- bin/handlers/404-to-fail2ban.py | 36 +++++++++++++++++++++++++++++++++ bin/handlers/README.md | 3 ++- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100755 bin/handlers/404-to-fail2ban.py diff --git a/bin/handlers/404-to-fail2ban.py b/bin/handlers/404-to-fail2ban.py new file mode 100755 index 00000000..9a94cff2 --- /dev/null +++ b/bin/handlers/404-to-fail2ban.py @@ -0,0 +1,36 @@ +# /!\ Warning: be careful, as webdav clients often generate a large number of 404 requets. + +# In your `jail.local`, add: +# [copyparty] +# enabled = true +# logtimezone = UTC +# logpath = /path/to/log/file # or keep the default value if you're using systemd + +# Create the `copyparty.conf` file in `filter.d` with the following: +# [Definition] +# failregex = ^ $ +# ignoreregex = +# datepattern = ^fail2ban: %%Y-%%m-%%dT%%H:%%M:%%S + +# First check `--dont-ban`, and if it doesn't match, log the line to be intercepted by fail2ban. +from datetime import datetime, UTC +def main(cli, vn="", rem=""): + now = datetime.now(UTC).isoformat()[:19] + msg = "\nfail2ban: %s %s" + if not vn and not rem: + # got called by --xban + cli["log"](msg % (now, cli["ip"]), 3) + return {"rc": 0} + + cond = cli.args.dont_ban + if ( + cond == "any" + or (cond == "auth" and cli.uname != "*") + or (cond == "aa" and cli.avol) + or (cond == "av" and cli.can_admin) + or (cond == "rw" and cli.can_read and cli.can_write) + ): + return "" + + cli.log(msg % (now, cli.ip), 3) + return "" diff --git a/bin/handlers/README.md b/bin/handlers/README.md index 60d8e23c..bcc66c4f 100644 --- a/bin/handlers/README.md +++ b/bin/handlers/README.md @@ -22,10 +22,11 @@ each plugin must define a `main()` which takes 3 arguments; * [redirect.py](redirect.py) sends an HTTP 301 or 302, redirecting the client to another page/file * [randpic.py](randpic.py) redirects `/foo/bar/randpic.jpg` to a random pic in `/foo/bar/` -* [sorry.py](answer.py) replies with a custom message instead of the usual 404 +* [sorry.py](sorry.py) replies with a custom message instead of the usual 404 * [nooo.py](nooo.py) replies with an endless noooooooooooooo * [never404.py](never404.py) 100% guarantee that 404 will never be a thing again as it automatically creates dummy files whenever necessary * [caching-proxy.py](caching-proxy.py) transforms copyparty into a squid/varnish knockoff +* [404-to-fail2ban.py](404-to-fail2ban.py) creates 404 logs for fail2ban ## on403