Przejdź do zawartości

Odoo 19 Community: Web RBL – lista blokad dla ruchu atakującego na własne strony internetowe

24 września 2026 przez
Odoo 19 Community: Web RBL – lista blokad dla ruchu atakującego na własne strony internetowe

Kod źródłowy: github.com/Alex0176/odoo-web-rbl — AGPL-3, do swobodnego użytku.

Kto prowadzi serwer Odoo w internecie, ma gości. Nie sporadycznie, lecz bez przerwy. Przez siedemnaście dni na naszych pięciu stronach internetowych zapisaliśmy i przeanalizowaliśmy 731 297 żądań. 110 511 z nich nie pochodziło od odwiedzających, lecz było zautomatyzowanym poszukiwaniem luk, danych dostępowych i plików konfiguracyjnych.

Ten wpis opisuje Web RBL, moduł open source dla Odoo 19 Community, który rozpoznaje, ocenia, rejestruje i odrzuca taki ruch — a listę blokad publikuje jako listę RBL, czyli w formacie, który firewalle i reverse proxy odczytują bezpośrednio. Wszystkie liczby pochodzą z rzeczywistej eksploatacji.

Co potrafi moduł — funkcje w skrócie

FunkcjaCo robiUstawienie domyślne
Rozpoznawanie wzorcówRozpoznaje sondowania po ścieżce i rozszerzeniu: .env, .git, pliki konfiguracyjne, klucze chmurowe, instrukcje budowania CI/CD, WordPress, PHP, path traversal, menedżery baz danych, GraphQL, wykonywanie poleceń przez /api/fs/exec i podobne interfejsyblokować
Trzy poziomy dla każdego wzorcablokować, liczyć lub zgłaszać — przestawiane dla każdego wzorca, bez kodudla każdego wzorca
ProgiTyle trafień tego samego wzorca, zanim nastąpi blokada; dla logowań dziesięć10 przy logowaniu
Obrona logowaniaNieudane logowania przez formularz i XML-RPC/JSON-RPC, nieudane kontrole sesji, dostęp do menedżera baz danych — w bazie danych, nie w pamięci operacyjnejwł.
Rozpoznawanie botów przy logowaniuKto ignoruje komunikat o oczekiwaniu po dziesięciu nieudanych próbach i nadal puka, zostaje natychmiast zablokowanyblokować
Rozpoznawanie zachowańAdresy, które w ciągu pięciu minut generują dwadzieścia błędnych stron i prawie żadnej trafnej — czyli zgadują zamiast czytaćzgłaszać
Ocena 0–100Jak pewne jest, że za adresem stoi atakujący? Na podstawie wagi wzorca, liczby różnych wzorców, rzucających się w oczy dni, objętych domen i liczby trafień — z uzasadnieniem otwartym tekstemwł.
Blokada logowania według ocenyOd ustawialnej oceny logowanie jest zabronione, strona internetowa pozostaje czytelnaod 40
Podejrzenie skradzionych danych dostępowychUdane logowanie z podejrzanego adresu zostaje zgłoszone i — na życzenie — przypisane jako zadanie — raz na adres i dzieńwł.
Listy zagrożeńWęzły wyjściowe Tor, Spamhaus DROP, FireHOL Level 1, blocklist.de skonfigurowane fabrycznie; każdą dodatkową listę RBL można dodać po adresie, codzienne porównanie, osobny poziom dla każdej listyzgłaszać
Brak dostępu do logowaniaCzwarty poziom dla list i krajów: strona czytelna, formularz logowania i interfejsy zamknięte — właściwa odpowiedź na TorOpcja
Kraj pochodzeniaKraj dla każdego trafienia i adresu przez GeoLite2; bazę moduł aktualizuje sam przy użyciu bezpłatnego klucza licencyjnegowyświetlanie
Reguły krajoweBlokuj, brak dostępu do logowania, zgłaszaj lub wyraźnie zezwalaj — dla każdego kraju, świadomie bez ustawienia domyślnegobrak
Błędne konfiguracjeQNAP, Synology, Exchange Autodiscover, ActiveSync, WebDAV/CalDAV/CardDAV są rozpoznawane, nigdy nie są blokowane i trafiają na listę zadań wraz z ustaleniem i dotkniętą domenązgłaszać
Zgłoszenie dla każdego adresuZ ustalenia powstaje na życzenie zgłoszenie — dokładnie jedno dla każdego adresu, zamknięte zostaje otwarte ponownie zamiast się dublowaćwyłączone
Strony obowiązkowe i zbieraczeKanoniczna ścieżka stopki prawnej zawsze pozostaje dostępna; automatyczne próbowanie obcych wariantów pisowni jest rozpoznawane i na życzenie blokowanezgłaszać
Lista dozwolonychAdresy i sieci, które nigdy nie są blokowane; codziennie uzupełnia się z firewalla (zdalne końce VPN) oraz z opublikowanych zakresów adresów Googlebota i Bingbotawł.
Przypisanie do klientaTrafienie z sieci klienta zostaje mu przypisane — z listy dozwolonych, nigdy na zgadywaniewł.
Domena i identyfikator dla każdego trafieniaDo jakiej strony się odwołano i z jakim User-Agent — obu tych informacji brakuje w dzienniku dostępuwł.
AnalizaWykres i tabela przestawna dla wszystkich trafień: wg wzorca, dnia, domeny, kraju, adresuwł.
PrzynętySondy dostają zmyślone odpowiedzi z wartością kanarkową; kto ją później pobierze, ten je przeczytałwyłączone
Dystrybucja RBLLista blokad jako zwykła lista adresów lub JSON pod własnym adresem chronionym tokenem — dla HAProxy, OPNsense i każdego firewalla, który czyta listy URLwł.

Wszystko, co jest dostarczane z ustawieniem zgłaszaj, wyłączone lub opcja, jest tak ustawione celowo: kto uruchamia ostrą blokadę, ma to zrobić dlatego, że przez kilka dni obserwował, kogo ona dotyka — a nie dlatego, że takie było ustawienie domyślne.

Analiza Web RBL: trafienia według wzorca w ciągu siedmiu dni

Analiza: trafienia według wzorca w ciągu siedmiu dni. Najwyższy słupek to wyszukiwanie plików .env.

Listy RBL: standardowy sposób dystrybucji blokad

RBL oznacza Real-time Blackhole List. Pojęcie pochodzi ze świata poczty, gdzie Spamhaus i inni od lat dziewięćdziesiątych publikują listy złośliwych adresów nadawców. Zasada jest niezwykle prosta i właśnie dlatego tak rozpowszechniona: jeden adres w wierszu, dostępny przez HTTP, regularnie ładowany ponownie. Żadnego formatu, który trzeba najpierw parsować, żadnego interfejsu, do którego potrzeba narzędzia.

Praktycznie każdy firewall i każdy reverse proxy potrafi wczytać taką listę i zbudować z niej reguły. Producenci nazywają to różnie, ale mechanizm wszędzie jest ten sam:

  • OPNsense i pfSense — URL Table Alias: lista adresów ładowana przez HTTP, używana jako alias w regułach firewalla, aktualizacja co godzinę lub codziennie
  • HAProxy — pliki ACL i mapy: src -f sperrliste.txt w regule http-request deny, możliwe do ponownego załadowania przez API czasu wykonania bez restartu
  • nginx — moduł geo z dołączonym plikiem adresów lub dyrektywy deny z wygenerowanego pliku include
  • Fortinet FortiGate — External Block List lub Threat Feed: jeden adres URL, z którego firewall pobiera listę IP i używa jej w politykach
  • Palo Alto Networks — External Dynamic List (EDL): ta sama zasada, jako osobny typ obiektu w politykach bezpieczeństwa
  • Check Point — Custom Intelligence Feeds i IP Block Lists przez adres URL
  • Cisco Secure Firewall (Firepower) — Security Intelligence Feeds z własnymi źródłami list
  • Sophos Firewall — Third-Party Threat Feeds: listy adresów z adresu URL jako źródło reguł blokujących
  • Juniper SRX — Dynamic Address Entries z kanałów (feeds)
  • MikroTik RouterOS — Address Lists, wypełniane skryptem i fetch z adresu URL
  • CrowdSec — własne listy jako źródło dla bouncerów w każdym obsługiwanym systemie

Dokładnie w tym formacie Web RBL dostarcza swoją listę blokad. Firewall odrzuca pakiety, zanim dotrą do serwera WWW — a wraz z nimi każdą inną próbę z tego samego adresu, na przykład na serwer pocztowy lub bramę VPN.

Oba kierunki, ale we właściwym miejscu

Ta droga działa także w odwrotną stronę: w Web RBL można dodać dowolną listę RBL — adres URL, poziom, gotowe. Węzły wyjściowe Tor, Spamhaus DROP, FireHOL i blocklist.de są skonfigurowane fabrycznie, kolejne dodaje się trzema kliknięciami. Moduł rozkłada każdą listę na zakresy adresów i sprawdza względem nich każde żądanie, w kilka mikrosekund.

A jednak: rozsądniej jest używać obcych list na firewallu przed serwerem. Z trzech powodów. Firewall widzi wszystkie usługi, nie tylko HTTP — adres z listy Spamhaus ma przecież zawieść także na serwerze pocztowym i VPN. Odrzuca na poziomie pakietów, zanim w ogóle dojdzie do połączenia, i nie obciąża przez to serwera aplikacji. A to właśnie tam takie listy i tak się prowadzi; druga kopia w aplikacji to drugie miejsce, które może się zestarzeć.

Do czego zatem służą listy w module: do tego, czego firewall nie potrafi. Nie zna formularza logowania. Web RBL może adresowi z listy Tor odmówić dostępu do logowania, nadal serwując stronę — kto chce czytać anonimowo, ma prawo; kto anonimowo próbuje zgadywać hasła, nie. Może też zgłosić udane logowanie z adresu z listy jako przypadek podejrzany. Jedno i drugie wymaga listy tam, gdzie odbywa się logowanie.

Ocena zamiast przeczucia

Adres, który raz zapytał o /wp-login.php, jest czymś innym niż taki, który w ciągu dwóch dni przeszedł pięcioma różnymi wzorcami po trzech domenach. Web RBL przelicza to na ocenę od 0 do 100 — na podstawie tego, co sam zaobserwował, bez obcej usługi i bez zapytań na zewnątrz.

Wpis Web RBL z oceną 84 i uzasadnieniem

Jeden wpis: 99 trafień, ocena 84 i uzasadnienie wprost — najcięższy wzorzec, pięć różnych poważnych wzorców, dwa podejrzane dni, ponad dwadzieścia trafień.

Ocena decyduje o dwóch rzeczach. Od ustawianej wartości logowanie jest zabronione — strona pozostaje czytelna, ale kto już szukał danych dostępowych, nie dostaje możliwości wypróbowania znalezionych. A udane logowanie z adresu z oceną jest zgłaszane: wtedy ktoś już nie zgadywał, tylko wiedział. Albo uprawniony użytkownik był w podróży, albo dane dostępowe zostały utracone — moduł tego nie rozstrzyga, przedstawia to komuś, kto może dopytać. Samego hasła przy tym nigdzie się nie dotyka.

Lista blokad Web RBL, filtrowana według oceny od 40

Lista blokad, filtrowana według oceny od 40: liczba trafień, podejrzane dni, dotknięte domeny i ostatnia ścieżka dla każdego adresu.

Przed czym chroni Web RBL — ochrona w szczegółach

1. Dane dostępowe pozostają nieodkryte

Największa zmierzona klasa ataków nie szuka luk w Odoo, lecz pozostawionych sekretów. W ciągu siedemnastu dni:

  • 57.721 żądań o pliki .env — znajdują się w nich hasła do baz danych, klucze API i sekrety sesji
  • 5.535 żądań o pliki konfiguracyjne
  • 4.388 żądań o dane dostępowe do chmury: credentials.json, service-account.json, firebase-adminsdk.json, rclone.conf, .git-credentials
  • 2.811 żądań o katalogi .git — kto znajdzie któryś, pobiera pełny kod źródłowy wraz z historią
  • 1.907 żądań o instrukcje budowania, takie jak .github/workflows/deploy.yml czy .gitlab-ci.yml, w których znajdują się rejestry i nazwy kluczy

Decydująca nie jest przy tym liczba żądań, lecz liczba różnych adresów: /credentials.json pochodziło z 98 adresów, /.git-credentials z 92. To nie jest pojedynczy skaner, lecz standardowy repertuar, który działa na całym świecie jednocześnie.

2. Próby logowania trafiają w próżnię — na stałe

Odoo ma własny hamulec przeciw zgadywaniu haseł. Ma trzy ograniczenia, udokumentowane w samym kodzie źródłowym Odoo: licznik znajduje się w pamięci operacyjnej procesu roboczego i przy każdym restarcie jest zerowany, on tylko opóźnia zamiast blokować i zlicza wyłącznie próby, które dotrą aż do sprawdzenia hasła.

Web RBL działa w tych samych punktach, ale zapisuje do bazy danych. Dzięki temu:

  • Stan przetrwa każdy restart i obowiązuje we wszystkich procesach roboczych
  • Rejestrowane są obie drogi: formularz logowania /web/login oraz interfejsy /xmlrpc/2/common i /jsonrpc
  • Rejestrowane są także próby, które nigdy nie dochodzą do sprawdzenia hasła — na przykład logowania bez ważnego znacznika sesji
  • Nieudany dostęp do menedżera baz danych jest wliczany; to najpoważniejsza próba logowania ze wszystkich

Próg dla logowań ustawiono na dziesięć, a powodem jest pomiar: z dziewięciu nieudanych logowań w ciągu siedemnastu dni większość pochodziła od klientów, którzy samodzielnie konfigurowali dostęp na kolejnym urządzeniu i wpisali przy tym błędną domenę — w jednym przypadku własną, tylko z myślnikiem zamiast kropki. Blokada przy pierwszej nieudanej próbie nie uderzyłaby więc w atakujących, lecz w klientów podczas konfiguracji.

Kto natomiast dalej pukał, mimo że serwer już odpowiedział „proszę chwilę poczekać”, zostaje natychmiast zablokowany. Ten komunikat czyta człowiek i czeka; kto go ignoruje, jest programem. Osobny wzorzec z progiem zero wychwytuje właśnie ten przypadek i nie może trafić w żadnego współpracownika: dociera tam tylko ten, kto ma już za sobą dziesięć nieudanych prób i potem kontynuuje.

3. Atak już nic serwera nie kosztuje

Sonda na ścieżkę taką jak /@fs/../../.env była przed modułem kosztowna: Odoo szuka strony błędu, renderuje ją, potyka się przy budowaniu adresu o segmenty z kropkami i w konsekwencji zawodzi również na stronie błędu strony błędu. Dwa ślady stosu na każdą sondę. Zmierzono 28.401 takich błędów w siedemnaście dni, do tego 9.467 błędów następczych.

Web RBL wkracza w ir.http._match, czyli przed wyznaczeniem trasy. Odpowiedź powstaje bez szablonu, bez dostępu do bazy danych ponad sprawdzenie blokady i bez wiersza w dzienniku. Sprawdzenie względem listy dozwolonych, list zagrożeń i reguł krajowych działa z pamięci podręcznej na posortowanych zakresach adresów — kilka mikrosekund, także przy ponad trzydziestu tysiącach zakresów.

4. Firewall wyrzuca atakującego, zanim dotrze

Lista blokad jest publikowana jako lista RBL, którą HAProxy i OPNsense czytają bezpośrednio. Atakujący nie dociera więc już wcale do serwera WWW — ani do żadnej innej usługi na tym samym hoście. Raz rozpoznany jako złośliwy dostęp chroni tak z mocą wsteczną całą maszynę.

Trzy poziomy: blokować, zliczać, zgłaszać

Nie każde żądanie w próżnię jest atakiem. Web RBL rozróżnia dlatego trzy poziomy, a poziom można zmienić dla każdego wzorca bez dotykania kodu.

PoziomŻądanie wyzwalająceSkutek dla adresu
blokujzostaje odrzuconezablokowany na 24 godziny, po trzech podejrzanych dniach na stałe
zliczajprzechodzitylko zaksięgowane, bez blokady
zgłaszajprzechodzizaksięgowane z tekstem ustalenia, nigdy nie jest blokowane

Dla list zagrożeń i krajów istnieje czwarty: brak dostępu do logowania. Strona pozostaje czytelna, formularz logowania i interfejsy są zamknięte. To złoty środek dla wszystkiego, co jest podejrzane, ale nie musi być złośliwe — Tor, zakres centrum danych, kraj bez klientów.

Jakie ataki są rozpoznawane

Wszystkie wzorce zostały sprawdzone na rzeczywistym ruchu. Liczba różnych adresów jest celowo podana obok — pokazuje, czy wzorzec trafia w pojedynczy skaner, czy w rozpowszechnioną metodę.

Klasa atakuŻądaniaAdresy
Wyciąganie plików .env57.721223
Sondy PHP12.237256
Path traversal z wartościowym celem10.04664
Pliki konfiguracyjne5.535114
Klucze dostępu do chmury4.388152
Sondy WordPress3.366385
Wyciąganie .git2.811255
Rozpoznanie Odoo (menedżer baz danych, zapytanie o wersję)2.500213
Łańcuchy narzędzi AI i wykonywanie poleceń (/mcp, /api/fs/exec)2.45074
Instrukcje budowania (CI/CD)1.90788
Punkty końcowe GraphQL1.87871

Godna uwagi jest najnowsza klasa. /api/fs/exec było wywoływane 369 razy przez 54 różne adresy — to nie jest dostęp odczytu, lecz próba wykonania poleceń. Takich celów dwa lata temu nie było; pochodzą z interfejsów nowych narzędzi AI i kolejek zadań. Kto swoją obronę kieruje wyłącznie na WordPress i PHP, nic z tego nie widzi. W oceniu ta klasa waży odpowiednio dużo.

Listy zagrożeń i kraj pochodzenia

Listy zagrożeń Web RBL: Tor, Spamhaus DROP, FireHOL, blocklist.de

Cztery listy, 32.851 zakresów adresów, wszystkie ustawione na „tylko zgłaszaj”. Każda kolejna lista to adres i poziom.

Obca lista to twierdzenie, które ktoś inny stawia, z powodów, których nie znamy, na temat ruchu, którego nigdy nie widzieliśmy. Może być błędna, nieaktualna lub przeznaczona do innego celu: blocklist.de zbiera głównie adresy, które gdzie indziej zgadywały logowania SSH, a to mało mówi o serwerze WWW. Dlatego Web RBL prowadzi obce listy odrębnie od własnej listy blokad i dlatego ustawieniem domyślnym jest zgłaszaj. A własna lista dozwolonych zawsze wygrywa: klient, którego znamy, waży więcej niż ocena osoby trzeciej.

Kraj pochodzenia widnieje przy każdym trafieniu i adresie. Do oceny jest niezastąpiony — próba logowania z własnego kraju o dziesiątej rano to coś innego niż próba z kraju, w którym nie mamy ani jednego klienta. Do hurtowego blokowania nadaje się słabo, co potwierdzają własne liczby: atakujący z naszej listy pochodzili w przeważającej części z zakresów chmurowych w Belgii, Finlandii i Holandii. Blokada wszystkiego poza obszarem niemieckojęzycznym by ich nie dotknęła — za to dotknęłaby własnych pracowników na urlopie i klientów w podróży służbowej.

Reguły krajowe Web RBL: dostarczane puste, z wyjaśnieniem

Reguły krajowe są dostarczane puste, a widok wyjaśnia, dlaczego.

Błędne konfiguracje zgłaszać zamiast blokować

Najczęstszy przypadek w rzeczywistym ruchu to ani atak, ani odwiedzający, lecz wadliwe oprogramowanie, które bierze serwer WWW za coś innego:

  • 1.367 wywołań interfejsu webowego NAS-a QNAP — klient synchronizacji, którego cel już się nie zgadza. Jedno jedyne łącze pukało 962 razy.
  • 65 zapytań Autodiscover — Outlook, który bierze domenę strony WWW za swój Exchange

Takie adresy nigdy nie są blokowane. Blokada nie usuwa usterki, lecz ją ukrywa — i uderza w tego, czyje urządzenie jest już źle ustawione. Zamiast tego powstaje wpis z tekstem ustalenia i dotkniętymi domenami, z którego na życzenie automatycznie powstaje zgłoszenie: dla każdego adresu dokładnie jedno, a jeśli zostanie zamknięte, a adres znów zwróci uwagę, to samo zgłoszenie otwiera się ponownie, zamiast powstawać drugie.

Rozpoznawane są QNAP, Synology, Exchange Autodiscover, ActiveSync oraz klienci WebDAV, CalDAV i CardDAV. Wzorce wskazują przy tym dokładne nazwy plików i katalogi, nigdy same rozszerzenia: W tym samym katalogu /cgi-bin/ nieszkodliwe wywołania synchronizacji leżą tuż obok klasycznych sond, takich jak printenv.pl.

Lista dozwolonych: adresy, które nigdy nie są blokowane

Cena pomyłki nie jest taka sama dla wszystkich adresów. W przypadku skanera z centrum danych fałszywy alarm nic nie kosztuje. W przypadku zdalnego końca tunelu między lokalizacjami kosztuje całą lokalizację.

Dlatego istnieje druga lista, która stoi przed pierwszą: adresy i sieci, które nigdy nie są blokowane. Niczego przy tym nie wycisza — kto na niej figuruje, nadal jest sprawdzany i księgowany, odpada tylko skutek. To różnica w stosunku do wyjątku w firewallu: ten zaślepia, ta tylko uczy cierpliwości.

Uzupełnia się ją codziennie z dwóch źródeł: z samego firewalla ze wszystkimi zdalnymi końcami VPN, aby nowo skonfigurowany tunel nie zależał od tego, czy ktoś pomyśli o liście blokad — oraz z opublikowanych zakresów adresów Google i Microsoft dla ich robotów. Tylko tak można odróżnić prawdziwego Googlebota od skanera, który się tak nazywa. Wyszukiwarek nigdy nie wolno blokować; kto je blokuje, wypycha swoją stronę z indeksu bez drogi powrotu.

Obowiązuje przy tym reguła ważniejsza niż samo porównanie: Pusta odpowiedź nigdy nie usuwa. Jeśli źródło nie odpowiada, odpowiada pustą lub niezrozumiałą odpowiedzią, lista pozostaje bez zmian. Lista dozwolonych, która przy awarii sama się opróżnia, zabiera ze sobą wszystkie tunele w najgorszym możliwym momencie.

Jeśli wpis listy dozwolonych jest powiązany z klientem, każde trafienie z jego sieci zostaje mu przypisane. Błędna konfiguracja ma tym samym od razu osobę do kontaktu, bez konieczności szukania adresów przez kogokolwiek.

Informacje obowiązkowe i zautomatyzowani zbieracze danych

Stopka prawna to nie zwykła strona. Musi pozostać dostępna dla ludzi, bo blokada na niej tworzy dokładnie to naruszenie, którego szuka zbieracz. Jednocześnie to strona, na której widnieją nazwa i adres — a tym samym cel maszynowego żniwa.

Podczas austriackiej fali wezwań do zaniechania z powodu osadzonych czcionek Google dzienniki pokazały, że pisma nie pochodziły z pojedynczych wizyt, lecz ze zautomatyzowanego masowego przeczesywania: różne, niepowiązane ze sobą hosty w odstępach milisekund.

Web RBL rozwiązuje to przez obniżenie poziomu zamiast wyjątku. Kanoniczna ścieżka /impressum nie pasuje do żadnego wzorca i zawsze pozostaje dostępna. Obce warianty pisowni, takie jak /impressum.php — które na stronie Odoo nie mogą istnieć — są zgłaszane, a kto nie chce tolerować maszynowego żniwa, przestawia jeden parametr. sitemap i robots są z tego wyłączone i zasadniczo nie podlegają blokadzie: nie zawierają żadnych danych osobowych, a ich pobieranie jest zadaniem każdego robota wyszukiwarki.

Domena i identyfikator: czego brakuje w dzienniku dostępu

Dziennik dostępu werkzeug nie zapisuje ani odpytanego hosta, ani identyfikatora wywołującego. Odoo oczywiście dostaje oba — bez hosta nie mogłoby przy kilku stronach w ogóle wybrać właściwej. Ale potem nie da się tego odczytać.

Web RBL zapisuje jedno i drugie przy każdym trafieniu. To odpowiada na dwa pytania, na które inaczej nie da się odpowiedzieć: która strona odpowiada błędnej konfiguracji — a tym samym, do którego klienta należy domena — oraz czy adres odwiedza jedną stronę, czy wszystkie. Kilka niepowiązanych domen tego samego adresu to cecha masowego przeczesywania i podnoszą one ocenę.

Jak wiele daje identyfikator, pokazała analiza na jednej z naszych stron: ponad siedemdziesiąt procent całego ruchu przypadało tam na jednego wywołującego, rozproszonego na ponad stu adresów. Bez identyfikatora wyglądałoby to jak rozproszony scraper. Był to GPTBot, robot OpenAI — pytał raz po raz o robots.txt i zachowywał się całkowicie poprawnie.

Aspekty bezpieczeństwa w szczegółach

1. Rozpoznawanie proxy — najniebezpieczniejsze miejsce ze wszystkich

Jeśli Odoo działa za reverse proxy, a proxy_mode jest ustawiony błędnie, moduł przy każdym żądaniu widzi ten sam adres: adres proxy. Blokada zablokowałaby wtedy wszystkich odwiedzających jednocześnie.

Dlatego Web RBL przed każdą blokadą sprawdza, czy ustalenie adresu jest wiarygodne. Wymaga proxy_mode razem z nagłówkiem przekierowania, odmawia pracy, gdy przekierowanie przychodzi bez proxy_mode, i odmawia jej tak samo przy więcej niż jednym pośredniczącym proxy. W razie wątpliwości nie blokuje.

2. Własnych sieci nigdy

Prywatne zakresy adresów, loopback, link-local i CGNAT są na stałe wyłączone. Nie mogą w żadnych okolicznościach trafić na listę, nawet ręcznie. To samo dotyczy obcych list: zakresy prywatne i zarezerwowane oraz absurdalnie duże sieci są odrzucane przy wczytywaniu.

3. Własny błąd nie może pociągnąć za sobą strony

Całe sprawdzanie działa w zabezpieczeniu, które przechwytuje każdy błąd. To, co tu pójdzie źle, jest zapisywane w dzienniku, a żądanie przebiega dalej bez zmian. Moduł ochronny, który przy własnym błędzie pociąga za sobą stronę, jest gorszy niż żaden. Wszystkie zapytania na ścieżce żądania działają ponadto bez języka przeglądarki odwiedzającego i bez sortowania według przetłumaczonych pól — odwiedzający z niezainstalowanym językiem nie może zepsuć sprawdzania.

4. Obserwować przed blokowaniem

Po instalacji blokowanie adresów z list przy zwykłych żądaniach jest wyłączone. Sondy są odrzucane i księgowane, wszystko inne przechodzi. Dzięki temu można przez kilka dni obserwować, kto faktycznie trafia na listę, zanim ktokolwiek zostanie zablokowany. To samo dotyczy rozpoznawania zachowań, list zagrożeń i reguł krajowych: najpierw zgłaszać, blokować po zapoznaniu się.

5. Wąskie wzorce zamiast szerokich sieci

Błędnie rozpoznany odwiedzający jest droższy niż przeoczona sonda. Każdy wzorzec ma dlatego swój poziom, który można zmieniać dla każdego wzorca. Samo rozszerzenie pliku rzadko wystarcza: przy .php stoi 14.012 prawdziwych sond przeciw garstce starych linków, przy .asp proporcja jest odwrotna. Takie decyzje należy mierzyć, a nie szacować.

6. Ręczne zwolnienie pozostaje w mocy

Kto zwalnia adres, miał ku temu powód. Kolejne trafienie nie unieważnia po cichu tej decyzji.

7. Lista jest chroniona, ale nie jest tajemnicą

Punkt końcowy wymaga tokenu, a bez ważnego tokenu odpowiada 404, nie 403 — istnienie adresu nie jest więc w ogóle potwierdzane. Porównanie przebiega w stałym czasie. Sama lista nie zawiera niczego poufnego: składa się z adresów, które same do nas zapukały.

8. Żadnych sekretów w księgowaniu

Przy nieudanych logowaniach odnotowywana jest próbowana nazwa użytkownika, nigdy hasło. W przypadku menedżera baz danych z przekazanych wartości nie jest odczytywane nic: na pierwszym miejscu stoi tam hasło główne, a wpis na liście blokad trafia do każdej kopii zapasowej bazy danych. Klucz licencyjny GeoLite2 znajduje się tylko w parametrze systemowym i w żadnym wierszu dziennika.

9. Przynęta nie zdradza niczego użytecznego

Opcjonalnie Web RBL odpowiada na sondy zmyślonymi treściami zawierającymi jednoznaczną wartość kanarkową. Kto tę wartość później pobierze, przeczytał sfałszowaną odpowiedź i na jej podstawie zadziałał — fałszywy alarm jest przy tym wykluczony. Przynęty nie zawierają żadnych użytecznych danych, żadnych prawdziwych ścieżek i żadnych ważnych danych dostępowych. Ta funkcja jest dostarczana wyłączona, ponieważ zmienia zachowanie widoczne na zewnątrz.

Czego moduł nie potrafi

Nie zastępuje firewalla ani Web Application Firewall. Rozpoznaje znane wzorce sondowania w ścieżkach, nieudane logowania i podejrzane zachowania — nie ataki na formularze ani próby wstrzykiwania w parametrach.

Widzi poza tym tylko to, co wraca przez HTTP. To, co atakujący zrobi ze zdobytymi dostępami do bazy danych lub skrzynki pocztowej, pozostaje niewidoczne — i właśnie dlatego wartości kanarkowe to ścieżki, a nie dane dostępowe.

I nie zastępuje staranności: moduł, który odrzuca sondy .env, nie czyni niegroźnym przypadkowo udostępnionego pliku .env.

Dostępność

Web RBL jest publicznie dostępny na licencji AGPL-3 i u nas działa produkcyjnie na pięciu stronach:

github.com/Alex0176/odoo-web-rbl

Moduł wymaga Odoo 19 Community i nie ma zależności poza base i web. Integracja z systemem zgłoszeń jest opcjonalna i nie wymaga żadnego konkretnego systemu zgłoszeń; bez niego po prostu nic się nie dzieje. Kraj pochodzenia wymaga bezpłatnej bazy GeoLite2 od MaxMind; jeśli jej brak, pole pozostaje puste, a wszystko inne działa bez zmian.

Dalsza lektura: Jak Web RBL wpisuje się w kompletną architekturę bezpieczeństwa -- razem z firewallem, uwierzytelnianiem dwuskładnikowym i uprawnieniami, wraz z instrukcją krok po kroku: Prawidłowe połączenie architektury bezpieczeństwa Odoo 19.

Pytania, uwagi i zgłoszenia błędów przyjmujemy z przyjemnością — najchętniej jako zgłoszenie (issue) na GitHubie.