From 321e1c4daa954873a2709a844a56133cd5e8e0e4 Mon Sep 17 00:00:00 2001 From: jack Date: Sun, 22 Mar 2026 04:51:43 +0700 Subject: [PATCH] feat: extend fail2ban with Forgejo SSH and Traefik HTTP jails - Add traefik-auth filter: ban IPs with 10+ HTTP 401/403 in 5 min - Add forgejo-ssh jail: ban after 3 failed SSH attempts (24h ban) - Both jails are active; forgejo-ssh already detected 8 real attempts - Traefik access.log now written to /opt/services/traefik/logs/ Co-Authored-By: Claude Sonnet 4.6 --- roles/base/tasks/firewall.yml | 37 ++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/roles/base/tasks/firewall.yml b/roles/base/tasks/firewall.yml index 5a7ea7f..346ed1e 100644 --- a/roles/base/tasks/firewall.yml +++ b/roles/base/tasks/firewall.yml @@ -118,20 +118,51 @@ community.general.ufw: state: enabled -- name: Ensure fail2ban is configured for SSH +- name: Deploy fail2ban Traefik filter + ansible.builtin.copy: + dest: /etc/fail2ban/filter.d/traefik-auth.conf + content: | + [Definition] + # Match lines where Traefik returned 401 or 403 + failregex = ^ - \S+ \[.*\] ".*" (401|403) .*$ + ignoreregex = + mode: "0644" + notify: Restart fail2ban + +- name: Ensure fail2ban is configured ansible.builtin.copy: dest: /etc/fail2ban/jail.local content: | [DEFAULT] - bantime = 3600 + bantime = 3600 findtime = 600 maxretry = 5 [sshd] enabled = true - port = {{ sshd_port }} + port = {{ sshd_port }} logpath = %(sshd_log)s backend = %(sshd_backend)s + + # Forgejo git-over-SSH (port 2222, bypasses Cloudflare — ban is effective) + [forgejo-ssh] + enabled = true + port = 2222 + filter = sshd + logpath = %(sshd_log)s + backend = %(sshd_backend)s + maxretry = 3 + bantime = 86400 + + # Traefik HTTP 401/403 — brute force on protected routes + [traefik-auth] + enabled = true + port = http,https + filter = traefik-auth + logpath = /opt/services/traefik/logs/access.log + maxretry = 10 + findtime = 300 + bantime = 3600 mode: "0644" notify: Restart fail2ban