Hey everyone,
I was looking through my server logs recently and noticed a lot of the usual background noise of the internet: bots scanning for .env
files, probing for WordPress admin panels, and other common attack vectors. Since I use Caddy as my web server and reverse proxy, I decided it was time to set up Fail2Ban to automatically block these bad actors.
The first step was to create a new filter specifically for Caddy's JSON-formatted logs. This filter uses a few regular expressions to catch the most common offenders.
Here's the filter, which I saved as /etc/fail2ban/filter.d/caddy-json.conf
:
[Definition]
# Matches the Unix epoch timestamp in Caddy's JSON logs.
datepattern = LongEpoch
# Multiple failregex lines are treated as OR.
failregex =
# Matches common authentication failures.
^.*"remote_ip":\s*"<HOST>".*"status":\s*(401|403).*$
# Matches scanners probing for common vulnerabilities/files (resulting in 404).
^.*"remote_ip":\s*"<HOST>".*"uri":\s*".*(?:/\.git|/\.env|/wp-admin|/wp-login\.php|/xmlrpc\.php).*".*"status":\s*404.*$
# Matches common malicious user agents.
^.*"remote_ip":\s*"<HOST>".*"User-Agent":\s*\[\s*"(?i:sqlmap|nmap|nikto|wpscan|masscan)".*].*$
ignoreregex =
This filter looks for three main things:
401
(Unauthorized) or 403
(Forbidden) responses.404
(Not Found) errors for common exploit paths like /wp-admin
or .env
.sqlmap
or nmap
.With the filter in place, the next step was to enable a new "jail" to use it. I added the following to my /etc/fail2ban/jail.local
file:
[caddy-json]
enabled = true
filter = caddy-json
port = http,https
logpath = /var/log/caddy/*.log
This configuration tells Fail2Ban to enable the caddy-json
jail, use our new filter, monitor all Caddy log files, and block offenders on the http
and https
ports. My default settings will ban an IP for one hour after three offenses, with an exponential backoff for repeat offenders.
Before letting it run wild, I used the fail2ban-regex
utility to test the filter against my actual Caddy access log. As you can see, it found plenty of malicious requests to block.
My previous attempts at this were sometimes a bit too aggressive, but based on these test results, I'm hopeful this setup will significantly slow down the automated scanning without blocking legitimate users.
As always,
Michael Garcia a.k.a. TheCrazyGM
Harden the shell GM!
!PAKX
!PIMP
!PIZZA
View or trade
PAKX
tokens.Use !PAKX command if you hold enough balance to call for a @pakx vote on worthy posts! More details available on PAKX Blog.
$PIZZA slices delivered:
@ecoinstant(1/20) tipped @thecrazygm
Come get MOONed!