Блокировка нежелательного DNS трафика
У Вас может быть идеально настроено конечное сетевое оборудование, полный порядок в кластерах, могут быть пустыми магистрали и не нагруженное оборудование ядра сети, но если у Вас плохо работает DNS, то Ваши клиенты будут недовольны.
Отсюда следует простой вывод — Ваши рекурсивные DNS сервера должны быть всегда доступны и в состоянии обслужить запросы клиента.
Все статьи о настройке производительного DNS сервера начинаются примерно так: «давайте померяемся различными параметрами различных рекурсивных DNS серверов и выберем из них самый-самый, и будет нам счастье». Могу сказать заранее, счастье таким методом наступит, но не на долго.
Следующим шагом идёт наращивание мощностей самого сервера. Данным методом счастье тоже достигается, но при стабильном росте абонентской базы оно быстро заканчивается.
Вы спросите, какое-же решение задачи существует, точнее, что же делать в данной ситуации?
Ответ прост — необходимо ограничивать количество рекурсивных запросов определённых типов от каждого из наших клиентов.
К огромному сожалению ни в одном из ныне существующих DNS серверов нет средств ограничения количества запросов определённого типа для каждого из рекурсивных клиентов. Мы возложим данную задачу на пакетный фильтр, в приведённых ниже примерах используется iptables.
В большинстве случаев от завирусованных клиентов идет шквал DNS запросов различных типов, огромное количество MX запросов направленных на поиск ip адресов почтовых серверов, запросы типа A для экзотических доменов типа kljhajlhfqweqwe.com или ioweurtisdvfso.org.
По нашим грубым оценкам 3% клиентских машин генерировали более 90% всех DNS запросов.
Простой обзвон клиента зачастую проблему не решает, ибо клиента может и не быть дома, клиент не обладает квалификацией или же просто клиент не хочет лечиться (у меня и так все работает). Также зачастую при отключении клиентского порта, провайдеры оставляют открытым трафик до DNS сервера чтобы клиент мог войти в свой личный кабинет по его имени и посмотреть причину блокировки, но т. к. клиентский компьютер «валит» именно DNS сервер, то для решения данной проблемы надо искать другой выход.
Итак нам необходимо решить две простые задачи.
1.Определить все допустимые типы DNS запросов которые мы будем обрабатывать.
2.Найти разумные интервалы поступления запросов каждого типа от каждого клиента.
Давайте разберём запросы каких типов могут приходить от наших клиентов и что нам с ними делать.
Запись A (address record) или запись адреса связывает имя хоста с адресом IP. Самый «наиполезнейший» тип запросов. Значения 100 запросов за 10 секунд вполне приемлемы даже для тех клиентов, которые серфят «ну очень быстро» :)
Запись AAAA (IPv6 address record) связывает имя хоста с адресом протокола IPv6. Пока IPv6 распространён не сильно, можно оставить данный тип запросов к нашему DNS серверу, ограничив двумя запросами в 10 секунд от каждого из клиентов, чтобы пустые запросы типа AAAA localhost. не влияли на работу DNS сервера.
Запись CNAME (canonical name record) или каноническая запись имени. Тип запроса полезный, блокировка должна быть мягкая чтобы запросов подобного типа блокировалось как можно меньше. Также как и для запросов типа A 100 запросов за 10 секунд вполне приемлемое значение.
Запись MX (mail exchange) или почтовый обменник указывает сервер(ы) обмена почтой для данного домена. Для домашних клиентов интенсивные запросы к данным типам записей явно свидетельствуют о том, что компьютер клиента заражен заразой которая рассылает спам. 5 запросов за 60 секунд хватит для работы диагностических утилит.
Запись NS (name server) указывает на DNS-сервер для данного домена. Напрямую пользователи услуг домашнего Интернет такие запросы не генерируют, в большинстве случаев такие запросы формируются вручную через диагностические утилиты типа nslookup в целях отладки работоспособности своих доменов и пр. 10 запросов данного типа за 60 секунд вполне приемлемое значение.
Запись PTR (pointer) или запись указателя связывает IP хоста с его каноническим именем. Применительно к пользователям услуг домашнего интернета запросы подобного типа поступают достаточно часто во время работы торрент или p2p клиентов, для разрешения имен хостов с которых вы скачиваете и которым вы раздаете. Например 50 запросов за 10 секунд вполне приемлемое значение, которого в большинстве случаев хватает для любого пользователя.
Запись SOA (Start of Authority) или начальная запись зоны указывает, на каком сервере хранится эталонная информация о данном домене, содержит контактную информацию лица, ответственного за данную зону, тайминги (параметры времени) кеширования зонной информации и взаимодействия DNS-серверов. Данный тип запросов может использоваться пользователями домашнего интернет только в целях отладки, разрешим каждому клиенту делать 5 запросов за 60 секунд.
Запись SRV (server selection) указывает на серверы для сервисов. Данный тип запросов может использоваться пользователями домашнего интернет только в целях отладки, разрешим каждому клиенту делать 5 запросов за 60 секунд.
Полный список типов DNS записей можно просмотреть
здесь.
Для того чтобы понять по каким сигнатурам нам классифицировать тот или иной DNS запрос необходимо «поймать» tcpdump-ом по одному типу пакета, заглянуть в тело запроса поле Type и убедиться что:
запрос типа MX содержит в поле type — 00 0F
запрос типа AAAA содержит в поле type — 00 1C
запрос типа A содержит в поле type — 00 01
запрос типа PTR содержит в поле type — 00 0C
запрос типа CNAME содержит в поле type — 00 05
запрос типа NS содержит в поле type — 00 02
запрос типа SOA содержит в поле type — 00 06
запрос типа SRV содержит в поле type — 00 21
Заметим также, что в DNS запросе после поля Type идёт поле Class оно всегда равно 00 01 для DNS запроса. Добавим это поле ко всем сигнатурам чтобы уменьшить количество ложных срабатываний.
Итак чтобы заблокировать DNS запросы типа MX нам необходимо на DNS серверах добавить правила iptables:
-A INPUT -p udp --dport 53 -m string --algo kmp --hex-string "|00 0F 00 01|" -j DROP
так как нам надо закрыть данные запросы не полностью а просто ограничить их количество в единицу времени чтобы данные запросы не «ложили» нам сервер просто добавим в правила модуль recent.
Например правило которое ограничивает поступления DNS запросов типа MX в 5 запросов за 60 секунд будет выглядеть так:
-A INPUT -p udp --dport 53 -m state --state NEW -m string --algo kmp --hex-string "|00 0F 00 01|" -m recent --set --name MXFLOOD --rsource
-A INPUT -p udp --dport 53 -m state --state NEW -m string --algo kmp --hex-string "|00 0F 00 01|" -m recent --update --seconds 60 --hitcount 5 --rttl --name MXFLOOD -j DROP
-A INPUT -p udp --dport 53 -m string --algo kmp --hex-string "|00 0F 00 01|" -j ACCEPT
Аналогичным образом ограничиваются и другие типы DNS запросов.
Так как DNS типов существует превеликое множество и мы разрешили все нужные нам типы DNS запросов, то было бы неплохо запретить все остальные запросы чтобы они не обрабатывались вашим DNS сервером.
-A INPUT -p udp --dport 53 -j DROP
Данные простейшие правила позволили нам сократить количество одновременных рекурсивных DNS запросов к нашим DNS серверам более чем в 20 раз (c 10000 до 400), без жалоб на работу DNS со стороны наших пользователей.