From fe284d8a384212110243a4337d4ec3467b65fb89 Mon Sep 17 00:00:00 2001 From: Damien Date: Fri, 31 Jul 2026 17:15:04 +0200 Subject: [PATCH 1/2] fix(proxy): exclude git-over-HTTPS 401s from traefik fail2ban jail Git smart-HTTP always fires an unauthenticated request first, gets a 401 challenge, then retries with credentials. On a private repo, ~10 git operations in 5 minutes hit maxretry and ban the legitimate client for an hour. Excludes 401s on info/refs, git-upload-pack and git-receive-pack while leaving other 401 sources (UI, API) covered. Closes #17 --- proxy/install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/proxy/install.sh b/proxy/install.sh index cfca993..d03f9bc 100644 --- a/proxy/install.sh +++ b/proxy/install.sh @@ -158,7 +158,11 @@ main() { # Two patterns cover both possible field orderings in the JSON. failregex = ^.*"ClientHost":"".*"DownstreamStatus":(401|403|429|5[0-9]{2}) ^.*"DownstreamStatus":(401|403|429|5[0-9]{2}).*"ClientHost":"" -ignoreregex = +# Git smart-HTTP always does an unauthenticated request first, gets a 401 +# WWW-Authenticate challenge, then retries with credentials. That first 401 +# is protocol, not abuse — without this exclusion a handful of git +# clone/fetch/push in a few minutes bans the client on a private repo. +ignoreregex = ^.*"RequestPath":"[^"]*/(info/refs|git-upload-pack|git-receive-pack)[^"]*".*"DownstreamStatus":401 EOF sudo tee /etc/fail2ban/jail.d/traefik.conf > /dev/null << 'EOF' -- 2.55.0 From 25bd5f2ac9b20b2b047f98cee5f9816c361274e2 Mon Sep 17 00:00:00 2001 From: Damien Date: Sat, 1 Aug 2026 10:58:51 +0200 Subject: [PATCH 2/2] fix(proxy): couvrir les deux ordres de champs dans l'ignoreregex git MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'ignoreregex n'excluait que l'ordre RequestPath puis DownstreamStatus, alors que le failregex juste au-dessus gère explicitement les deux ordres possibles de sérialisation JSON de Traefik. Si Traefik sérialise dans l'autre ordre, l'exclusion ne matchait pas et le ban sur git fetch revenait silencieusement. Ajoute la seconde ligne (DownstreamStatus puis RequestPath), symétrique au failregex. --- proxy/install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proxy/install.sh b/proxy/install.sh index d03f9bc..55660f6 100644 --- a/proxy/install.sh +++ b/proxy/install.sh @@ -162,7 +162,9 @@ failregex = ^.*"ClientHost":"".*"DownstreamStatus":(401|403|429|5[0-9]{2}) # WWW-Authenticate challenge, then retries with credentials. That first 401 # is protocol, not abuse — without this exclusion a handful of git # clone/fetch/push in a few minutes bans the client on a private repo. +# Same two-orderings caveat as failregex above. ignoreregex = ^.*"RequestPath":"[^"]*/(info/refs|git-upload-pack|git-receive-pack)[^"]*".*"DownstreamStatus":401 + ^.*"DownstreamStatus":401.*"RequestPath":"[^"]*/(info/refs|git-upload-pack|git-receive-pack)[^"]*" EOF sudo tee /etc/fail2ban/jail.d/traefik.conf > /dev/null << 'EOF' -- 2.55.0