Files
familienarchiv/infra/fail2ban/jail.d/familienarchiv.conf
Marcel e5363913ec
Some checks failed
CI / Unit & Component Tests (push) Failing after 2m49s
CI / OCR Service Tests (push) Successful in 16s
CI / Backend Unit Tests (push) Successful in 4m8s
CI / fail2ban Regex (push) Successful in 37s
CI / Compose Bucket Idempotency (push) Failing after 53s
CI / Unit & Component Tests (pull_request) Failing after 2m46s
CI / OCR Service Tests (pull_request) Successful in 15s
CI / Backend Unit Tests (pull_request) Successful in 4m14s
CI / fail2ban Regex (pull_request) Successful in 37s
CI / Compose Bucket Idempotency (pull_request) Failing after 50s
fix(fail2ban): pin polling backend so jail actually reads Caddy access log
Closes #503.

Debian's fail2ban package ships defaults-debian.conf with
`[DEFAULT] backend = systemd`. Without an explicit override, our
familienarchiv-auth jail inherits the systemd backend at runtime,
reads from journald, and never inspects /var/log/caddy/access.log.
A live login brute-force would not be banned.

Add `backend = polling` to the jail and a CI step that links the jail
into /etc/fail2ban/ and asserts `fail2ban-client -d` resolves it to
the polling backend, not the inherited systemd backend.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 14:59:40 +02:00

34 lines
1.4 KiB
Plaintext

# Jail definition for the Familienarchiv login endpoint.
#
# Install: ln -sf /opt/familienarchiv/infra/fail2ban/jail.d/familienarchiv.conf \
# /etc/fail2ban/jail.d/familienarchiv.conf
# ln -sf /opt/familienarchiv/infra/fail2ban/filter.d/familienarchiv-auth.conf \
# /etc/fail2ban/filter.d/familienarchiv-auth.conf
# systemctl reload fail2ban
#
# Verify with:
# fail2ban-client status familienarchiv-auth
# fail2ban-regex /var/log/caddy/access.log familienarchiv-auth
#
# Tuning rationale:
# - maxretry 10: legitimate users mistyping passwords don't trip the jail
# - findtime 10m: rolling window that catches automated brute force
# - bantime 30m: long enough to discourage scripted attacks, short
# enough that a user who fat-fingered their VPN comes
# back online within a coffee break
[familienarchiv-auth]
enabled = true
# Override Debian's `backend = systemd` default (set in
# /etc/fail2ban/jail.d/defaults-debian.conf). Without this line our jail
# inherits the systemd backend, reads from journald, and never inspects
# Caddy's file-based JSON access log — i.e. brute-force protection is inert.
# `polling` works without inotify and is fine for one rotated log file.
backend = polling
filter = familienarchiv-auth
logpath = /var/log/caddy/access.log
maxretry = 10
findtime = 10m
bantime = 30m
action = iptables-multiport[name=familienarchiv-auth, port="http,https"]