Odoo е достъпен от отворения интернет на петте ни уебсайта и това не е изключение, а нормалният случай: Който предлага оферта, магазин или клиентски вход, има публичен сървър. Една-единствена уязвима парола, един забравен конфигурационен файл или едно прекалено щедро право за достъп е достатъчно, за да стане един публичен сървър отворен.
Тази статия показва как да защитите Odoo 19 правилно — не с една-единствена мярка, а с няколко слоя, които се допълват взаимно: защитна стена и обратен прокси, нашият модул с отворен код Web RBL, двуфакторно удостоверяване, политика за пароли и права за достъп — и кои опити за атака всяка от тях действително улавя. В края има ръководство стъпка по стъпка, с което може да се повтори всяка собствена инсталация на Odoo.
Съдържание на тази статия
- Защита в дълбочина: защо една мярка никога не стига
- Слой 1: защитна стена и обратен прокси
- Слой 2: Web RBL — мостът към защитната стена
- Слой 3: защита на самия Odoo (2FA, политика за пароли, права за достъп)
- Слой 4: база данни и експлоатация
- Пътят на входа като цяло
- Сценарии на атаки и защитата срещу тях
- Ръководство стъпка по стъпка
- Често задавани въпроси
Защита в дълбочина: защо една мярка никога не стига
Всяка отделна мярка за сигурност има пропуск. Една защитна стена не вижда какво се случва във формуляра за вход на Odoo. Силната парола не защитава, ако вече е била открадната другаде. Структурата от права за достъп не помага срещу нападател, който още изобщо не е влязъл. Принципът, който затваря тези пропуски, се нарича защита в дълбочина (defense in depth): няколко независими слоя, всеки от които поотделно би могъл да бъде заобиколен — но всички заедно не.
При нас слоевете са четири, всеки с различна задача:
- Защитна стена / обратен прокси — държи очевидно злонамереното далеч, още преди изобщо да стигне до сървъра
- Web RBL — свързва двете страни: Odoo се учи от собствения протокол на приложението какво защитната стена изобщо не може да види и го подава обратно към нея
- Самият Odoo — двуфакторно удостоверяване, политика за пароли, права за достъп, управление на сесии
- База данни & експлоатация — архивиране, защита на достъпа до управлението, тайни извън всеки протокол
Следващите раздели разглеждат всеки слой поотделно.
Слой 1: защитна стена и обратен прокси
Защитната стена е първата инстанция, която вижда една заявка, и единствената, която може да държи нападателя далеч от всяка услуга на сървъра — не само от уебсайта, но и от пощенския сървър, от VPN достъпа и от собствения интерфейс за управление. Кое е смислено да се активира на това място, зависи от производителя, но видовете са едни и същи при OPNsense, pfSense, HAProxy, FortiGate, Sophos или Check Point:
| Функция | Срещу какво помага |
|---|---|
| Актуална версия на TLS и ограничени методи за криптиране | Подслушване и манипулиране на връзката; остарелите методи от години се считат за пробити или слаби |
| Списъци за репутация и произход (RBL) | Известни мрежи на нападатели, изходни възли на Tor, цели държави без собствени клиенти — вижте по-долу |
| Ограничаване на честотата за всеки адрес | Пробване на пароли и скенери на директории, които за секунди изпращат десетки заявки |
| Разделяне на управлението от трафика с данни | Самият интерфейс на защитната стена не бива да е достъпен през същия адрес като публичния уебсайт |
| IDS/IPS (разпознаване/отблъскване на атаки) | Известни шаблони на атаки на мрежово ниво, независимо какво приложение работи зад тях |
| Автоматични актуализации за сигурност на самата защитна стена | Незаздравена защитна стена вече не е защитна стена, а допълнителна цел |
RBL списъци: стандартният начин, по който се доставя репутация
RBL означава Real-time Blackhole List, понятие от света на пощата: един адрес на ред, достъпен през HTTP, зареждан редовно наново. Практически всяка защитна стена може да прочете такъв списък и да изгради правила от него — OPNsense и pfSense като URL Table Alias, HAProxy като ACL файл, FortiGate като External Block List, Palo Alto като External Dynamic List, Cisco, Sophos, Juniper и MikroTik със собствени имена за същия принцип.
Точно тук се включва нашият собствен модул — и точно тук започва вторият слой.
Слой 2: Web RBL — мостът между приложението и защитната стена
Защитната стена вижда пакети, не логиката на приложението. Тя не знае, че заявка към /xmlrpc/2/common е опит за вход, че двадесет различни пътя за четиринадесет секунди са скенер или че един адрес току-що е познал успешно парола. Всичко това знае само самият Odoo. Web RBL, нашият собствен модул с отворен код (AGPL-3), прави това знание използваемо — за самия Odoo и, доставян като RBL списък, и за защитната стена пред него.
Списъци със заплахи, непрекъснато сверявани, всеки със собствено ниво.
Накратко какво е описано подробно в предишната статия:
- Разпознаване на шаблони в пътища:
.envфайлове, директории.git, конфигурационни файлове, WordPress и PHP сонди, обхождане на път (path traversal), изпълнение на команди през нови AI интерфейси - Защита на входа, която брои и след рестартиране — за разлика от собствения брояч на Odoo, живеещ в оперативната памет
- Оценка на всеки адрес от 0 до 100, с обосновка на ясен език
- Погрешни конфигурации (QNAP, Autodiscover, Synology) се разпознават и никога не се блокират, защото блокирането не отстранява дефекта, а само го скрива
- Чужди списъци със заплахи като Spamhaus, FireHOL и изходни възли на Tor, непрекъснато сверявани
- Разрешен списък за адреси, които никога не бива да се блокират
За тази статия две свойства са особено важни, защото са пряко свързани със защитната стена и с входа.
Бавният списък е списък, на който може да се има доверие
Разрешеният списък — адреси, които никога не се блокират, например собствените връзки между обекти — по правило се променя рядко. Именно това е неговата стойност, а не недостатък: Когато един спокоен списък почти не се мърда с дни, всяка рядка промяна веднага се набива на очи. Ежедневното автоматично поддържане съществува не защото много неща ще се променят, а за да не се налага рядката промяна да се вписва на ръка — и точно това е мястото, където се забравя. Една от собствените ни погрешни конфигурации през миналия месец се забеляза точно така: не чрез много събития, а чрез единственото, което никой не познаваше, докато уеб API на QNAP на един клиент не беше блокиран по погрешка. Оттогава QNAP е в списъка с погрешни конфигурации, които никога не се блокират, а само се докладват.
Входът е мястото, което защитната стена не вижда
Една защитна стена може да блокира адрес. Тя не може да знае дали един вход е успешен, а още по-малко дали е дошъл от адрес, който малко преди това е търсил данни за достъп. Web RBL може: Оценка над настройваем праг забранява входа изцяло, а успешният вход от подозрителен адрес се докладва — това е връзката със следващия слой.
Слой 3: защита на самия Odoo
Двуфакторно удостоверяване: втора тайна, която не може да се използва повторно
Най-големият проблем на паролите не е тяхното качество, а повторното им използване. Парола, открадната от друга услуга, работи и при нас също толкова добре, стига да е същата. Двуфакторното удостоверяване (2FA, наричано още TOTP) му противопоставя втора тайна: шестцифрен код, който се сменя на всеки тридесет секунди и се изчислява от тайна, която знае само собственият смартфон. Откраднатата парола сама вече не стига.
Odoo 19 Community го носи вградено — като инсталируем модул Two-Factor Authentication (TOTP), допълнен с резервна възможност чрез имейл. Всеки потребител го настройва сам за себе си, чрез QR код, с всяко разпространено приложение за удостоверяване:
Настройката: сканирайте QR кода, потвърдете веднъж шестцифрения код, готово.
Само това обаче помага единствено на онези, които сами си го настройват — и опитът показва, че без принуда те остават малцинство. Затова Odoo познава политика за задължително прилагане: или само за служители (вътрешни потребители), или за всички, включително потребителите на портала. Без настроена втора тайна никой вече не минава покрай формуляра за вход, без поне да потвърди чрез код по имейл.
Политика за пароли: минималната дължина не е нещо от само себе си
Без допълнителен модул Odoo Community не разчита на никаква минимална дължина на паролите — потребител може да зададе парола от три знака, ако никой не го спре. Собственият модул Password Policy затваря точно този пропуск: минимална дължина, която се налага от страна на сървъра, а не само се предлага в браузъра. Който иска повече — принудителен срок на валидност, история срещу повторна употреба — има нужда за това от модул на OCA или от трета страна; във версията Community това е нарочно запазено скромно.
Права за достъп: достъп получава само който има нужда
Odoo по подразбиране разделя три нива: потребители на портала (само собственият портал за клиенти или доставчици), вътрешни потребители (бекендът, с права за всяко приложение) и администратори (неограничен достъп заедно с техническите настройки). Най-честата грешка не е твърде слабата парола, а твърде щедро раздадената роля на администратор: Който трябва само да създава фактури, няма нужда от достъп до системните настройки.
Два принципа носят основната тежест:
API ключ вместо парола: всяка външна връзка (счетоводен софтуер, отчитане на времето, собствени скриптове) получава собствен ключ, който може да бъде отнет по всяко време, никога паролата на потребителя.
И двете могат да се проверят в същия изглед, в който се настройва и двуфакторното удостоверяване:
Един преглед, четири лоста: парола, втори фактор, API ключове, влезли устройства.
Сесии и устройства: кой е влязъл в момента
Същият изглед показва и от кои устройства в момента е влязъл един акаунт — и позволява да се излезе от едно или от всички наведнъж. След изгубен лаптоп или при подозрение за компрометирана парола това е най-бързата ефективна стъпка: Сесията завършва веднага, независимо дали паролата вече е сменена.
Слой 4: база данни и експлоатация
Четвъртият слой е най-малко видимият и същевременно най-непростимият, защото грешка тук може да обезсмисли всичко изградено преди това.
/web/database/manager интерфейс, с който могат да се създават, архивират, възстановяват и изтриват бази данни — защитен само с една-единствена главна парола. Този интерфейс трябва да бъде достъпен само вътрешно или напълно изключен.
- Редовни, проверени архивни копия, съхранявани отделно от самия сървър. Архивно копие, което никога не е било възстановявано, е предположение, а не архивно копие.
- Тайните не са място в нито един лог файл. Пароли, API ключове, лицензни данни — който пише собствени разширения, трябва да ги третира като самата главна парола: никъде да не ги записва, дори „само за дебъгване“.
- Поддържайте модулите актуални, и особено модулите на трети страни. Свободните допълнителни модули (OCA и други) естествено изостават от новите версии на Odoo; преди всяка инсталация си струва да се види кои зависимости се добавят автоматично.
Пътят на входа като цяло
Четирите слоя не действат последователно в отделни стаи, а върху една и съща заявка, степен по степен. Най-ясно се вижда това при пример с вход:
Пет места, на които една злонамерена заявка може да приключи, преди да стигне до същинската цел — и само едно, на което един легитимен потребител ги преминава всичките.
Сценарии на атаки и защитата срещу тях
Следващият преглед свързва реални шаблони на атаки със слоевете, които действително ги спират. Няколко от тях не са теория, а собствени наблюдения от седемнадесет дни реален трафик на петте ни уебсайта.
| Сценарий на атака | Как протича | Какво я спира |
|---|---|---|
| Пробване на пароли | Скрипт опитва стотици комбинации срещу формуляра за вход или XML-RPC | Ограничаване на честотата от защитната стена, брояч на Web RBL, който работи и след рестартиране, блокиране след десет опита, незабавно блокиране при игнорирано съобщение за изчакване |
| Повторно използвани данни за достъп, откраднати другаде | Нападателят вече знае потребителско име и парола — от друга, хакната услуга | Двуфакторното удостоверяване спира входа въпреки вярната парола; освен това Web RBL докладва успешен вход от подозрителен адрес |
| Търсене на забравени тайни | Автоматизирани заявки за .env, .git, ключове за достъп до облака — при нас 57 721 заявки за седемнадесет дни само за .env |
Web RBL блокира при първото попадение; защитната стена след това получава адреса като RBL запис за всички други услуги |
| Скенери на директории и пътища | Десетки измислени пътища за няколко секунди, в търсене на забравени приложения | Разпознаване на поведение: много несъществуващи страници, почти никакво попадение, за кратко време — независимо дали пътят отговаря на известен шаблон |
| Погрешно конфигурирано собствено устройство | Клиент за синхронизация или програма за електронна поща по погрешка сочи към грешния адрес и чука на всяка минута | Разпознаване като погрешна конфигурация, а не като атака, тикет вместо блокиране — блокирането не би отстранило дефекта, а само би го отложило |
| Автоматизирано събиране на задължителна информация | Събирач извиква страници с impressum под чужди изписвания, често като подготовка за вълна от предупредителни писма | Каноничният път остава винаги достъпен (правно необходимо), чуждите изписвания се разпознават и докладват или блокират |
| Изгубено или откраднато устройство | Влязъл с профила си лаптоп или мобилен телефон попада в чужди ръце | Преглед на сесиите с незабавно излизане от всички устройства, независимо от паролата |
| Твърде широко вътрешно право за достъп | Потребителски акаунт с повече права от необходимото бива компрометиран или злоупотребен | Най-малкото необходимо право за всяко приложение ограничава щетите предварително до това, което акаунтът наистина има нужда |
| Злоупотреба с външен интерфейс | Откраднат API ключ или компрометирана външна система получава достъп през XML-RPC/JSON-RPC | Собствени API ключове, които могат да бъдат отнети, вместо парола на потребител; Web RBL следи и неуспешните RPC входове |
| Погрешно оценен робот на търсачка | Легитимен робот генерира толкова трафик, че изглежда като разпределен нападател — на един от нашите сайтове това бяха над седемдесет процента от целия трафик, причинен от GPTBot | Разрешеният списък с публикуваните адресни диапазони на известни търсачки предотвратява погрешно блокиране, което би извадило собствения сайт от индексирането |
| Остарял модул на трета страна с известна уязвимост | Уязвимост в свободен допълнителен модул става публично известна, а актуализацията идва едва седмици по-късно | Преди всяка инсталация да се проверява какво се добавя автоматично; актуализациите първо на тестова инстанция, а не на отворено сърце |
| Достъпно управление на базите данни | Интерфейсът за управление е достъпен през отворения интернет; отгатната или слаба главна парола е достатъчна, за да се изтрият или копират бази данни | Интерфейсът никога не се излага публично, главната парола остава дълга, случайна и никъде записана |
Стъпка по стъпка: защита на собствената инсталация на Odoo
Следващата последователност е тази, в която бихме действали и ние самите — от най-голямото въздействие към най-фината настройка.
1. Налагане на двуфакторното удостоверяване
- Ако още не е инсталирано: отворете Приложения, потърсете „Two-Factor Authentication“ и го инсталирайте (при няколко уебсайта се препоръчва допълнително „Two-Factor Authentication by Mail“ като резервна възможност).
- Отворете Настройки → Общи настройки → Права за достъп.
- Активирайте „Налагане на двуфакторно удостоверяване“.
- Изберете политика: „Само служители“ за вътрешни потребители, „Всички потребители“, ако трябва да се включат и потребителите на портала (клиенти с достъп).
- Запазете. От следващия опит за вход Odoo изисква от всеки потребител без настроена втора тайна поне кода по имейл, докато не настрои приложението за удостоверяване.
2. Определяне на минимална дължина на паролите
- Отворете Приложения, потърсете „Password Policy“ и го инсталирайте.
- Отворете Настройки → Общи настройки → Права за достъп.
- Задайте „Минимална дължина на паролата“ — дванадесет знака е разумна начална стойност.
- Запазете. Правилото важи веднага за всяка нова или променена парола, но не и със задна дата за съществуващите пароли.
3. Преглед на правата за достъп
- Отворете Настройки → Потребители & компании → Потребители.
- Отворете всеки потребител поотделно и проверете раздела с правата за достъп за всяко приложение: Наистина ли това лице има нужда от „Мениджър“ или „Администратор“, или стига „Потребител“?
- Проверете особено: Кой има достъп до самите „Настройки“? Това трябва да е много малка група.
- За всяка външна връзка (счетоводство, собствени скриптове, отчитане на времето) в раздела „Сигурност на акаунта“ на съответния технически потребител създайте собствен API ключ, вместо да предавате паролата на потребителя.
4. Инсталиране на Web RBL и наблюдение, преди да се включи в пълна сила
- Модул от github.com/Alex0176/odoo-web-rbl поставете в пътя за addons и инсталирайте.
- Наблюдавайте няколко дни: менюто Web RBL → Анализ показва кои шаблони действително се задействат.
- Едва след това включете
web_rbl.sperren_aktiv(Настройки → Технически → Системни параметри) — оттук нататък разпознатите сонди действително се отхвърлят. - Включете списъка за блокиране в защитната стена като RBL списък, от адреса, посочен в модула и защитен с токен (при OPNsense/pfSense като URL Table Alias, при HAProxy като ACL файл).
5. Защита на самата защитна стена
- Направете интерфейса за управление на защитната стена достъпен единствено от вътрешната мрежа, никога през същия публичен адрес като уебсайта.
- Активирайте автоматичните актуализации за сигурност на софтуера на защитната стена, доколкото производителят ги предлага.
- Проверете конфигурацията на TLS: само актуални версии на протоколите, деактивирайте остарелите методи за криптиране.
- Ако е налично: включете известен списък за репутация (например Spamhaus DROP) директно на защитната стена — независимо от Web RBL, защото така защитната стена вижда и трафика към услуги, до които Odoo никога не стига.
6. Затваряне на управлението на базите данни
- Проверете дали
/web/database/managerе достъпен отвън — ако да, задайте в конфигурацията на Odoolist_db = Falseили блокирайте пътя на ниво защитна стена. - Задайте главната парола на управлението на базите данни дълга и случайна и не я записвайте на никое място, което някой друг може да прочете.
7. Проверка на архивното копие, а не само настройването му
- Настройте автоматично, редовно архивиране, съхранявано отделно от сървъра на Odoo.
- Възстановете поне веднъж действително копието и проверете дали възстановяването работи — непроверено архивно копие е предположение.
Никоя от тези стъпки не замества друга. Който приложи само една от тях, е укрепил една врата и е оставил всички останали отворени — който приложи и седемте, има защита, която издържа и когато един отделен слой се провали.
Какво тази архитектура не замества
Никоя от описаните мерки не прави грижливостта излишна. Модул, който отхвърля сонди за .env, не прави безопасен един по невнимание публикуван .env файл. Двуфакторното удостоверяване не защитава от потребител, който прочита кода си на човек, обаждащ се по телефона. А защитната стена не замества решението кой от какво право действително има нужда. Архитектурата за сигурност създава условия, при които една отделна грешка не става веднага инцидент — тя не освобождава никого от грижливостта.
Често задавани въпроси
Достатъчна ли е силна парола, за да се защити Odoo 19?
Не. Една парола може да бъде открадната другаде, напълно независимо от качеството ѝ, и тогава работи при всяка услуга, която приема същата парола. Едва комбинацията с двуфакторно удостоверяване, защитна стена отпред и смислена структура от права за достъп дава защита, която издържа и след открадната парола.
Как да активирам двуфакторното удостоверяване в Odoo 19?
Инсталирайте модула „Two-Factor Authentication (TOTP)“ през управлението на приложенията, след това в Настройки → Общи настройки → Права за достъп активирайте налагането и изберете между „Само служители“ и „Всички потребители“. Всеки потребител след това настройва собствения си втори фактор чрез QR код.
Какво е RBL списък и защо Odoo има нужда от такъв?
RBL (Real-time Blackhole List) е списък с адреси, достъпен през HTTP, който практически всяка защитна стена може да прочете. Самият Odoo не носи такъв списък — нашият модул Web RBL затваря този пропуск, като разпознава трафика на атаки от собствения протокол на приложението и го връща като RBL списък към предхождащата защитна стена.
Достатъчно ли е защитен Odoo 19 Community без допълнителни модули?
Не напълно. Без модула Password Policy няма минимална дължина на паролите, без Two-Factor Authentication няма втори фактор, а без модул като Web RBL Odoo не разпознава нито опити за сондиране, нито повторни опити за вход през рестартиране. И четирите могат да бъдат добавени безплатно.
Наличност
Web RBL е публично достъпен под AGPL-3 и работи при нас продуктивно на пет уебсайта:
github.com/Alex0176/odoo-web-rbl
Пълното описание на функциите с всички шаблони, оценката и списъците със заплахи е в предишната статия: Web RBL – списък за блокиране на трафик на атаки към собствените уебсайтове.
Въпроси, бележки и съобщения за грешки приемаме с удоволствие — най-добре като Issue в GitHub.