Обнаружение и защита от DDoS-атак

Опасность большинства DDoS-атак – в их абсолютной прозрачности и «нормальности». Ведь если ошибка в программном обеспечении всегда может быть исправлена, то полное сжирание ресурсов - явление почти обыденное. С ним сталкиваются многие администраторы, когда ресурсов машины (ширины канала) становится недостаточно, или web-сайт подвергается слэшдот-эффекту (twitter стал недоступен уже через несколько минут после первого известия о смерти Майкла Джексона). И если резать трафик и ресурсы для всех подряд, то спасешься от DDoS, но потеряешь добрую половину клиентов.

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

Существует два типа DoS/DDoS-атак, и наиболее распространенная из них основана на идее флуда, то есть заваливания жертвы огромным количеством пакетов. Флуд бывает разным: ICMP-флуд, SYN-флуд, UDP-флуд и HTTP-флуд. Современные DoS-боты могут использовать все эти виды атак одновременно, поэтому следует заранее позаботиться об адекватной защите от каждой из них.

Универсальные советы для защиты. Чтобы не попасть в безвыходное положение во время обрушения DDoS на системы, необходимо тщательным образом подготовить их к такой ситуации:

  1. Все сервера, имеющие прямой доступ во внешнюю сеть, должны быть подготовлены к простому и быстрому удаленному ребуту (sshd спасет отца русской демократии). Большим плюсом будет наличие второго, административного, сетевого интерфейса, через который можно получить доступ к серверу в случае забитости основного канала.
  2. ПО, используемое на сервере, всегда должно находиться в актуальном состоянии. Все дырки - пропатчены, обновления установлены (простой, как сапог, совет, которому многие не следуют). Это оградит тебя от DoS-атак, эксплуатирующих баги в сервисах.
  3. Все слушающие сетевые сервисы, предназначенные для административного использования, должны быть спрятаны брандмауэром ото всех, кто не должен иметь к ним доступ. Тогда атакующий не сможет использовать их для проведения DoS-атаки или брутфорса.

Обнаружение DoS-атак

Первым делом смотрим показатель Загрузка системы (Load average, LA) (в статье указаны допустимые значения LA для двухъядерного процессора.)

  • Вариант №1. Подсчитать количество соединений для каждого IP по протоколам tcp и udp: netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
cat /proc/net/nf_conntrack | grep udp | wc -l
cat /proc/net/ip_conntrack | grep udp | wc -l

Наличие SYN- флуда устанавливается легко - через подсчет числа «полуоткрытых» TCP- соединений. В обычной ситуации их не должно быть совсем (или очень небольшое количество: максимум 1-3).

netstat -na | grep ":1720\ " | grep SYN_RCVD
netstat -na | grep ":443\ " | grep SYN_RCVD
netstat -na | grep ":80\ " | wc -l

Один из распространенных способов не только забить канал связи, но и ввести сетевой стек операционной системы в такое состояние, когда он уже не сможет принимать новые запросы на подключение. Основан на попытке инициализации большого числа одновременных TCP-соединений через посылку SYN-пакета с несуществующим обратным адресом. После нескольких попыток отослать ответный ACK-пакет на недоступный адрес большинство операционок ставят неустановленное соединение в очередь. И только после n-ой попытки закрывают соединение. Так как поток ACK-пакетов очень велик, вскоре очередь оказывается заполненной, и ядро дает отказ на попытки открыть новое соединение. Наиболее умные DoS-боты еще и анализируют систему перед началом атаки, чтобы слать запросы только на открытые жизненно важные порты. Идентифицировать такую атаку просто: достаточно попробовать подключиться к одному из сервисов. Оборонительные мероприятия обычно включают в себя:

Увеличение очереди «полуоткрытых» TCP-соединений:

# sysctl -w net.ipv4.tcp_max_syn_backlog=1024

Уменьшение времени удержания «полуоткрытых» соединений:

# sysctl -w net.ipv4.tcp_synack_retries=1

Включение механизма TCP syncookies:

# sysctl -w net.ipv4.tcp_syncookies=1

Что такое Спуфинг

iptables -A INPUT -m conntrack --ctstate NEW,INVALID -p tcp --tcp-flags SYN,ACK SYN,ACK
-j LOG --log-level info --log-prefix "DROP SYN,ACK: "
iptables -A INPUT -m conntrack --ctstate NEW,INVALID -p tcp --tcp-flags SYN,ACK SYN,ACK
-j REJECT --reject-with tcp-reset

Ведь если мы получаем пакет с установленными флагами SYN и ACK (такой комбинацией флагов обладает только ответ на SYN-пакет) по еще не открытому соединению, это означает, что кто-то послал другому хосту SYN-пакет от нашего имени, и ответ пришел к нам. Конечно, злоумышленнику предстоит еще угадать номер последовательности, но лучше не предоставлять ему такого шанса. Согласно приведенному правилу, наш хост ответит RST- пакетом, после получения которого атакуемый хост закроет соединение. Добавление такого правила в конфигурацию фаервола настоятельно рекомендуется, потому что если злоумышленнику удастся осуществить спуфинг-атаку от вашего имени, при расследовании этого эпизода следы приведут к вам.

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

Метод захламления полосы пропускания. Основан на бесконечной посылке UDP-пакетов на порты различных UDP-сервисов. Легко устраняется за счет отрезания таких сервисов от внешнего мира и установки в фаерволе лимита на количество соединений в единицу времени.

# udp 5060
iptables -A INPUT -p udp --dport 5060 -m connlimit --connlimit-above 60 -j LOG --log-level info --log-prefix "REJECT 5060: "
iptables -A INPUT -p udp --dport 5060 -m connlimit --connlimit-above 60 -j REJECT
# tcp 1720
iptables -A INPUT -p tcp --syn --dport 1720 -m connlimit --connlimit-above 60 -j LOG --log-level info --log-prefix "REJECT 1720: "
iptables -A INPUT -p tcp --syn --dport 1720 -m connlimit --connlimit-above 60 -j REJECT

Очень примитивный метод забивания полосы пропускания и создания нагрузок на сетевой стек через монотонную посылку запросов ECHO (пинг) Не умеешь правильно фильтровать ICMP - не фильтруй вообще!!!. Легко обнаруживается с помощью анализа потоков трафика в обе стороны: во время атаки типа ICMP-флуд они практически идентичны. Почти безболезненный способ абсолютной защиты основан на отключении ответов на запросы ICMP ECHO:

sysctl net.ipv4.icmp_echo_ignore_all=1

Или с помощью брандмауэра:

iptables -A INPUT -p icmp -j DROP --icmp-type 8

Полностью заблокировать протокол icmp (не рекомендуется):

iptables -A INPUT -p icmp -f -j DROP

Нужно подсчитать количество процессов Web - сервера (например Apache) и количество конектов на 80-ый порт. Значения, в несколько раз превышающие среднестатистические, дают основания задуматься.

  • Количество процессов
ps aux | grep apache | wc -l
ps aux | grep nginx | wc -l
  • Количество конектов на 80, 443 порту
netstat -na | grep ":80\ " | wc -l
netstat -na | grep ":443\ " | wc -l
  • Просмотреть список IP- адресов, с которых идут запросы на подключение на порт 443:
netstat -na | grep ":443\ " | sort | uniq -c | sort -nr
      1 tcp6       0      0 :::443                  :::*                    LISTEN
      1 tcp        0      0 193.233.203.51:443      54.36.149.33:60447      TIME_WAIT
      1 tcp        0      0 193.233.203.51:443      178.64.46.67:60800      ESTABLISHED
      1 tcp        0      0 193.233.203.51:443      178.64.46.67:60796      ESTABLISHED
      1 tcp        0      0 193.233.203.51:443      178.64.46.67:60795      ESTABLISHED
      1 tcp        0      0 193.233.203.51:443      144.76.58.13:51728      ESTABLISHED
      1 tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN

Алгоритм защиты от HTTP флуда (подразумевается в мир смотрит Nginx):

  • Выяснить какой именной сайт, а чаще всего какую именно страницу засыпают запросами, например при помощи httpry или просмотр логов вебсервера.
  • Предположим DDOS идет на страницу сайта с url sitemap. Можем создать команду, которая создаст файл с ip для подключения к Nginx.
cat /var/log/nginx/site-access.log | grep sitemap | awk '{ print $1 }' |  sort |uniq -c | sort -nr | awk '{ if ($1>100 ) print "deny " $2 ";"}'  >> /etc/nginx/vhosts-includes/block_ddos.conf && nginx -t && nginx -s reload && echo > /var/log/nginx/site-access.log

Еще один вариант создания списка IP для блокировки, после его запуска не забываем обнулять файл лога site.error.log, например командой echo:

cat /var/www/httpd-logs/site.error.log| grep perip | cut -d : -f5 | cut -d , -f1 | sort | uniq  -c | sort -nr | awk '{ if ($1>100) print "deny " $2";"}'
 
echo -n > /var/www/httpd-logs/site.error.log
  • Вариант жесткой блокировки DDOS. На выходе получаем подобный файл, где в начале блокируем: ботов, устаревший протокол HTTP1.0, некоторые юзер агенты (вы можете добавить на свое усмотрение) и ниже добавлены ip из предыдущего пункта. Если расположить этот файл в директории /etc/nginx/vhosts-includes/block_ddos.conf, то он автоматически, после перезагрузки nginx, подключиться ко всем доменам.
if ($http_referer ~* (arm-eais.rkn.gov.ru|eais.rkn.gov.ru|cases.corp.google.com|iframe-toloka.com|classdom.ru|savemyass.org|yahoo.com|facebook|ba
idu.com|qq.com|reddit.com|bing.com|youtube.com|gmail.com) ) { return 444; }
if ($server_protocol ~* "HTTP/1.0") {
return 444;
}
if ($http_user_agent ~ "python-requests") {
return 444;
}
if ($http_user_agent ~ "Wget") {
return 444;
}
if ($http_user_agent ~ "curl/7.36.0") {
return 444;
}
if ($http_user_agent ~ Siege.*) {
        return 444;
}
if ($http_user_agent ~ ApacheBench.*) {
        return 444;
}
deny 196.xxx.xxx.xxx;
deny 104.xxx.xxx.xxx;
...

Bash cкрипт выводит топ-список ip адресов для конкретного домена, в запускаемый скрипт нужно передать параметр - имя домена:

#!/bin/bash
 
# Скрипт выводит топ-список ip адресов для конкретного домена
# в запускаемый скрипт нужно передать параметр - имя домена, например
# ./top_ips.sh YourDomen.ua
 
# Доменное имя
DM=$1
#DM='YourDomen.ua'
# Директория для отчетов
RPDir='/var/log/apache2'
# Файл журнала
LOGFILE="/var/log/apache2/$DM.access.log"
 
if [ ! -f "$RPDir/$DM.txt" ] 
then
     touch "$RPDir/$DM.txt"
fi
 
if [ -f $LOGFILE ]
then
    echo "Start log $DM..."
    awk '{ print $1}' $LOGFILE | sort | uniq -c | sort -nr >> $RPDir/$DM.txt|
    echo "End log $RPDir/$DM.txt"
fi

Блокирование атак при помощи null route или blackhole

Blackhole — это запись в таблице маршрутизации, которая направляет трафик «в никуда», пакеты с таким маршрутом будут удалены с причиной «No route to host».

ip route add blackhole 192.0.2.0/24

Отображение таблицы маршрутизации с помощью iproute

ip route
default via 203.0.113.1 dev eth0  metric 2
blackhole 192.0.2.0/24
127.0.0.0/8 dev lo  scope host
203.0.113.0/24 dev eth0  proto kernel  scope link  src 203.0.113.10

и отображать с помощью netstat

netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         203.0.113.1     0.0.0.0         UG        0 0          0 eth0
192.0.2.0       0.0.0.0         255.255.255.0   U         0 0          0 *
127.0.0.0       0.0.0.0         255.0.0.0       U         0 0          0 lo
203.0.113.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0

Таким образом, можно исключить определенные IP из доступа к целевому IP.

Чтобы удалить добавленный маршрут:

ip route del blackhole 192.0.2.0/24

DDoS-атака с использованием SSDP

Атака с использованием простого протокола обнаружения сервисов (SSDP) – это тип DDoS-атак с отражением, эксплуатирующий набор сетевых протоколов Universal Plug and Play (UPnP) для отправки амплифицированного потока трафика серверу-жертве. Этот трафик переполняет инфраструктуру атакуемого сервера и приводит к его отказу. В обычном режиме протокол SSDP используется для объявления доступности устройств, использующих стандарт Universal Plug and Play. К примеру, когда UPnP-принтер соединяется с обычной сетью, он сообщает о своих сервисах, которые предоставляет, компьютерам в этой сети, отправив сообщение на специальный IP-адрес, называемый групповым. Групповой адрес после этого сообщает всем компьютерам в сети о новом принтере. Как только каждый отдельный компьютер получает сообщение о принтере, он запрашивает у него полное описание его функций, после чего принтер формирует прямой ответ с полным списком всего, что он может предложить. SSDP-атака использует уязвимость этого конечного запроса о предоставляемых сервисах, вынуждая устройство отправлять ответ в адрес выбранной цели атаки.

Как защититься от SSDP-атаки? Ключевым моментом для системных администраторов является блокирование входящего UDP-трафика с портом 1900 при помощи межсетевого экрана. Если объема атакующего трафика не хватает для переполнения сетевой инфраструктуры, таких мер достаточно.


Как протестировать скрипт или установщик VPN? Используйте Надежные VPS для кратковременного использования.
PQ VPS сервера в 38+ странах.
💥 Подпишись в Телеграм 💥 и задай вопрос по сайтам и хостингам бесплатно!