Не так давно я столкнулся с проблемой (и ее решением), учитывая актуальность этой темы в последнее время, а также то, как много людей сейчас страдают от этой проблемы, я решил объединить информацию в одну статью.
Возможно, кто-то еще найдет это полезным.
Начинать
Пару недель назад я заметил странную активность, направленную на мой DNS-сервер.Скажу сразу, что я использую шлюз в Linux, поэтому там установлен DNS-сервер привязки.
Активность заключалась в том, что на 53-й порт (DNS) моего сервера с разных IP-адресов сыпалось несколько UDP-пакетов в секунду: 10:41:42.163334 IP 89.149.221.182.52264 > MY_IP.53: 22912+ NS?.
(17) 10:41:42.163807 IP MY_IP.53 > 89.149.221.182.52264:22912 Отказано-0/0/0 (17) На что, как видно из лога, сервер ответил отказами.
Естественно, я заинтересовался, какие IP-адреса заполняет мой DNS. Посмотрев несколько адресов через whois, я определил, что это крупные хостинговые компании, написал в техподдержку некоторых из них просьбу остановить атаку на мой сервер.
В ответ я получил ответ, что этот тип атаки они не могут блокировать и что они сами страдают от этой аномальной активности.
Было решено разобраться со всем самостоятельно.
Усиление DNS. Теория
Сам тип атаки не нов — о нем было известно еще в 2006 году.Подробности на английском языке можно найти здесь , однако активно использовать его стали относительно недавно.
В январе-феврале 2009 года ряд интернет-изданий опубликовали информацию о масштабном использовании этого типа DDOS киберпреступниками, о чем можно узнать Здесь и на английском языке Здесь Говоря простым языком, суть амплификации заключается в том, что злоумышленник отправляет (обычно короткий) запрос уязвимому DNS-серверу, который отвечает на запрос пакетом гораздо большего размера.
Если при отправке запроса использовать адрес компьютера жертвы в качестве IP-адреса источника (подмена ip), то уязвимый DNS-сервер будет отправлять на компьютер жертвы большое количество ненужных пакетов, пока полностью не парализует его работу.
Упражняться
Этот тип атаки наиболее эффективен на старом (непропатченном) или неправильно настроенном DNS-сервере, который, как уже говорилось, на короткие запросы злоумышленников отвечает большими пакетами.
Вот пример такого взаимодействия (кстати, именно эти запросы чаще всего используют злоумышленники):
Отправляем запрос на NS сервер командой #dig @SERVER_IP NS
где SERVER_IP — IP-адрес сервера.
В итоге в логе для 53 порта сервера получаем: 11:08:47.994604 IP MY_IP.47816 > SERVER_IP.53: 5655+ NS?.
(17) те.
именно те 17 байт запроса, которые мы хотели отправить.
В ответ в том же логе видим: 11:08:47.995853 IP 192.168.100.254.53 > 192.168.100.100.47816: 5655 0/13/6 NS C.ROOT-SERVERS.NET.,[|домен] те.
сервер ответил нам подсказкой в виде адресов корневых DNS-серверов, а это уже 360 байт. Это длины DNS-запроса и ответа, общая длина пакетов составляет 60 и 402 байта соответственно.
Выигрыш очевиден.
Что делать?
Сначала, конечно же, убедитесь, что версия вашего DNS-сервера обновлена, независимо от того, на какой платформе он работает. Во-вторых, убедитесь, что сервер настроен достаточно безопасно и не отвечает всем подряд на «неуместные» запросы.В Интернете можно найти множество инструкций и рекомендаций по этому поводу.
Упомяну здесь лишь один документ, который я нашел не так давно.
.
Что еще можно сделать?
В моем случае делать особо было нечего.Если посмотреть самый первый лог, который я предоставил, то можно увидеть, что злоумышленник отправляет запрос длиной 17 байт и получает REJECT той же длины (17 байт), т.е.
никакого усиления не происходит. Но, судя по всему, «ддозеры» не особо торопятся удалять из своих списков адреса DNS-серверов, не подверженных данной уязвимости, и продолжают докучать им своими приставаниями.
? Меня эта ситуация не устроила.
Неприятно, что с моего адреса кто-то получает на свой сервер ненужный трафик (даже если это не моя вина).
Сначала я начал заносить адреса отправителей в черный список, но этого не произошло, атака со старых адресов прекратилась, но появлялись все новые и новые.
Было решено использовать более сложные методы фильтрации и использовать на моем Linux-сервере модули iptables, до которых я раньше никогда не добирался.
Убить, так сказать, двух зайцев - и сделать злоумышленникам -1 и разобраться с парой модулей iptables.
Строковый модуль
Полностью закрыть 53 порт (DNS) я, конечно, не смог — у меня много клиентов, которым он нужен.Я решил отфильтровать пакеты по содержимому DNS-запросов и удалить те, которые содержали запросы от злоумышленников, и все они содержали «NS».
Для этой задачи подойдет строковый модуль iptables, который позволяет заглянуть в содержимое пакетов.
Чтобы понять, что фильтровать, посмотрим на пакет злоумышленника через Wireshark.
Здесь И Здесь Вы можете прочитать о структуре UDP-пакетов и формате DNS-фрейма соответственно.
Для краткости скажу, что первые 14 байт пакета занимают данные протокола Ethernet (красный цвет на рисунке), далее идут 20 байт заголовка IP-протокола (синий цвет на рисунке), далее 8 байт. — это UDP-заголовок (зеленый на рисунке), после которого следуют данные протокола DNS (желтый на рисунке).
Первые 12 байт кадра DNS занимают заголовок, после чего, наконец, начинается поле DNS Query (т.е.
сам запрос, на рисунке выделен оранжевым цветом).
Пакеты, отправленные злоумышленниками, начиная с 54-го (14+20+8+12) байта, содержат следующие данные: 00 00 02 00 01 (в шестнадцатеричном коде), что соответствует запросу «NS», о котором я говорил.
ранее.
Таким образом, необходимо выбрать пакеты, которые, начиная с 54 байта, содержат эти байты.
Это будет выглядеть так: iptables -A INPUT --in-interface eth1 --protocol udp --dport 53 --match state --state NEW --match string --algo kmp --hex-string "|00 00 02 00 01|" --from 40 --to 45 --jump DROP
Позвольте мне немного объяснить.
--in-interface — указывает, на каком интерфейсе перехватывать пакеты.
Вам необходимо установить только тот внешний интерфейс, который подвергается атаке (нет необходимости ущемлять пользователей внутри сети).
--match state --state NEW — ловим пакеты только со статусом NEW, чтобы не проверять все транзакции подряд, а только инициирующие пакеты (мало ли что можно передать на 53 порту).
Дальше самое интересное — используем модуль sting. Мы используем следующие параметры: --algo — указывает алгоритм поиска, по сути это не важно, я указал kmp, но можно указать и bm; --hex-string — записывается та самая строка в шестнадцатеричном формате, которую мы ищем; --from 40 - ищем начиная с 40 байта (обратите внимание, не с 54, т.к.
строка начинает поиск, и соответственно начинает отсчет с первого байта протокола IP, т.е.
протокол Ethernet, длина которого 14 байт, является выброшено (на рисунке выше красным цветом Всего 54 – 14 = 40); --to 45 — соответственно поиск до 45-го байта пакета.
Последний модуль
Мы могли бы остановиться на этом.Пакеты больше не будут доходить до бинда, но меня всё равно не утешала мысль, что я закрыл ВСЕМ возможность делать NS запросы к моему DNS-серверу, поэтому я решил использовать другой модуль iptables — недавний.
Этот модуль позволяет создавать динамические таблицы IP-адресов в зависимости от определенных условий, а затем устанавливать разрешающие и запрещающие правила для этих таблиц.
Давайте посмотрим на простой двухстрочный пример использования недавних: iptables -A INPUT --protocol tcp --match state --state NEW --dport 22 --match recent --update --seconds 30 --name SSHT --jump DROP
iptables -A INPUT --protocol tcp --match state --state NEW --dport 22 --match recent --set --name SSHT --jump ACCEPT
Начнем со второго правила.
Любой, кто пытается войти в систему (а именно войти, потому что мы используем --state NEW) через порт 22 (SSH), разрешен через (--jump ACCEPT), но его IP-адрес попадает в таблицу с именем SSHT. При повторной попытке подключения с этого адреса начинает работать первое правило, смысл которого заключается в обновлении (--update) записи в таблице и одновременно проверке, когда эта запись устанавливалась/обновлялась в последний раз .
Если запись была установлена/обновлена менее 30 секунд назад (--секунд 30), то срабатывает --jump DROP и пакет отбрасывается.
Таким образом, брутфорсеры, пытающиеся забить SSH-порт, будут отвергнуты, если частота отправки их пакетов превышает 1 пакет в 30 секунд.
Давайте попробуем использовать недавние для наших нужд: iptables -A INPUT --in-interface eth1 --protocol udp --dport 53 --match state --state NEW --match string --algo kmp --hex-string "|00 00 02 00 01|" --from 40 --to 45 --match recent --name DNST --update --seconds 600 --jump DROP
iptables -A INPUT --in-interface eth1 --protocol udp --dport 53 --match state --state NEW --match string --algo kmp --hex-string "|00 00 02 00 01|" --from 40 --to 45 --match recent --name DNST --set --jump ACCEPT
Таким образом, я разрешаю делать запросы NS к внешнему интерфейсу не чаще, чем раз в 10 минут.
После добавления этих правил в /proc/net/xt_recent моего сервера появился DNST-файл, в котором стали записываться IP-адреса злоумышленников.
И DNS-сервер перестал реагировать на провокации: 14:10:19.011818 IP 89.149.221.182.40320 > MY_IP.53: 23508+ NS?.
(17) 14:10:25.243499 IP 89.149.221.182.64984 > MY_IP.53: 25306+ NS?.
(17) 14:11:08.832827 IP 89.149.221.182.15864 > MY_IP.53:48029+ NS?.
(17) 14:11:15.063058 IP 89.149.221.182.30959 > MY_IP.53:64444+ NS?.
(17) Через несколько дней работы правил количество пакетов от злоумышленников уменьшилось в несколько раз.
Теперь получаю 2-3 пакета в минуту, которые сразу отклоняются фаерволом.
UPD: В последнем блоке кода я поспешил и написал ошибку, уже исправил, спасибо, что заметили Теги: #dns #ddos #dns amplification #iptables #mod string #mod недавний #linux #firewall #информационная безопасность
-
Адаптация Вашего Ит-Решения К Вашему Бизнесу
19 Oct, 24 -
Жесткокрылые
19 Oct, 24 -
Где В России Легально Слушать Музыку?
19 Oct, 24 -
Штаб-Квартира: Московский Офис Икеа.
19 Oct, 24