Лежим


Заказчик, чьи сайты я поддерживал ранее, обратился с тем, что сайт лежит и отдает 500 ошибку. У него стандартный сайт на ASP.NET WebForms, не скажу, что очень нагруженный, но бывали проблемы с производительностью базы данных (MS SQL Server на отдельном сервере). Недавно сервер БД поменяли и перенесли данные.

Этот сайт не основной бизнес заказчика, поэтому практически не обслуживался. У него не настроено никакого мониторинга  и сбора метрик и вообще за ним особо не следят.

Данные телеметрии


Какие аномалии бросились в глаза:

  1. Процесс w3wp использовал более 50% CPU (обычно сильно меньше).
  2. Количество потоков в этом процесс стабильно прирастало (сайт не успевал обслужить клиентов).
  3. Диск на сервере БД использовался на 100% (Active Time).
  4. Длина очереди обращений к диску с базами проекта была большой (обычно в районе нуля-единиц).
  5. Оперативная память на сервер БД использована полностью.
  6. Профайлер показал, что есть один горячий метод, который ходит в БД.

Тюнинг СУБД


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

Память — сразу стало ясно, что при переносе СУБД забыли ограничить использование оперативной памяти  на новом сервере — ограничиваем. По прошлому опыту этой конфигурации вполне хватало 24Гб (из общих 32).

Проверям джобы — все норм. Запускаем Tuning Advisor и достраиваем недостающие индексы (среди них был и индекс для горячего запроса из профайлера). Выхлоп близок к нулю: сайт лежит.

IIS


Захожу в логи и сразу все становится понятно — DDoS:


Первый раз такая ситуация, неясно кому понадобилось. Запросов стало на порядок больше, что же в логах?

В логах видим около 200 запросов в секунду (обычные пользователи генерят до десяти в минуту по метрике). Все запросы с разных IP, объединяет их только схожий user-agent:
GET 101.200.177.82 WordPress/4.2.2; www.renwenqifei.com;+verifying+pingback+from+37.1.211.155 503
GET 54.69.1.242 WordPress/4.2.10; 54.69.1.242;+verifying+pingback+from+37.1.211.155 503
GET 123.57.33.117 WordPress/4.0; www.phenomenon.net.cn;+verifying+pingback+from+37.1.211.155 503
GET 54.69.236.133 WordPress/4.3.1;+http://www.the-call-button.com;+verifying+pingback+from+37.1.211.155 503
GET 52.19.227.86 WordPress/4.3.6; 52.19.227.86;+verifying+pingback+from+37.1.211.155 503
GET 52.27.233.237 WordPress/4.1.13; 52.27.233.237; verifying+pingback+from+37.1.211.155 503
GET 202.244.241.54 WordPress/3.5.1; www.fm.geidai.ac.jp 503
GET 52.34.12.105 WordPress/4.3.6; 52.34.12.105; verifying+pingback+from+37.1.211.155 503
GET 128.199.195.155 WordPress/4.3.6; www.glamasia.com;+verifying+pingback+from+37.1.211.155 503
GET 61.194.65.94 WordPress/4.2.10; wpwewill.help;+verifying+pingback+from+37.1.211.155 503
GET 23.226.237.2 WordPress/4.3.1; hypergridder.com;+verifying+pingback+from+37.1.211.155 503
GET 104.239.228.203 WordPress/4.2.5; pjtpartners.com;+verifying+pingback+from+37.1.211.155 503
GET 104.239.168.88 WordPress/4.2.10; creatorinitiative.com;+verifying+pingback+from+37.1.211.155 503
GET 166.78.66.195 WordPress/3.6; remote.wisys.com/website 503
GET 212.34.236.214 WordPress/3.5.1; nuevavista.am 503

Это известный тип атаки: WordPress сайт с включенным Pingback (включен по умолчанию), может использоваться в DDOS-атаке на другие сайты. Более подробная статья на Хабре.

Настраиваем фильтр запросов


Есть несколько уровней где можно фильтровать запросы. Первый — это файрвол. Грепаем ip — добавляем их в файрволл, по расписанию собираем вновь появившиеся. Плюсы — отличная скорость, нет мусорных запросов в логах. Минусы — надо писать скрипты и следить.

Второй уровень — сам IIS (из явных минусов — мусорные запросы попадают в логи). Третий уровень — написать модуль и использовать его. Это самый гибкий подход, но трудоемкий и имеет невысокую производительность.

Я остановился на втором уровне из соображений получить решение совершив минимум действий.
У IIS много возможностей по фильтрации запросов. В данном случае подходит Request Filtering. Более подробно об установке и настройке.

Выбираем сайт > Request Filtering > Rules > Add filtering rules

И указываем, что мы хотим отфильтровать все запросы где в Header: User-Agent есть слово WordPress.


Или можно указать соответствующие настройки в файле web.config:

<system.webServer>
    <security>
        <requestFiltering>
            <filteringRules>
                <filteringRule name="ddos" scanUrl="false" scanQueryString="false">
                    <scanHeaders>
                        <clear />
                        <add requestHeader="User-Agent" />
                    </scanHeaders>
                    <denyStrings>
                        <clear />
                        <add string="WordPress" />
                    </denyStrings>
                </filteringRule>
            </filteringRules>
        </requestFiltering>
    </security>
</system.webServer>

Сразу после применения этого фильтра сайт заработал. Все показатели вернулись к норме. Если бы я сразу проверил логи — на все ушло бы менее получаса.

Что еще умеет IIS?


IIS — очень крутой и производительный сервер для веб-приложений. Помимо передачи запроса в управляемую среду он много что умеет делать и по производительности сильно обыгрывает managed-решения.

В разделе Request Filtering вы можете настроить еще много различных фильтров: по методам, сегментам урла, query-параметрам, расширению и т.д. Можно запретить в asp.net проекте специфичные для PHP query-параметры (попытка получить доступ к htaccess или файлу с паролями). Можно запретить злонамеренные запросы, например, содержащие sql-инъекции. Это делается не как защита от этих атак, а в целях экономии ресурса сервера: IIS самостоятельно откинет эти запросы и сделает это быстро с минимальными затратами памяти и процессорного времени.

Еще один механизм называется IP Address and Domain Restrictions. Этот механизм позволяет составлять белые и черные списки IP-адресов для ограничения доступа к сайту. Вы можете заблокировать злобного парсера или наоборот открыть доступ на тестовый сайт или админку только с определенных IP. Более подробно читать в официальной документации.

И третий механизм, который может вам помочь противодействовать ддос-атакам и нежелательным парсерам — Dynamic IP Address Restrictions. 

Не всегда мы можем следить за постоянно меняющимися ip-адресами злоумышленника. Но с помощью этого инструмента мы можем ограничить частоту запросов. Таким образом, IIS на аномально большое количество запросов с одного IP-адреса будет быстро отдавать 403 или 404. Будьте аккуратнее с поисковыми ботами. Официальная документация.

Выводы


Не отключайте логи, настраивайте мониторинг, который явно вас предупредит об аномалиях в показателях. Это можно сделать быстро и недорого, и сэкономит вам время при расследованиях инцидентов. Настройку мониторинга, а также административные и организационные меры противодействия оставим за рамками этой статьи.
Поделиться с друзьями
-->

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


  1. KlimovDm
    30.11.2016 18:25
    +1

    Второй уровень — сам IIS (из явных минусов — мусорные запросы попадают в логи).
    Вот ведь дались вам эти логи :) Из явных минусов — запрос доходит до веб-сервера. И опять таки ручная работа по настройке фильтрации.

    А 200 запросов в секунду, упомянутые вами — это суммарная нагрузка или от одного IP?


    1. GraDea
      30.11.2016 21:17
      +1

      200 в секунду всего. Проблема в том, что главная этого сайта генерит большое количество запросов в БД, а эта БД размещена на относительно медленных дисках. В итоге получалось, что дисковая подсистема на сервере БД стала тонким местом из-за которой в итоге все встало колом.
      По уму надо переписывать главную, кэши и прочее, но проектом никто не хочет заниматься — кое-как работает и ладно.

      Про логи отметил отдельно, потому что люди делают аналитику на логах IIS. И чтобы аналитик или сео-специалист не начали бить тревогу из-за внезапно появившихся 404 ошибок, эти логи надо подчистить сначала.


  1. Photon79
    30.11.2016 21:10
    -2

    200 запросов в секунду и сайт лёг? Это что ж там за хостинг-то?


    1. GraDea
      30.11.2016 21:20

      Ответил выше. Так то пара железных серверов, в том числе хостящих и этот сайт, но не в хостинге дело.


  1. strapony
    04.12.2016 23:23

    CF нельзя ли закрыться просто?


    1. GraDea
      04.12.2016 23:23

      Что такое CF? Не гуглится.


      1. strapony
        05.12.2016 12:51

        1. GraDea
          05.12.2016 13:09

          Сложно и за деньги. Критичность данного сервиса минимальна, атака не серьезна. В данном случае, использование встроенных функций веб-сервера полностью закрыло проблему. Я даже не смотрел — продолжалась ли атака, так как сайт работал хорошо и не генерил лишнюю нагрузку на железо.