mirror of
https://github.com/deunix-educ/Fail2banMqttActionBanishment.git
synced 2026-08-24 03:11:58 +02:00
First commit
This commit is contained in:
@@ -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
|
||||
@@ -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 =
|
||||
@@ -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 =
|
||||
@@ -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, \+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 =
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user