Защита nginx от DDoS атак. Защита web сервера от программ для ddos атак Защита nginx от ddos атак

Некоторое время назад я написал подробную статью про установку и настройку web сервера на базе последних версий. Там я упомянул, что это первая статья из цикла заметок о веб сервере. Сегодня я расскажу как простыми и подручными средствами защититься от простых ddos атак.

Сразу сделаю оговорку по поводу слова ddos, которое тут не совсем уместно, но я не придумал, как еще популярно объяснить о чем идет речь. От полноценной ddos атаки вы не сможете защититься в рамках настройки веб сервера. У вас просто будет забит весь канал и сервер перестанет отвечать. Если мощности сервера не достаточно для обработки и фильтрации входящих запросов, то он ляжет, чтобы вы там не делали. Для полноценной защиты от ddos нужны полноценные средства, которые стоят ощутимых финансовых затрат. Более подробно с теорией по читайте в отдельной статье.

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

Я приведу советы по защите от простых атак ботов или каких-то мелких вредителей и пакостников, которые без должных действий с вашей стороны могут положить ваш сайт или сервер без особых проблем. Вот простой пример. Есть не очень слабый , на борту которого 2 ярда, 8 гигов оперативы и ssd диск.

Сервер настроен по моей предыдущей статье, ссылку на которую привел в начале. На сервере развернут wordpress сайт с некоторым содержимым. И есть у нас вредитель, который на своем сервере запускает простой тест от apache на производительность веб сервера:

# ab -c 50 -n 30000 "https://hl.zeroxzed.ru/"

Всего лишь 50 параллельных потоков. Что мы видим на своем веб сервере:

Не очень приятная картина. Сервер загружен на 100%. И хотя он нормально обрабатывает запросы и в целом корректно работает. Даже не очень тормозит, но все равно это плохо. А если будет 3 сервера и по 100 потоков на каждом? Нет никаких проблем даже на тест взять у разных хостеров по виртуальной машине и запускать на них подобные штуки, имитируя ддос атаку.

В общем, если вы совсем не сделали никакой защиты на своем сервере, то любой человек сможет вам без особых проблем доставить некоторые неудобства. Защититься от такой «атаки» не сложно. Дальше я расскажу как это сделать.

Защита от ddos с помощью iptables

Для защиты от простейшей атаки мы будем использовать firewall — iptables , модуль ядра ipset для хранения больших списков ip и самописные скрипты. По фаерволу смотрите мою статью — . Здесь я не буду на этом останавливаться.

Вопрос настройки ipset я подробно рассматривал в своей статье по . Советую посмотреть материал, так как он напрямую связан с этой статьей и дополняет ее.

Итак, приступим к созданию нашей простой защиты от dos атаки с большим количеством подключений с одного ip адреса. Для начала проверим команду, которая покажет нам количество подключений с каждого ip адреса:

# netstat -ntu | awk "{print $5}" | grep -vE "(Address|servers|127.0.0.1)" | cut -d: -f1 | sort | uniq -c | sort -n| sed "s/^[ \t]*//"

Вот он, нарушитель нашего спокойствия, пытающийся организовать дос атаку на наш сервер. Теперь нарисуем скрипт, который будет блокировать всех кто устанавливает более 50-ти одновременных соединений с сайтом.

#!/bin/sh netstat -ntu | awk "{print $5}" | grep -vE "(Address|servers|127.0.0.1)" | cut -d: -f1 | sort | uniq -c | sort -n| sed "s/^[ \t]*//" | awk "{if ($1 > 50) print$2}" > /root/ddos/much_conn.txt sleep 3 list=$(cat /root/ddos/much_conn.txt) for ipnet in $list do ipset -A much_conn $ipnet done

В принципе, комментировать тут особо нечего. Берем список подключений, который только что вывели, в нем сравниваем первую колонку, если она больше 50, то результат второй колонки, где записан ip адрес, передаем в файл.

Далее читаем этот файл и добавляем все ip адреса из него в ipset список под названием much_conn. Предварительно его надо создать. Подробно об этом я рассказывал в статье, на которую привел ссылку выше, но повторю еще раз здесь:

# ipset -N much_conn iphash

Посмотреть содержимое списка можно командой:

# ipset -L much_conn

Теперь нужно добавить в iptables правило, по которому будут блокироваться все подключения из указанного списка ipset.

# iptables -A INPUT -m set --match-set much_conn src -j DROP

На всякий случай предупреждаю, чтобы вы проверили свой доступ к консоли сервера, прежде чем настраивать правила iptables. Всякое бывает, можно просто ошибиться, скопировать и вставить не то, что нужно.

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

Единственный момент, о котором хочу сказать. Сам я не проверял, сколько подключений открывают поисковые боты, когда приходят на сайт. Я подозреваю, что явно не 50 и даже не 30, но наверняка я не проверял. В общем, будьте аккуратны, когда используете это средство.

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

Было бы неплохо как-то автоматически очищать список забаненных, удаляя оттуда тех, кто уже сутки к вам не подключается, но это сильно усложняет задачу. Нужно как минимум вести лог по блокирующему списку, сохранять время последнего обращения. Обрабатывать все это, высчитывать. В общем, задача хоть и не сильно сложная, но уже не тривиальная. Мне не захотелось этим заниматься.

Есть хоть и не очень изящное, но простое решение этой проблемы. Создать список ipset с заданным временем жизни записи с помощью timeout . Например вот так:

Ipset -N much_conn iphash timeout 3600

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

Нужно понимать, что в данном примере с 1 ip адресом использовать ipset нет никакого смысла, можно сразу банить средствами самого iptables. Ipset нужен только тогда, когда этот список хотя бы в сотни строк. Если там несколько десяткой адресов, хватит и одного iptables.

Анализ лог файла web сервера для защиты от ddos

Рассмотрим еще один простой, но все же более сложный тип ддос атаки, когда идут типовые запросы с разных IP. То есть простой ботнет, может быть даже собранный руками из нескольких дешевых vds серверов. Одновременных подключений будет не много, но если у вас тяжелый сайт и злоумышленник найдет его слабое место (например поиск), то этого может быть достаточно, чтобы положить сайт.

Банить будем тоже через iptables, а список адресов для бана будем извлекать из логов веб сервера. Для этого у вас должно быть включено логирование запросов к веб серверу. Например, в nginx за это отвечает такая настройка виртуального хоста:

Access_log /web/sites/hl.zeroxzed.ru/log/access.log main;

Мы не будем каждый раз анализировать весь лог файл. Эта операция сама по себе будет сильно нагружать веб сервер. Возьмем последние 1000 строк из лог файла и посчитаем количество подключений с одного ip с типовым содержимым, например запрос главной страницы по протоколу http 1.0, «GET / HTTP/1.0». Если вы заметите другой постоянный признак ботнета, который вас атакует, используйте его. Это может быть один и тот же user agent или что-то еще. Допустим, если атакующий будет долбить в уязвимое место, то это будет адрес этой страницы.

# tail -1000 /web/sites/hl.zeroxzed.ru/log/ssl-access.log | egrep "GET / HTTP/1.0" | awk "{print $1}" | sort -n | uniq -c

Результатом этой команды будет примерно такой список.

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

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

#!/bin/sh tail -1000 /web/sites/hl.zeroxzed.ru/log/ssl-access.log | egrep "GET / HTTP/1.0" | awk "{print $1}" | sort -n | uniq -c | sort -n | tail -n100 | awk "{if ($1 > 50) print $2}" > /root/ddos/much_gets.txt sleep 3 list=$(cat /root/ddos/much_gets.txt) for ipnet in $list do ipset -A much_gets $ipnet done

Здесь делаем то же самое, что и раньше. Те, кто сделали более 50-ти одинаковых запросов по нашей маске на последние 1000 строк в лог файле, отправляются в бан.

Обращаю внимание на строку, по которой вы будете фильтровать запросы. В данном случае я показал только пример. Не надо брать и применять в том виде, как я показываю. Я демонстрирую технические возможности и подход. Настраивать и калибровать систему вам нужно у себя по месту. Важно это понимать и не применять решение бездумно. Будет только вред.

Не забудьте создать отдельный список в ipset и добавить отдельное правило в ipables. Можно использовать уже существующий список и добавленное правило из предыдущего примера, но я рекомендую все разделять. Так удобнее для последующего анализа.

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

Баним ботов с неправильным referer

194.67.215.242 - - "POST /index.php HTTP/1.1" 200 913 "g0dfw4p1.ru " "Mozilla/5.0 (Windows NT 6.0; rv:34.0) Gecko/20100101 Firefox/34.0" "-"

Корректное поле referer должно содержать либо http, либо https, либо быть пустым. Все, что иначе, можно смело блокировать или возвращать статус ошибки. Добавляем примерно такую конструкцию в конфигурацию виртуального хоста, в раздел server {} .

If ($http_referer !~* ^($|http://|https://)) { return 403; }

После этого проверьте конфигурацию nginx и перечитайте ее.

# nginxt -t # nginx -s reload

Если вас достает какой-то бот с конкретным referer, можно забанить именно его. Для этого можно дополнить условие, или изменить. Например, вот так:

If ($http_referer = "https://bots.ru/dostanim_tebya.html") { return 403; }

В дополнение, можно всех этих ботов с помощью простого скрипта банить на iptables, как в примерах выше. К слову сказать, их можно банить сразу, разбирая http запросы еще до того, как они будут попадать к nginx, например, с помощью ngrep, но это более сложная задача. Не все это умеют делать, там есть нюансы, а с nginx знакомы все. Не составит большого труда реализовать данный метод.

Защита от ддос с помощью модулей nginx — limit_conn и limit_req

Поделюсь еще одним простым способом снизить нагрузку на сервер и частично защититься от ддос с помощью модулей nginx — limit_conn и limit_req . Настроить их не сложно, частично результат работы первого модуля будет пересекаться с первыми двумя способами ddos защиты, описанными в начале. Он более простой для настройки, так что если не справились с теми способами, можно попробовать этот.

Смысл данных модулей в том, что один может ограничить одновременное количество разрешенных соединений с сайтом, а другой количество соединений в единицу времени.

Я ограничу в своем примере количество одновременных подключений к сайту с одного ip числом 50, а количество одновременных запросов к динамическому контенту не более 2-х в секунду. При этом будет разрешен всплеск (burst ) запросов до 5-ти. Объясню, как понимать этот всплеск, так как сам не сразу понял, что конкретно он означает.

Если у нас идет превышение количества установленных запросов в секунду, то их выполнение задерживается, и они выстраиваются в очередь на исполнение с указанной скоростью. Размер этой очереди и равен значению всплеска. Все запросы, которым не хватит места в очереди, будут завершены с ошибкой. То есть, если запросов будет 4 в секунду, то 2 выполнятся сразу и еще 2 встанут в очередь. А если будет 10, то 2 выполнятся сразу, 5 встанут в очередь на выполнение по 2 штуки в секунду, а остальные будут завершены с ошибкой.

Исходя из этих условий, ограничение на подключения нужно установить в контексте server , а на доступ к динамическому контенту в соответствующем location . При этом описание зон, которые будут использовать директивы, нужно расположить в http .

Вот пример конфига nginx для реализации установленных ограничений с целью защиты от ддос атак.

Http { ... limit_conn_zone $binary_remote_addr zone=perip:10m; limit_req_zone $binary_remote_addr zone=dynamic:10m rate=2r/s; ... server { ... limit_conn perip 50; ... location ~ \.php$ { ... limit_req zone=dynamic burst=5 nodelay; ... } } }

После этого перезапустите nginx и проверьте как работают лимиты. Ограничение на количество выполняемых динамических запросов можно увидеть, просто нажимая очень быстро F5 в браузере. Если будете достаточно ловки, то скоро увидите картинку

и запись в логе с ошибками:

2017/11/30 15:25:26 9773#9773: *51482 limiting requests, excess: 5.664 by zone "dynamic", client: 195.91.248.43, server: hl.zeroxzed.ru, request: "GET / HTTP/2.0", host: "hl.zeroxzed.ru", referrer: "https://hl.zeroxzed.ru/2013/03/15/featured-image-vertical/"

Лимит на количество подключений можете проверить той же утилитой ab , о которой я рассказал во введении.

017/11/30 15:38:56 9773#9773: *53938 limiting connections by zone "perip", client: 94.142.141.246, server: hl.zeroxzed.ru, request: "GET /wp-content/uploads/2013/03/the-dark-knight-rises.jpg HTTP/1.0", host: "hl.zeroxzed.ru"

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

При выставлении ограничений, не забудьте проконтролировать, не попадают ли в эти ограничения поисковые боты. По-умолчанию, они стараются не создавать повышенную нагрузку на сайт. При желании, роботу яндекса можно указать через robots.txt, с какой скоростью сканировать ваш сайт. А роботу гугла то же самое можно сделать через webmaster.

Заключение

Я рассмотрел наиболее простые способы для защиты web сервера от не менее простых ddos атак, которые больше похожи на баловство. Серьезная атака, которая просто зальет весь входящий канал сервера, даже не заметит наших защит. Но тем не менее, мне приходилось убеждаться в эффективности этих способов в отражении некоторых атак.

Существует до сих пор огромное количество веб серверов, которые вообще никак не защищены даже от утилиты ab :) Я знаю о чем говорю, так как мне попадаются в работу такие серверы. И есть так же много всяких ботов и простых программ, которые можно найти на просторах интернета и побаловаться, заваливая сайты, которые не готовы к нагрузкам вообще.

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

Суть защиты в том, что с помощью nginx выдаем пользователю определенную cookies, а потом редиректим на запрашиваемую страницу. Если бот не понимает кукисов или редиректов, то он отваливается. Нормальные пользователи ничего не замечают. Возможно позже я отдельно расскажу про этот способ и дополню статью. А пока все. Буду рад замечаниям по существу в статьях.

Онлайн курс по Linux

Если у вас есть желание научиться строить и поддерживать высокодоступные и надежные системы, рекомендую познакомиться с онлайн-курсом «Администратор Linux» в OTUS. Курс не для новичков, для поступления нужны базовые знания по сетям и установке Linux на виртуалку. Обучение длится 5 месяцев, после чего успешные выпускники курса смогут пройти собеседования у партнеров. Что даст вам этот курс:
  • Знание архитектуры Linux.
  • Освоение современных методов и инструментов анализа и обработки данных.
  • Умение подбирать конфигурацию под необходимые задачи, управлять процессами и обеспечивать безопасность системы.
  • Владение основными рабочими инструментами системного администратора.
  • Понимание особенностей развертывания, настройки и обслуживания сетей, построенных на базе Linux.
  • Способность быстро решать возникающие проблемы и обеспечивать стабильную и бесперебойную работу системы.
Проверьте себя на вступительном тесте и смотрите подробнее программу по.

В нашем блоге на Хабре мы пишем не только о развитии нашего облачного проекта 1cloud , но и рассказываем о том, как решать те или иные технологические задачи. Летом 2015 года в блоге проекта NGINX появился материал о том, как с его помощью можно противостоять DDoS-атакам. Заметка показалась нам интересной, поэтому мы приводим здесь ее основные моменты.

Введение: что такое DDoS

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

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

Технические характеристики DDoS-атаки

На прикладном уровне DDoS-атака производится специальными программами (ботами), которые могут использовать уязвимости в конкретной системе. Например, система, которая не заточена под управление большим числом параллельных соединений, может быть выведена из строя путем создания большого числа таких «коннектов». В активном состоянии их можно поддерживать, время от времени засылая через них небольшие объемы трафика. Другой вариант – заваливать систему большим количеством запросов или делать эти запросы достаточно тяжелыми. Речь ведь идет не об актуальных соединениях, поэтому через боты очень легко отправлять огромное число запросов и быстро создавать множество новых соединений.

Ниже приведены технические характеристики DDoS-атак, по которым их можно распознать, и, учитывая которые, с ними справиться:

  • Трафик обычно идет с фиксированного числа IP-адресов, предназначенных для атаки. В результате каждый такой адрес производит ненормальное число соединений и запросов, не характерное для реального пользователя. Для справки: Не всегда подобный расклад свидетельствует о проведении DDoS-атаки. Подобные же действия можно наблюдать при использовании forward (анонимного) прокси, потому что его IP-адрес на сервере служит для идентификации любого пользователя, которого он обслуживает. Однако, число заходов и запросов от анонимного прокси будет в разы меньше, чем при атаке.
  • Поскольку речь идет о ботах, производящих трафик, «перегревающий» сервер, интенсивность этого трафика гораздо выше, чем способен производить реальный пользователь.
  • Заголовок клиентского приложения User-Agent иногда отображается в нестандартной конфигурации.
  • Иногда атаку можно распознать по заголовку Referer.

Возможности NGINX и NGINX Plus по борьбы с DDoS-атаками

Многие характеристики NGINX и NGINX Plus могут оказать неоценимую помощь при решении вопросов, как справиться с DDoS-атакой. Работает это по двум направлениям: через управление входящим трафиком и через контроль его распределения по внутренним серверам.
Ограничение частоты запросов
Вы можете отрегулировать частоту входящих запросов через NGINX и NGINX Plus до значения, характерного для реальных пользователей. Например, вы полагаете, что на вашу главную страницу пользователи заходят каждые две секунды. Вы можете настроить оборудование на эту частоту запросов к странице – 30 в минуту.

Limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m; server { ... location /login.html { limit_req zone=one; ... } }
Директива limit_req_zone формирует общую зону памяти one для хранения установленного числа запросов по заданному ключу. В данном случае это клиентский IP-адрес ($binary_remote_addr). Директива limit_req в блоке /login.html отсылает к этой зоне памяти.

Ограничение числа соединений
Вы можете наложить ограничения на число соединений, которые могут исходить от одного IP-адреса клиента. Опять же оценив их значение, характерное для реального пользователя. Например, вы можете установить не больше 10 заходов с одного IP в область /store вашего сайта.

Limit_conn_zone $binary_remote_addr zone=addr:10m; server { ... location /store/ { limit_conn addr 10; ... } }
Как и в предыдущем примере, директива limit_conn_zone формирует общую зону памяти add для хранения запросов по заданному ключу – клиентскому IP-адресу $binary_remote_addr . limit_conn в теле /store отсылает к этой зоне памяти и устанавливает ограничение 10 соединениями с каждого клиентского IP.

Закрытие медленных соединений
Вы можете закрыть соединения, которые посылают данные чересчур редко, что может быть признаком того, что их главная цель – быть открытыми на протяжении долгого времени и препятствовать новым соединениям. Этот тип программы для атаки называют Slowloris. Директива client_body_timeout контролирует время ожидания NGINX между записями в теле клиента. Директива client_header_timeout делает то же для заголовков. По умолчанию в обоих случаях ставится 60 секунд. В следующем примере этот интервал устанавливается на значении 5 секунд.

Server { client_body_timeout 5s; client_header_timeout 5s; ... }

Внесение IP-адресов в «черный список»
Если вы распознали IP, используемые для атаки, вы можете внести их в «черный список» при помощи директивы deny, NGINX и NGINX Plus больше не будут реагировать на запросы с этих адресов. Например, если вы выяснили, что атака идет из области 123.123.123.1 через адрес 123.123.123.16:

Location / { deny 123.123.123.0/28; ... }
Если таких адресов несколько:

Location / { deny 123.123.123.3; deny 123.123.123.5; deny 123.123.123.7; ... }

Создание разрешенного списка IP-адресов
Допустим, доступ к вашему сайту или приложению открыт для заранее известного диапазона IP-адресов. Вы можете прописать его с помощью директив allow и deny. К примеру, вы можете предоставить доступ лишь адресам локальной сети.

Location / { allow 192.168.1.0/24; deny all; ... }
IP-адреса, не отвечающие условиям установленного диапазона, будут заблокированы.

Кэширование для предотвращения скачков трафика
Вы можете настроить NGINX и NGINX Plus, чтобы они поглощали скачки трафика во время атаки через кэширование и пропись его параметров, они будут игнорировать обратные запросы. Это можно сделать следующими вариантами:

Параметр обновления в proxy_cache_use_stale сообщает NGINX, что, когда ему необходимо провести обновление устаревших объектов в кэше, ему следует отправлять лишь один запрос и держать открытым доступ к таким объектам для клиентов, пока обновление с внутренних серверов не получено.

Key defined by the proxy_cache_key обычно состоит из встроенных вариаций (default key , $scheme$proxy_host$request_uri имеет три вариации). Если значение включает $query_string , то атака, посылающая редкие строки запросов, может привести к избыточному кэшированию. Не рекомендуется включать этот вариант в ключ, если в этом нет насущной необходимости.

Блокировка запросов
Вы можете настроить NGINX и NGINX Plus для блокировки следующих видов запросов:
  • Запросы к определенному URL, которое может быть под угрозой.
  • Запросы, где заголовки User-Agent имеют значение, не соответствующее обычному клиентскому трафику.
  • Запросы, в которых заголовки Referer могут быть определены, как связанные с атакой.
  • Запросы, в которых остальные заголовки кажутся подозрительными.
Например, если вы решили, что атака нацелена на URL /foo.php, можете заблокировать все запросы к странице:

Location /foo.php { deny all; }
Если вы выяснили, что запросы DDoS-атаки имеют значение foo или bar в заголовках User Agent, можете заблокировать и их:

Location / { if ($http_user_agent ~* foo|bar) { return 403; } ... }
По такому же принципу можно работать с другими заголовками, которые имеют значения, указывающие на угрозу атаки.

Ограничение соединений к внутренним серверам
NGINX и NGINX Plus могут одновременно управляться с большим числом соединений, чем позволяют себе внутренние серверы. С помощью NGINX Plus вы можете ограничить количество соединений к каждому из внутренних серверов. Допустим, вы желаете ограничить число подключений к двум внутренним серверам группы, обслуживающей сайт, числом 200:

Upstream website { server 192.168.100.1:80 max_conns=200; server 192.168.100.2:80 max_conns=200; queue 10 timeout=30s; }
Параметр max_conns устанавливает для каждого сервера максимальное число подключений, открытых NGINX Plus. Директива queue ограничивает число запросов находящихся в очереди, если все серверы группы превысили свой лимит. В этой же строке прописано время нахождение запроса в очереди – 30 секунд.

Range-Based-атаки
Есть вариант атаки, при котором заголовок функции Range отправляется с очень большим значением, что может привести к переполнению буфера. Для того чтобы узнать, как с помощью NGINX и NGINX Plus справляться с этим типом атаки советуем почитать .
Как управляться с большими загрузками
DDoS-атаки обычно ведут к критическому повышению уровня загрузки. Почитать о том, как научить NGINX и NGINX Plus и ОС справляться с этой проблемой, можно .

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

До сих пор мы обсуждали, как можно использовать NGINX и NGINX Plus, чтобы смягчить последствия DDoS-атаки. Но можно ли с помощью этих серверов обнаружить саму атаку? Модуль NGINX Plus Status предоставляет детальные метрические показатели трафика, который был распределен по внутренним серверам. Этот инструмент позволяет распознать ненормальные состояния трафика. NGINX Plus имеет функцию панели управлении страницей сайта, где отображаются графики текущего состояния работы его системы (пример можно посмотреть здесь: demo.nginx.com/status.html). Те же самые показатели доступны через API, их можно встроить в собственную или стороннюю систему мониторинга, и отслеживать во времени изменения трафика, предупреждая необычные его состояния.

Резюме

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

Вы можете помочь и перевести немного средств на развитие сайта



Рассмотрим защиту веб-сервера ngix работающей на операционной системе Ubuntu (в принципе - любой Linux).

Существует два типа DoS/DDoS-атак основанных на идее флуда, то есть заваливания жертвы огромным количеством пакетов.

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

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

    сохраним и применим:

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

    Оборонительные мероприятия обычно включают в себя:
    Увеличение очереди "полуоткрытых" TCP-соединений,
    Уменьшение времени удержания "полуоткрытых" соединений,
    Включение механизма TCP syncookies,
    Ограничение максимального числа "полуоткрытых» соединений с одного IP к конкретному порту"

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

    iptables -I INPUT -p udp --dport 53 -j DROP -m iplimit --iplimit-above 1

    Скорей всего придётся пересобрать ядро. Но это уже сами.......

  • HTTP-флуд
  • Один из самых популярных на сегодняшний день способов флуда. Основан на бесконечной посылке GET запросов на 80-ый порт с целью загрузить web-сервер настолько, чтобы он оказался не в состоянии обрабатывать все остальные запросы.
    Бывает, что целью флуда становится не корень web-сервера, а один из скриптов, выполняющих ресурсоемкие задачи или работающий с базой данных. В любом случае, индикатором начавшейся атаки будет служить аномально быстрый рост логов web-сервера.
    Методы борьбы с HTTP-флудом включают в себя настройку web-сервера и базы данных с целью снизить эффект от атаки, а также для отсеивания DoS-ботов с помощью различных приемов.

    Во-первых, следует увеличить максимальное число коннектов к базе данных одновременно.
    Во-вторых, установить перед web-сервером Apache легкий и производительный nginx – он будет кэшировать запросы и отдавать статику. Это решение из списка "must have", которое не только снизит эффект DoS-атак, но и позволит серверу выдержать огромные нагрузки.
    Например:

    nano /etc/nginx/nginx.conf
    # Увеличиваем максимальное количество используемых файлов
    worker_rlimit_nofile 8192;
    ## Число рабочих процессов, рекомендуется ставить по количеству ядер
    worker_processes 1;
    # Уменьшает число системных вызовов gettimeofday(), что приводит к увеличению производительности
    timer_resolution 100ms;
    # Директива задаёт приоритет рабочих процессов от -20 до 20 (отрицательное число означает более высокий приоритет).
    worker_priority -5;

    events {
    # Увеличиваем максимальное количество соединений
    worker_connections 2048;
    # Использовать эффективный метод epoll для обработки соединений
    use epoll;
    }
    http {
    # Включить sendfile(). Использование sendfile() экономит системные вызовы, уменьшает число копирований данных
    sendfile on;
    output_buffers 2 64k;

    gzip on;
    gzip_min_length 1100;
    gzip_buffers 64 8k;
    gzip_comp_level 3;
    gzip_http_version 1.1;
    gzip_proxied any;
    gzip_types text/plain application/xml application/x-javascript text/css;
    # Отключаем таймаут на закрытие keep-alive соединений
    keepalive_timeout 0;
    # Не отдавать версию nginx в заголовке ответа
    server_tokens off;
    # Сбрасывать соединение по таймауту
    reset_timedout_connection on;
    #Директива описывает зону, в которой хранятся состояния сессий. Значения сессий определяется заданной переменной.
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
    listen 80 default;
    server_name localhost;

    access_log /var/log/nginx/localhost.access.log;

    location / {
    root /var/www/;
    index index.html index.htm index.php;
    open_file_cache max=1024 inactive=600s;
    open_file_cache_valid 2000s;
    open_file_cache_min_uses 1;
    open_file_cache_errors on;
    }
    location ~ \.php$ {
    limit_req zone=one burst=5;
    fastcgi_pass unix://tmp/php5-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
    include fastcgi_params;
    fastcgi_hide_header "Cache-Control";
    }
    location ~ /\.ht {
    deny all;
    }
    expires max; # Внимание!!! Эта строка expires необходима!
    add_header Last-Modified $sent_http_Expires;
    }


    В случае необходимости можно задействовать nginx-модуль ngx_http_limit_req_module, ограничивающий количество одновременных подключений с одного адреса. Ресурсоемкие скрипты можно защитить от ботов с помощью задержек, кнопок "Нажми меня", выставления кукисов и других приемов, направленных на проверку "человечности".

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

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

    Повторить пробу через десять секунд

    Сохраним, и применим:

    sudo sysctl -p

    Все приемы, приведенные в этом топике, направлены на снижение эффективности DDoS-атак, ставящих своей целью израсходовать ресурсы машины.
    От флуда, забивающего канал мусором, защититься практически невозможно, и единственно правильный, но не всегда осуществимый способ борьбы заключается в том, чтобы "лишить атаку смысла".
    Если вы заимеешь в свое распоряжение действительно широкий канал, который легко пропустит трафик небольшого ботнета, то считай, что от 90% атак твой сервер защищен. Есть и более изощренный способ защиты.
    Он основан на организации распределенной вычислительной сети, включающей в себя множество дублирующих серверов, которые подключены к разным магистральным каналам.
    Когда вычислительные мощности или пропускная способность канала заканчиваются, все новые клиенты перенаправляются на другой сервер (или же постепенно "размазываются" по серверам по принципу round-robin).
    Это очень дорогая, но очень стойкая структура, завалить которую практически нереально.
    Ещё одно более-менее эффективное решение заключается в покупке дорогостоящих хардварных систем Cisco Traffic Anomaly Detector и Cisco Guard.
    Работая в связке, они могут подавить начинающуюся атаку, но, как и большинство других решений, основанных на обучении и анализе состояний, дают сбои.
    Поэтому следует подумать перед тем, как выбивать из начальства десятки тысячи баксов на такую защиту.

    "CENSORED, началось. Что делать?"

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

    Наличие SYN-флуда устанавливается легко - через подсчет числа "полуоткрытых" TCP-соединений:

    Значения, в несколько раз превышающие среднестатистические, дают основания задуматься. Далее следует просмотреть список IP-адресов, с которых идут запросы на подключение:

    Убедитесь в существовании интерфейса eth1. Проверить это просто - ifconfig. В случае чего замените на свой.

    Показателем служит большой поток однообразных (и не содержащих полезной информации) пакетов от разных IP, направленных на один порт/сервис (например, корень web-сервера или определенный cgi-скрипт).
    Окончательно определившись, начинаем дропать неугодных по IP-адресам (будет гораздо больше эффекта, если ты сделаешь это на маршрутизаторе):

    Это даст вам некоторую фору (совсем маленькую; зачастую IP-адрес источника спуфится), которую ты должен использовать для того, чтобы обратиться к провайдеру/хостеру (с приложенными к сообщению логами web-сервера, ядра, брандмауэра и списком выявленных тобой IP-адресов).
    Большинство из них, конечно, проигнорируют это сообщение (а хостинги с оплатой трафика еще и порадуются - DoS-атака принесет им прибыль) или просто отключат ваш сервер. Но в любом случае это следует сделать обязательно, – эффективная защита от DDoS возможна только на магистральных каналах. В одиночку ты справишься с мелкими нападками, направленными на истощение ресурсов сервера, но окажешься беззащитным перед более-менее серьезным DDoS"ом.

    Не нужно копировать всё отсюда и вставлять в конфиг. Проверьте сначала, может параметр уже определён, и его стоит просто переопределить. Например

    cat /etc/sysctl.conf |grep net.ipv6.conf.lo.disable_ipv6

    Развернем два сервера: Frontend (будет выполнять роль фильтрующего сервера: nginx, iptables, naxsi\modsecurity, fail2ban etc) и Backend (защищаемое веб-приложение). В данной статье будет описаны практически примеры фильтрации вредоносного трафика средствами Frontend-сервера.

    1. Оптимизируем ОС

    Первым делом оптимизируем ОС на сервере Frontend под большие нагрузки. Отредактируем файл /etc/sysctl.conf:

    ## Оптимизация ОЗУ
    kernel.shmmax = ХХХ
    kernel.shmall = ХХХ

    ## Оптимизация подсистемы вывода сообщений
    kernel.msgmnb = 65536
    kernel.msgmax = 65536

    ## Оптимизация работы со SWAP
    vm.swappiness = 10
    vm.dirty_ratio = 40
    vm.dirty_background_ratio = 5

    ## Оптимизация подсистемы работы с файлами ("Too many open files fix")
    fs.file-max = 2097152

    ## Оптимизация сетевой подсистемы
    net.ipv4.ip_forward = 1
    net.core.somaxconn = 65535
    net.netfilter.nf_conntrack_max = 10000000
    net.netfilter.nf_conntrack_tcp_loose = 0
    net.netfilter.nf_conntrack_tcp_timeout_established = 1800
    net.netfilter.nf_conntrack_tcp_timeout_close = 10
    net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10
    net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 20
    net.netfilter.nf_conntrack_tcp_timeout_last_ack = 20
    net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 20
    net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 20
    net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10
    net.ipv4.tcp_congestion_control = hybla
    net.ipv4.tcp_slow_start_after_idle = 0
    net.ipv4.ip_local_port_range = 1024 65000
    net.ipv4.ip_no_pmtu_disc = 1
    net.ipv4.route.flush = 1
    net.ipv4.route.max_size = 8048576
    net.ipv4.icmp_echo_ignore_broadcasts = 1
    net.ipv4.icmp_ignore_bogus_error_responses = 1
    net.ipv4.tcp_mem = 65536 131072 262144
    net.ipv4.udp_mem = 65536 131072 262144
    net.ipv4.tcp_rmem = 4096 87380 33554432
    net.ipv4.udp_rmem_min = 16384
    net.ipv4.tcp_wmem = 4096 87380 33554432
    net.ipv4.udp_wmem_min = 16384
    net.ipv4.tcp_max_tw_buckets = 1440000
    net.ipv4.tcp_tw_recycle = 0
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_max_orphans = 400000
    net.ipv4.tcp_window_scaling = 1
    net.ipv4.tcp_rfc1337 = 1
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_synack_retries = 1
    net.ipv4.tcp_syn_retries = 2
    net.ipv4.tcp_max_syn_backlog = 16384
    net.ipv4.tcp_timestamps = 1
    net.ipv4.tcp_sack = 1
    net.ipv4.tcp_fack = 1
    net.ipv4.tcp_ecn = 2
    net.ipv4.tcp_fin_timeout = 10
    net.ipv4.tcp_keepalive_time = 600
    net.ipv4.tcp_keepalive_intvl = 60
    net.ipv4.tcp_keepalive_probes = 10
    net.ipv4.tcp_no_metrics_save = 1
    net.ipv4.conf.all.accept_redirects = 0
    net.ipv4.conf.all.send_redirects = 0
    net.ipv4.conf.all.accept_source_route = 0
    net.ipv4.conf.all.rp_filter = 1

    Значения параметров kernel.shmmax и kernel.shmall рассчитываются исходя из объема ОЗУ. Для подсчета можно воспользоваться скриптом:

    #!/bin/bash # simple shmsetup script page_size=`getconf PAGE_SIZE` phys_pages=`getconf _PHYS_PAGES` shmall=`expr $phys_pages / 2` shmmax=`expr $shmall \* $page_size` echo kernel.shmmax = $shmmax echo kernel.shmall = $shmall

    Указанные параметры позволят оптимизировать работу системы под высокие нагрузки. Применение изменений производится командой «sysctl -p» или перезагрузкой системы.

    2. Iptables

    Фильтруем атаки на сетевом\транспортном уровне с использованием iptables:

    ## Блокирование INVALID-пакетов
    iptables -A INPUT -i eth0 -m conntrack --ctstate INVALID -j DROP
    ## Блокирование новых пакетов, которые не имеют флага SYN
    iptables -A INPUT -i eth0 -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
    ## Блокирование нестандартных значений MSS
    iptables -A INPUT -i eth0 -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
    ## Блокирование фрагментированных пакетов
    iptables -A INPUT -i eth0 -f -j DROP
    ## Блокирование пакетов с неверными TCP флагами
    iptables -A INPUT -i eth0 -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags FIN,ACK FIN -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags ACK,URG URG -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags ACK,FIN FIN -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags ACK,PSH PSH -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL ALL -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL NONE -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
    iptables -A INPUT -i eth0 -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
    ## Защита от сканирования портов
    iptables -N port-scanning
    iptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN
    iptables -A port-scanning -j DROP

    Ограничим количество соединений с веб-сервером:

    Iptables -A INPUT -i eth0 -o eth1 -p tcp --syn -m multiport --dports 80,443 -m connlimit --connlimit-above 30 --connlimit-mask 32 -j DROP
    iptables -A INPUT -i eth0 -o eth1 -p tcp -m multiport --dports 80,443 -j ACCEPT

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

    3. Nginx

    3.1 Блокируем избыточные обращения

    Настроим Nginx на Frontend-сервере таким образом, чтобы ограничить избыточные обращения к серверу. Отредактируем vhost-файл:

    # nano /etc/nginx/sited-enabled/frontend

    Limit_req_zone$binary_remote_addrzone=сайт:10m rate=10r/s;
    server {
    listen 80;
    server_name сайт;
    ...
    }
    location / {
    proxy_pass ...
    ...
    limit_req zone=сайт burst=20;
    limit_req_log_level error;
    limit_req_status 503;
    ...
    }

    Таким образом Nginx будет проксировать обращения клиентов на Backend-сервер не чаще, чем 10 запросов в секунду (параметр rate). Избыточные обращения будут накапливаться в очереди и проксироваться по мере освобождения «пула» обращений. В случае, если количество обращений превысит значение 20 (параметр burst), nginx на Frontend начнет отдавать 503 ошибку до тех пор, пока «пул» не начнет высвобождаться.

    3.2 Блокируем подозрительные юзерагенты

    Заблокируем юзерагенты, которые, как правило, не используют легитимные пользователи:

    # nano /etc/nginx/nginx.conf

    Map $http_user_agent $bad_useragent {
    include /etc/nginx/bad_useragents;
    }

    # nano /etc/nginx/bad_useragents

    ~*nmap 1;
    ~*nikto1 1;
    ~*wikto 1;
    ~*sf 1;
    ~*sqlmap 1;
    ~*bsqlbf 1;
    ~*acunetix 1;
    ~*havij 1;
    ~*appscan 1;
    ~*wpscan 1;
    ~*mj12bot 1;
    ~*ApacheBench 1;
    ~*WordPress 1;
    ~*DirBuster 1;
    ~*perl 1;
    ~*PhpStorm 1;
    ~*python 1;
    ~*w3af 1;
    ~*WhatWeb 1;
    ~*Arachni 1;
    ~*XSpider 1;
    ~*Hydra 1;
    ~*Evasions 1;
    ~*OpenVas 1;
    ~*visionutils 1;
    ~*Synapse 1;
    ~*HTTP_Request2 1;
    ~*GuzzleHttp 1;
    ~*Paros 1;
    ~*Synapse 1;
    ~*Python-urllib 1;

    Отдельно стоит обратить внимание на user-agent «WordPress». Если защищаемое веб-приложение не использует CMS WordPress, или же функционал «track-back» и «ping-back» не планируется использовать (скорее всего), то блокирование запросов с данным user-agent позволит перекрыть атаки, использующие особенности реализации такого функционала в WordPress. изучить особенности таких атак можно .

    Реализация таких простых правил позволит обеспечить качественную защиту от DDoS-атак веб-сайта с минимальными затратами.

    P.S.: Убедитесь, что другие сервисы на Frontend-сервере хорошо защищены и не позволят злоумышленнику получить удаленный доступ (например, по SSH или FTP).

    UPD: В качестве альтернативы можно попробовать Nemesida WAF Free - полностью бесплатный, представлен в виде динамического модуля Nginx, устанавливается и обновляется из репозитория, не требует компиляции, подключается за несколько минут к уже установленному Nginx. waf.pentestit.ru/about/2511

    Бывает сидишь такой, никого не трогаешь, а тут тебе звонят и говорят что сервисы работают медленно, сайты открываются по 2-3 минуты умудряются выдавать 504 ошибку.
    Расстроенным лезешь в cacti, а там такое:

    Ниже будут приведены команды, которые помогут понять вам, что случилось, и точно ли это DDos.

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

    Какими командами, и что мы можем определить?

    Для начала можно посмотреть число запущенных процессов Apache. Если их более 20-30 то явно уже что-то не так.

    Смотрим число процессов Apache в Debian:

    Ps aux | grep apache | wc -l

    Смотрим число процессов Apache в CentOS:

    Ps aux | grep httpd | wc -l

    Данной командой мы можем посмотреть количество соединений с сервером:

    Cat /proc/net/ip_conntrack | wc -l

    Так же показателем того, что на сервер идет DDos может служить числе коннектов на 80 или 443 порт. Вот команды способные показать это число:

    Netstat -na | grep:80 | wc -l netstat -na | grep:443 | wc -l

    Существует еще такая разновидность DDod, как SYN. Ниже приведена команда позволяющая определить число SYN запросов на те же 80 и 443 порты:

    Netstat -na | grep:80 | grep SYN | sort -u | more netstat -na | grep:443 | grep SYN | sort -u | more

    А эта команда показывает количество SYN запросов:

    Netstat -n -t | grep SYN_RECV | wc -l

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

    Tcpdump -npi eth0 port domain

    Теперь посмотрим какое количество запросов приходит с каждого IP. Эта команда показывает по всем портам:

    Netstat -ntu | awk "{print $5}"| cut -d: -f1 | sort | uniq -c | sort -nr | more

    аналогичные команды:

    Netstat -anp |grep "tcp\|udp" | awk "{print $5}" | cut -d: -f1 | sort | uniq -c | sort -n netstat -antu | awk "$5 ~ /:/{split($5, a, ":"); ips[a]++} END {for (ip in ips) print ips, ip | "sort -k1 -nr"}"

    Эта команда показывает количество запросов только по 80 порту:

    Netstat -ntu | grep ":80\ " | awk "{print $5}"| cut -d: -f1 | sort | uniq -c | sort -nr | more

    Эта команда показывает все запросы на 80 порт, не считая их, т.е. «упрощенный» но «наиболее полный» вариант вывода:

    Netstat -na | grep:80 | sort | uniq -c | sort -nr | more

    Вычислив наиболее активный IP можно так же посмотреть на какие порты идут с него запросы. Тут для примера подставлен IP 127.0.0.1:

    Netstat -na | grep 127.0.0.1

    Кстати, если у вас не настроен server-status на Apache, то статус этого сервера можно посмотреть в CLI:

    Apachectl status

    Лог Файлы

    Глобальные логи Apache, в Debian, обычно находятся там:

    • /var/log/apache2/error.log
    • /var/log/apache2/access.log
    • /var/log/httpd/error.log
    • /var/log/httpd/access.log

    Глобальные логи Nginx находятся там:

    /var/log/nginx/error.log
    /var/log/nginx/access.log

    Так же не забывайте просматривать логи виртуальных хостов, если хосты у вас настроены. Нас будет интересовать самый большой лог, который «растет» на глазах.

    Искать в этих логах нужно аномалии, а именно однотипные запросы без юзер агентов (или с одним и тем же), большое количество запросов с одного и того же IP, запросы без указания виртуального хоста и т.д.

    Выявить конкретные IP с числом запросов до сайта можно данной командой:

    Cat access.log | awk "{print $1}" | sort | uniq -c

    Так же можно получить статистика по запросам с группировкой по IP с помощью утилиты logtop .

    Для начала установим эту утилиту:

    Apt-get install git libncurses5-dev uthash-dev gcc #на случай, если у вас не стоят пакеты для корректной работы GIT git clone https://github.com/JulienPalard/logtop.git

    И теперь получим статистику:

    Tail -f access.log | awk {"print $1; fflush();"} | logtop

    Следующая команда поможет нам выявить популярные user-агенты:

    Cat access.log | awk -F\" "{print $6}" | sort | uniq -c | sort -n

    Как блокировать?

    Так или иначе у вас должен стоять iptables. Скорее всего он может быть не настроен, особенно если вы не знаете что это такое. Ранее я уже писал статью о том как им пользоваться: « » , поэтому тут я приведу только необходимые команды, чтобы решить проблему здесь и сейчас.

    Вот как можно заблокировать tcp запросы на 80 порт с определенного IP :

    Iptables -A INPUT -p tcp --dport 80 -s 12.34.56.78 -j DROP

    Так мы блокируем запросы на все порты с определенного IP :

    Iptables -A INPUT -s 12.34.56.78 -j DROP

    Посмотреть список уже заблокированных мы можем данными командами:

    Iptables -L -n

    Iptables -L -n --line-numbers

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

    Iptables -D INPUT -s 1.2.3.4 -j DROP

    или можно удалить правило по его номеру , предварительно посмотрев его номер командой iptables -L -n —line-numbers:

    Iptables -D INPUT 6

    Чтобы удалить все правила , можно воспользоваться командой:

    Iptables -F

    Немного профилактики, в целях защиты от DDos…

    Есть еще некоторые правила, которые смогут оградить нас от бездумных ботов, создающих нагрузку на сервер.

    Следующей командой мы установим максимальное количество подключений с одного IP на 80 порт :

    Iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 128 -j DROP iptables -A INPUT -p tcp --dport 80 -j ACCEPT

    Тоже самое можно сделать и для DNS :

    Iptables -A INPUT -p udp --dport 53 -m connlimit --connlimit-above 16 -j DROP iptables -A INPUT -p udp --dport 53 -j ACCEPT

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

    Iptables -I INPUT -m conntrack --ctstate NEW,INVALID -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT --reject-with tcp-reset

    Iptables-save > /etc/iptables.rules

    Что еще можно сделать?

    Еще не помешает немного «оттюнинговать» ядро, сделать тонкую настройку Apache и Nginx (если таковой стоит), поставить дополнительные модули и пакеты для защиты от атак, такие как Fail2Ban, mod_evasive, ModSecurity..

    Но все это темы других статей, которые скоро будут написаны…

    В продолжение темы:
    Интернет

    Как создать пассивный доход – 14 работающих способов + 12 советов начинающим бизнесменам. Чтобы ответить на вопрос: как создать пассивный доход , нужно понять, как действуют...