Как стать автором
Обновить
0
Pentestit
Информационная безопасность

Что нам стоит WAF настроить

Время на прочтение 11 мин
Количество просмотров 12K


Занимаясь разработкой или обслуживанием веб-приложений, в какой-то момент времени приходится сталкиваться с необходимостью использовать WAF (Web Application Firewall). Если опыта работы с такого класса решением у вас нет или устали от постоянных ложных срабатываний, я расскажу, как упростить задачу, а также поделюсь советами и фишками. В качестве инструмента будем использовать Nemesida WAF Free — бесплатную версию Nemesida WAF.

Визуализация, или начнем с конца


Наблюдать за работой Nemesida WAF Free можно через браузер, поэтому после недолгой настройки системы мы получим доступ к веб-интерфейсу, в котором будет доступна информация по заблокированным атакам, причинах блокировки, информации об IP-адресах и т.д. Кроме этого появятся разделы со сводной статистикой в виде графиков, диаграмм и данными по трафику от модуля VTS (если он используется).



Демонстрационный стенд: demo.lk.nemesida-security.com (demo@pentestit.ru / pentestit)



Приступаем к установке.

Установка Nemesida WAF Free


Несмотря на то, что бесплатная версия — ответвление полноценной, она содержит большой набор возможностей для выявления, блокирования и визуализации атак на веб-приложения. Под веб-приложением подразумеваем все, что построено на протоколе HTTP: сайты, личные кабинеты, интернет-магазины, площадки для обучения, API и все остальное.

В предыдущем абзаце я специально разделил функционал блокирования атак на выявление и блокирование, поскольку есть 2 (даже три) режима работы продукта: IDS, IPS и PseudoIDS (режим LM).

Режим IDS


IDS режим позволяет использовать WAF на копии трафика, выявляя, но не блокируя атаки. Такой режим работы полезен, например, для первичного запуска или для пассивного мониторинга, чтобы исключить любое блокирование запросов или увеличение, пусть и незначительное, времени отклика. Для примера настройки будем использовать Nginx для передающего сервера (хотя можно использовать любой другой, например, Apache2 или IIS).

Настройка передающего сервера:

location / {
    mirror /mirror;
    ...
}

location = /mirror {
    internal;
    proxy_pass http://192.168.0.1$request_uri;
}
(вместо 192.168.0.1 необходимо указать адрес сервера с установленным Nemesida WAF)

После внесения изменений и перезапуска веб-сервера, поступающие на этот сервер запросы будут транслироваться на сервер 192.168.0.1 с установленным Nemesida WAF (его настройка проста и будет описана ниже). Такая схема работы позволяет мониторить атаки без их блокирования, но в то же время, без воздействия на основной сервер.

Режим IPS и PseudoIDS


Остальные 2 режима работы предполагают использование WAF «вразрез», при этом в режиме IPS выявленные инциденты безопасности блокируются, в режиме PseudoIDS — фиксируются, но не блокируются. Последний режим удобен тем, что переключение между этими двумя режими происходит с помощью простых опций: возможность перевода в режим PseudoIDS как по имени сервера (опция nwaf_host_lm), так и по IP-адресу клиента (опция nwaf_ip_lm).

Вообще, в Nemesida WAF Free предусмотрено множество параметров для «тонкой» настройки системы: гибкий функционал создания собственных правил блокировок и исключений, возможность добавлять IP клиента в «список исключений», опция настройка бана для всех и для каждого отдельного виртуального хоста и т.д. Всем этим хозяйством можно управлять через конфигурационный файл в бесплатной версии, а в полноценной — еще и через вызовы API.

Вернемся к процедуре установки. Nemesida WAF представлен в виде нескольких компонентов:

  • Динамический модуль для Nginx
  • Nemesida WAF API (принимает события от Nemesida WAF и помещает их в Postgres для последующего вывода в ЛК или интеграции с SIEM-системами)
  • Личный кабинет (веб-интерфейс для мониторинга за инцидентами)
  • Модуль машинного обучения Nemesida AI
  • Сканер уязвимостей Nemesida WAF Scanner
  • Nemesida WAF Signtest — веб-интерфейс для управления модулем машинного обучения

В Nemesida WAF Free нам потребуются только первые три — сам динамический модуль, Nemesida WAF API и Личный кабинет. Все компоненты доступны в виде установочных дистрибутивов и позволяют подключать Nemesida WAF к уже установленному экземпляру Nginx, начиная с версии 1.12 (поддерживаются Stable, Mainline и Plus версии Nginx).

Динамический модуль Nemesida WAF


Для тех, кто устанавливает дистрибутив не в первый раз, процесс установки и запуска динамического модуля занимает примерно 5-10 минут. Динамический модуль Nemesida WAF можно подключить к уже установленному Nginx (или скомпилированному из исходников с собственными модулями).

Репозитории Nemesida WAF доступны для следующих ОС: Debian 9/10, Ubuntu 16.04/18.04/20.04, Centos 7/8. На Youtube-канале опубликованы видео-инструкции по установке и первичной настройке компонентов. Рекомендуем ознакомиться с одной из них, но установку и настройку советуем производить по документации на основном сайте, поскольку некоторые параметры могут устаревать, другие — добавляться.

Установка динамического модуля Nemesida WAF (видео)

После того, как Nginx будет настроен, подключите соотвествующий вашей ОС репозиторий Nemesida WAF и приступайте к установке. Обновление продукта производится также из репозитория. Инструкция по установке доступна по ссылке: waf.pentestit.ru/about/2511.

Nemesida WAF API и Личный кабинет


После того, как динамический модуль будет установлен и запущен, пора переходить к установке оставшихся двух компонентов: Nemesida WAF API и Личный кабинет.

Nemesida WAF API представлен в виде API, написанного с использованием Flask, и предназначен для приема событий от Nemesida WAF, Nemesida WAF Scanner и Nemesida AI с последующим помещением этих событий в БД. В качестве СУБД используется PostgreSQL. В бесплатной версии Nemesida WAF в БД будут передаваться только информация о заблокированных запросах.

После того, как Nemesida WAF API будет настроен и подключен к PostgreSQL, пора приступать к запуску Личного кабинета. Согласно документации производим установку, настройку, выполняем миграцию, указываем пользователя и пароль для входа.

По опыту установка двух последних компонентов вызывает больше затруднений (обычно пропускаются какие-то шаги, например, забывают сделать миграцию или разрешить подключение к Postgres), поэтому для быстрого старта мы подготовили Virtual Appliance (виртуальный диск с Debian 10 и компонентами Nemesida WAF, 3GB до распаковки), а также сделали 2 Docker-образа: для динамического модуля и для Nemesida WAF API/Личного кабинета.

Ну что, самая скучная часть позади, теперь можем проверить WAF в действии.

Первый hack


Чтобы проверить работу уже настроенного WAF, не обязательно вспоминать различные вариации атак. Мы создали тестовую сигнатуру, которая позволит проверить, работает ли Nemesida WAF и отображаются ли заблокированные атаки в ЛК. Актуальный набор используемых сигнатур всегда можно посмотреть на rlinfo.nemesida-security.com.

Отправляем запрос (я это сделал через консоль, но лучше делать через браузер для наглядности):

curl --noproxy '*' example.com/nwaftest

или, если хочется что-то более приближенное к реальности:

curl --noproxy '*' example.com/?cmd=;+cat+/etc/passwd

В ответ получаем код ответа 403:

<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

А в ЛК через несколько секунд должна появиться атака:



Если запрос не заблокировался — WAF некорректно подключен или настроен (возможно, адрес или хост добавлен в WL/LM), если блокирование запроса произошло, но в ЛК информации нет — проверьте корректность настройки взаимодействия с Nemesida WAF API и ЛК. В любом случае, всегда можно задать вопрос на форуме.

Кастомная 403 страница


По умолчанию 403 страница (страница с 403 кодом ответа) невзрачна и скупа на информацию. Nemesida WAF в связке с Nginx позволяет ее сделать красивой и более информативной.

Чтобы ваш сервер отдавал такую страницу, необходимо:

1. Создать файл конфигурации для кастомных страниц (например, в /etc/nginx/snippets/custom_pages.conf);

Добавить необходимые параметры в Nginx
## Error pages
error_page      403 405 = 222 /403.html;

## Locations
location /403.html {

        internal;
        root /var/www/custom_pages/;
        proxy_no_cache 1;
        proxy_cache_bypass 1;

        add_header X-Request-ID $request_id always;
        add_header Host $host always;
        add_header X-Remote-IP $remote_addr always;
        add_header NemesidaWAF-BT $nwaf_block_type always;

}


Описание:


error_page 403 405 = 222 /403.html; — задаем кастомный 222 код ответа для кодов ответа 403 и 405 и возвращаем локацию /403.html;

Определяем локацию /403.html как внутреннюю (то есть если обратиться к ней example.com/403.html — она не будет доступна), добавляя специальные заголовки для вывода ID запроса ($request_id), виртуального хоста ($host), к которому обращаемся, IP посетителя ($remote_addr) и реакцию (причину блокировки) Nemesida WAF ($nwaf_block_type). У Nemesida WAF есть несколько типов блокировки, например, 1 и 2 — запрос заблокирован сигнатурным анализом, 3 — модулем машинного обучения, 4 — антивирусом и т.д.




2. Подключить созданный файл:

Подключить созданный файл к конфигурации Nginx
Пример подключения файла конфигурации кастомных страниц в файле с виртуальным хостом (например, в /etc/nginx/conf.d/example.com.conf):

server {
        ...
        ## Custom pages
        include                 snippets/custom_pages.conf;
       ....
}


3. Создать кастомную страницу (например, /var/www/custom_pages/403.html) следующего содержания (для примера):

Пример кастомной страницы 403
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <meta http-equiv="Cache-Control" content="no-cache">
    <meta http-equiv="refresh" content="7; URL=/" />
    <style type="text/css">
        .error {color:#000; font-family:Arial, sans-serif; text-align: center; position: absolute; top: 50%; left: 50%; -moz-transform: translateX(-50%) translateY(-50%); -webkit-transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%);}
        .error-fon {font-weight:bold; color:#d0e3f7;}
        .error-text-top {font-size:16px; color:#434141}
        hr { display: block; height: 10px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
    </style>
    <title>403 Access denied</title>
</head>
<body>
<div class="error">
    <div class="error-fon">
        <font style="font-size:240px;">403</font>
        <br>
        <font style="font-size:40px;">ACCESS IS BLOCKED</font>
    </div>
    <br>
    <div class="error-text-wrap">
        <div class="error-text-top">
            <p>
            <hr>
            <p style="text-align: justify;">

              Suspicious activity. If the request is blocked by mistake, please email us at <a href="mailto:blocked@example.com">blocked@example.com</a> and  be sure to include technical information below (domain, IP, request ID), or try again in 5 minutes.

              <br><br>

              Подозрительная активность. Если запрос заблокирован по ошибке, пожалуйста, напишите нам на <a href="mailto:blocked@example.com">blocked@example.com</a>, обязательно указав техническую информацию ниже (domain, IP, request ID), или повторите попытку через 5 минут.

            </p>
	    <hr>
            <table style="text-align: left; margin: auto">
                <tr>
                    <td>
                        <code style="font-size:14px;"> Domain:</code>
                    </td>
                    <td>
                        <code style="font-size:14px;"> <span id="domain">-</span> </code>
                    </td>
                </tr>
                <tr>
                    <td>
                        <code style="font-size:14px;"> IP address:</code>
                    </td>
                    <td>
                        <code style="font-size:14px;"> <span id="ip">-</span> </code>
                    </td>
                </tr>
                <tr>
                    <td>
                        <code style="font-size:14px;"> Request ID:</code>
                    </td>
                    <td>
                        <code style="font-size:14px;"> <span id="id">-</span> </code>
                    </td>
                </tr>
            </table>
            </p>
        </div>
        <script type="application/javascript">
            function replace() {
                window.location.replace('/');
            }
            const req = new XMLHttpRequest();
            req.open('GET', document.location, false);
            req.send(null);
            const req_id = req.getResponseHeader('x-request-id');
            const req_domain = req.getResponseHeader('host');
            let req_ip = req.getResponseHeader('x-remote-ip');
            const req_bt = req.getResponseHeader('nemesidawaf-bt');
            if (req_bt == 6)
            {
                req_ip = req_ip  + " (banned)";
            }
            if (req_bt ==7)
            {
                req_ip = req_ip  + " (banned, bruteforce)";
            }
            document.getElementById('domain').innerHTML = req_domain;
            document.getElementById('ip').innerHTML = req_ip;
            document.getElementById('id').innerHTML = req_id;
            if (req_bt != 6 & req_bt !=7)
            {
                setTimeout(replace,3000);
            }
        </script>
    </div>
</div>
</body>
</html>


После перезапуска Nginx (с установленным Nemesida WAF) все страницы, имеющие код ответа 403 и 405, будут выглядеть следующим образом:



При этом кастомная страница будет обновляться каждые 7 секунд, и если IP клиента не будет забанен, то возвратится корневая страница сайта.

Автоматический бан


Вы, наверняка, слышали или даже используете системы автоматического бана вроде Fail2ban и знаете об их достоинствах и недостатках. В Nemesida WAF используется встроенный и простой в настройке механизм бана, позволяющий устанавливать произвольный период блокировки для виртуальных хостов сервера. Блокирование происходит по IP-адресу, а для управления доступны следующие опции:

  • Количество атак с IP, которое приводит к блокированию;
  • Период блокирования;
  • Виртуальный хост, на который направлены атаки (опционально).

Управление параметром автоматического блокирование осуществляется с помощью параметра nwaf_limit, доступного в файле /etc/nginx/nwaf/conf/global/nwaf.conf. Использование параметра будет полезным в случаях, когда сайт подвергается сканированию на уязвимости или при попытках раскрутить обнаруженную уязвимость.

Списки исключений (While lists)


Работа WAF построена по принципу анализа поступающих на сервер запросов и реакции в случаях, когда в них содержатся признаки атаки или аномалий. Применение алгоритмов машинного обучения вкупе с улучшенной технологией нормализации в полноценной версии Nemesida WAF позволяет выявлять такие атаки точно и с ультра-минимальным количеством ложных срабатываний (порядка 0.01%), но в бесплатной версии для снижения количества ложных срабатываний мы упираемся в ограничения, заложенные в архитектуру сигнатурного анализа. Таким образом, бесплатная версия имеет большее количество ложных срабатываний, и для решения этой проблемы приходится использовать списки исключений (или «white lists»). В Nemesida WAF также доступно создание правил исключений.

Чаще всего ложные срабатывания появляются, когда администратор/модератор веб-ресурса производит обновление или изменение через веб-интерфейс, передавая в теле запроса нетипичные для пользователя конструкции:
...
$html = curl_exec($ch);
curl_close($ch);
return json_decode($html,true);
...


Легитимный запрос будет заблокирован, поскольку содержит вхождение функции json_decode(), при этом такие запросы не характерны для обычных посетителей веб-ресурса.

В случаях, когда администраторы приложений не могут взаимодействовать с ним в обход WAF, можно добавить IP-адрес, с которого они обращаются к ресурсу, в список исключений или же перевести адрес в режим PseudoIDS (опция nwaf_ip_lm) для фиксации событий без блокирования. Но с такими действиями всегда нужно быть достаточно осторожными.

Кстати, Nemesida WAF позволяет добавлять не только IP-адреса, но и подсети, если в этом появляется необходимость.

Заключение


Независимо от того, насколько качественно на ваш взгляд написан код, применяются в нем функции фильтрации ввода и специальные фреймворки вроде HTML Purifier, призванные удалять если не весь вредоносный код, то большую его часть, необходимо использовать WAF для повышения уровня защищенности.

Если использовать WAF предполагается впервые, или вы устали от бесконечных добавлений правил исключения, рекомендуем попробовать бесплатную Nemesida WAF Free. Для профессионального использования (блокирование сложных атак, атак методом перебора, СМС флуда; поиск уязвимостей; наличие системы виртуального патчинга и т.д.) требуется полноценная версия Nemesida WAF с модулем машинного обучения и сканером уязвимостей. Тем не менее, для большинства нецелевых атак и массовых сканирований Nemesida WAF Free будет хорошим и удобным инструментом.

В статье я постарался раскрыть ситуации, чаще других возникающие при использовании решений такого класса. Буду рад, если в комментариях вы вспомните еще.
Теги:
Хабы:
+7
Комментарии 6
Комментарии Комментарии 6

Публикации

Информация

Сайт
www.pentestit.ru
Дата регистрации
Дата основания
Численность
11–30 человек
Местоположение
Россия

Истории