Code source : github.com/Alex0176/odoo-web-rbl — AGPL-3, librement utilisable.
Qui exploite un serveur Odoo sur Internet reçoit des visites. Pas occasionnellement, mais sans interruption. Pendant dix-sept jours, nous avons enregistré et analysé sur nos cinq sites web 731 297 requêtes. 110 511 d'entre elles n'étaient pas des visiteurs, mais des recherches automatisées de vulnérabilités, d'identifiants et de fichiers de configuration.
Cet article décrit Web RBL, un module open source pour Odoo 19 Community qui détecte, évalue, comptabilise et repousse ce trafic — et qui publie la liste de blocage sous forme de liste RBL, c'est-à-dire dans le format que les pare-feu et les reverse proxys lisent directement. Tous les chiffres proviennent de l'exploitation réelle.
Ce que sait faire le module — les fonctions en un coup d'œil
| Fonction | Ce qu'elle fait | Distribution |
|---|---|---|
| Détection de motifs | Détecte les sondages d'après le chemin et l'extension : .env, .git, fichiers de configuration, clés cloud, instructions de build CI/CD, WordPress, PHP, traversée de chemin, gestionnaire de base de données, GraphQL, exécution de commandes via /api/fs/exec et interfaces similaires | bloquer |
| Trois niveaux par motif | bloquer, compter ou signaler — modifiable pour chaque motif, sans code | par motif |
| Seuils | Nombre de correspondances d'un même motif avant blocage ; pour les connexions, dix | 10 pour la connexion |
| Défense de connexion | Connexions échouées via le formulaire et XML-RPC/JSON-RPC, vérifications de session échouées, accès au gestionnaire de base de données — dans la base de données, pas dans la mémoire vive | activé |
| Détection de bots à la connexion | Qui ignore le message d'attente après dix tentatives infructueuses et continue de frapper est immédiatement bloqué | bloquer |
| Détection comportementale | Adresses qui génèrent en cinq minutes vingt pages d'erreur et presque aucune page valide — donc qui devinent au lieu de lire | signaler |
| Évaluation de 0 à 100 | Dans quelle mesure est-il certain qu'un attaquant se trouve derrière l'adresse ? À partir de la gravité du motif, du nombre de motifs différents, de jours remarquables, des domaines concernés et du nombre de correspondances — avec justification en clair | activé |
| Blocage de connexion selon l'évaluation | À partir d'une évaluation réglable, la connexion est interdite, le site web reste lisible | à partir de 40 |
| Soupçon d'identifiants volés | Une connexion réussie depuis une adresse suspecte est signalée et, sur demande, attribuée comme tâche — une fois par adresse et par jour | activé |
| Listes de menaces | Nœuds de sortie Tor, Spamhaus DROP, FireHOL Level 1 et blocklist.de préconfigurés ; toute autre liste RBL peut être ajoutée par son adresse, comparaison quotidienne, niveau propre à chaque liste | signaler |
| Accès à la connexion refusé | Le quatrième niveau pour les listes et les pays : le site reste lisible, le formulaire de connexion et les interfaces sont fermés — la bonne réponse à Tor | Option |
| Pays d'origine | Pays par occurrence et par adresse via GeoLite2 ; le module met lui-même à jour la base de données avec une clé de licence gratuite | afficher |
| Règles par pays | Bloquer, accès à la connexion refusé, signaler ou autoriser expressément — par pays, volontairement sans valeur par défaut | aucune |
| Erreurs de configuration | QNAP, Synology, Exchange Autodiscover, ActiveSync, WebDAV/CalDAV/CardDAV sont reconnus, jamais bloqués, et versés dans une liste de travail avec le constat et le domaine concerné | signaler |
| Un ticket par adresse | Un constat devient, sur demande, un ticket — exactement un par adresse ; un ticket fermé est rouvert au lieu d'être dupliqué | désactivé |
| Pages obligatoires et collecteurs | Le chemin canonique des mentions légales reste toujours accessible ; les essais automatisés d'orthographes étrangères sont détectés et, sur demande, bloqués | signaler |
| Liste blanche | Adresses et réseaux qui ne sont jamais bloqués ; elle se remplit chaque jour à partir du pare-feu (extrémités VPN) et des plages d'adresses publiées de Googlebot et de Bingbot | activé |
| Attribution aux clients | Une occurrence provenant du réseau d'un client lui est attribuée — à partir de la liste blanche, jamais devinée à la main | activé |
| Domaine et identifiant par occurrence | Quel site a été sollicité, avec quel User-Agent — les deux manquent dans le journal d'accès | activé |
| Analyse | Graphique et tableau croisé sur toutes les occurrences : par motif, jour, domaine, pays, adresse | activé |
| Leurre | Les sondes reçoivent des réponses inventées contenant une valeur canari ; celui qui la consulte plus tard les a lues | désactivé |
| Diffusion RBL | La liste de blocage sous forme de simple liste d'adresses ou de JSON, à une adresse dédiée protégée par jeton — pour HAProxy, OPNsense et tout pare-feu qui lit des listes d'URL | activé |
Tout ce qui est livré avec signaler, désactivé ou option l'est volontairement : celui qui active un blocage doit le faire parce qu'il a observé pendant quelques jours qui est touché — et non parce que la valeur par défaut l'exigeait.
L'analyse : occurrences par motif sur sept jours. La barre la plus haute correspond à la recherche de fichiers .env.
Listes RBL : une méthode standardisée pour diffuser des blocages
RBL signifie Real-time Blackhole List. Le terme vient du monde du courrier électronique, où Spamhaus et d'autres publient depuis les années quatre-vingt-dix des listes d'adresses d'expéditeurs malveillants. Le principe est d'une simplicité extrême, et c'est précisément pourquoi il est si répandu : une adresse par ligne, accessible via HTTP, rechargée régulièrement. Aucun format à analyser au préalable, aucune interface nécessitant un outil.
Pratiquement tous les pare-feu et tous les reverse proxys peuvent lire une telle liste et en tirer des règles. Les fabricants lui donnent des noms différents, mais le mécanisme est partout le même :
- OPNsense et pfSense — URL Table Alias : charger la liste d'adresses via HTTP, l'utiliser comme alias dans les règles de pare-feu, mise à jour toutes les heures ou tous les jours
- HAProxy — fichiers ACL et Maps :
src -f sperrliste.txtdans une règlehttp-request deny, rechargeable via l'API d'exécution sans redémarrage - nginx — module geo avec fichier d'adresses inclus, ou directives
denyissues d'un fichierincludegénéré - Fortinet FortiGate — External Block List ou Threat Feed : une URL à partir de laquelle le pare-feu obtient une liste d'adresses IP et l'utilise dans ses politiques
- Palo Alto Networks — External Dynamic List (EDL) : le même principe, sous forme de type d'objet propre dans les politiques de sécurité
- Check Point — Custom Intelligence Feeds et IP Block Lists via une URL
- Cisco Secure Firewall (Firepower) — Security Intelligence Feeds avec des sources de listes personnalisées
- Sophos Firewall — Third-Party Threat Feeds : listes d'adresses provenant d'une URL comme source de règles de blocage
- Juniper SRX — Dynamic Address Entries issues de feeds
- MikroTik RouterOS — Address Lists, alimentées depuis une URL par script et
fetch - CrowdSec — listes personnalisées comme source pour les bouncers sur tout système pris en charge
C'est exactement dans ce format que Web RBL diffuse sa liste de blocage. Le pare-feu rejette les paquets avant qu'ils n'atteignent le serveur web — et avec eux toute autre tentative de la même adresse, par exemple vers le serveur de messagerie ou la passerelle VPN.
Les deux sens, mais au bon endroit
Cela fonctionne aussi dans l'autre sens : dans Web RBL, on peut saisir n'importe quelle liste RBL — une URL, un niveau, et c'est fait. Les nœuds de sortie Tor, Spamhaus DROP, FireHOL et blocklist.de sont préconfigurés, d'autres s'ajoutent en trois clics. Le module décompose chaque liste en plages d'adresses et vérifie chaque requête par rapport à elles, en quelques microsecondes.
Et pourtant : il est plus judicieux d'utiliser les listes tierces sur le pare-feu en amont. Pour trois raisons. Le pare-feu voit tous les services, pas seulement HTTP — une adresse figurant sur la liste Spamhaus doit aussi échouer sur le serveur de messagerie et sur le VPN. Il rejette au niveau des paquets, avant même qu'une connexion ne soit établie, et ne coûte donc rien au serveur d'application. Et c'est l'endroit où ces listes sont de toute façon tenues à jour ; une deuxième copie dans l'application est un deuxième endroit où elle peut devenir obsolète.
À quoi servent alors les listes dans le module : à ce que le pare-feu ne sait pas faire. Il ne connaît pas de formulaire de connexion. Web RBL peut refuser à une adresse de la liste Tor l'accès à la connexion tout en livrant malgré tout le site — celui qui veut lire anonymement doit pouvoir le faire ; celui qui veut tester anonymement des mots de passe, non. Et il peut signaler comme cas suspect une connexion réussie depuis une adresse listée. Les deux exigent la liste là où la connexion a lieu.
Une évaluation plutôt qu'une intuition
Une adresse qui a demandé une seule fois /wp-login.php
n'est pas comparable à une adresse qui, sur deux jours, a essayé cinq motifs différents
sur trois domaines. Web RBL convertit cela en une
note de 0 à 100 — à partir de ce qu'il a lui-même
observé, sans service tiers et sans requête vers l'extérieur.
Une entrée : 99 occurrences, note 84, et la justification en clair — motif le plus grave, cinq motifs sérieux différents, deux jours suspects, plus de vingt occurrences.
La note détermine deux choses. À partir d'une valeur réglable, la connexion est interdite — le site reste lisible, mais celui qui a déjà cherché des identifiants n'a aucune occasion d'essayer ceux qu'il a trouvés. Et une connexion réussie depuis une adresse notée est signalée : quelqu'un n'a alors plus deviné, mais su. Soit l'utilisateur légitime était en déplacement, soit les identifiants ont été volés — le module ne tranche pas, il le soumet à quelqu'un qui peut poser la question. Le mot de passe lui-même n'est jamais touché.
La liste de blocage, filtrée par note à partir de 40 : nombre d'occurrences, jours suspects, domaines concernés et dernier chemin par adresse.
Ce que Web RBL protège — l'effet protecteur en détail
1. Les identifiants restent introuvables
La plus grande classe d'attaques mesurée ne cherche pas de failles dans Odoo, mais des secrets laissés à l'abandon. Sur dix-sept jours :
- 57 721 requêtes de fichiers
.env— on y trouve des mots de passe de bases de données, des clés d'API et des secrets de session - 5 535 requêtes de fichiers de configuration
- 4 388 requêtes d'identifiants cloud :
credentials.json,service-account.json,firebase-adminsdk.json,rclone.conf,.git-credentials - 2 811 requêtes de répertoires
.git— celui qui en trouve un télécharge l'intégralité du code source avec son historique - 1 907 requêtes d'instructions de build comme
.github/workflows/deploy.ymlou.gitlab-ci.yml, où figurent les registres et les noms de clés
Ce qui est décisif, ce n'est pas le nombre de requêtes, mais le nombre
d'adresses distinctes : /credentials.json provenait
de 98 adresses, /.git-credentials de 92. Il ne s'agit pas d'un
scanner isolé, mais d'un répertoire standard qui tourne dans le monde entier
simultanément.
2. Les tentatives de connexion tombent dans le vide — durablement
Odoo intègre son propre frein contre le test systématique de mots de passe. Il a trois limites, documentées dans le code source d'Odoo lui-même : le compteur se trouve dans la mémoire vive du processus de travail et est réinitialisé à chaque redémarrage, il ne fait que ralentir au lieu de bloquer, et il ne compte que les tentatives qui parviennent jusqu'à la vérification du mot de passe.
Web RBL intervient aux mêmes endroits, mais écrit dans la base de données. Il en résulte que :
- L'état survit à chaque redémarrage et vaut pour tous les processus de travail
- Les deux voies sont couvertes : le formulaire de connexion
/web/loginet les interfaces/xmlrpc/2/commonet/jsonrpc - Sont également couvertes les tentatives qui n'arrivent jamais jusqu'à la vérification du mot de passe — par exemple des connexions sans jeton de session valide
- Un accès échoué au gestionnaire de bases de données est également compté ; c'est la tentative de connexion la plus grave qui soit
Le seuil pour les connexions est fixé à dix, et la raison en est une mesure : sur neuf connexions échouées en dix-sept jours, la majorité provenait de clients qui configuraient eux-mêmes leur accès sur un autre appareil et saisissaient alors le mauvais domaine — dans un cas, le leur, mais avec un tiret à la place du point. Un blocage dès la première tentative échouée n'aurait donc pas touché des attaquants, mais des clients en pleine configuration.
En revanche, celui qui continue de frapper alors que le serveur a déjà répondu « veuillez patienter un instant » est bloqué immédiatement. Ce message, un humain le lit et attend ; celui qui l'ignore est un programme. Un motif propre avec un seuil de zéro intercepte précisément ce cas, et il ne peut pas toucher un collègue : n'y arrive que celui qui a déjà dix tentatives échouées derrière lui et qui continue ensuite.
3. L'attaque ne coûte plus rien au serveur
Une sonde sur un chemin comme /@fs/../../.env était coûteuse avant
le module : Odoo cherche la page d'erreur, la génère, trébuche
lors de la construction de l'adresse sur les segments de points et échoue
alors aussi sur la page d'erreur de la page d'erreur. Deux
piles d'appels journalisées par sonde. On a mesuré 28 401 erreurs de ce type
en dix-sept jours, plus 9 467 erreurs consécutives.
Web RBL intervient dans ir.http._match, donc avant la
recherche de route. La réponse est envoyée sans modèle, sans accès à la base de données
au-delà du contrôle de blocage et sans ligne de journal. La vérification
face à la liste blanche, aux listes de menaces et aux règles par pays s'exécute depuis le
cache, sur des plages d'adresses triées — quelques
microsecondes, même avec plus de trente mille plages.
4. Le pare-feu expulse l'attaquant avant son arrivée
La liste de blocage est publiée comme liste RBL que HAProxy et OPNsense lisent directement. L'attaquant n'atteint ainsi plus du tout le serveur web — ni aucun autre service sur le même hôte. Un accès reconnu une fois comme malveillant protège ainsi rétroactivement toute la machine.
Trois niveaux : bloquer, compter, signaler
Toute requête dans le vide n'est pas une attaque. Web RBL distingue donc trois niveaux, et le niveau peut être modifié pour chaque motif, sans toucher au code.
| Niveau | La requête déclenchante | Conséquence pour l'adresse |
|---|---|---|
| bloquer | est rejetée | bloquée 24 heures, définitivement après trois jours suspects |
| compter | passe | simplement enregistrée, aucun blocage |
| signaler | passe | enregistrée avec un texte de constat, n'est jamais bloquée |
Pour les listes de menaces et les pays, il en existe un quatrième : accès à la connexion refusé. Le site reste lisible, le formulaire de connexion et les interfaces sont fermés. C'est la voie médiane pour tout ce qui est suspect sans être forcément malveillant — Tor, une plage de centre de données, un pays sans clients.
Quelles attaques sont détectées
Tous les motifs ont été validés sur du trafic réel. Le nombre d'adresses distinctes figure volontairement à côté — il montre si un motif touche un scanner isolé ou une pratique répandue.
| Classe d'attaque | Requêtes | Adresses |
|---|---|---|
Collecte de .env | 57.721 | 223 |
| Sondes PHP | 12.237 | 256 |
| Traversée de chemin vers une cible intéressante | 10.046 | 64 |
| Fichiers de configuration | 5.535 | 114 |
| Clés d'accès cloud | 4.388 | 152 |
| Sondes WordPress | 3.366 | 385 |
Collecte de .git | 2.811 | 255 |
| Reconnaissance d'Odoo (gestionnaire de bases de données, requête de version) | 2.500 | 213 |
Chaînes d'outils d'IA et exécution de commandes (/mcp, /api/fs/exec) | 2.450 | 74 |
| Instructions de build (CI/CD) | 1.907 | 88 |
| Points de terminaison GraphQL | 1.878 | 71 |
La classe la plus récente est remarquable. /api/fs/exec
a été sollicité 369 fois par 54 adresses distinctes — ce
n'est pas un accès en lecture, mais une tentative d'exécuter des commandes. De telles
cibles n'existaient pas il y a deux ans ; elles proviennent des interfaces
de nouveaux outils d'IA et de files d'attente de tâches. Celui qui n'oriente sa défense que
sur WordPress et PHP n'en voit rien. Dans la
notation, cette classe pèse en conséquence très lourd.
Listes de menaces et pays d'origine
Quatre listes, 32 851 plages d'adresses, toutes sur « signaler uniquement ». Chaque liste supplémentaire se résume à une adresse et un niveau.
Une liste tierce est une affirmation que quelqu'un d'autre
établit, pour des raisons que nous ignorons, sur un trafic que nous
n'avons jamais vu. Elle peut être fausse, périmée ou conçue pour
un autre usage : blocklist.de recense surtout des
adresses qui ont tenté ailleurs de deviner des connexions SSH, et cela
en dit peu sur un serveur web. C'est pourquoi Web RBL tient les listes tierces
séparées de sa propre liste de blocage, et c'est pourquoi la valeur par défaut est
signaler. Et notre propre liste blanche l'emporte toujours : un client que
nous connaissons pèse plus lourd que l'avis d'un tiers.
Le pays d'origine figure sur chaque occurrence et chaque adresse. Pour évaluer, il est irremplaçable — une tentative de connexion depuis le pays même à dix heures du matin n'est pas comparable à une tentative depuis un pays sans aucun client. Pour un blocage général, il convient peu, et nos propres chiffres le disent : les attaquants de notre liste venaient majoritairement de plages cloud en Belgique, en Finlande et aux Pays-Bas. Un blocage de tout ce qui se trouve en dehors de l'espace germanophone ne les aurait pas touchés — mais nos propres collaborateurs en vacances et des clients en voyage d'affaires, si.
Les règles par pays sont livrées vides, et la vue explique pourquoi.
Signaler les erreurs de configuration au lieu de bloquer
Le cas le plus fréquent dans le trafic réel n'est ni une attaque ni un visiteur, mais un logiciel défectueux qui prend le serveur web pour autre chose :
- 1 367 appels à l'interface web d'un NAS QNAP — un client de synchronisation dont la cible n'est plus correcte. Une seule connexion a frappé 962 fois.
- 65 requêtes Autodiscover — un Outlook qui prend le domaine web pour son Exchange
De telles adresses ne sont jamais bloquées. Un blocage ne corrige pas le défaut, il le masque — et touche celui dont l'appareil est de toute façon mal configuré. À la place, une entrée est créée avec un texte de constat et les domaines concernés, dont sur demande un ticket est automatiquement généré : exactement un par adresse ; s'il est fermé et que l'adresse se remarque à nouveau, le même ticket se rouvre au lieu qu'un second soit créé.
Sont détectés QNAP, Synology, Exchange Autodiscover, ActiveSync
ainsi que les clients WebDAV, CalDAV et CardDAV. Les motifs désignent
des noms de fichiers et des répertoires exacts, jamais de simples extensions :
dans le même répertoire /cgi-bin/, les appels de
synchronisation inoffensifs côtoient directement des sondes classiques comme
printenv.pl.
La liste blanche : des adresses qui ne sont jamais bloquées
Le prix d'une erreur n'est pas le même pour toutes les adresses. Avec un scanner issu d'un centre de données, une fausse alerte ne coûte rien. Avec l'extrémité d'un tunnel de site, elle coûte le site.
C'est pourquoi il existe une deuxième liste, placée avant la première : des adresses et des réseaux qui ne sont jamais bloqués. Elle ne met pourtant rien en sourdine — celui qui y figure continue d'être vérifié et enregistré, seule la conséquence disparaît. C'est la différence avec une exception dans le pare-feu : celle-ci rend aveugle, celle-là rend seulement patient.
Elle est alimentée chaque jour à partir de deux sources : du pare-feu lui-même avec toutes les extrémités VPN, afin qu'un tunnel nouvellement configuré ne dépende pas de quelqu'un pour penser à la liste de blocage — et des plages d'adresses publiées par Google et Microsoft pour leurs robots d'exploration. C'est la seule façon de distinguer un vrai Googlebot d'un scanner qui se fait passer pour tel. Les moteurs de recherche ne doivent jamais être bloqués ; celui qui les bloque retire son site de l'indexation sans voie de retour.
Une règle s'applique alors, plus importante que la comparaison : une réponse vide n'efface jamais. Si la source ne répond pas, répond vide ou de façon incompréhensible, la liste reste inchangée. Une liste blanche qui se vide d'elle-même en cas de panne emporte, au pire moment imaginable, tous les tunnels avec elle.
Si une entrée de la liste blanche porte un client, chaque occurrence provenant de son réseau lui est attribuée. Une erreur de configuration a ainsi immédiatement un interlocuteur, sans que personne n'ait à rechercher des adresses.
Mentions obligatoires et collecteurs de données automatisés
Les mentions légales ne sont pas une page ordinaire. Elles doivent rester accessibles aux humains, car un blocage sur celles-ci crée précisément l'infraction que recherche un collecteur. En même temps, c'est la page où figurent le nom et l'adresse — et donc la cible de la récolte automatisée.
Lors de la vague d'avertissements autrichienne liée aux polices Google intégrées, les journaux ont montré que les courriers ne provenaient pas de visites isolées, mais d'un balayage automatisé : des hôtes différents et sans rapport, à quelques millisecondes d'intervalle.
Web RBL résout cela par un déclassement plutôt qu'une exception. Le
chemin canonique /impressum ne correspond à aucun motif et
reste toujours accessible. Les orthographes étrangères comme
/impressum.php — qui ne peuvent pas
exister sur une page Odoo — sont signalées, et celui qui ne veut pas
tolérer la récolte automatisée modifie un paramètre.
sitemap et robots en sont exclus
et ne sont par principe pas blocables : ils ne contiennent aucune
donnée personnelle, et les récupérer est la mission de tout
robot d'exploration de moteur de recherche.
Domaine et identifiant : ce qui manque dans le journal d'accès
Le journal d'accès de werkzeug n'enregistre ni l'hôte sollicité ni l'identifiant de l'appelant. Odoo reçoit évidemment les deux — sans l'hôte, il ne pourrait pas, avec plusieurs sites, choisir le bon. Mais on ne peut pas les relire après coup.
Web RBL conserve les deux pour chaque occurrence. Cela répond à deux questions auxquelles on ne peut sinon pas répondre : quel site une erreur de configuration sollicite — et donc à quel client le domaine appartient — et si une adresse visite un site ou tous. Plusieurs domaines sans rapport pour la même adresse sont la marque du balayage, et ils augmentent la note.
L'importance de l'identifiant a été démontrée par une analyse sur l'un
de nos sites : plus de soixante-dix pour cent de l'ensemble du trafic
venait d'un seul appelant, réparti sur plus de
cent adresses. Sans l'identifiant, cela aurait ressemblé à un scraper
distribué. C'était GPTBot, le robot d'exploration d'OpenAI
— il demandait sans cesse robots.txt et
se comportait de façon parfaitement correcte.
Les aspects de sécurité en détail
1. La détection du proxy — le point le plus dangereux qui soit
Si Odoo tourne derrière un reverse proxy et que proxy_mode
est mal réglé, le module voit la même adresse à chaque requête :
celle du proxy. Un blocage exclurait alors tous les visiteurs
en même temps.
C'est pourquoi Web RBL vérifie avant tout blocage que la détermination de l'adresse
est fiable. Il exige proxy_mode avec
un en-tête de redirection, refuse de travailler lorsqu'une
redirection arrive sans proxy_mode, et refuse
de même en présence de plus d'un proxy intermédiaire. Dans le doute, on ne
bloque pas.
2. Jamais les réseaux propres
Les plages d'adresses privées, loopback, link-local et CGNAT sont exclues de manière permanente. Elles ne peuvent en aucun cas figurer sur la liste, même à la main. Il en va de même pour les listes tierces : les plages privées et réservées ainsi que les réseaux absurdement grands sont rejetés à l'importation.
3. Une erreur du module ne doit pas emporter le site web
L'ensemble de la vérification s'exécute dans une protection qui intercepte toute erreur. Ce qui échoue ici est journalisé, et la requête poursuit son cours sans changement. Un module de protection qui, en cas de propre erreur, emporte le site web est pire que pas de module du tout. Toutes les requêtes dans le chemin de traitement s'exécutent en outre sans la langue du navigateur du visiteur et sans tri sur des champs traduits — un visiteur avec une langue non installée ne doit pas faire échouer la vérification.
4. Observer avant de bloquer
Après l'installation, le blocage des adresses listées pour les requêtes ordinaires est désactivé. Les sondes sont rejetées et enregistrées, tout le reste passe. On peut ainsi observer pendant quelques jours qui se retrouve réellement sur la liste, avant que quelqu'un ne soit exclu. Il en va de même pour la détection de comportement, les listes de menaces et les règles par pays : signaler d'abord, bloquer après examen.
5. Des motifs étroits plutôt que de larges réseaux
Un visiteur mal identifié coûte plus cher qu'une sonde manquée.
Chaque motif porte donc son niveau, modifiable pour chacun. Une extension de fichier seule suffit rarement : pour
.php, on compte 14 012 vraies sondes contre une poignée
de liens anciens, pour .asp le rapport est inversé. De telles
décisions se mesurent, elles ne s'estiment pas.
6. Une autorisation manuelle reste en vigueur
Celui qui autorise une adresse avait une raison. Une nouvelle occurrence n'annule pas cette décision en silence.
7. La liste est protégée, mais n'est pas un secret
Le point de terminaison exige un jeton et répond sans jeton valide
par 404, non par 403 — l'existence
de l'adresse n'est ainsi même pas confirmée. La comparaison s'effectue
en temps constant. La liste elle-même ne contient rien de confidentiel : elle
se compose d'adresses qui sont venues frapper d'elles-mêmes à notre porte.
8. Aucun secret dans la comptabilité
Pour les connexions échouées, le nom d'utilisateur tenté est noté, jamais le mot de passe. Pour le gestionnaire de bases de données, rien du tout n'est lu dans les valeurs transmises : le mot de passe principal s'y trouve en tout premier lieu, et une entrée dans une liste de blocage migre dans chaque sauvegarde de base de données. La clé de licence GeoLite2 ne figure que dans le paramètre système et dans aucune ligne de journal.
9. Le leurre ne révèle rien d'exploitable
En option, Web RBL répond aux sondes par un contenu inventé qui contient une valeur canari unique. Celui qui consulte cette valeur plus tard a lu la réponse falsifiée et agi en conséquence — une fausse alerte est ainsi exclue. Les leurres ne contiennent aucune donnée exploitable, aucun chemin réel et aucun identifiant valide. Cette fonction est livrée désactivée, car elle modifie le comportement de façon visible de l'extérieur.
Ce que le module ne sait pas faire
Il ne remplace ni un pare-feu ni un pare-feu applicatif web. Il détecte des motifs de sondage connus dans les chemins, les connexions échouées et les comportements suspects — pas les attaques sur les formulaires, pas les tentatives d'injection dans les paramètres.
Il ne voit en outre que ce qui revient via HTTP. Ce qu'un attaquant fait avec des accès volés à la base de données ou à la boîte aux lettres reste invisible — et c'est précisément pourquoi les valeurs canari sont des chemins et non des identifiants.
Et il ne remplace pas la rigueur : un module qui rejette les sondes
.env ne rend pas inoffensif un fichier .env
livré par mégarde.
Disponibilité
Web RBL est disponible publiquement sous AGPL-3 et tourne chez nous en production sur cinq sites web :
github.com/Alex0176/odoo-web-rbl
Le module nécessite Odoo 19 Community et n'a aucune
dépendance autre que base et web. La
connexion aux tickets est facultative et ne requiert aucun système de tickets particulier ;
sans un tel système, il ne se passe tout simplement rien. Le
pays d'origine requiert la base de données gratuite GeoLite2 de MaxMind ;
si elle manque, le champ reste vide et tout le reste fonctionne
sans changement.
Pour aller plus loin : comment Web RBL s'intègre dans une architecture de sécurité complète -- avec pare-feu, authentification à deux facteurs et droits d'accès, avec un guide pas à pas : Combiner correctement l'architecture de sécurité d'Odoo 19.
Nous accueillons volontiers vos questions, remarques et rapports de bogues — de préférence sous forme d'issue sur GitHub.