Episode 10: hardening - firewall rules Docker cannot bypass, Caddy access log and rate limiting, fail2ban in the right chain

- hardening/: ufw after.rules block for DOCKER-USER (ctorigdstport, not dport),
  fail2ban jail.local with sshd (systemd backend) and caddy-probes (chain DOCKER-USER),
  filter for the JSON access log, sshd hardening.conf, README with the order and
  the two traps measured in the episode
- caddy/Dockerfile: xcaddy build with caddy-ratelimit, compose builds the image
- Caddyfile: common snippet (JSON access log, Server header stripped), vault /admin 404,
  rate_limit zones on the vault token endpoint and the git login form
- HARDENING.md: firewall and fail2ban sections rewritten around what the port scan saw

Claude-Session: https://claude.ai/code/session_017iP581CYtPfxdZYPPAyWZA
This commit is contained in:
Maximilian Grimm 2026-09-11 10:20:56 +02:00
parent ccbddab46c
commit bed41cfaf3
12 changed files with 319 additions and 16 deletions

View file

@ -0,0 +1,8 @@
# /etc/fail2ban/filter.d/caddy-probes.conf (episode 10)
# Matches the JSON access log: bots that harvest 401/403/404/429 (probing for
# /.env, /wp-login.php, /xmlrpc.php, or hammering a login past the rate limit).
# The whole log entry is one line; client_ip sits in the request object and
# status at the top level, so client_ip always comes before status.
[Definition]
failregex = ^.*"client_ip":"<HOST>".*"status":(401|403|404|429)\b.*$
ignoreregex =