В этой статье представлена инструкция по установке динамического модуля ModSecurity на веб-сервер NGINX в качестве межсетевого экрана веб-приложения (WAF). NGINX работает в режиме обратного прокси-сервера. Работу выполнено на дистрибутиве Linux – CentOS 7. Модуль установлено в качестве «динамического», что бы сервис оставался гибким в настройке. Использовано официальное руководство NGINX по установке.


1. Предварительная установка компонентов


Для корректной работы службы необходимо установить дополнительные библиотеки для работы. Библиотеки понадобятся для сборки проекта из исходного кода. Предполагается что у пользователя обновлена система (# yum update).

yum install install -y apt-utils autoconf automake build-essential git libcurl4-openssl-dev libgeoip-dev liblmdb-dev libpcre++-dev libtool libxml2-dev libyajl-dev pkgconf wget zlib1g-dev


2. Начало установки службы



Для того что бы потом не было проблем с запуском службы с помощью команды service nginx start установлена версия из официального репозитория на GitHub.

Создадим файл /etc/yum.repos.d/nginx.repo в который нужно добавить версию дистрибутива. Без указания версии NGINX подтягивается последняя, которую запушили на сайт.

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

Далее просто устанавливаем

yum install nginx

3. Компиляция модуля




Для начала перейдём в соответствующую директорию:

cd /home/user/Downloads 

Скачаем модуль с главной ветки на GitHub:

git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity.git

Далее переходим в папку с межсетевым экраном и компилируем исходный код:


cd ModSecurity
git submodule init
git submodule update
./build.sh
./configure
make
make install

4. Установка коннектора


Для того чтобы вся система была гибкой будет установлено коннектор для соединения NGINX и ModSecurity. Это означает, что модуль не будет зашит в код сервера, а будет лишь динамической составляющей, что позволит его удалить в любой момент, изменить код и тд.

git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git

5. Повторная сборка веб-сервера


Для того что бы NGINX работал с коннектором, к которому будет подключён модуль нужно пересобрать сервер. Для этого сначала узнаем какая версия NGINX установлена:

nginx –v

Вывод должен быть примерно таким (в зависимости от версии)

nginx version: nginx/1.13.7

Далее с официального сайта скачаем соответствующую версию, что бы не было ошибки при запуске службы и компилируем с определённым параметром:


        cd ..
	wget http://nginx.org/download/nginx-1.13.7.tar.gz
	tar zxvf nginx-1.13.7.tar.gz
	cd nginx-1.13.7
	./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
	make modules

Далее копируем файл модуля в папку веб-сервиса:

cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules

Перед первым блоком в /etc/nginx/nginx.conf добавить:

load_module modules/ngx_http_modsecurity_module.so;

6. Файл конфигурации модуля


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


        mkdir /etc/nginx/modsec
	cd /etc/nginx/modsec
	sudo wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
	sudo mv modsecurity.conf-recommended modsecurity.conf


В файле modsecurity.conf заменить SecRuleEngine DetectionOnly на SecRuleEngine On
Далее создадим файл /etc/nginx/modsec/main.conf и додадим в него:

# Include the recommended configuration
		Include /etc/nginx/modsec/modsecurity.conf

7. OWASP rules


Ни для кого не секрет что OWASP – это лидер по вопросам веб-безопасности. У них есть свой рул-сет для данного модуля, который, как и проект, открытый для пользователей. Поэтому установим его как базовый набор правил:


        cd /usr/local
	wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/v3.0.0.tar.gz
	tar -xzvf v3.0.0.tar.gz
	mv owasp-modsecurity-crs-3.0.0 /usr/local
	cd /usr/local/owasp-modsecurity-crs-3.0.0
	cp crs-setup.conf.example crs-setup.conf

В /etc/nginx/modsec/main.conf добавить следующее:

# OWASP CRS v3 rules
Include /usr/local/owasp-modsecurity-crs-3.0.0/crs-setup.conf
Include /usr/local/owasp-modsecurity-crs-3.0.0/rules/*.conf

8. Завершение работы


В файл /etc/nginx/conf.d/proxy.conf добавить

server {
    listen 80;
	modsecurity on;
	modsecurity_rules_file /etc/nginx/modsec/main.conf;

# If you have proxy
    location / {    	
    	proxy_pass http://192.168.x.x;
    }
}

9. Проверка работоспособности


Для проверки компонентов веб-сервиса достаточно его запустить и просмотреть ошибки. Часто потребуется удалить правило, которое отвечает за проверку, где используется другой модуль (GeoIP, например). Поэтому можна смело удалить это правило.

rm /usr/local/owasp-modsecurity-crs-3.0.0/rules/REQUEST-910-IP-REPUTATION.conf

Так же возможна ошибка, связанная с Юникодом. Для того что бы она не мешала работе службы просто закомментируем её в конфигурационном файле (в конце).

#SecUnicodeMapFile unicode.mapping 20127

Для проверки работы сервера используйте утилиту curl. Она покажет, возвращает ли приложение. Если всё правильно вам прийдет оптет с кодом 200 ОК

curl -I 127.0.0.1

Для проверки работы защитных механизмов можно использовать любую, предназначенную для этого утилиту. В качестве рекомендаций предлагается использовать nikto:

nikto -host localhost

Для запуска сервера:

service nginx start

Комментарии (8)


  1. Vasily_T
    22.01.2019 10:58

    Что то у Вас какое то месиво из тэгов в статье,
    и я не очень понял зачем это вообще нужно чтоб NGINX работал в таком режиме?


    1. richard_fender Автор
      22.01.2019 14:13

      Готово, спасибо


    1. richard_fender Автор
      22.01.2019 23:28

      Спасибо за вопрос Vasily_T. Такой режим работы нужен по той причине, что ModSecurity — это модуль и сам по себе работать не может. Конечно же, можно залить и сам сайт на этот NGINX, как этот предлагают в самой компании с помощью коммерческого продукта NGINX Plus. Но перенос сайта на отдельную машину создаст прирост в производительности и в случае взлома не затронет основной ресурс. Такую технологию используют в гос структурах и крупных предприятиях, так как гибкость архитектуры сети определяется ее многослойностью. По этому лучше если каждый элемент будет выполнять только одну функцию. Это позволит повысить безопасность, так как остальные службы будут запрещены из вне и останется только настроить взаимосвязь между 2-мя машинами, которые выполняют только поставленную задачу. Так же на практике такое построение сети будет лучше по той причине, что скорость развертки будет выше. Так как вы используете отдельные ее компоненты. Хочу отметить что особо удобно все это засунуть в отдельные контейнеры (Докер). Это позволит развернуть структуру в 2 клика.


  1. pupsegadm
    22.01.2019 13:39

    автор — поправьте разметку текста


  1. perl_demon
    23.01.2019 10:01

    Вы сначала ставите nginx из репозитория, а потом пересобираете его же из исходных кодов для добавления поддержки ModSecurity. А не возникнут ли проблемы с этим при обновлении системы? Если вдруг в репозитории окажется более новая версия, то система ее обновит и все сломается, насколько я понимаю.


  1. richard_fender Автор
    23.01.2019 10:13

    Это сделано для того чтобы самому не задавать пути при сборке. Тогда все на своем месте. Для неопытных пользователей это будет плюсом. И потом в начале я добавил версию которая должна быть установлена при обновлении Nginx, по этому обновление системы никак не повлияет на работу. Пересобран он просто для подключения модуля, ведь в open source его нет


    1. perl_demon
      23.01.2019 10:20

      … И потом в начале я добавил версию которая должна быть установлена при обновлении Nginx, по этому обновление системы никак не повлияет на работу…

      Вы где-то «залочили» версию Nginx? В статье я этого не увидел.


      1. richard_fender Автор
        23.01.2019 10:26

        Пересмотрел пост. Вы правы, спасибо. Скорее всего ничего не вылетит, но все же для перестраховки лучше залочить версию. Видно я просто забыл за это. Сегодня подправлю это. Я здесь привязал только до версии дистрибутива и забыл сказать в скобках версию nginx