Web Application Firewall на базе modsecurity v3

    Была мысль написать заметку о настройке modsecurity v3 (https://github.com/SpiderLabs/ModSecurity) в связке с nginx. Есть небольшая книжка как данный софт настраивать, где всё более-менее ясно описано что необходимо сделать, чтобы данная связка заработала. Но жизнь все-таки немного отличается от написанного в книгах.  Оказалось, что modsecurity v3 по факту в производственной среде просто не годен (по состоянию на июль 2020 года). Там встретились настолько детские ошибки, что возникает резонный вопрос - как такой софт можно писать? Я не работал с версией 2 (которая глубоко связана с apache2), но версия 3 произвела печальное впечатление.  Но обо всем по порядку.

   Чтобы начать пользоваться modsecurity + nginx в производственной среде, потребуется:

  • пакетировать библиотеку libmodsecurity (не руками ведь делать на сервере make && make install)
  • собрать nginx с модулем-коннектором modsecurity 

Это всё есть в интернете. Далее вы хотите начать писать какие-нибудь правила. В моем случае хотелось блокировать на некоторый период ip адреса, которые делали некие "плохие" запросы (например перебор популярных URL ).

   Ладно, синтаксис не очень легкий, но сталкиваетесь сразу с тем, что еще много функионала еще не портировано с версии 2 на версию 3. Мне было необходимо, чтобы по истечении времени "плохой" ip адрес удалялся из коллекции. Но все 3 переменные, которые могли бы это сделать автоматически, еще не портированы

https://github.com/SpiderLabs/ModSecurity/issues/1803

https://github.com/SpiderLabs/ModSecurity/issues/1705

https://github.com/SpiderLabs/ModSecurity/issues/1944

    OK, нашли костыльную альтернативу как это сделать. Тесты на дев-сервере прошли успешно. Выкатываем на прод-сервер. То блокирует, то нет. Долго разбираемся почему на тесте работало стабильно, на проде - нет. В итоге создаем issue https://github.com/SpiderLabs/ModSecurity/issues/2262 и в конце получаем отличный ответ:

often the difference between dev and prod is that you'll have a stronger machine and be running more threads. Looks like you figured it out for yourself.

It seems from the latest update you made that you're using the in-memory collection, which as you worked out is not shared between processes, you could instead use LMDB which does use shared memory and should thus give you the consistent results you're looking for.

Согласен, что не полностью прочитал документацию, где в принципе это сказано:

ModSecurity's persistent collections are saved per thread (or process). From time to time the different values from each thread (or process) are merged into a global storage. A simple counter (for instance: IP:counter) will have different values for the different web server "workers", depending on the process that answers the request. That behavior happens in both versions of ModSecurity (2 and 3). But, the time that is expected to merge the collections is higher in ModSecurity version 2. In practical aspect it means that in ModSecurity version 3 the values for the threads should me more precise.

     Но по-моему мнению, пользы от такой реализации - ноль, т.к. никто не гарантирует что "плохой" адрес был заблокирован и мы всегда будем получать плавающее поведение WAF (а вместе с ним и трудность отладки, если заблокировали валидный ip адрес). Да и вообще получается какая-то "дырявая" защита, если бы увидели подобное поведение у iptables - вы бы тоже сильно расстроились?

    OK, вняли совету и собрали modsecurity с поддержкой LMDB. Это позволит хранить коллекции ip адресов в файловой системе сервере и не бояться, что после релоада/перезагрузки  списки адресов очистятся. После внедрения LMDB действительно появилась стабильность в работе софта - никакого плавающего поведения. Но в процессе эксплуатации вылез другой неприятный баг - https://github.com/SpiderLabs/ModSecurity/issues/2354. Данный "баг" окончательно показывает качество данного софта (зачем создавать каждый раз файлы для modsecurity?/зачем их вообще создавать при вызове команды nginx -t?/почему нельзя никак законфигурировать данное поведение?/создались данные файлы - где же теперь modsecurity хранит коллекции заблокированных адресов?).

В итоге - много зря потреченного времени и отказ от внедрения modsecurity на серверах с nginx.

Please publish modules in offcanvas position.