Поиск по сайту:

Как настроить mod_security с помощью Apache в Debian/Ubuntu


Прелюдия

Mod security — это бесплатный брандмауэр веб-приложений (WAF), который работает с Apache, Nginx и IIS. Он поддерживает гибкий механизм правил для выполнения простых и сложных операций и поставляется с основным набором правил (CRS), в котором есть правила для SQL-инъекций, межсайтовых сценариев, троянов, плохих пользовательских агентов, перехвата сеансов и множества других эксплойтов. Для Apache это дополнительный модуль, упрощающий установку и настройку.

Для выполнения этого руководства вам понадобится LAMP, установленный на вашем сервере.

Установка mod_security

Modsecurity доступен в репозитории Debian/Ubuntu:

apt-get install libapache2-modsecurity

Убедитесь, что модуль mod_security был загружен.

apachectl -M | grep --color security

Вы должны увидеть модуль с именем security2_module (shared), который указывает, что модуль был загружен.

Установка Modsecurity включает рекомендуемый файл конфигурации, который необходимо переименовать:

mv /etc/modsecurity/modsecurity.conf{-recommended,}

Перезагрузить Апач

service apache2 reload

Вы найдете новый файл журнала для mod_security в каталоге журнала Apache:

root@droplet:~# ls -l /var/log/apache2/modsec_audit.log
-rw-r----- 1 root root 0 Oct 19 08:08 /var/log/apache2/modsec_audit.log

Настройка mod_security

Из коробки modsecurity ничего не делает, так как для работы ему нужны правила. Файл конфигурации по умолчанию имеет значение DetectionOnly, которое регистрирует запросы в соответствии с правилами и ничего не блокирует. Это можно изменить, отредактировав файл modsecurity.conf:

nano /etc/modsecurity/modsecurity.conf

Найдите эту строку

SecRuleEngine DetectionOnly

и измените его на:

SecRuleEngine On

Если вы пробуете это на рабочем сервере, меняйте эту директиву только после проверки всех ваших правил.

Еще одна директива, которую необходимо изменить, — это SecResponseBodyAccess. Это настраивает, буферизуются ли тела ответов (т.е. читаются modsecurity). Это необходимо только в том случае, если требуется обнаружение утечки данных и защита. Таким образом, если оставить его Включенным, ресурсы дроплетов будут израсходованы, а также увеличится размер файла журнала.

Найдите это

SecResponseBodyAccess On

и измените его на:

SecResponseBodyAccess Off

Теперь мы ограничим максимальное количество данных, которые можно отправить в ваше веб-приложение. Две директивы настраивают их:

SecRequestBodyLimit
SecRequestBodyNoFilesLimit

Директива SecRequestBodyLimit указывает максимальный размер данных POST. Если клиент отправляет что-то большее, сервер ответит ошибкой 413 Request Entity Too Large. Если в вашем веб-приложении нет загрузки файлов, это значение можно значительно уменьшить.

Значение, указанное в файле конфигурации, равно

SecRequestBodyLimit 13107200

что составляет 12,5 МБ.

Подобной директиве является SecRequestBodyNoFilesLimit. Единственное отличие состоит в том, что эта директива ограничивает размер данных POST за вычетом загружаемых файлов — это значение должно быть «как можно меньше».

Значение в файле конфигурации

SecRequestBodyNoFilesLimit 131072

что составляет 128 КБ.

Наряду с этими директивами есть еще одна, влияющая на производительность сервера: SecRequestBodyInMemoryLimit. Эта директива говорит сама за себя; он указывает, сколько данных «тела запроса» (данные POST) должны храниться в памяти (ОЗУ), все остальное будет помещено на жесткий диск (точно так же, как подкачка). Поскольку капли используют SSD, это не так уж много. проблема; тем не менее, это может быть установлено приличное значение, если у вас есть свободная оперативная память.

SecRequestBodyInMemoryLimit 131072

Это значение (128 КБ), указанное в файле конфигурации.

Тестирование SQL-инъекций

Прежде чем приступить к настройке правил, мы создадим PHP-скрипт, который уязвим для SQL-инъекций, и попробуем его. Обратите внимание, что это всего лишь базовый PHP-скрипт входа в систему без обработки сеанса. Обязательно измените пароль MySQL в приведенном ниже скрипте, чтобы он подключился к базе данных:

/var/www/login.php

<html>
<body>
<?php
    if(isset($_POST['login']))
    {
        $username = $_POST['username'];
        $password = $_POST['password'];
        $con = mysqli_connect('localhost','root','password','sample');
        $result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' AND password='$password'");
        if(mysqli_num_rows($result) == 0)
            echo 'Invalid username or password';
        else
            echo '<h1>Logged in</h1><p>A Secret for you....</p>';
    }
    else
    {
?>
        <form action="" method="post">
            Username: <input type="text" name="username"/><br />
            Password: <input type="password" name="password"/><br />
            <input type="submit" name="login" value="Login"/>
        </form>
<?php
    }
?>
</body>
</html>

Этот скрипт отобразит форму входа. При вводе правильных учетных данных появится сообщение «Секрет для вас».

Нам нужны учетные данные в базе данных. Создайте базу данных MySQL и таблицу, затем вставьте имена пользователей и пароли.

mysql -u root -p

Это приведет вас к подсказке mysql>.

create database sample;
connect sample;
create table users(username VARCHAR(100),password VARCHAR(100));
insert into users values('jesin','pwd');
insert into users values('alice','secret');
quit;

Откройте браузер, перейдите по адресу http://yourwebsite.com/login.php и введите правильную пару учетных данных.

Username: jesin
Password: pwd

Вы увидите сообщение об успешном входе в систему. Теперь вернитесь и введите неправильную пару учетных данных - вы увидите сообщение Неверное имя пользователя или пароль.

Мы можем подтвердить, что скрипт работает правильно. Следующая задача — попробовать свои силы с SQL-инъекцией, чтобы обойти страницу входа. Введите следующее в поле имени пользователя:

' or true -- 

Обратите внимание, что после должен быть пробел — эта инъекция не будет работать без этого пробела. Оставьте поле пароля пустым и нажмите кнопку входа.

Вуаля! Сценарий показывает сообщение, предназначенное для аутентифицированных пользователей.

Настройка правил

Чтобы облегчить вам жизнь, существует множество правил, которые уже установлены вместе с mod_security. Они называются CRS (основной набор правил) и расположены в

root@droplet:~# ls -l /usr/share/modsecurity-crs/
total 40
drwxr-xr-x 2 root root  4096 Oct 20 09:45 activated_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 base_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 experimental_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 lua
-rw-r--r-- 1 root root 13544 Jul  2  2012 modsecurity_crs_10_setup.conf
drwxr-xr-x 2 root root  4096 Oct 20 09:45 optional_rules
drwxr-xr-x 3 root root  4096 Oct 20 09:45 util

Документация доступна по адресу

root@droplet1:~# ls -l /usr/share/doc/modsecurity-crs/
total 40
-rw-r--r-- 1 root root   469 Jul  2  2012 changelog.Debian.gz
-rw-r--r-- 1 root root 12387 Jun 18  2012 changelog.gz
-rw-r--r-- 1 root root  1297 Jul  2  2012 copyright
drwxr-xr-x 3 root root  4096 Oct 20 09:45 examples
-rw-r--r-- 1 root root  1138 Mar 16  2012 README.Debian
-rw-r--r-- 1 root root  6495 Mar 16  2012 README.gz

Чтобы загрузить эти правила, нам нужно указать Apache просмотреть эти каталоги. Отредактируйте файл modsecurity.conf.

nano /etc/apache2/mods-enabled/modsecurity.conf

Добавьте следующие директивы внутрь :

Include "/usr/share/modsecurity-crs/*.conf"
Include "/usr/share/modsecurity-crs/activated_rules/*.conf"

Каталог activated_rules аналогичен каталогу Apache mods-enabled. Правила доступны в каталогах:

/usr/share/modsecurity-crs/base_rules
/usr/share/modsecurity-crs/optional_rules
/usr/share/modsecurity-crs/experimental_rules

Симлинки должны быть созданы внутри каталога activated_rules для их активации. Давайте активируем правила SQL-инъекций.

cd /usr/share/modsecurity-crs/activated_rules/
ln -s /usr/share/modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf .

Чтобы правила вступили в силу, необходимо перезагрузить Apache.

service apache2 reload

Теперь откройте страницу входа, которую мы создали ранее, и попробуйте использовать запрос SQL-инъекции в поле имени пользователя. Если вы изменили директиву SecRuleEngine на On, вы увидите ошибку 403 Forbidden. Если оставить параметр DetectionOnly, внедрение будет успешным, но попытка будет зарегистрирована в файле modsec_audit.log.

Написание собственных правил mod_security

В этом разделе мы создадим цепочку правил, которая блокирует запрос, если определенные «спамные» слова вводятся в HTML-форму. Во-первых, мы создадим PHP-скрипт, который получает ввод из текстового поля и отображает его обратно в Пользователь.

/var/www/form.php

<html>
    <body>
        <?php
            if(isset($_POST['data']))
                echo $_POST['data'];
            else
            {
        ?>
                <form method="post" action="">
                        Enter something here:<textarea name="data"></textarea>
                        <input type="submit"/>
                </form>
        <?php
            }
        ?>
    </body>
</html>

Пользовательские правила могут быть добавлены в любой из файлов конфигурации или помещены в каталоги modsecurity. Мы поместим наши правила в отдельный новый файл.

nano /etc/modsecurity/modsecurity_custom_rules.conf

Добавьте в этот файл следующее:

SecRule REQUEST_FILENAME "form.php" "id:'400001',chain,deny,log,msg:'Spam detected'"
SecRule REQUEST_METHOD "POST" chain
SecRule REQUEST_BODY "@rx (?i:(pills|insurance|rolex))"

Сохраните файл и перезагрузите Apache. Откройте http://yourwebsite.com/form.php в браузере и введите текст, содержащий любое из этих слов: таблетки, страхование, ролекс.

Вы увидите либо страницу 403 и запись в журнале, либо только запись в журнале, основанную на настройке SecRuleEngine. Синтаксис для SecRule:

SecRule VARIABLES OPERATOR [ACTIONS]

Здесь мы использовали цепочку действий для сопоставления переменных REQUEST_FILENAME с form.php, REQUEST_METHOD с POST и REQUEST_BODY с регулярным выражением (@rx) string (pills|insurance|rolex) . ?i: соответствует регистру. При успешном совпадении всех этих трех правил ДЕЙСТВИЕ заключается в отклонении и регистрации с сообщением \Обнаружен спам. Действие chain имитирует логическое И для соответствия всем трем правилам.

Исключение хостов и каталогов

Иногда имеет смысл исключить конкретный каталог или доменное имя, если оно работает с таким приложением, как phpMyAdmin, в качестве modsecurity и будет блокировать SQL-запросы. Также лучше исключить серверные части администрирования приложений CMS, таких как WordPress.

Чтобы отключить modsecurity для полного виртуального хоста, поместите следующее

<IfModule security2_module>
    SecRuleEngine Off
</IfModule>

внутри раздела .

Для определенного каталога:

<Directory "/var/www/wp-admin">
    <IfModule security2_module>
        SecRuleEngine Off
    </IfModule>
</Directory>

Если вы не хотите полностью отключать modsecurity, используйте директиву SecRuleRemoveById, чтобы удалить определенное правило или цепочку правил, указав его идентификатор.

<LocationMatch "/wp-admin/update.php">
    <IfModule security2_module>
        SecRuleRemoveById 981173
    </IfModule>
</LocationMatch>

Дальнейшее чтение

Официальная документация по модбезопасности https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual

Прислано: Джесин А