feat(proxy): jail fail2ban gitea + rate-limit et fermeture de /metrics #28

Closed
Damien wants to merge 1 commits from feat/proxy-jail-gitea into feat/proxy-rsyslog
1 Commits
Author SHA1 Message Date
Damien 5c6bee3335 feat(proxy): add gitea-auth fail2ban jail, rate-limit, close /metrics
Gitea returns HTTP 200 on a failed web login (the page is simply
re-rendered with an error), so the existing traefik-auth jail, which
matches on DownstreamStatus, is structurally blind to brute force on
the login form. Adds a dedicated gitea-auth jail reading the
forwarded application log (routed by the new 50-gitea.conf on top of
#20's generic receiver), plus a Traefik-side rate limit on
/user/login, /user/sign_up and /user/forgot_password as a second
layer.

[DEFAULT] ignoreip in jail.local guards every jail (not just
gitea-auth) so a misconfigured X-Forwarded-For chain can't ban the
tailnet itself — this must be in place before the jail, since the
whole point is to make that failure mode structurally impossible
rather than caught after the fact.

conf.d/gitea.yml gains a highest-priority router that denies public
access to /metrics (ipAllowList limited to loopback) while leaving it
reachable on the tailnet, where Gitea's own tailscale serve answers
directly. The backend also moves to https://gitea.taila5ad8.ts.net
(443, no port) — the result of #19's tailscale serve --https=443 —
which is NOT compatible with the previous :3000 backend of the old
community-scripts deployment; only apply once the data migration has
actually happened.

Verified with real fail2ban/rsyslog/Traefik v3 in disposable
containers: the gitea filter matches real failure log lines and
misses the normal login-page line; 5 failed logins from an external
IP bans it while 5 from the Tailscale CGNAT range never do (ignoreip
in effect); a forwarded "gitea"-tagged message lands in
/var/log/gitea/gitea.log; Traefik loads all three routers, both
middlewares, and the stated priorities without error.

Closes #21
2026-08-01 08:45:38 +02:00