Вычисляем DDOS на сервере
Бывает сидишь такой, никого не трогаешь, а тут тебе звонят и говорят что сервисы работают медленно, сайты открываются по 2-3 минуты умудряются выдавать 504 ошибку.
Расстроенным лезешь в cacti, а там такое:
Далее начинаешь судорожно искать причину всего этого, и выясняется что это обычный DDos…
Ниже будут приведены команды, которые помогут понять вам, что случилось, и точно ли это DDos.
Для начала я рекомендую прочитать статью «Средства мониторинга Linux системы (часть 1?)» в ней подробно описано какие логи нам интересны, как читать вывод команды 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 ~ /[0-9]:/{split($5, a, ":"); ips[a[1]]++} END {for (ip in ips) print ips[ip], 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 и Nginx (если он есть).
Глобальные логи Apache, в Debian, обычно находятся там:
- /var/log/apache2/error.log
- /var/log/apache2/access.log
В CentOS:
- /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. Скорее всего он может быть не настроен, особенно если вы не знаете что это такое. Ранее я уже писал статью о том как им пользоваться: «Краткая памятка по 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..
Но все это темы других статей, которые скоро будут написаны…
Источники и все такое…
- https://avionwd.wordpress.com/2011/06/30/команды-для-проверки-нагрузки-на-серв/
- https://www.stableit.ru/2010/01/dosddos.html
- http://man-linux.ru/notes/security/ddos-commands/
- http://adminunix.ru/komandy-dlya-proverki-ddos-ataki/
- https://geekelectronics.org/linux/pamyatka-pri-ddos-atake.html
- https://www.stableit.ru/2010/01/dosddos.html
- http://denik.od.ua/ddos-audit
- https://habrahabr.ru/company/infobox/blog/232227/
- http://adminunix.ru/komandy-dlya-proverki-ddos-ataki/
- http://linux-notes.org/zashhita-ot-ddos-atak/
- https://eax.me/iptables/
- https://askubuntu.com/questions/270381/how-do-i-install-ncurses-header-files
- наиболее полный мануал по iptables: http://vasilisc.com/21-examples-iptables