First commit

This commit is contained in:
2026-07-20 11:05:07 +02:00
commit b592ab669f
159 changed files with 10294 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
[Definition]
# Filtre générique réutilisable par TOUTE appli de ce VPS qui veut se
# protéger d'un brute-force applicatif (pas seulement ce projet — cf.
# jail.d/app-auth.conf.template pour le mode d'emploi). Une seule
# convention de ligne de log à respecter, peu importe l'appli :
# Verrouillage <NOM_APPLI> après échecs répétés depuis <IP> (...)
# <NOM_APPLI> n'est volontairement pas capturé (\S+ générique, un seul
# mot) : un seul filtre sert toutes les jails app-auth-*, quelle que soit
# l'appli protégée — pas de fichier filter.d dédié à réécrire à chaque
# nouvelle appli. Premier consommateur : emitter-admin-auth (Django +
# django-axes, cf. emitter/banevents/signals.py pour l'exemple concret).
failregex = ^.*Verrouillage \S+ après échecs répétés depuis <HOST>.*$
ignoreregex =
# Piège vécu (emitter-admin-auth, 2026-07-18) : le timestamp EN TÊTE de
# ligne doit porter un fuseau explicite (ex. suffixe "Z" ISO 8601, UTC).
# fail2ban lit l'horloge système réelle du VPS pour juger la fraîcheur
# d'une ligne ; un process applicatif qui journalise en UTC sans le dire
# (courant avec Django : TIME_ZONE='UTC' force tout le process en UTC via
# time.tzset(), cf. config/settings/base.py) produit des timestamps qui
# paraissent "vieux" de plusieurs heures dès que le fuseau système diffère
# d'UTC — fail2ban les ignore alors silencieusement juste après un
# restart ("Ignoring all log entries older than 3600s"), sans aucune
# erreur visible. Toute appli qui adopte ce filtre doit journaliser avec
# un marqueur de fuseau non ambigu.
@@ -0,0 +1,19 @@
# Generic configuration file for -botsearch filters
[Init]
# Block is the actual non-found directories to block
block = \/?(<webmail>|<phpmyadmin>|<wordpress>|cgi-bin|mysqladmin)[^,]*
# These are just convenient definitions that assist the blocking of stuff that
# isn't installed
webmail = roundcube|(ext)?mail|horde|(v-?)?webmail
phpmyadmin = (typo3/|xampp/|admin/|)(pma|(php)?[Mm]y[Aa]dmin)
wordpress = wp-(login|signup|admin)\.php
# DEV Notes:
# Taken from apache-botsearch filter
#
# Author: Frantisek Sumsal
+16
View File
@@ -0,0 +1,16 @@
[INCLUDES]
before = common.conf
[Definition]
# Coturn log format :
# 2024-01-15 10:23:45.123 : ERROR: <pid>: <session>,from=<ip>:<port>,...: Wrong credentials
# 2024-01-15 10:23:45.123 : WARNING: <pid>: ...: No credentials
#
# Vérifier le chemin des logs : /var/log/turnserver*.log ou /var/log/coturn.log
# et adapter si nécessaire avec : fail2ban-regex /var/log/coturn.log /etc/fail2ban/filter.d/coturn.conf
failregex = ^.*: (?:ERROR|WARNING).*from=<HOST>:\d+.*: (?:Wrong credentials|No credentials|Cannot find credentials|authentication failed|Auth error)
^.*: (?:ERROR|WARNING).*\(<HOST>,\d+\).*: (?:Wrong credentials|No credentials|Cannot find credentials)
ignoreregex =
@@ -0,0 +1,14 @@
[Definition]
# Filtre volontairement inerte : cette jail n'est jamais déclenchée par un
# log, uniquement par injection manuelle (fail2ban-client set banip),
# depuis master_client.py sur réception d'un SYNC_BAN du master. logpath
# pointe vers un fichier réel existant (fail2ban.log) pour satisfaire
# fail2ban au démarrage (cf. incident coturn, ROADMAP.md Phase 1.b), mais
# ce failregex ne doit jamais matcher quoi que ce soit dedans.
#
# <HOST> est obligatoire même ici : fail2ban rejette au chargement tout
# failregex sans groupe d'identification de l'hôte ("No failure-id group
# in ..."), qu'il soit ou non censé matcher un jour. Le préfixe littéral
# improbable garantit qu'aucune ligne réelle de fail2ban.log ne matchera.
failregex = ^NEVER_MATCH_ANYTHING_master_sync_is_manual_only <HOST>$
ignoreregex =
+24
View File
@@ -0,0 +1,24 @@
[INCLUDES]
before = common.conf
[Definition]
# Mosquitto ne logue pas l'IP sur la ligne d'échec d'auth — deux approches :
#
# Approche A (défaut) : capturer les connexions répétées sur le port TLS (8883/8884)
# Nécessite : log_type connect (ou all) dans mosquitto.conf
# Régler maxretry à 10+ pour éviter les faux positifs (reconnexions légitimes MQTT)
#
# Approche B (recommandée) : activer un plugin d'auth qui logue l'IP sur les échecs
# Ex: mosquitto-go-auth → logue "Login Failed: <user> from <ip>"
#
# Adapter la regex au format de ton mosquitto.log avec :
# fail2ban-regex /var/log/mosquitto/mosquitto.log /etc/fail2ban/filter.d/mosquitto.conf
# Approche A — connexions sur port TLS
failregex = ^.*: New connection from <HOST>(?::\d+)? on port (?:8883|8884)\.$
# Approche B — si plugin d'auth avec IP sur la ligne d'échec (décommenter)
#failregex = ^.*: (?:Login Failed|authentication failed|not authorised).*from <HOST>
ignoreregex =
+3
View File
@@ -0,0 +1,3 @@
[Definition]
failregex = ^<HOST>.*"(GET|POST).*" (400|403|404|405|444) .*$
ignoreregex = .*(robots\.txt|favicon\.ico|\.jpg|\.png|\.css|\.js)
@@ -0,0 +1,24 @@
# Fail2Ban configuration file
#
# Regexp to catch known spambots and software alike. Please verify
# that it is your intent to block IPs which were driven by
# above mentioned bots.
[Definition]
badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider|(?:Mozilla/\d+\.\d+ )?Jorgee
badbots = Atomic_Email_Hunter/4\.0|atSpider/1\.0|autoemailspider|bwh3_user_agent|China Local Browse 2\.6|ContactBot/0\.2|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailSpider|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Guestbook Auto Submitter|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 \+http\://letscrawl\.com/|Lincoln State Web Browser|LMQueueBot/0\.2|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|MVAClient|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/3\.0 \(compatible; scan4mail \(advanced version\) http\://www\.peterspages\.net/?scan4mail\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|NameOfAgent \(CMS Spider\)|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|ShablastBot 1\.0|snap\.com beta crawler v0|Snapbot/1\.0|Snapbot/1\.0 \(Snap Shots&#44; \+http\://www\.snap\.com\)|sogou develop spider|Sogou Orion spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sogou spider|Sogou web spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|VadixBot|WebVulnCrawl\.unknown/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00
failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$
ignoreregex =
datepattern = ^[^\[]*\[({DATE})
{^LN-BEG}
# DEV Notes:
# List of bad bots fetched from http://www.user-agents.org
# Generated on Thu Nov 7 14:23:35 PST 2013 by files/gen_badbots.
#
# Author: Yaroslav Halchenko
@@ -0,0 +1,25 @@
# Fail2Ban filter to match web requests for selected URLs that don't exist
#
[INCLUDES]
# Load regexes for filtering
before = botsearch-common.conf
[Definition]
failregex = ^<HOST> \- \S+ \[\] \"(GET|POST|HEAD) \/<block> \S+\" 404 .+$
^ \[error\] \d+#\d+: \*\d+ (\S+ )?\"\S+\" (failed|is not found) \(2\: No such file or directory\), client\: <HOST>\, server\: \S*\, request: \"(GET|POST|HEAD) \/<block> \S+\"\, .*?$
ignoreregex =
datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
^[^\[]*\[({DATE})
{^LN-BEG}
journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx
# DEV Notes:
# Based on apache-botsearch filter
#
# Author: Frantisek Sumsal
@@ -0,0 +1,32 @@
# Generic nginx error_log configuration items (to be used as interpolations) in other
# filters monitoring nginx error-logs
#
[DEFAULT]
# Type of log-file resp. log-format (file, short, journal):
logtype = file
# Daemon definition is to be specialized (if needed) in .conf file
_daemon = nginx
# Common line prefixes (beginnings) which could be used in filters
#
# [bsdverbose]? [hostname] [vserver tag] daemon_id spaces
#
# This can be optional (for instance if we match named native log files)
__prefix = <lt_<logtype>/__prefix>
__err_type = error
__prefix_line = %(__prefix)s\[%(__err_type)s\] \d+#\d+: \*\d+\s+
[lt_file]
__prefix = \s*
[lt_short]
__prefix = \s*(?:(?!\[)\S+ %(_daemon)s\[\d+\]: [^\[]*)?
[lt_journal]
__prefix = %(lt_short/__prefix)s
@@ -0,0 +1,43 @@
# fail2ban filter configuration for nginx
[INCLUDES]
before = nginx-error-common.conf
[Definition]
mode = normal
__err_type = <_ertp-<mode>>
_ertp-auth = error
mdre-auth = ^%(__prefix_line)suser "(?:[^"]+|.*?)":? (?:password mismatch|was not found in "[^\"]*"), client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(?:, referrer: "\S+")?\s*$
_ertp-fallback = crit
mdre-fallback = ^%(__prefix_line)sSSL_do_handshake\(\) failed \(SSL: error:\S+(?: \S+){1,3} too (?:long|short)\)[^,]*, client: <HOST>
_ertp-normal = %(_ertp-auth)s
mdre-normal = %(mdre-auth)s
_ertp-aggressive = (?:%(_ertp-auth)s|%(_ertp-fallback)s)
mdre-aggressive = %(mdre-auth)s
%(mdre-fallback)s
failregex = <mdre-<mode>>
ignoreregex =
datepattern = {^LN-BEG}
journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx
# DEV NOTES:
# mdre-auth:
# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files
# Extensive search of all nginx auth failures not done yet.
#
# Author: Daniel Black
# mdre-fallback:
# Ban people checking for TLS_FALLBACK_SCSV repeatedly
# https://stackoverflow.com/questions/28010492/nginx-critical-error-with-ssl-handshaking/28010608#28010608
# Author: Stephan Orlowsky
@@ -0,0 +1,56 @@
# Fail2ban filter configuration for nginx :: limit_req
# used to ban hosts, that were failed through nginx by limit request processing rate
#
# Author: Serg G. Brester (sebres)
#
# To use 'nginx-limit-req' filter you should have `ngx_http_limit_req_module`
# and define `limit_req` and `limit_req_zone` as described in nginx documentation
# http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
#
# Example:
#
# http {
# ...
# limit_req_zone $binary_remote_addr zone=lr_zone:10m rate=1r/s;
# ...
# # http, server, or location:
# location ... {
# limit_req zone=lr_zone burst=1 nodelay;
# ...
# }
# ...
# }
# ...
#
[INCLUDES]
before = nginx-error-common.conf
[Definition]
# Specify following expression to define exact zones, if you want to ban IPs limited
# from specified zones only.
# Example:
#
# ngx_limit_req_zones = lr_zone|lr_zone2
#
ngx_limit_req_zones = [^"]+
# Depending on limit_req_log_level directive (may be: info | notice | warn | error):
__err_type = [a-z]+
# Use following full expression if you should range limit request to specified
# servers, requests, referrers etc. only :
#
# failregex = ^%(__prefix_line)slimiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>, server: \S*, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"(, referrer: "\S+")?\s*$
# Shortly, much faster and stable version of regexp:
failregex = ^%(__prefix_line)slimiting requests, excess: [\d\.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,
ignoreregex =
datepattern = {^LN-BEG}
journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx
@@ -0,0 +1,5 @@
[Definition]
failregex = ^<HOST> -.*GET .*/~.*
ignoreregex =
@@ -0,0 +1,5 @@
[Definition]
failregex = ^<HOST> -.*GET http.*
ignoreregex =
@@ -0,0 +1,6 @@
[Definition]
failregex = ^<HOST> -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\.scgi)
ignoreregex =
@@ -0,0 +1,3 @@
[Definition]
failregex = ^<HOST>.*"(GET|POST).*" 401 .*$
ignoreregex =
+16
View File
@@ -0,0 +1,16 @@
[INCLUDES]
before = common.conf
[Definition]
_daemon = openvpn
# TLS handshake échouée et AUTH_FAILED
# Format log : <ip>:<port> TLS Error: ...
# Compatible avec log-append et syslog
failregex = ^%(__prefix_line)s<HOST>:\d+ TLS Error: TLS key negotiation failed
^%(__prefix_line)s<HOST>:\d+ TLS Error: TLS handshake failed
^%(__prefix_line)s<HOST>:\d+ AUTH_FAILED
^%(__prefix_line)s<HOST>:\d+ Connection reset, restarting
ignoreregex =
@@ -0,0 +1,16 @@
[INCLUDES]
before = common.conf
[Definition]
_daemon = (?:fail2ban(?:-server|\.actions)\s*)
_jailname = recidive
failregex = ^%(__prefix_line)s(?:\s*fail2ban\.actions\s*%(__pid_re)s?:\s+)?NOTICE\s+\[(?!%(_jailname)s\])(?:.*)\]\s+Ban\s+<HOST>\s*$
datepattern = ^{DATE}
# Ne pas traiter les bans émis par les jails recidive eux-mêmes
ignoreregex = \[recidive.*\]\s+Ban\s+<HOST>
journalmatch = _SYSTEMD_UNIT=fail2ban.service PRIORITY=5