Overslaan naar inhoud

Odoo 19 Community: Web RBL – blokkeerlijst voor aanvalsverkeer op de eigen websites

24 september 2026 in
Odoo 19 Community: Web RBL – blokkeerlijst voor aanvalsverkeer op de eigen websites

Broncode: github.com/Alex0176/odoo-web-rbl — AGPL-3, vrij te gebruiken.

Wie een Odoo-server op internet beheert, krijgt bezoek. Niet incidenteel, maar onafgebroken. Over zeventien dagen hebben we op onze vijf websites 731.297 verzoeken geregistreerd en geanalyseerd. 110.511 daarvan waren geen bezoekers, maar geautomatiseerd zoeken naar kwetsbaarheden, inloggegevens en configuratiebestanden.

Dit bericht beschrijft Web RBL, een open-sourcemodule voor Odoo 19 Community die dit verkeer herkent, beoordeelt, vastlegt en afwijst — en die de blokkeerlijst als RBL-lijst publiceert, dus in het formaat dat firewalls en reverse proxy's rechtstreeks lezen. Alle cijfers komen uit de praktijk.

Wat de module kan — de functies in overzicht

FunctieWat ze doetLevering
PatroonherkenningHerkent sonderingen aan pad en extensie: .env, .git, configuratiebestanden, cloudsleutels, CI/CD-bouwinstructies, WordPress, PHP, pad-traversal, databasebeheerders, GraphQL, opdrachtuitvoering via /api/fs/exec en vergelijkbare interfacesblokkeren
Drie niveaus per patroonblokkeren, tellen of melden — per patroon aan te passen, zonder codeper patroon
DrempelsZoveel treffers van hetzelfde patroon voordat wordt geblokkeerd; voor aanmeldingen tien10 bij aanmelding
AanmeldingsafweerMislukte aanmeldingen via het formulier en XML-RPC/JSON-RPC, mislukte sessiecontroles, toegang tot de databasebeheerder — in de database, niet in het werkgeheugenaan
Botherkenning bij de aanmeldingWie de wachtmelding na tien mislukte pogingen negeert en blijft kloppen, wordt direct geblokkeerdblokkeren
GedragsherkenningAdressen die in vijf minuten twintig foutpagina's en nauwelijks een treffer genereren — dus raden in plaats van lezenmelden
Beoordeling 0–100Hoe zeker is het dat achter het adres een aanvaller zit? Uit de ernst van het patroon, het aantal verschillende patronen, opvallende dagen, getroffen domeinen en aantal treffers — met een toelichting in gewone taalaan
Aanmeldblokkade op basis van beoordelingVanaf een instelbare beoordeling is aanmelden verboden, de website blijft leesbaarvanaf 40
Vermoeden van gestolen inloggegevensEen geslaagde aanmelding vanaf een opvallend adres wordt gemeld en op verzoek als taak toegewezen — één keer per adres en per dagaan
DreigingslijstenTor-exitnodes, Spamhaus DROP, FireHOL Level 1 en blocklist.de zijn vooraf geconfigureerd; elke andere RBL-lijst is per adres toe te voegen, dagelijkse vergelijking, per lijst een eigen niveaumelden
Geen toegang tot de aanmeldingHet vierde niveau voor lijsten en landen: website leesbaar, aanmeldscherm en interfaces dicht — het passende antwoord op TorOptie
HerkomstlandLand per treffer en adres via GeoLite2; de database wordt door de module zelf bijgewerkt met een gratis licentiesleuteltonen
LandregelsBlokkeren, geen toegang tot de aanmelding, melden of uitdrukkelijk vrij — per land, bewust zonder standaardwaardegeen
Foutieve configuratiesQNAP, Synology, Exchange Autodiscover, ActiveSync, WebDAV/CalDAV/CardDAV worden herkend, nooit geblokkeerd en met bevinding en betrokken domein in een werklijst geplaatstmelden
Ticket per adresVan een bevinding wordt op verzoek een ticket gemaakt — precies één per adres; een gesloten ticket wordt heropend in plaats van verdubbelduit
Verplichte pagina’s en verzamelaarsHet canonieke pad van het impressum blijft altijd bereikbaar; geautomatiseerd uitproberen van afwijkende schrijfwijzen wordt herkend en op verzoek geblokkeerdmelden
VrijlijstAdressen en netwerken die nooit worden geblokkeerd; wordt dagelijks aangevuld vanuit de firewall (VPN-tegenstations) en uit de gepubliceerde adresbereiken van Googlebot en Bingbotaan
KlanttoewijzingEen treffer uit het netwerk van een klant wordt aan die klant toegewezen — op basis van de vrijlijst, nooit op de gokaan
Domein en identificatie per trefferWelke website werd aangesproken, met welke user-agent — beide ontbreken in het toegangslogboekaan
AnalyseDiagram en draaitabel over alle treffers: per patroon, dag, domein, land, adresaan
LokaasSondes krijgen verzonnen antwoorden met een kanariewaarde; wie die later opvraagt, heeft ze gelezenuit
RBL-leveringDe blokkeerlijst als kale adreslijst of JSON op een eigen, met een token beveiligd adres — voor HAProxy, OPNsense en elke firewall die URL-lijsten inleestaan

Alles wat met melden, uit of optie wordt geleverd, is bewust zo: wie een blokkade activeert, moet dat doen omdat hij een paar dagen heeft meegekeken, wie erin trapt — niet omdat de standaardinstelling het zo wilde.

Web RBL-analyse: treffers per patroon over zeven dagen

De analyse: treffers per patroon over zeven dagen. De hoogste balk is het zoeken naar .env-bestanden.

RBL-lijsten: een gestandaardiseerde manier om blokkades te leveren

RBL staat voor Real-time Blackhole List. De term komt uit de mailwereld, waar Spamhaus en anderen sinds de jaren negentig lijsten van kwaadaardige afzenderadressen publiceren. Het principe is uiterst eenvoudig en juist daarom zo wijdverbreid: één adres per regel, via HTTP op te halen, regelmatig opnieuw geladen. Geen formaat dat je eerst moet parsen, geen interface waarvoor je een tool nodig hebt.

Vrijwel elke firewall en elke reverse proxy kan zo’n lijst inlezen en er regels van maken. De fabrikanten noemen dat verschillend, het mechanisme is overal hetzelfde:

  • OPNsense en pfSense — URL Table Alias: adreslijst via HTTP laden, als alias in firewallregels gebruiken, bijwerken per uur of per dag
  • HAProxy — ACL-bestanden en maps: src -f sperrliste.txt in een http-request deny-regel, herlaadbaar via de runtime-API zonder herstart
  • nginx — geo-module met ingesloten adresbestand, of deny-instructies uit een gegenereerd include-bestand
  • Fortinet FortiGate — External Block List resp. Threat Feed: een URL waaruit de firewall een IP-lijst haalt en die in beleidsregels gebruikt
  • Palo Alto Networks — External Dynamic List (EDL): hetzelfde principe, als apart objecttype in het beveiligingsbeleid
  • Check Point — Custom Intelligence Feeds en IP Block Lists via een URL
  • Cisco Secure Firewall (Firepower) — Security Intelligence Feeds met eigen lijstbronnen
  • Sophos Firewall — Third-Party Threat Feeds: adreslijsten van een URL als bron voor blokkeerregels
  • Juniper SRX — Dynamic Address Entries uit feeds
  • MikroTik RouterOS — Address Lists, met een script en fetch gevuld vanaf een URL
  • CrowdSec — eigen lijsten als bron voor de bouncers op elk ondersteund systeem

Precies in dit formaat levert Web RBL zijn blokkeerlijst. De firewall weigert de pakketten voordat ze de webserver bereiken — en daarmee ook elke andere poging van hetzelfde adres, bijvoorbeeld op de mailserver of de VPN-gateway.

Beide richtingen, maar op de juiste plek

De route werkt ook omgekeerd: in Web RBL kan elke willekeurige RBL-lijst worden toegevoegd — een URL, een niveau, klaar. Tor-exitnodes, Spamhaus DROP, FireHOL en blocklist.de zijn vooraf geconfigureerd, meer komen er met drie klikken bij. De module splitst elke lijst op in adresbereiken en controleert elk verzoek daartegen, in enkele microseconden.

En toch: het is zinvoller om externe lijsten op de firewall daarvóór te gebruiken. Om drie redenen. De firewall ziet alle diensten, niet alleen HTTP — een adres van de Spamhaus-lijst moet ook bij de mailserver en de VPN stranden. Hij weigert op pakketniveau, voordat er ook maar een verbinding tot stand komt, en kost de applicatieserver daardoor niets. En hij is de plek waar dergelijke lijsten sowieso worden beheerd; een tweede kopie in de applicatie is een tweede plek die kan verouderen.

Waar de lijsten in de module dan nog goed voor zijn: voor wat een firewall niet kan. Die kent geen aanmeldscherm. Web RBL kan een adres van de Tor-lijst de toegang tot de aanmelding weigeren en de website toch leveren — wie anoniem wil lezen, mag dat; wie anoniem wachtwoorden wil uitproberen, niet. En het kan een geslaagde aanmelding vanaf een adres op de lijst als verdacht geval melden. Beide vereisen de lijst op de plek waar de aanmelding plaatsvindt.

Beoordeling in plaats van onderbuikgevoel

Een adres dat één keer naar /wp-login.php heeft gevraagd, is iets anders dan een adres dat op twee dagen met vijf verschillende patronen over drie domeinen is gegaan. Web RBL rekent dat om in een score van 0 tot 100 — op basis van wat het zelf heeft gezien, zonder externe dienst en zonder query naar buiten.

Web RBL-vermelding met score 84 en motivering

Een vermelding: 99 treffers, score 84, en de motivering in duidelijke taal — zwaarste patroon, vijf verschillende ernstige patronen, twee opvallende dagen, meer dan twintig treffers.

De score bepaalt twee dingen. Vanaf een instelbare waarde is de aanmelding verboden — de website blijft leesbaar, maar wie al naar toegangsgegevens heeft gezocht, krijgt geen kans om gevonden gegevens uit te proberen. En een geslaagde aanmelding vanaf een adres met een score wordt gemeld: dan heeft iemand niet meer geraden, maar geweten. Ofwel was de bevoegde gebruiker onderweg, ofwel zijn de toegangsgegevens kwijtgeraakt — de module beslist dat niet, het legt het voor aan iemand die kan navragen. Het wachtwoord zelf wordt daarbij nergens aangeraakt.

Web RBL-blokkeerlijst, gefilterd op score vanaf 40

De blokkeerlijst, gefilterd op score vanaf 40: aantal treffers, opvallende dagen, getroffen domeinen en het laatste pad per adres.

Wat Web RBL beschermt — de beschermende werking in detail

1. Toegangsgegevens blijven onontdekt

De grootste gemeten aanvalsklasse zoekt niet naar kwetsbaarheden in Odoo, maar naar achtergebleven geheimen. Over zeventien dagen:

  • 57.721 verzoeken om .env-bestanden — daarin staan databasewachtwoorden, API-sleutels en sessiegeheimen
  • 5.535 verzoeken om configuratiebestanden
  • 4.388 verzoeken om cloudtoegangsgegevens: credentials.json, service-account.json, firebase-adminsdk.json, rclone.conf, .git-credentials
  • 2.811 verzoeken om .git-mappen — wie er een vindt, downloadt de volledige broncode inclusief historie
  • 1.907 verzoeken om buildinstructies zoals .github/workflows/deploy.yml of .gitlab-ci.yml, waarin registries en sleutelnamen staan

Doorslaggevend is daarbij niet het aantal verzoeken, maar het aantal verschillende adressen: /credentials.json kwam van 98 adressen, /.git-credentials van 92. Dat is geen enkele scanner, maar een standaardrepertoire dat wereldwijd gelijktijdig draait.

2. Aanmeldpogingen lopen dood — blijvend

Odoo heeft een eigen rem tegen het uitproberen van wachtwoorden. Die heeft drie beperkingen, die in de Odoo-broncode zelf gedocumenteerd zijn: de teller staat in het werkgeheugen van het werkproces en wordt bij elke herstart gereset, hij vertraagt alleen in plaats van te blokkeren, en hij telt uitsluitend pogingen die tot aan de wachtwoordcontrole doorkomen.

Web RBL grijpt op dezelfde plekken in, maar schrijft naar de database. Daardoor geldt:

  • De stand overleeft elke herstart en geldt over alle werkprocessen heen
  • Beide routes worden vastgelegd: het aanmeldscherm /web/login en de interfaces /xmlrpc/2/common en /jsonrpc
  • Ook pogingen die nooit tot de wachtwoordcontrole komen worden vastgelegd — bijvoorbeeld aanmeldingen zonder geldig sessiekenmerk
  • Een mislukte toegang tot de databasebeheerder wordt meegeteld; dat is de ernstigste aanmeldpoging die er is

De drempel voor aanmeldingen staat op tien, en de reden is een meting: van negen mislukte aanmeldingen in zeventien dagen kwam de meerderheid van klanten die zelf de toegang op een ander apparaat instelden en daarbij het verkeerde domein invoerden — in één geval hun eigen domein, maar met een streepje in plaats van een punt. Een blokkade bij de eerste mislukte poging had dus niet aanvallers getroffen, maar klanten bij de installatie.

Wie daarentegen blijft aankloppen, hoewel de server al met “een ogenblik geduld” heeft geantwoord, wordt onmiddellijk geblokkeerd. Die melding leest een mens en die wacht; wie haar negeert, is een programma. Een eigen patroon met drempel nul vangt precies dit geval op, en het kan geen collega treffen: daar komt alleen terecht wie al tien mislukte pogingen achter de rug heeft en daarna doorgaat.

3. De aanval kost de server niets meer

Een sonde op een pad als /@fs/../../.env was vóór de module duur: Odoo zoekt de foutpagina, rendert die, struikelt bij het opbouwen van het adres over de puntsegmenten en faalt vervolgens ook op de foutpagina van de foutpagina. Twee stacktraces per sonde. Gemeten werden 28.401 van dergelijke fouten in zeventien dagen, plus 9.467 vervolgfouten.

Web RBL grijpt in bij ir.http._match, dus vóór de routering. Het antwoord komt zonder sjabloon, zonder databasetoegang buiten de blokkadecontrole om en zonder logregel. De controle tegen vrijlijst, dreigingslijsten en landregels loopt vanuit de cache over gesorteerde adresbereiken — enkele microseconden, zelfs bij meer dan dertigduizend bereiken.

4. De firewall gooit de aanvaller eruit voordat hij aankomt

De blokkeerlijst wordt als RBL-lijst gepubliceerd, die HAProxy en OPNsense rechtstreeks inlezen. De aanvaller bereikt de webserver daarmee helemaal niet meer — en ook geen andere dienst op dezelfde host. Eén keer als kwaadaardig herkende toegang beschermt zo met terugwerkende kracht de hele machine.

Drie niveaus: blokkeren, tellen, melden

Niet elk verzoek in het niets is een aanval. Web RBL onderscheidt daarom drie niveaus, en het niveau is per patroon aan te passen, zonder de code aan te raken.

NiveauHet uitlokkende verzoekGevolg voor het adres
blokkerenwordt geweigerd24 uur geblokkeerd, na drie opvallende dagen permanent
tellengaat dooralleen geboekt, geen blokkade
meldengaat doorgeboekt met bevindingstekst, wordt nooit geblokkeerd

Voor dreigingslijsten en landen is er een vierde: geen toegang tot de aanmelding. De website blijft leesbaar, aanmeldscherm en interfaces zijn dicht. Dat is de middenweg voor alles wat verdacht is, maar niet kwaadaardig hoeft te zijn — Tor, een datacenterbereik, een land zonder klanten.

Welke aanvallen worden herkend

Alle patronen zijn getoetst aan echt verkeer. Het aantal verschillende adressen staat bewust ernaast — het laat zien of een patroon een enkele scanner treft of een wijdverbreide werkwijze.

AanvalsklasseVerzoekenAdressen
.env-afhandeling57.721223
PHP-sondes12.237256
Padtraversal met een lonend doel10.04664
Configuratiebestanden5.535114
Cloudtoegangssleutels4.388152
WordPress-sondes3.366385
.git-afhandeling2.811255
Odoo-verkenning (databasebeheerder, versieopvraging)2.500213
AI-toolketens en opdrachtuitvoering (/mcp, /api/fs/exec)2.45074
Buildinstructies (CI/CD)1.90788
GraphQL-endpoints1.87871

Opmerkelijk is de jongste klasse. /api/fs/exec werd 369 keer door 54 verschillende adressen opgevraagd — dat is geen leestoegang, maar een poging om opdrachten uit te voeren. Zulke doelen bestonden twee jaar geleden niet; ze komen uit interfaces van nieuwe AI-tools en taakwachtrijen. Wie zijn verdediging alleen op WordPress en PHP richt, ziet hier niets van. In de score weegt deze klasse dan ook zwaar.

Dreigingslijsten en herkomstland

Web RBL-dreigingslijsten: Tor, Spamhaus DROP, FireHOL, blocklist.de

Vier lijsten, 32.851 adresbereiken, alle op “alleen melden”. Elke andere lijst is een adres en een niveau.

Een externe lijst is een bewering die iemand anders doet, om redenen die wij niet kennen, over verkeer dat wij nooit hebben gezien. Ze kan onjuist zijn, verouderd of voor een ander doel bedoeld: blocklist.de verzamelt vooral adressen die elders SSH-aanmeldingen hebben uitgeprobeerd, en dat zegt weinig over een webserver. Daarom houdt Web RBL externe lijsten gescheiden van de eigen blokkeerlijst, en daarom is de standaardwaarde melden. En de eigen vrijlijst wint altijd: een klant die wij kennen, weegt zwaarder dan het oordeel van een derde.

Het herkomstland staat bij elke treffer en elk adres. Voor de beoordeling is het onmisbaar — een aanmeldpoging uit het eigen land om tien uur ’s ochtends is iets anders dan een poging uit een land zonder één enkele klant. Voor algemeen buitensluiten is het weinig geschikt, en dat zeggen de eigen cijfers: de aanvallers in onze lijst kwamen overwegend uit cloudbereiken in België, Finland en Nederland. Een blokkade voor alles buiten het Duitstalige gebied had hen niet getroffen — wel eigen medewerkers op vakantie en klanten op zakenreis.

Web RBL-landregels: leeg geleverd, met uitleg

Landregels worden leeg geleverd, en de weergave zegt waarom.

Foutieve configuraties melden in plaats van blokkeren

Het meest voorkomende geval in echt verkeer is geen aanval en geen bezoeker, maar defecte software die de webserver voor iets anders houdt:

  • 1.367 aanroepen van de webinterface van een QNAP-NAS — een synchronisatieclient waarvan het doel niet meer klopt. Eén enkele aansluiting klopte 962 keer aan.
  • 65 Autodiscover-verzoeken — een Outlook die het webdomein voor zijn Exchange houdt

Zulke adressen worden nooit geblokkeerd. Een blokkade verhelpt het defect niet, ze verbergt het — en treft degene wiens apparaat al verkeerd is ingesteld. In plaats daarvan ontstaat een vermelding met bevindingstekst en de betrokken domeinen, waaruit op verzoek automatisch een ticket wordt: per adres precies één, en wordt het gesloten en valt het adres opnieuw op, dan wordt hetzelfde ticket heropend in plaats van dat er een tweede ontstaat.

Herkend worden QNAP, Synology, Exchange Autodiscover, ActiveSync en WebDAV-, CalDAV- en CardDAV-clients. De patronen noemen daarbij exacte bestandsnamen en mappen, nooit kale extensies: In dezelfde map /cgi-bin/ staan de onschuldige synchronisatieaanroepen direct naast klassieke sondes zoals printenv.pl.

De vrijlijst: adressen die nooit worden geblokkeerd

De prijs van een vergissing is niet bij alle adressen gelijk. Bij een scanner uit een datacenter kost een valse melding niets. Bij het tegenstation van een locatietunnel kost het de locatie.

Daarom is er een tweede lijst, die vóór de eerste staat: adressen en netwerken die nooit worden geblokkeerd. Ze zet daarbij niets op stil — wie erop staat, wordt nog steeds gecontroleerd en geboekt, alleen het gevolg vervalt. Dat is het verschil met een uitzondering in de firewall: die maakt blind, deze maakt alleen geduldig.

Ze wordt dagelijks gevuld uit twee bronnen: uit de firewall zelf met alle VPN-tegenstations, zodat een nieuw ingerichte tunnel er niet van afhangt dat iemand aan de blokkeerlijst denkt — en uit de gepubliceerde adresbereiken van Google en Microsoft voor hun crawlers. Alleen zo is een echte Googlebot te onderscheiden van een scanner die zich zo noemt. Zoekmachines mogen nooit worden geblokkeerd; wie ze buitensluit, haalt zijn site zonder terugweg uit de indexering.

Daarbij geldt een regel die belangrijker is dan de vergelijking: Een leeg antwoord wist nooit. Antwoordt de bron niet, leeg of onbegrijpelijk, dan blijft de lijst ongewijzigd. Een vrijlijst die zichzelf bij een storing leegmaakt, neemt op het slechtst denkbare moment alle tunnels mee.

Heeft een vermelding op de vrijlijst een klant, dan wordt elke treffer uit diens netwerk aan die klant toegewezen. Een foutieve configuratie heeft daarmee direct een aanspreekpunt, zonder dat iemand adressen hoeft op te zoeken.

Verplichte gegevens en geautomatiseerde gegevensverzamelaars

Het impressum is geen gewone pagina. Het moet voor mensen bereikbaar blijven, want een blokkade daarop creëert precies de overtreding die een verzamelaar zoekt. Tegelijk is het de pagina waarop naam en adres staan — en daarmee het doelwit van machinale oogst.

Bij de Oostenrijkse golf van waarschuwingsbrieven over ingesloten Google-lettertypen toonden de logboeken dat de brieven niet uit enkele bezoeken voortkwamen, maar uit een geautomatiseerde bulkactie: verschillende, niet met elkaar samenhangende hosts met een tussenpoos van milliseconden.

Web RBL lost dat op door terugzetten in plaats van uitzondering. Het canonieke pad /impressum valt onder geen enkel patroon en blijft altijd bereikbaar. Afwijkende schrijfwijzen zoals /impressum.php — die op een Odoo-pagina niet kunnen bestaan — worden gemeld, en wie de machinale oogst niet wil accepteren, zet één parameter om. sitemap en robots zijn hiervan uitgezonderd en in beginsel niet te blokkeren: ze bevatten geen persoonsgegevens, en ze op te halen is de taak van elke zoekmachinecrawler.

Domein en identificatie: wat in het toegangslogboek ontbreekt

Het toegangslogboek van werkzeug schrijft noch de aangesproken host noch de identificatie van de aanroeper mee. Odoo krijgt beide vanzelfsprekend — zonder de host zou het bij meerdere websites niet eens de juiste kunnen kiezen. Achteraf nalezen kan het echter niet.

Web RBL legt beide per treffer vast. Dat beantwoordt twee vragen die anders niet te beantwoorden zijn: welke website een foutieve configuratie aanspreekt — en daarmee welke klant het domein toebehoort — en of een adres één pagina bezoekt of alle. Meerdere niet-samenhangende domeinen van hetzelfde adres zijn het kenmerk van de bulkactie, en ze verhogen de score.

Hoeveel de identificatie uitmaakt, toonde een analyse op een van onze websites: meer dan zeventig procent van het totale verkeer kwam daar van één enkele aanroeper, verdeeld over meer dan honderd adressen. Zonder de identificatie had dat eruit gezien als een gedistribueerde scraper. Het was GPTBot, de crawler van OpenAI — die steeds opnieuw naar robots.txt vroeg en zich volkomen correct gedroeg.

De beveiligingsaspecten in detail

1. De proxyherkenning — het gevaarlijkste punt van allemaal

Draait Odoo achter een reverse proxy en is proxy_mode verkeerd ingesteld, dan ziet de module bij elk verzoek hetzelfde adres: dat van de proxy. Een blokkade zou dan alle bezoekers tegelijk buitensluiten.

Daarom controleert Web RBL vóór elke blokkade of de adresbepaling betrouwbaar is. Het eist proxy_mode samen met een doorstuur-header, weigert te werken als een doorsturing zonder proxy_mode binnenkomt, en weigert dat evenzo bij meer dan één tussenliggende proxy. In geval van twijfel wordt niet geblokkeerd.

2. Eigen netwerken nooit

Privé-adresbereiken, loopback, link-local en CGNAT zijn vast uitgezonderd. Ze kunnen onder geen enkele omstandigheid op de lijst belanden, ook niet met de hand. Hetzelfde geldt voor externe lijsten: privé- en gereserveerde bereiken en absurd grote netwerken worden bij het inlezen verworpen.

3. Een eigen fout mag de website niet meenemen

De volledige controle draait in een beveiligingslaag die elke fout opvangt. Wat hier misgaat, wordt gelogd, en het verzoek loopt ongewijzigd verder. Een beveiligingsmodule die bij een eigen fout de website meeneemt, is erger dan helemaal geen. Alle query’s in het verzoekpad draaien bovendien zonder de browsertaal van de bezoeker en zonder sortering op vertaalde velden — een bezoeker met een niet-geïnstalleerde taal mag de controle niet laten mislukken.

4. Observeren vóór blokkeren

Na de installatie is het blokkeren van vermelde adressen bij gewone verzoeken uitgeschakeld. Sondes worden geweigerd en geboekt, al het andere loopt door. Zo kan men enkele dagen meelezen wie er werkelijk op de lijst belandt, voordat iemand wordt buitengesloten. Hetzelfde geldt voor gedragsherkenning, dreigingslijsten en landregels: eerst melden, blokkeren na beoordeling.

5. Smalle patronen in plaats van brede netten

Een ten onrechte herkende bezoeker is duurder dan een gemiste sonde. Elk patroon draagt daarom zijn niveau, en dat is per patroon aan te passen. Een bestandsextensie alleen volstaat zelden: bij .php staan 14.012 echte sondes tegenover een handvol oude links, bij .asp is de verhouding omgekeerd. Zulke beslissingen moeten gemeten worden, niet geschat.

6. Een handmatige vrijgave blijft bestaan

Wie een adres vrijgeeft, had daar een reden voor. Een volgende treffer zet die beslissing niet stilzwijgend buiten werking.

7. De lijst is beschermd, maar geen geheim

Het eindpunt eist een token en antwoordt zonder geldig token met 404, niet met 403 — het bestaan van het adres wordt zo niet eens bevestigd. De vergelijking verloopt in constante tijd. De lijst zelf bevat niets vertrouwelijks: ze bestaat uit adressen die uit zichzelf bij ons hebben aangeklopt.

8. Geen geheimen in de boekhouding

Bij mislukte aanmeldingen wordt de geprobeerde gebruikersnaam vastgelegd, nooit het wachtwoord. Bij de databasebeheerder wordt uit de doorgegeven waarden helemaal niets gelezen: daar staat vooraan het hoofdwachtwoord, en een vermelding in een blokkeerlijst belandt in elke databaseback-up. De licentiesleutel voor GeoLite2 staat alleen in de systeemparameter en in geen enkele logregel.

9. Het lokaas verraadt niets bruikbaars

Optioneel beantwoordt Web RBL sondes met verzonnen inhoud die een unieke kanariewaarde bevat. Wie die waarde later opvraagt, heeft het valse antwoord gelezen en is daarop gaan handelen — een valse melding is daarbij uitgesloten. Het lokaas bevat geen bruikbare gegevens, geen echte paden en geen geldige toegangsgegevens. Deze functie wordt uitgeschakeld geleverd, want ze verandert het gedrag naar buiten toe zichtbaar.

Wat de module niet kan

Ze vervangt geen firewall en geen Web Application Firewall. Ze herkent bekende verkenningspatronen in paden, mislukte aanmeldingen en opvallend gedrag — geen aanvallen op formulieren, geen injectiepogingen in parameters.

Ze ziet bovendien alleen wat via HTTP terugkomt. Wat een aanvaller met buitgemaakte database- of mailboxtoegang doet, blijft onzichtbaar — en juist daarom zijn de kanariewaarden paden en geen toegangsgegevens.

En ze vervangt geen zorgvuldigheid: een module die .env-sondes weigert, maakt een per ongeluk uitgeleverd .env-bestand niet ongevaarlijk.

Beschikbaarheid

Web RBL is onder de AGPL-3 openbaar beschikbaar en draait bij ons in productie op vijf websites:

github.com/Alex0176/odoo-web-rbl

De module vereist Odoo 19 Community en heeft geen afhankelijkheden behalve base en web. De ticketkoppeling is optioneel en vereist geen specifiek ticketsysteem; zonder zo’n systeem gebeurt er gewoon niets. Het herkomstland vereist de gratis GeoLite2-database van MaxMind; ontbreekt die, dan blijft het veld leeg en werkt al het andere ongewijzigd.

Verder lezen: Hoe Web RBL past in een complete beveiligingsarchitectuur -- samen met firewall, tweefactorauthenticatie en rechten, inclusief stapsgewijze handleiding: Odoo 19-beveiligingsarchitectuur juist combineren.

Vragen, opmerkingen en foutrapporten nemen wij graag in ontvangst — het liefst als issue op GitHub.