mod_security2 для Apache
Date January 10th, 2010 Author Vitaly Agapov
Для защиты своих Web-приложений надо прикладывать максимум усилий и всегда быть готовым к тому, что этого всё равно окажется недостаточно. Руки, само собой, опускаться не должны (только если на клавиатуру), а мы должны знать и помнить о всех возможностях нашего любимого ПО.
Сегодня я себе в качестве памятки (а всем прочим для ознакомления или праздного интереса) вкратце опишу весьма нужный модуль для Web-сервера Apache: mod_security2.
Нельзя создать идеальный с точки зрения безопасности код Web-приложения и поместить его в абсолютно безопасное окружение, защищающее контент от любых посягательств со стороны сетевых антисоциальных элементов. Тут, конечно, можно было бы завести схоластическую беседу о текстовых html-страничках, созданных на компьютере, хранящемся в чулане без подключения к сети… но не будем.
Проблема в том, что все серверные сценарии пишутся с такими встроенными полезными фичами, как дыры в безопасности. В подавляющем большинстве они связаны с возможностью передать в качестве параметра в HTTP-запросе какое-то значение, которое девелопер просто не предусмотрел и не сделал толковую проверку входных параметров. Сам я, хоть и стараюсь постоянно об этом помнить, периодически ловлю себя на том, в том или ином месте опять забыл проверить значение переменной. Обнаружить такую дыру непросто, обычное добросовестное кликанье по ссылкам на странице приводит к ожидаемому результату – всё работает очень круто. Здесь требуется запустить шаловливые ручки в адресную строку и начать экспериментировать. Те самые упомянутые антисоциальные элементы умеют делать это в совершенстве.
mod_security
Поставить дополнительную преграду на пути SQL-инъекций нам поможет модуль mod_security для Apache. Он распространяется бесплатно, а раздобыть его или почитать про него кое-какую информацию можно на сайте www.modsecurity.org.
Модуль mod_security наделяет Apache возможностями брандмауэра: мы можем, задавая правила в конфигурации, определять, какие запросы являются легитимными, а какие следует запретить как потенциально опасные. При этом модуль поддерживает регулярные выражения, что и определяет его мощность и гибкость в использовании. Второй его важной особенностью является возможность работы как с запросами GET, так и с запросами POST.
На установке останавливаться не буду. Модуль легко ставится из репозиториев либо собирается из исходников. У него есть некоторые зависимости, но проблем с ними возникать не должно. Расписывать установку – дело неблагодарное уже хотя бы из-за особенностей установки для разных ОС. Если ставить из исходников, то потребуется в httpd.conf добавлять строки для загрузки нужных библиотек libxml, liblua и самого модуля mod_security:
LoadFile /usr/lib/libxml2.so.2 LoadFile /usr/lib/liblua5.1.so.0 LoadModule security2_module modules/mod_security2.so
Если, например, ставить из репозитория в Ubuntu с помощью
sudo aptitude install libapache-mod-security mod-security-common
,то автоматически создастся файл /etc/apache2/mods-available/mod-security.load и соответствующая ссылка в mods-available. То есть лишних телодвижений не понадобится.
Перейдем к конфигурации. После установки модуля в конфигурации сервера можно использовать директивы фильтрации запросов. Некоторые из этих директив можно использовать внутри стандартных апачевских директив Directory, Location, VirtualHost и т.д. А некоторые – только в основном конфигурационном файле. Полную документацию по всем директивам можно найти на ModSecurity.org, упомянутом выше.
В файл httpd.conf вставляем строки:
<IfModule mod_security2.c> Include conf.d/modsec/*.conf </IfModule>
И создаём файлы:
mkdir /etc/httpd/conf.d/modsec mkdir /var/log/httpd/modsec touch /etc/httpd/conf.d/modsec/modsecurity_crs_10_config.conf touch /etc/httpd/conf.d/modsec/modsecurity_crs_15_customrules.conf
В файле modsecurity_crs_10_config.conf содержатся все основные директивы модуля, например, пути к лог-файлам и директивы включения режима фильтрации, а файл modsecurity_crs_15_customrules.conf при запуске Apache будет прочитан вторым и до всех остальных файлов конфигурации, что позволяет более гибко управлять правилами, например, в нём можно прописать нужные IP-адреса в белые списки, тем самым отменив необходимость продираться им через все остальные системы фильтров.
Итак, пропишем в основной лог следующее:
# Включить движок фильтра SecRuleEngine On # Вести лог только для подозрительных запросов SecAuditEngine RelevantOnly # Имя файла лога SecAuditLog /var/log/httpd/modsec/audit_log # Вывод отладочной информации SecDebugLog /var/log/httpd/modsec/debug_log SecDebugLogLevel 1 # Для подозрительных запросов по умолчанию писать в лог # и возвращать HTTP ответ с кодом 403 SecDefaultAction log,auditlog,deny,status:403,phase:2
Эта конфигурация просто активирует движок mod_security и в общем-то больше ничего не делает. Мы просто подготовили себе и модулю рабочее место и подошли к самому интересному – к правилам фильтрации. Прежде, чем к ним обратиться, стоит сделать небольшую ремарку относительно фаз обработки запросов сервером Apache. Их всего пять, и, начиная, с версии mod_security 2.5, для правил эту фазу надо указывать. Итак, на первой фазе обрабатываютя заголовки запроса, на второй – тело запроса, на третьей – заголовки ответа, на четвёртой – тело ответа, а на пятой происходит логирование события.
Обычно формат правила фильтрации выглядит следующим образом:
SecRule <Переменная> <Оператор> [<Действия>]
Переменная определяет объект для сравнения с шаблоном. Самые используемые значения:
- ARGS – параметры запроса GET или тело запроса POST (как частные случаи – ARGS_GET и ARGS_POST).
- ARGS_NAMES – имена параметров в запросе GET или POST
- FILES – запрошенные файлы
- FILES_COMBINED_SIZE – общий объем загружаемых файлов
- FILES_NAMES – имена загружаемых файлов
- FILES_SIZES – отдельные размеры загружаемых файлов
- GEO – наборы параметров для управления трафиком в зависимости от региона, к которому принадлежит IP-адрес
- PATH_INFO – путь (часть URL)
- QUERY_STRING – полная строка запроса с аргументами
- REMOTE_ADDR или REMOTE_HOST – IP-адрес или доменное имя удаленного пользователя
- REMOTE_PORT – порт, с которого устанавливается соединение
- REQUEST_BASENAME – имя запрашиваемого файла (например, index.php)
- REQUEST_HEADERS – заголовки запроса
- REQUEST_HEADERS_NAMES – имена заголовков
- REQUEST_LINE – полная строка запроса, включая версию HTTP
- REQUEST_URI – URL запроса без доменного имени
- REQUEST_URI_RAW – URL запроса с доменным именем
В качестве оператора используется либо некоторая константа, либо регулярное выражение (оператор по умолчанию – rx), либо непосредственно оператор, использующийся для сравнения:
- beginsWith
- contains
- endsWith
- eq
- ge – больше или равно
- gt
- le – меньше или равно
- lt
- pm – сравнение по списку слов
- pmFromFile – сравнение со списком слов из файла
- rx – регулярное выражение
- streq – сравнение строк на точное соответствие
- validateByteRange – сравнение с диапазоном байтов
В поле действий мы можем задать последовательность действий для модуля в случае соответствия переменной шаблону. Поле является необязательным, и по умолчанию будут выполнены действия, указанные директивой SecDefaultAction. Действия перечисляются через запятую. Из полезных действий следует упомянуть следующие:
- allow – прекратить проверку и разрешить транзакцию
- auditlog – сделать запись в auditlog
- deny – прекратить проверку и завершить транзакцию
- deprecatevar – уменьшать переменную с течением времени
- drop – завершить IP-соединение
- exec – выполнить внешний скрипт или команду
- expirevar – обнулять переменную через промежуток времени
- id – уникальный id правила
- initcol – создать набор переменных (например, для слежения за IP-адресами)
- log – создать запись в error.log и audit.log
- logdata – записать часть запроса в лог
- msg – записать в лог дополнительное сообщение
- pass – продолжить проверку
- pause – задержать обработку транзакции на определенное количество миллисекунд
- phase – приписать правило к определенной фазе
- proxy – перенаправить запрос на другой web-сервер
- redirect – вернуть ответ 302с новым адресом
- setvar – создание и управление переменными
- status – ответить с данным HTTP-кодом
- within
Вся эта теория очень, конечно, полезна, но самое интересное впереди – мы рассмотрим некоторые полезные правила, которые либо прямо так, либо после некоторого допиливания можно использовать на своих серверах:
SecRule FILES "\.conf$" log,deny,status:403,phase:2
Проверяет запросы, требующие файлы конфигурации.
SecRule PATH_INFO "^/(bin|etc|sbin|opt|usr)"
Проверяет запросы, обращающиеся к файлам в системных директориях.
SecRule REQUEST_BASENAME "^login\.php$" phase:2,t:none,t:lowercase
Проверяет обращение к определённому скрипту
SecAction phase:1,initcol:ip=%{REMOTE_ADDR},nolog SecRule ARGS:login "!^$" nolog,phase:1,setvar:ip.auth_attempt=+1,deprecatevar:ip.auth_attempt=20/120 SecRule IP:AUTH_ATTEMPT "@gt 25" \ "log,drop,phase:1,msg:'Possible Brute Force Attack'"
Подсчитывает количество попыток логина для каждого IP (здесь попыткой логина считается непустое значение поля login), и если их было более 25 за две минуты, то IP-соединение разрывается.
SecRule ARGS:text "@validateByteRange 10, 13, 32-126"
Проверяет наличие символов на соответствие указанному диапазону в поле text.
SecRule ARGS "\.\./"
Проверяет наличие двух точек в запросе. Одна из возможных атак на сервер.
SecRule ARGS "delete.+from" "t:lowercase" SecRule ARGS "insert.+into" "t:lowercase" SecRule ARGS "select.+from" "t:lowercase"
Проверяет на возможные SQL-инъекции.
Ссылки:
www.modsecurity.org
Tags: Apache, ModSecurity
Category:
Apache, Linux, Security, Web-dev |
6 Comments »
10 September 2010 - 18:52
В статье наконец-то нашёл ответ чем отличаются настройки mod_security от настройки mod_security2. Краткая, полезная и понятная статья!
2 September 2013 - 15:07
Как удалить установленный модуль mod_security2 и все настройки.
2 September 2013 - 15:08
как удалить mod_security2
15 October 2013 - 15:45
Например, так:
apt-get purge libapache-mod-security
О какой системе вообще идёт речь?
22 September 2015 - 16:30
[…] в заголовке XHR (XMLHttpRequest), а на стороне сервера с помощью mod_security фильтруем всё Ajax-запросы, не содержащие этого поля или […]
22 September 2015 - 16:48
[…] эдак, три назад я уже постил здесь статейку "mod_security2 для Apache", касающуюся использования модуля ModSecurity. Она и […]