ModSecurity — це відкритий Web Application Firewall (WAF), який працює як модуль Apache або Nginx. Він аналізує HTTP-трафік у реальному часі та блокує SQL-ін'єкції, XSS, RFI та інші атаки.
Встановлення ModSecurity на Ubuntu/Apache
sudo apt update
sudo apt install -y libapache2-mod-security2
# Увімкнути модуль
sudo a2enmod security2
sudo systemctl restart apache2
# Перевірити
apachectl -M | grep security
Базове налаштування
# Скопіювати конфіг
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
# Змінити режим з DetectionOnly на On
sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf
Встановлення OWASP CRS (Core Rule Set)
sudo apt install -y modsecurity-crs
# Або вручну:
cd /etc/modsecurity
sudo git clone https://github.com/coreruleset/coreruleset.git
cd coreruleset
sudo cp crs-setup.conf.example crs-setup.conf
Режими роботи
| Режим | Конфіг | Дія |
|---|---|---|
| Detection Only | SecRuleEngine DetectionOnly | Логує, не блокує |
| Active (On) | SecRuleEngine On | Блокує запити |
| Off | SecRuleEngine Off | Повністю вимкнено |
Керування хибними спрацюваннями
# Вимкнути правило для конкретного URL
SecRule REQUEST_URI "@beginsWith /wp-admin/post.php" "id:1000001,phase:1,pass,nolog,ctl:ruleRemoveById=941100"
# Вимкнути правило глобально (не рекомендується)
SecRuleRemoveById 941100
Логи ModSecurity
# Переглянути заблоковані запити
sudo tail -f /var/log/apache2/modsec_audit.log | grep "HTTP 403"
# Статистика атак
sudo grep "OWASP" /var/log/apache2/modsec_audit.log | awk '{print $NF}' | sort | uniq -c | sort -rn
Розбір реальних повідомлень ModSecurity
AH00526: Syntax error on line X ...: Invalid command 'SecRule', perhaps misspelled or defined by a module not included in the server configuration— саме такapachectl configtestповідомляє, що файли з правилами підключені, а сам модульsecurity2не увімкнено або сервер не перезапущено післяa2enmod.ModSecurity: Access denied with code 403 (phase 2). Matched "Operator ... to variable ARGS:..." [id "941100"] [msg "XSS Attack Detected via libinjection"]— типовий рядок в audit-журналі при спрацюванні правила; значенняid— номер конкретного правила, який використовується для точкового вимкнення черезctl:ruleRemoveById.ModSecurity: Warning. ... [id "200002"] [msg "Failed to parse request body."]— часте хибне спрацювання під час завантаження файлу через multipart-форму, зазвичай коли тіло запиту перевищуєSecRequestBodyLimitабо містить нестандартний boundary.ModSecurity: Rule ... execution error - PCRE limit exceeded— регулярний вираз одного з правил CRS не встиг відпрацювати на надто довгому значенні поля; лікується збільшеннямSecPcreMatchLimitабо обмеженням довжини поля на рівні застосунку.- Правило вимкнено директивою
SecRuleEngine Offусередині конкретного<VirtualHost>, тоді як у загальному конфігу стоїтьOn— Apache застосовує більш специфічну директиву, і саме цей сайт залишається без захисту, поки в журналах решти доменів видно нормальну роботу WAF.
Рівні Paranoia в OWASP CRS
| Paranoia Level | Що покриває | Хибні спрацювання | Рекомендація |
|---|---|---|---|
| PL1 | Базові правила проти найчастіших атак: SQL-ін'єкції та XSS із явними сигнатурами | Мінімум | Стартовий рівень для більшості сайтів |
| PL2 | Додає ширші евристики та перевірки нестандартних кодувань | Періодично, на нетипових формах | Для сайтів із підвищеними вимогами до безпеки |
| PL3 | Суворі перевірки, багато додаткових патернів | Часто, потребує ручного налаштування винятків | Лише після тижнів тестування в режимі DetectionOnly |
| PL4 | Максимально консервативний набір правил | Дуже часто на будь-якому нестандартному вводі | Спеціалізовані середовища на кшталт платежів чи держсектору, майже завжди з ручними винятками |
Коли ModSecurity не підходить
- Сайт із мілісекундним бюджетом на відповідь і дуже високим навантаженням — інспекція кожного запиту всіма правилами CRS додає помітну затримку; на таких проєктах WAF частіше ставлять на периметрі (наприклад Cloudflare), а не на кожному бекенд-сервері.
- Проєкт з активною розробкою і формами, що часто змінюються — на рівні paranoia вище PL1 доведеться регулярно розбирати нові хибні спрацювання замість того, щоб налаштувати правила один раз і забути.
- Віртуальний хостинг без root-доступу, лише PHP через FTP — ModSecurity працює на рівні вебсервера і потребує адміністративного доступу; на shared-хостингу без нього увімкнути його не можна, доступний лише вбудований WAF провайдера, якщо він є.
- Захист від атак на бізнес-логіку — підміна ціни в замовленні, обхід платного контенту через формально коректні запити — ModSecurity шукає ознаки відомих атак у самому запиті, а не перевіряє логіку застосунку; тут потрібен код на боці застосунку, а не правила WAF.
Перевірка, що WAF реально блокує атаки
# Перевірити, що модуль дійсно завантажений, а не просто є в конфігу
apachectl -M | grep security
# Надіслати безпечний тестовий payload і переконатися, що WAF його ловить
curl "https://example.com/?test=<script>alert(1)</script>"
# Очікується відповідь 403, якщо правило проти XSS активне
# Подивитися, яке саме правило спрацювало
sudo tail -20 /var/log/apache2/modsec_audit.log | grep -E "id \"|msg "
Якщо curl повернув не 403, а звичайну сторінку сайту — або рушій у режимі DetectionOnly, або конкретне правило проти XSS вимкнене чи перевизначене на рівні віртуального хоста; тоді варто повернутися до першого пункту цього розділу.
Часті питання
Чи замінює ModSecurity антивірус або перевірку файлів на шкідливий код?
Ні, це різні задачі. ModSecurity аналізує вхідні HTTP-запити в реальному часі і шукає ознаки відомих атак у самому запиті, а не вміст файлів на диску. Для пошуку вже завантажених шкідливих скриптів і веб-шелів потрібен окремий антивірусний сканер файлової системи — ModSecurity його не замінює і не виконує цю функцію.
Якщо сайт вже захищений WAF від Cloudflare, чи потрібен ще й ModSecurity на самому сервері?
Це розумне дублювання, а не надмірність. Cloudflare фільтрує трафік на периметрі мережі і ловить більшість масових атак ще до того, як вони дістануться сервера, але не захищає від запитів, які йдуть напряму на IP сервера в обхід проксування. ModSecurity на сервері лишається останньою лінією захисту саме для такого обходу.
Чи можна налаштувати правила ModSecurity окремо для кожного сайту, а не одним спільним набором на весь сервер?
Так, правила можна задавати як глобально для всього сервера, так і всередині конфігурації конкретного VirtualHost — більш специфічне налаштування в Apache завжди перевизначає загальне. Це зручно, коли один сайт на сервері потребує суворішого рівня перевірки, а інший регулярно дає хибні спрацювання на тому самому наборі правил.
Чи помітно сповільнює ModSecurity завантаження сайту для звичайних відвідувачів?
Сповільнення є, однак для більшості сайтів воно непомітне на око: правила перевіряють запит за частку секунди. Затримка стає відчутною лише на дуже високонавантажених проєктах або за включеного максимального рівня Paranoia з десятками додаткових перевірок на кожен запит — у таких випадках WAF частіше виносять на периметр мережі, а не тримають на кожному бекенді.