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 чаще выносят на периметр сети, а не держат на каждом бэкенде.