Обеспечение безопасности веб-сайта на базе ОС Linux (в примере будет использован Linux Debian), nginx, naxsi, iptables и fail2ban:

  • nginx — веб-сервер;
  • naxsi — web application firewall;
  • также нам потребуется fail2ban и iptables.

Установка и первичная настройка nginx и naxsi

Компилируем и устанавливаем nginx с модулем naxsi. Я использую следующий скрипт для автоматической компиляции:

# mkdir -p /opt/src/
# nano /opt/src/nginx_compiler.sh

Установим необходимые для сборки пакеты:

# apt-get install git make checkinstall libssl-dev

И запустим скрипт. В его параметр достаточно подставить ссылку на последнюю версию nginx, модуль naxsi подгрузится автоматически.

# chmod +x /opt/src/nginx_compiler.sh
# /opt/src/nginx_compiler.sh http://nginx.org/download/nginx-1.8.0.tar.gz

После компиляции nginx с модулем naxsi необходимо произвести настройку конфигурационного файла nginx и виртуального хоста. Убедимся, что в настройках nginx имеется строка с каталогом размещения виртуальных хостов и правилами WAF, в противном случае добавим эти строки:

# grep 'sites-enabled' /etc/nginx/nginx.conf

# grep '/etc/nginx/naxsi_core.rules' /etc/nginx/nginx.conf

Файл naxsi_core.rules содержит паттерны, по которым и происходит анализ обращений к серверу на предмет атаки. Далее переходим к настройке vhost:

# nano /etc/nginx/sites-enabled/example.com

После перезапуска nginx модуль naxsi будет фиксировать атаки в /var/log/nginx/example.com_error.log. Формат записей атак будет следующего вида:

Атаки фиксируются, но не будут блокироваться до тех пор, пока не будет деактивирован «режим обучения» в файле /etc/nginx/naxsi.rules:

Смысл режима обучения заключается в том, что в отличие от обычного («боевого») режима, атака фиксируется в логе, но блокировака не происходит, в то время как в боевом режиме в случае атаки клиенту отдается страница «/RequestDenied» (при настроках по-умолчанию, секция DeniedUrl файла naxsi.rules). Для деактивации необходимо закоментировать строку «LearningMode;» и перезапустить nginx, но к этому мы вернемся чуть позже. На этом процесс сброки и первичной настройки WAF закончен.

Настройка iptables и fail2ban

iptables в качестве первичной защиты от Dos-атак

Для первичной защиты от Dos-атак ограничим количество одновременных подключений к веб-серверу с одного IP-адреса:

# apt-get install iptables
# iptables -A INPUT -i eth0 -p tcp --syn --dport 80 -m state --state NEW -m recent --update --seconds 1 --hitcount 20 -j REJECT --reject-with tcp-reset
# iptables -A INPUT -i eth0 -p tcp --syn --dport 443 -m state --state NEW -m recent --update --seconds 1 --hitcount 20 -j REJECT --reject-with tcp-reset
# iptables -A INPUT -i eth0 -p tcp -m multiport --dports 80,443 -j ACCEPT

Правила не позволят устанавливать больше 20 соединений в секунду. При желании можно сократить количество соединений, увеличив количество секунд или уменьшив значение hitcount. Для hitcount значение 20 является максимальным.

fail2ban

Сервис fail2ban предназначен для блокирования доступа. Читая лог-файлы других сервисов, fail2ban сверяет их содержимое с правилами, и если события в логах удовлетворяют условию, выполняет заданное администратором действие. В нашем случае мы будем использовать сервис для блокирования доступа с IP адресов, пытающихся атаковать наш веб-сервер. Произведем установку и настройку сервиса:

# apt-get install fail2ban
# nano /etc/fail2ban/jail.conf

Добавим в конфиг секцию nginx-naxsi

Далее произведем настройку фильтра nginx-naxsi:

# nano /etc/fail2ban/filter.d/nginx-naxsi.conf

Готово. Перезапускаем fail2ban.

# service fail2ban restart

Таким образом, fail2ban анализируя error-log nginx, будет искать соотвествие строки:

и в случае обнаружения извлекать IP-адрес. Как только в интервале в 20 секунд количество таких строк составит 10 (для каждого IP-адреса), fail2ban добавит в цепочку iptables на 600 секунд (опция bantime) правило, блокирующее подключение к серверу для данного IP адреса. По умолчанию правило имеет следующий вид:

Информация по забаненным и разбаненным хостам доступна в файле /var/log/fail2ban.log и имеет следующий вид:

Правила блокировки расположены в каталоге /etc/fail2ban/action.d. Система обеспечения безопасности веб-сайта готова, рассмотрим вариант перевода WAF  в «боевой» режим работы.

Настройка white-листов naxsi и отключение режима обучения

В white-листах содержатся исключения для станадртного набора правил (файл naxsi_core.rules). Чтобы понять логику создания исключений, рассмотрим лог атаки:

Запись разделена на секции:

  • ip — IP-адрес клиента;
  • server — доменное имя сервера;
  • uri — идентификатор ресурса;
  • learning — сообщеает, активирован ли режим обучения (0) илинет (1);
  • vers — версия naxsi;
  • total_processed — количество обработанных запросов воркером nginx;
  • total_blocked — количество заблокированных naxsi запросов воркера;
  • block — сообщает, заблокирован запрос (1) или нет (0);
  • cscore0 — тег группы сигнатур, под который попадает атака;
  • score0 — уровень атаки;
  • zone0 — зона, в которой обнаружена атака;
  • id0 — идентификатор сигнатуры, под которое попадает атака;
  • var_name — имя переменной, в которой обнаружена атака.

С первыми семью секциями все понятно, перейдем к тем, что нас интересуют.

CscoreX информирует нас о теге, под который попадает атака. В нашем случае тег $EVADE сообщает о том, что была попытка выполнить обход чего-либо. К примеру, закодировать в UTF-8 вредоносный код. А «X» — сообщает нам о том, что в данном запросе это первая по счету блокировка.

Score0 информирует нас об уровне атаки.  В данном случае она равна 4. Кстати, в файле naxsi.rules, имеющий следующий вид:

указано, при каком уровне должен отрабатывать naxsi.

Zone0 сообщает нам зону, в которой произошло совпадение с сигнатурой. Список зон представлен ниже:

  • ARGS — GET args;
  • HEADERS — HTTP Headers;
  • BODY — POST args;
  • URL — The URL (before ‘?’);
  • FILE_EXT — Filename (in a multipart POST containing a file).

id0 информирует нас об идентификаторе сигнатуры, с которой произошло совпадение. В данном случае 1402 указывает нам на то, что была попытка выполнить попытку передать на сервер данные или файл. Если такой функционал на сайте не реализован, то, соотвественно, такой запрос может позакаться подозрительным.

var_name0 сообщает нам о названии поля заголовка, содержащее подозрительный контент.

Мы без труда можем найти сигнатуру, по которой произошла блокировка. В файле naxsi_core.rules найдем строку, содержащую «id:1402». Вот это правило:

Создадим правило-исключение для данной сигнатуры. К примеру, наш сайт использует форму авторизации и данные передаются через форму, используя заголовок «Content-Type: application/x-www-form-urlencoded». Для создания white-листа необходимо добавить файл исключения в конфиг vhost:

и создать соотвествующий файл:

# nano /etc/nginx/naxsi_rule.wl

следующего содержания:

После перезапуска nginx сигнатура 1402 будет игнорироваться naxsi для текущего виртуального хоста.

Игнорирование сигнатуры #1000 для всех ссылок для GET аргументов ‘foo’

Игнорирование сигнатуры #1000 для GET аргументов ‘foo’ для ссылки ‘/bar’

Игнорирование сигнатуры #1000 для всех GET аргументов для ссылки ‘/bar’

и т.д. Но на практике white-листу naxsi не хватает гибкости — поиска по шаблону. Он отсуствует в готовых сборках nginx-naxsi для Debian (используется устаревшая версия naxsi), но в нашем случае все гораздо лучше. Начиная с версии 0.52 naxsi поддерживает регекспы. Рассмотрим пару примеров:
Игнорирование сигнатуры #1000 во всех GET аргументах, содержащих ‘bla’

Игнорирование сигнатуры #1000 в GET аргументах, имеющих название ‘bla’ :

Игнорирование сигнатуры #1000 во всех GET аргументах, содержащих bla_<цифры> :

P.S.

C подробной документацией naxsi на английском языке можно ознакомиться в wiki.

Парсинг и визуализацию логов naxsi, а также создание white-листов можно осуществлять с помощью утилиты nxapi.

На этом все! Если есть дополнения, замечания, с удовольствием готов обсудить в комментариях или в ЛС.