Ограничить интенсивность ответов response rate limiting на dns сервере

Обновлено: 02.07.2024

Rate limit можно использовать для усиления безопасности. Например, замедлив перебор паролей для злоумышленника, или для предотвращения DDoS-атаки, снизив количество входящих запросов до типичных для пользователей значений. И тем временем определять по логам атакуемые URL. Также можно предотвратить перегрузку вышестоящих серверов (upstream) во время внезапного наплыва пользователей на сайт.

Как лимиты вообще работают?

Схематичное изображение Windows специально для CoolAdmin Схематичное изображение Windows специально для CoolAdmin

Ограничения запросов в Nginx используют алгоритм "дырявого ведра", широко используемый, чтобы справится со всплесками трафика, когда ширина канала ограничена. Дырявое ведро - хорошая аналогия, ведь, из него вода медленно вытекает сквозь дырки, и оно может переполнится, если добавлять воду слишком быстро. В терминах обработки запросов, вода - это входящий трафик, а ведро - очередь запросов на обработку FIFO-алгоритмом. Протекающая сквозь ведро вода - это запросы, переданные на обработку, а всё, что проливается через край - отклонённые запросы пользователей.

Простая настройка Rate Limit

Ограничения настраиваются при помощи двух директив, limit_req_zone и limit_req .

Рассмотрим простой пример:

В этом примере директива limit_req_zone описывает лимиты, которые далее используются для ограничения числа пользовательских запросов в локации /cooladmin/ при помощи limit_req .

  • Key – характеристика запросов для их группировки. В примере выше используется системная переменная $binary_remote_addr, которая содержит бинарные представления IP-адресов пользователей. Это означает, что лимиты из третьего параметра будут применяться к каждому уникальному IP-адресу клиента из запроса. В примере мы используем переменную $binary_remote_addr , поскольку она занимает меньше места в памяти, чем её строковая альтернатива $remote_addr.
  • Zone – зона разделяемой памяти, которая используется для хранения состояний IP-адресов и количества их обращений к URL-адресам. Эта память является общей для всех процессов Nginx. Следует отнестись к настройке этого параметра с особым вниманием (см. ниже). Параметр состоит из двух частей: названия зоны zone и объема памяти, после двоеточия. Сведения о состоянии около 16 000 IP-адресов занимают 1 мегабайт, так что в нашей зоне можно хранить около 160 000 записей.
  • Rate задаёт максимальное количество запросов. В примере выше будет принято 10 запросов в секунду. На самом деле, Nginx измеряет количество запросов каждую миллисекунду, поэтому такой лимит означает 1 запрос каждые 100 миллисекунд. Поскольку мы не настраивали всплески (bursts) , каждый следующий запрос, пришедший быстрее, чем через 100 мс после предыдущего, будет отброшен.

Закрепим. Директива limit_req_zone задаёт параметры лимитов и общей памяти, но не управляет применением самих лимитов к запросам. Для окончательной настройки необходимо добавить в блоки location или server директиву limit_req. Выше мы применили лимиты для локации /cooladmin/ в блоке server нашей конфигурации. Тем самым мы ограничили число запросов с уникального IP-адреса клиента одним, сделанным не ранее чем 100 миллисекунд после предыдущего.

Обработка очередей и всплесков

Что же будет, если в нашей конфигурации пользователь отправит 2 запроса к нашему серверу за 100 мс? Сервер вернёт код 503 для второго запроса. Это может оказаться не очень удачным решением, ведь в реальности наши приложения способны обрабатывать такие всплески. Необходимо настроить буфер для входящих запросов. За эту настройку отвечает параметр burst в директиве limit_req. Посмотрим на примере:

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

Параметр burst настраивает количество запросов, которые пользователь может сделать прежде, чем лимиты будут применены и Nginx начнёт отбрасывать запросы.

Очереди без задержек

В конфигурациях с простым использованием burst есть недостаток. Они обеспечивают сервер плавным потоком трафика, но слишком медлительны для пользователя. Так в примере выше, обработка 20 пакетов от пользователя занимает 2 секунды (Карл!) . Если вам не подходит такое поведение, добавьте параметр nodelay вместе с burst:

С параметром nodelay Nginx по-прежнему выделяет очередь для каждого потока запросов, но не делает паузы в отправках запросов из очереди. Вместо этого запросы пересылаются на обработку как только возможно, а очистка слотов в очереди происходит как и выше (да-да, те самые 1 раз в 100 миллисекунд) .

Теперь предположим, что к нам поступает 21 запрос с одного IP-адреса одновременно. Nginx незамедлительно отправляет все эти запросы в обработку, и начинает освобождать очередь, очищая 1 слот каждые 100 миллисекунд. Если мы получили 25 запросов от одного IP адреса, то четыре из них отклоняются со статусом 503, а остальные отправляются в обработку.

Теперь предположим, что через 101 миллисекунду после первой порции запросов отправляется еще 20 запросов одновременно. Свободен только 1 слот в очереди, поэтому Nginx передаёт в обработку только один запрос, а остальные 19 отклоняет с кодом 503. Если спустя 501 миллисекунду пришло ещё 20 новых запросов, то в очереди появилось 5 свободных слотов, потому 5 запросов будут обработаны, а остальные 15 отклонены.

Хозяйке на заметку: Для большинства инсталляций разработчики Nginx рекомендуют использовать burst и nodelay совместно. Cooladmin присоединяется к рекомендации.

Примеры расширенных конфигураций

Комбинируя базовые ограничения скорости с другими функциями Nginx можно реализовать более тонкие ограничения трафика.

Белые списки

Например, мы можем наложить ограничения на количество обращений к серверу со всех IP-адресов, кроме внесённых в белый список.

geo $cooladmin default 1;
10.0.0.0/8 0;
192.168.0.0/24 0;
>
map $cooladmin $cooladmin_key 0 "";
1 $binary_remote_addr;
>

limit_req_zone $cooladmin_key zone=cool_admin_zone:10m rate=5r/s;

server location / limit_req zone=cool_admin_zone burst=10 nodelay;

В этом примере мы используем директивы geo и map . Блок geo устанавливает значение 0 адресам из белого списка и 1 - всем остальным (по умолчанию) . Затем мы используем map для назначения лимитов:

  • Если $cooladmin равен 0, то в $сooladmin_key будет записана пустая строка.
  • Если в $cooladmin записано 1, $cooladmin_key заполнится как адрес клиента в бинарном формате (используйте именно бинарный формат, экономьте память).

Таким образом, мы обрабатываем одновременно адреса из белого списка и адреса клиентов. Для адресов из белого списка переменная $cooladmin_key будет содержать пустую строку, и директива limit_req_zone для них применена не будет. Как следствие, на адреса из сетей 10.0.0.0/8 и 192.168.0.0/24 не будет наложено ограничений. Для адресов, не входящих в белый список, будет применён лимит в 5 запросов в секунду (или 1 запрос в 200 миллисекунд).

Такой лимит мы применили к корневой "/" локации сервера. Ещё мы настроили возможность всплеска до 10 дополнительных запросов, которые будут обработаны так быстро, как это позволит наш сервер, без дополнительных задержек, так как используется nodelay.

Использование нескольких ограничений в одной локации

Вы можете использовать несколько директив limit_req в одной локации вашего сервера. В таком случае применяться будет только наиболее строгий лимит. Например, если несколько ограничений вводят задержку на входящие запросы, будет использована самая долгая. Если несколько директив разрешают запрос, а одна директива его отклоняет - запрос будет отклонён .

Расширим предыдущий пример, введём дополнительные лимиты для адресов из белого списка:

Адреса из белого списка не попадают под первый лимит cooladmin_zone, но попадают под второй cooladmin_zone_wl и к ним будет применяться ограничение в 15 запросов в секунду (или 1 запрос в 66 миллисекунд). Для всех остальных адресов, по прежнему, применяется лимит в пять запросов в секунду.

В обоих случаях мы дополнительно настроили поддержку всплеска и отключили задержку на перенаправление пакетов в обработку.

Настройка связанных функций

Логирование

По умолчанию лог Nginx будет содержать отложенные или отброшенные лимитами записи в формате:

Поля этого лога:

По умолчанию лог отклонённых запросов будет располагаться на уровне error, и будет показан в топике [error]. Лог задержанных запросов будет находится на другом уровне, в info по умолчанию. Чтобы поменять такое поведение, используйте директиву limit_req_log_level . В примере ниже мы помещаем лог отклонённых запросов на уровень warn:

Коды ошибок, возвращаемые клиенту

По умолчанию Nginx возвращает код 503 (Service Temporarily Unavailable ), если клиент превысил допустимые лимиты. Используйте директиву limit_req_status , чтобы изменить код на другой. Например, на 444 - "Закрытие соединения без передачи заголовка ответа", нестандартный код:

location /cooladmin/ limit_req zone=coollimit burst=20 nodelay;
limit_req_status 444;
>

Блокирование доступа к локации

Если вам необходимо запретить доступ к определённой локации, используйте директиву deny совместно с параметром all:

Заключение

Этот перевод подготовлен специально для канала ( угадайте какого ) . Надеюсь, статья и её перевод окажутся вам полезны, и помогут настроить веб-сервер правильно.

I would like to know benefits with response rate limiting? Is this option good way of securing DNS and when should we use it?

Ответы

DNS clients and DNS servers are configured in such a way that when a DNS client requests an address it will put the result that it gets back from a DNS server in its cache for the time to live period of the record. Maybe it gets reverted, maybe that cache gets flushed so maybe it might need to request the same record again but what a DNS client shouldn’t be doing is it shouldn’t be repeatedly asking for the same record in a very short period of time.
So what response rate limiting or RRL does is, it allows you to configure how a DNS server will respond in the event that a specific client or computers from a specifically defined subnet seem to be frequently requesting the same record over a short period of time. RRL is not the only security option in DNS and you should take a look at DNSSEC, disable recursion, secure dynamic updates etc. it all depends on your requirements.

------------------------------------------------------------------------------------------------------------
If you found this post helpful, please give it a "Helpful" vote.
Please remember to mark the replies as answers if they help.

Yes they are still valid but you don't need to modify those. They are enabled by default. Server Cache Locking is already at 100 so no need to change that and socket pool have 2500 ports by default which is enough so no need to change it. RRL is optional feature and it is disabled because it is you who decide if you need it or not.

------------------------------------------------------------------------------------------------------------
If you found this post helpful, please give it a "Helpful" vote.
Please remember to mark the replies as answers if they help.

When you enable it you can modify it so that policy fits your organization and/or if it is ok you can use default settings. Just to point that ResponsesPerSec –> This is the maximum number of times a server will send the same response per second to clients on a defined subnet. The default is 5 (responses per sec is what triggers the policy)

Check this link to see what those options mean

------------------------------------------------------------------------------------------------------------
If you found this post helpful, please give it a "Helpful" vote.
Please remember to mark the replies as answers if they help.

Об атаках этого типа было известно еще в 2006 году, но сегодня это обретает масштабы бедствия.

Вы можете наблюдать неоправданно значительный исходящий трафик udp пакетов.

Или утилитой iptraf:


Решение:

Обновление пакетов

Обновите bind. Старые версии более подвержены уязвимости и имеют еще несколько дырок кроме этой.

Для Centos:

Для Debian (Ubuntu):

Проверка рекурсии

Для проверки рекурсии вы должны запросить у вашего сервера сведения о чужом домене:

Команда должна выполнятся извне, для таких запросов, выполняемых непосредственно на вашем сервере, рекурсия должна выполняться.

Ответ защищенного сервера (не поддерживающего рекурсию):

Если ваш сервер выдаст вам подробную информацию о домене, то ваш сервер уязвим. Рекурсию надо отключить.

Если в указанных командах указать имя ваших доменов которые прописаны на этом сервере, то вы должны получить подробный ответ.


Отключение рекурсии

На Debian (Ubuntu): /etc/bind/named.conf.options

И в самый верх файла /etc/named.conf (CentOS ):

Или в существующий блок значений options файла /etc/bind/named.conf.options (Debian) добавляем следующее:

Затем перезапускаем демон named (CentOS):

Проверка

И снова следует проверить работу вашей службы DNS и доступность рекурсии.

Через некоторое время проверьте как изменился трафик на вашем сервере в статистике панели управления виртуальным сервером.


Как видите хотя трафик был относительно небольшой, но огромное количество мелких UDP пакетов создавало загрузку (Load Average) этого сервера при минимальном количестве клиентов на уровне 30 единиц.

Отключение рекурсии - минимально необходимое действие. Для усиления защиты используйте методики описанные в статьях по ссылкам внизу. Но следует знать, что использование этих методик требует специальных знаний и опыта.

Бездумное повторение описанных действий может привести ваш сервер к неработоспособности.


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

Как известно, рекомендуется поднимать минимум две днс-ки в разных подсетях класса C, с этим проблем у меня не возникло, т.к. у меня этих подсетей упаковки и небольшая ведерка, но чертик кроется в деталях. Если упадет вся хостинг инфраструктура, инфраструктура днс должна хотя-бы частично выжать, это и есть предпосыл который изначально закладывался в идею размещения на разных подсетях, но о нем как-то все дружно забывают. Но я то помню! По этому было решено две днс-ки повесить на два собственных разных сервера, а третью разместить на арендованном сервере далеко за пределами моей инфраструктуры.

Поскольку инфраструктура у меня не большая и запросов к DNS-кам немного, то для каждого сервера кластера я выделил по одной виртуалки 2vCPU, 1GB RAM, 5GB HDD.

Если с установкой проблем не возникает, обычно, поскольку любая адекватная ось умеет делать apt install bind9 То вот с настройкой некоторые путаются, ща разжуем!

Обязательно надо на картинке показать что дает RRL(Response Rate Limiting) которому посвящена большая часть конфига.


Причем заметьте серверам разрешено обслуживать рекурсивные запросы из своих подсетей, это значит что мы полностью отвязываемся от инфраструктуры датацентра, и можем со своих серверов все запросы к DNS обрабатывать сами. Не все знают, что если в системе где есть bind9 не указано вышестоящих днс-ок (форвардеров), бинд начинает сам все резолвить, проходя трассу от корневых днс-ок до конечных обслуживающих чужие зоны. Но я рекомендую как минимум на одном слейве отключать такую возможность и использовать его только как Authoritative DNS.

Я реализовал так:

На мастере был размещен скрипт:

Его суть проста как 2 копейки!

  • Сканируем папку зон master_zones
  • При нахождении файлов зон принимаем имя файла за имя зоны.
  • Проверяем файлы зон на ошибки и приводим их формат к установленному по дефолту.
  • Генерируем конфиг мастера и конфиг слейва.
  • Загружаем на слейвы конфиги.
  • Перезагружаем конфигурации.

Не забываем конечно-же заинклюдить в конфигах наш автогенерируемый конфиг файл:

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

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

Читайте также: