Odoo je na našich pěti webech dostupné z otevřeného internetu, a to není výjimka, ale běžný stav: Kdo provozuje nabídku, e-shop nebo přihlášení zákazníků, má veřejný server. Jediné zranitelné heslo, zapomenutý konfigurační soubor nebo příliš velkorysé oprávnění stačí k tomu, aby se z veřejného serveru stal otevřený.
Tento článek ukazuje, jak Odoo 19 správně zabezpečit — ne jediným opatřením, ale několika vrstvami, které se vzájemně doplňují: firewall a reverzní proxy, náš open-source modul Web RBL, dvoufázové ověření, zásady hesel a oprávnění — a jaké pokusy o útok každá z nich skutečně zachytí. Na konci je návod krok za krokem, podle kterého lze zabezpečit každou vlastní instalaci Odoo.
Obsah tohoto článku
- Obrana do hloubky: proč jediné opatření nikdy nestačí
- Vrstva 1: firewall a reverzní proxy
- Vrstva 2: Web RBL — most k firewallu
- Vrstva 3: zabezpečení samotného Odoo (2FA, zásady hesel, oprávnění)
- Vrstva 4: databáze a provoz
- Přihlašovací cesta jako celek
- Scénáře útoků a jejich odražení
- Návod krok za krokem
- Časté dotazy
Obrana do hloubky: proč jediné opatření nikdy nestačí
Každé jednotlivé bezpečnostní opatření má mezeru. Firewall nevidí, co se děje v přihlašovacím formuláři Odoo. Silné heslo nechrání, pokud už bylo jinde ukradeno. Struktura oprávnění nepomůže proti útočníkovi, který se ještě vůbec nepřihlásil. Princip, který tyto mezery uzavírá, se jmenuje obrana do hloubky (defense in depth): několik nezávislých vrstev, z nichž každou by šlo samu o sobě obejít — ale všechny dohromady nikoli.
U nás jsou to čtyři vrstvy, každá s jiným úkolem:
- Firewall / reverzní proxy — udržuje zjevně škodlivé věci daleko, než se vůbec dostanou k serveru
- Web RBL — spojuje obě strany: Odoo se z vlastního aplikačního protokolu učí, co firewall vidět nemůže, a předává to zpět firewallu
- Samotné Odoo — dvoufázové ověření, zásady hesel, oprávnění, správa relací
- Databáze & provoz — zálohování, ochrana přístupu ke správě, tajemství mimo jakýkoli protokol
Následující oddíly procházejí jednotlivé vrstvy po jedné.
Vrstva 1: firewall a reverzní proxy
Firewall je první instance, která požadavek vidí, a jediná, která může útočníka udržet pryč od každé služby na serveru — nejen od webu, ale také od poštovního serveru, přístupu VPN a vlastního administračního rozhraní. Co se na tomto místě smysluplně aktivuje, závisí na výrobci, ale konstrukční prvky jsou u OPNsense, pfSense, HAProxy, FortiGate, Sophos nebo Check Point stejné:
| Funkce | Proti čemu pomáhá |
|---|---|
| Aktuální verze TLS a omezené šifrovací postupy | Odposlech a manipulace se spojením; zastaralé postupy jsou již léta považovány za prolomené nebo slabé |
| Reputační a geografické seznamy (RBL) | Známé sítě útočníků, výstupní uzly Tor, celé země bez vlastních zákazníků — viz níže |
| Omezení četnosti na adresu | Zkoušení hesel a skenery adresářů, které během sekund zadají desítky požadavků |
| Oddělení správy a datového provozu | Rozhraní firewallu samotného nesmí být dostupné na téže adrese jako veřejný web |
| IDS/IPS (detekce/prevence útoků) | Známé vzory útoků na síťové úrovni, bez ohledu na to, jaká aplikace za tím běží |
| Automatické bezpečnostní aktualizace samotného firewallu | Nezaplatovaný firewall už není firewallem, ale dalším cílem |
Seznamy RBL: standardní cesta, kterou se doručuje reputace
RBL znamená Real-time Blackhole List, pojem ze světa e-mailu: jedna adresa na řádek, dostupné přes HTTP, pravidelně znovu načítané. Prakticky každý firewall dokáže takový seznam načíst a vytvořit z něj pravidla — OPNsense a pfSense jako URL Table Alias, HAProxy jako soubor ACL, FortiGate jako External Block List, Palo Alto jako External Dynamic List, Cisco, Sophos, Juniper a MikroTik s vlastními názvy pro tentýž princip.
Právě zde nasazuje náš vlastní modul — a právě zde začíná druhá vrstva.
Vrstva 2: Web RBL — most mezi aplikací a firewallem
Firewall vidí pakety, ne aplikační logiku. Neví, že požadavek na /xmlrpc/2/common je pokus o přihlášení, že dvacet různých cest za čtrnáct sekund je skener, nebo že nějaká adresa právě úspěšně uhodla heslo. To všechno ví jen samotné Odoo. Web RBL, náš vlastní open-source modul (AGPL-3), tyto znalosti zužitkuje — pro samotné Odoo a, poskytovaný jako seznam RBL, také pro firewall před ním.
Seznamy hrozeb průběžně porovnávané, každý s vlastní úrovní.
Stručné shrnutí toho, co je podrobně popsáno v předchozím článku:
- Rozpoznávání vzorů v cestách: soubory
.env, adresáře.git, konfigurační soubory, sondy WordPress a PHP, path traversal, spouštění příkazů přes nová rozhraní AI - Obrana přihlášení, která počítá i přes restarty — na rozdíl od vlastního počitadla Odoo, žijícího v operační paměti
- Skóre každé adresy od 0 do 100, s odůvodněním běžným jazykem
- Chybné konfigurace (QNAP, Autodiscover, Synology) se rozpoznají a nikdy neblokují, protože blokace závadu neodstraní, ale jen skryje
- Cizí seznamy hrozeb jako Spamhaus, FireHOL a výstupní uzly Tor, průběžně porovnávané
- Seznam výjimek pro adresy, které se nikdy nemají blokovat
Pro tento článek jsou obzvlášť důležité dvě vlastnosti, protože přímo souvisejí s firewallem a s přihlášením.
Netečný seznam je seznam, kterému lze důvěřovat
Seznam výjimek — adresy, které se nikdy neblokují, například vlastní připojení poboček — se zpravidla mění jen zřídka. Právě to je jeho hodnota, nikoli nedostatek: Pokud se klidný seznam po dny sotva pohne, každá vzácná změna okamžitě upoutá pozornost. Denní automatická aktualizace neexistuje proto, že by se toho mnoho měnilo, ale aby se vzácná změna nemusela doplňovat ručně — a právě to je místo, kde se na ni zapomíná. Jedna z našich vlastních chybných konfigurací v minulém měsíci byla odhalena přesně takto: ne množstvím událostí, ale tou jednou, kterou nikdo neznal, dokud nebylo omylem zablokováno webové API QNAP jednoho zákazníka. Od té doby je QNAP na seznamu chybných konfigurací, které se nikdy neblokují, ale jen hlásí.
Přihlášení je místo, které firewall nevidí
Firewall může adresu zablokovat. Nemůže vědět, zda se přihlášení zdařilo, a už vůbec ne, zda přišlo z adresy, která krátce předtím ještě hledala přístupové údaje. Web RBL to ví: Skóre od nastavitelné prahové hodnoty přihlášení zcela zakáže a úspěšné přihlášení z nápadné adresy je nahlášeno — to je spojnice k další vrstvě.
Vrstva 3: zabezpečení samotného Odoo
Dvoufázové ověření: druhé tajemství, které nelze znovu použít
Největším problémem hesel není jejich kvalita, ale jejich opakované používání. Heslo, které bylo ukradeno u jiné služby, funguje i u nás, pokud je totéž. Dvoufázové ověření (2FA, též TOTP) tomu staví do cesty druhé tajemství: šestimístný kód, který se mění každých třicet sekund a počítá se z tajemství, které zná jen vlastní chytrý telefon. Samotné ukradené heslo tak už nestačí.
Odoo 19 Community to má vestavěné — jako instalovatelný modul Two-Factor Authentication (TOTP), doplněný o záložní možnost přes e-mail. Každý uživatel si to nastaví sám, pomocí QR kódu, v kterékoli běžné aplikaci Authenticator:
Nastavení: naskenovat QR kód, jednou potvrdit šestimístný kód, hotovo.
To však pomáhá jen těm, kdo si to nastaví sami — a zkušenost ukazuje, že bez nátlaku to zůstane menšina. Odoo proto zná politiku vynucení: buď jen pro zaměstnance (interní uživatele), nebo pro všechny, včetně uživatelů portálu. Bez nastaveného druhého tajemství už nikdo nepřejde přihlašovací formulář, aniž by jej potvrdil alespoň kódem z e-mailu.
Zásady hesel: minimální délka není samozřejmost
Bez dodatečného modulu se Odoo Community nespoléhá na žádnou minimální délku hesel — uživatel může zadat heslo o třech znacích, pokud mu v tom nikdo nezabrání. Vlastní modul Password Policy uzavírá právě tuto mezeru: minimální délku, která se prosazuje na straně serveru, nejen navrhuje v prohlížeči. Kdo chce víc — vynucenou dobu platnosti, historii proti opakovanému použití — potřebuje k tomu modul OCA nebo od třetí strany; ve verzi Community je to záměrně držené štíhlé.
Oprávnění: přístup dostane jen ten, kdo ho potřebuje
Odoo odděluje již ze své podstaty tři úrovně: uživatelé portálu (jen vlastní zákaznický nebo dodavatelský portál), interní uživatelé (backend, s právy podle aplikace) a správci (neomezený přístup včetně technických nastavení). Nejčastější chybou není příliš slabé heslo, ale příliš velkoryse přidělená role správce: Kdo má jen vystavovat faktury, nepotřebuje přístup k systémovým nastavením.
Většinu zátěže nesou dvě zásady:
Klíč API místo hesla: každé externí napojení (účetní software, evidence času, vlastní skripty) dostane vlastní, kdykoli odvolatelný klíč, nikdy uživatelské heslo.
Obojí lze ověřit ve stejném zobrazení, v němž se nastavuje i dvoufázové ověření:
Jeden přehled, čtyři páky: heslo, druhý faktor, klíče API, přihlášená zařízení.
Relace a zařízení: kdo je právě přihlášen
Totéž zobrazení ukazuje také, z kterých zařízení je účet právě přihlášen — a umožňuje odhlásit jedno nebo všechna najednou. Po ztraceném notebooku nebo při podezření na kompromitované heslo je to nejrychlejší účinný krok: Relace skončí okamžitě, bez ohledu na to, zda již bylo heslo změněno.
Vrstva 4: databáze a provoz
Čtvrtá vrstva je nejméně viditelná a zároveň nejméně prominutelná, protože chyba zde může zmařit vše, co bylo předtím vybudováno.
/web/database/manager rozhraní, které umožňuje databáze vytvářet, zálohovat, obnovovat a mazat — chráněné jediným hlavním heslem. Toto rozhraní musí být dostupné výhradně interně nebo zcela vypnuté.
- Pravidelné, ověřené zálohy, uložené odděleně od samotného serveru. Záloha, která nikdy nebyla obnovena, je domněnka, nikoli záloha.
- Tajemství nepatří do žádného souboru protokolu. Hesla, klíče API, licenční údaje — kdo píše vlastní rozšíření, měl by s nimi zacházet jako se samotným hlavním heslem: nikam je nezapisovat, ani „jen kvůli ladění“.
- Udržovat moduly aktuální, a to i — a právě — moduly třetích stran. Volné doplňkové moduly (OCA a další) přirozeně zaostávají za novými verzemi Odoo; před každou instalací stojí za to zkontrolovat, jaké závislosti se automaticky přidají.
Přihlašovací cesta jako celek
Čtyři vrstvy nepůsobí postupně v oddělených místnostech, ale na tentýž požadavek, stupeň po stupni. Nejlépe to vynikne na příkladu přihlášení:
Pět míst, na kterých může škodlivý požadavek skončit, než dorazí k vlastnímu cíli — a jen jediné, na kterém je všechna splní oprávněný uživatel.
Scénáře útoků a jejich odražení
Následující přehled přiřazuje skutečné vzory útoků vrstvám, které je skutečně zastaví. Několik z nich není teorie, ale vlastní pozorování ze sedmnácti dnů skutečného provozu na našich pěti webech.
| Scénář útoku | Jak probíhá | Co ho zastaví |
|---|---|---|
| Zkoušení hesel | Skript zkouší stovky kombinací proti přihlašovacímu formuláři nebo XML-RPC | Omezení četnosti na firewallu, počitadlo Web RBL přes restarty, blokace po deseti pokusech, okamžitá blokace při ignorované výzvě k čekání |
| Znovu použité přístupové údaje ukradené jinde | Útočník už zná uživatelské jméno a heslo — z jiné, napadené služby | Dvoufázové ověření zastaví přihlášení navzdory správnému heslu; Web RBL navíc nahlásí úspěšné přihlášení z nápadné adresy |
| Hledání zapomenutých tajemství | Automatizované dotazy na .env, .git, přístupové klíče do cloudu — u nás 57.721 dotazů za sedmnáct dní jen na .env |
Web RBL blokuje při prvním zásahu; firewall následně dostane adresu jako záznam RBL pro všechny ostatní služby |
| Skenery adresářů a cest | Desítky vymyšlených cest během několika sekund, při hledání zapomenutých aplikací | Rozpoznávání chování: mnoho chybných stránek, sotva jeden zásah, v krátkém čase — bez ohledu na to, zda cesta odpovídá známému vzoru |
| Chybně nakonfigurované vlastní zařízení | Synchronizační klient nebo e-mailový program omylem míří na špatnou adresu a klepe každou minutu | Rozpoznání jako chybná konfigurace místo útoku, tiket místo blokace — blokace by závadu neodstranila, jen oddálila |
| Automatizovaná sklizeň povinných údajů | Sběrač stahuje stránky s impresem pod cizími zápisy, často jako příprava vlny upozornění na porušení | Kanonická cesta zůstává vždy dostupná (právně nezbytné), cizí zápisy se rozpoznají a nahlásí nebo zablokují |
| Ztracené nebo odcizené zařízení | Přihlášený notebook nebo mobilní telefon se dostane do cizích rukou | Přehled relací s okamžitým odhlášením všech zařízení, bez ohledu na heslo |
| Příliš široké interní oprávnění | Uživatelský účet s většími právy, než je nutné, je kompromitován nebo zneužit | Nejnižší nezbytné oprávnění podle aplikace omezí škodu předem na to, co účet skutečně potřebuje |
| Zneužití externího rozhraní | Ukradený klíč API nebo kompromitovaný cizí systém přistupuje přes XML-RPC/JSON-RPC | Vlastní, odvolatelné klíče API místo uživatelského hesla; Web RBL sleduje i neúspěšná přihlášení přes RPC |
| Špatně posouzený crawler vyhledávače | Legitimní crawler vyvolává tolik provozu, že vypadá jako distribuovaný útočník — na jednom z našich webů to bylo přes sedmdesát procent veškerého provozu, způsobeného GPTBotem | Seznam výjimek s publikovanými rozsahy adres známých vyhledávačů zabrání chybné blokaci, která by vlastní web vyřadila z indexace |
| Zastaralý modul třetí strany se známou zranitelností | Bezpečnostní mezera ve volném doplňkovém modulu se stane veřejnou, aktualizace přijde až o týdny později | Před každou instalací zkontrolovat, co se přidá automaticky; aktualizace nejdřív na testovací instanci, ne na živém organismu |
| Otevřená správa databází | Administrační rozhraní je dostupné z otevřeného internetu; uhodnuté nebo slabé hlavní heslo stačí ke smazání nebo zkopírování databází | Rozhraní není nikdy veřejně vystaveno, hlavní heslo zůstává dlouhé, náhodné a nikde nezapsané |
Krok za krokem: zabezpečení vlastní instalace Odoo
Následující pořadí je to, v jakém bychom postupovali sami — od největšího účinku po nejjemnější nastavení.
1. Vynutit dvoufázové ověření
- Pokud ještě není nainstalováno: otevřít Aplikace, vyhledat „Two-Factor Authentication“ a nainstalovat (u více webů se doporučuje navíc „Two-Factor Authentication by Mail“ jako záložní možnost).
- Otevřít Nastavení → Obecná nastavení → Oprávnění.
- Aktivovat „Vynutit dvoufázové ověření“.
- Zvolit politiku: „Pouze zaměstnanci“ pro interní uživatele, „Všichni uživatelé“, pokud mají být zahrnuti i uživatelé portálu (zákazníci s přístupem).
- Uložit. Od dalšího pokusu o přihlášení vyžaduje Odoo od každého uživatele bez nastaveného druhého tajemství alespoň kód z e-mailu, dokud nenastaví aplikaci Authenticator.
2. Stanovit minimální délku hesel
- Otevřít Aplikace, vyhledat „Password Policy“ a nainstalovat.
- Otevřít Nastavení → Obecná nastavení → Oprávnění.
- Nastavit „Minimální délka hesla“ — dvanáct znaků je rozumná výchozí hodnota.
- Uložit. Pravidlo platí od nynějška pro každé nové nebo změněné heslo, zpětně se na stávající hesla nevztahuje.
3. Projít oprávnění
- Otevřít Nastavení → Uživatelé & společnosti → Uživatelé.
- Otevřít každého uživatele zvlášť a zkontrolovat záložku s přístupovými právy podle aplikace: Potřebuje tato osoba skutečně „Manažer“ nebo „Správce“, nebo stačí „Uživatel“?
- Zvlášť zkontrolovat: Kdo má přístup k samotnému „Nastavení“? Měla by to být velmi malá skupina.
- Pro každé externí napojení (účetnictví, vlastní skripty, evidence času) vytvořit v záložce „Zabezpečení účtu“ příslušného technického uživatele vlastní klíč API, místo aby se předávalo uživatelské heslo.
4. Nainstalovat Web RBL a pozorovat, než se zapne ostrý provoz
- Modul z github.com/Alex0176/odoo-web-rbl vložit do cesty addonů a nainstalovat.
- Několik dní pozorovat: nabídka Web RBL → Vyhodnocení ukazuje, které vzory skutečně zabírají.
- Teprve poté zapnout
web_rbl.sperren_aktiv(Nastavení → Technické → Systémové parametry) — od tohoto okamžiku jsou rozpoznané sondy skutečně odmítány. - Blokovací seznam na adrese uvedené v modulu, chráněné tokenem, zapojit do firewallu jako seznam RBL (u OPNsense/pfSense jako URL Table Alias, u HAProxy jako soubor ACL).
5. Zabezpečit samotný firewall
- Administrační rozhraní firewallu zpřístupnit výhradně z interní sítě, nikdy přes tutéž veřejnou adresu jako web.
- Aktivovat automatické bezpečnostní aktualizace softwaru firewallu, pokud je výrobce nabízí.
- Zkontrolovat konfiguraci TLS: jen aktuální verze protokolu, zastaralé šifrovací postupy deaktivovat.
- Pokud je k dispozici: zapojit známý reputační seznam (například Spamhaus DROP) přímo na firewallu — nezávisle na Web RBL, neboť firewall tak vidí i provoz ke službám, které Odoo nikdy nedosáhne.
6. Uzavřít správu databází
- Zkontrolovat, zda je
/web/database/managerdostupné zvenčí — pokud ano, nastavit v konfiguraci Odoolist_db = Falsenebo cestu zablokovat na úrovni firewallu. - Hlavní heslo správy databází nastavit dlouhé a náhodné a nezapisovat je na žádné místo, které může číst kdokoli jiný.
7. Zálohu ověřit, nejen nastavit
- Nastavit automatickou, pravidelnou zálohu, uloženou odděleně od serveru Odoo.
- Alespoň jednou ji skutečně obnovit a ověřit, zda obnova funguje — neověřená záloha je domněnka.
Žádný z těchto kroků nenahrazuje jiný. Kdo provede jen jeden z nich, zesílil jedny dveře a všechny ostatní nechal otevřené — kdo provede všech sedm, má obranu, která drží i tehdy, když selže jediná vrstva.
Co tato architektura nenahrazuje
Žádné z popsaných opatření nečiní pečlivost zbytečnou. Modul, který odmítá sondy .env, neučiní nebezpečným o nic méně omylem zveřejněný soubor .env. Dvoufázové ověření nechrání před uživatelem, který svůj kód přečte volajícímu po telefonu. A firewall nenahrazuje rozhodnutí o tom, kdo skutečně jaké oprávnění potřebuje. Bezpečnostní architektura vytváří podmínky, za nichž se jednotlivá chyba hned nestane incidentem — pečlivosti však nikoho nezbavuje.
Časté dotazy
Stačí silné heslo k zabezpečení Odoo 19?
Ne. Heslo lze ukrást jinde, zcela nezávisle na jeho kvalitě, a pak funguje u každé služby, která přijímá totéž heslo. Teprve kombinace s dvoufázovým ověřením, firewallem před systémem a rozumnou strukturou oprávnění dává zabezpečení, které drží i po ukradeném heslu.
Jak aktivuji dvoufázové ověření v Odoo 19?
Nainstalovat modul „Two-Factor Authentication (TOTP)“ přes správu aplikací, poté v Nastavení → Obecná nastavení → Oprávnění aktivovat vynucení a zvolit mezi „Pouze zaměstnanci“ a „Všichni uživatelé“. Každý uživatel si poté nastaví vlastní druhý faktor pomocí QR kódu.
Co je seznam RBL a proč ho Odoo potřebuje?
RBL (Real-time Blackhole List) je seznam adres dostupný přes HTTP, který dokáže načíst prakticky každý firewall. Odoo samo takový seznam neposkytuje — náš modul Web RBL tuto mezeru uzavírá tím, že rozpoznává útočný provoz z vlastního aplikačního protokolu a předává jej jako seznam RBL zpět předřazenému firewallu.
Je Odoo 19 Community bez doplňkových modulů dostatečně zabezpečeno?
Ne zcela. Bez modulu Password Policy neexistuje minimální délka hesel, bez Two-Factor Authentication žádný druhý faktor a bez modulu jako Web RBL Odoo nerozpozná ani sondovací pokusy, ani opakované pokusy o přihlášení přes restart. Všechny čtyři lze doplnit zdarma.
Dostupnost
Web RBL je veřejně dostupný pod licencí AGPL-3 a u nás běží produkčně na pěti webech:
github.com/Alex0176/odoo-web-rbl
Úplný popis funkcí se všemi vzory, skóre a seznamy hrozeb je v předchozím článku: Web RBL – blokovací seznam pro útočný provoz na vlastních webech.
Dotazy, připomínky a hlášení chyb rádi přijmeme — nejraději jako issue na GitHubu.