Fail2ban fails to ban lighttpd login attempts

Hi,
I have a raspberry pi 3 running rpi-cam, lighttpd and letsencrypt. It works well, but before I open a port in my firewall to allow the live stream to be viewed from the internet I want to enable fail2ban.
Lighttpd has username and password login configured and failed attempts are recorded to error.log
According to this output fail2ban can see these failed login attempts but doesn’t act on them.

dietpi@camera:~$ sudo fail2ban-regex /var/log/lighttpd/error.log /etc/fail2ban/filter.d/lighttpd-auth.conf --print-all-missed

Running tests
=============

Use   failregex filter file : lighttpd-auth, basedir: /etc/fail2ban
Use         log file : /var/log/lighttpd/error.log
Use         encoding : UTF-8


Results
=======

Failregex: 0 total

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [21] {^LN-BEG}ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T|  ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
`-

**

**Lines: 21 lines, 0 ignored, 0 matched, 21 missed**

**
[processed in 0.03 sec]

|- Missed line(s):
|  2022-07-20 08:47:22: mod_openssl.c.3059) SSL: -1 5 32 Broken pipe
|  2022-07-20 08:47:24: mod_auth.c.828) password doesn't match for /status_mjpeg.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:25: mod_auth.c.828) password doesn't match for /cam_pic.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:26: mod_auth.c.828) password doesn't match for /status_mjpeg.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:26: mod_auth.c.828) password doesn't match for /cam_pic.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:27: mod_auth.c.828) password doesn't match for /status_mjpeg.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:27: mod_auth.c.828) password doesn't match for /status_mjpeg.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:28: mod_auth.c.828) password doesn't match for /cam_pic.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:29: mod_auth.c.828) password doesn't match for /status_mjpeg.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:29: mod_auth.c.828) password doesn't match for /cam_pic.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:30: mod_auth.c.828) password doesn't match for /status_mjpeg.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:30: mod_auth.c.828) password doesn't match for /status_mjpeg.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:31: mod_auth.c.828) password doesn't match for /cam_pic.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:32: mod_auth.c.828) password doesn't match for /status_mjpeg.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:32: mod_auth.c.828) password doesn't match for /cam_pic.php username:  IP: 192.168.0.106
|  2022-07-20 08:47:41: mod_auth.c.828) password doesn't match for /status_mjpeg.php username: 3 IP: 192.168.0.106
|  2022-07-20 08:47:51: mod_auth.c.828) password doesn't match for /status_mjpeg.php username: 4 IP: 192.168.0.106
|  2022-07-20 08:47:52: mod_auth.c.828) password doesn't match for /cam_pic.php username: 4 IP: 192.168.0.106
|  2022-07-20 08:47:57: mod_auth.c.828) password doesn't match for /status_mjpeg.php username: 5 IP: 192.168.0.106
|  2022-07-20 08:47:57: mod_auth.c.828) password doesn't match for /cam_pic.php username: 5 IP: 192.168.0.106
|  2022-07-20 08:48:00: mod_auth.c.828) password doesn't match for /status_mjpeg.php username:  IP: 192.168.0.106
`-

I use the default lighttpd-auth.conf that came with the standard dietpi fail2ban install.

dietpi@camera:/etc/fail2ban$ cat jail.local
[DEFAULT]
enabled = true
ignoreip = 127.0.0.1/8
ignorecommand =
backend = systemd
mode = normal
filter = %(__name__)s[mode=%(mode)s]
findtime = 600
maxretry = 3
bantime = 600
banaction = route
action = %(banaction)s[blocktype=blackhole]

[dropbear]

[sshd]
# Mode: normal (default), ddos, extra or aggressive (combines all)
# See "filter.d/sshd.conf" for details.
#mode = normal

[lighttpd-auth]
enabled = true
port = http https
filter = lighttpd-auth
logpath = /var/log/lighttpd/error.log

Even though fail2ban sees the errors it labels them as Missed and does nothing. How can I get fail2ban to recognise the errors correctly and block more login attempts?

Thanks

Luke

Hmm, probably the filter needs an update. Lighttpd is rarely used nowadays, so that not enough people are reporting such upstream, I guess.

Can you show:

cat /etc/fail2ban/filter.d/lighttpd-auth.conf

EDIT: The upstream filter however looks like it should match: fail2ban/lighttpd-auth.conf at master · fail2ban/fail2ban · GitHub

Ah, this commit seems to have fixed it: filter.d/lighttpd-auth.conf: adjusted to the current source code + av… · fail2ban/fail2ban@ba839af · GitHub
Can you try to apply it?

I applied the new filter and it has made a difference.
My failed logins are now matched, but I’m not blocked after 3 attempts.

dietpi@camera:~$ sudo fail2ban-regex /var/log/lighttpd/error.log /etc/fail2ban/filter.d/lighttpd-auth.conf --print-all-missed --print-all-matched

Running tests
=============

Use   failregex filter file : lighttpd-auth, basedir: /etc/fail2ban
Use         log file : /var/log/lighttpd/error.log
Use         encoding : UTF-8


Results
=======

Failregex: 17 total
|-  #) [# of hits] regular expression
|   1) [17] ^\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*$
`-

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [18] {^LN-BEG}ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T|  ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
`-

Lines: 18 lines, 0 ignored, 17 matched, 1 missed
[processed in 0.03 sec]

|- Matched line(s):
|  2022-07-21 12:38:37: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 3 IP: 192.168.0.106
|  2022-07-21 12:38:43: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 3 IP: 192.168.0.106
|  2022-07-21 12:38:48: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 3 IP: 192.168.0.106
|  2022-07-21 12:38:53: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 3 IP: 192.168.0.106
|  2022-07-21 12:39:55: mod_auth.c.828) password doesn't match for / username: guess IP: 192.168.0.106
|  2022-07-21 12:39:59: mod_auth.c.828) password doesn't match for / username: guess IP: 192.168.0.106
|  2022-07-21 12:40:03: mod_auth.c.828) password doesn't match for / username: guess IP: 192.168.0.106
|  2022-07-21 12:40:09: mod_auth.c.828) password doesn't match for / username: guess IP: 192.168.0.106
|  2022-07-21 12:41:15: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 1 IP: 192.168.0.105
|  2022-07-21 12:41:16: mod_auth.c.828) password doesn't match for /js/script.js username: 1 IP: 192.168.0.105
|  2022-07-21 12:41:18: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 1 IP: 192.168.0.105
|  2022-07-21 12:41:18: mod_auth.c.828) password doesn't match for /js/script.js username: 1 IP: 192.168.0.105
|  2022-07-21 12:41:20: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 1 IP: 192.168.0.105
|  2022-07-21 12:41:20: mod_auth.c.828) password doesn't match for /js/script.js username: 1 IP: 192.168.0.105
|  2022-07-21 12:41:23: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 1 IP: 192.168.0.105
|  2022-07-21 12:41:25: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 1 IP: 192.168.0.105
|  2022-07-21 12:41:27: mod_auth.c.828) password doesn't match for /css/style_minified.css username: 1 IP: 192.168.0.105
`-
|- Missed line(s):
|  2022-07-21 12:37:19: server.c.1513) server started (lighttpd/1.4.59)
`-

The first 4 matches are from Opera, the next 4 are from Firefox and the rest are from Chrome.

Luke

Use backend=polling in the lighttpd-auth section. The default is systemd, which works for both SSH servers.

SUCCESS

Jul 22 10:07:55 camera fail2ban-server[1016]: fail2ban.actions [1016]: NOTICE [lighttpd-auth] Ban 192.168.0.105

The 2 part solution was…

  1. Set backend=polling in jail.local
  2. Copy lighttpd-auth.conf to lighttpd-auth.local, and in the new file change the failregex line to

failregex = ^\s*(?:: )?(?(?:http|mod)_auth.c.\d+) (?:password doesn't match for (?:\S+|.?) username:\s+(?:\S+|.?)\s*|digest: auth failed(?: for\s+<F-ALT_USER>(?:\S+|.?)</F-ALT_USER>\s)?: (?:wrong password|uri mismatch ([^)]))|get_password failed),? IP: \s$

Thank you for your help, this is the first time that something hasn’t worked in any of my 3 dietpi Pi’s.

Luke