Пара полезных команд, которые могут пригодиться при DDoS и не только

    В моем случае, в качестве frontend сервера, стоит nginx и формат access-лога имеет вид:

    log_format main '$remote_addr — $remote_user [$time_local] "$host" "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for" -> $upstream_response_time';

    Что на выходе дает что-то вроде такой строки:

    188.142.8.61 — - [14/Sep/2014:22:51:03 +0400] «www.mysite.ru» «GET / HTTP/1.1» 200 519 «6wwro6rq35muk.ru» «Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.191602; .NET CLR 3.5.191602; .NET CLR 3.0.191602» "-" -> 0.003

    1. tail -f /var/log/nginx/nginx.access.log | cut -d ' ' -f 1 | logtop

    Позволяет получить общую картину: распределение уникальных IP, с которых идут запросы, кол-во запросов с одного IP и т.д.
    Самое ценное — что все это работает в режиме реального времени и можно мониторить ситуацию, внося какие-либо изменения в конфигурацию (например просто забанить ТОП 20 самых активных IP через iptables или временно ограничить географию запросов в nginx через GeoIP http://nginx.org/ru/docs/http/ngx_http_geoip_module.html).

    Покажет (и будет обновляться в режиме реального времени) что-то вроде:

    3199 elements in 27 seconds (118.48 elements/s)
    1 337 12.48/s 95.65.66.183
    2 308 11.41/s 122.29.177.10
    3 304 11.26/s 122.18.251.54
    4 284 10.52/s 92.98.80.164
    5 275 10.19/s 188.239.14.134
    6 275 10.19/s 201.87.32.17
    7 270 10.00/s 112.185.132.118
    8 230 8.52/s 200.77.195.44
    9 182 6.74/s 177.35.100.49
    10 172 6.37/s 177.34.181.245


    Где в данном случае колонки означают:

    • 1 — порядковый номер
    • 2 — количество запросов с данного IP
    • 3 — количество запросов в секунду с данного IP
    • 4 — собственно сам IP


    Вверху показывается суммарная статистика по всем запросам

    В данном случае мы видим, что с IP 95.65.66.183 идет 12,48 запросов/секунду и за последние 27 секунд было сделано 337 запросов. По остальным строкам аналогично.

    Разберем по частям:
    tail -f /var/log/nginx/nginx.access.log — в непрерывном режиме считываем конец лог-файла

    cut -d ' ' -f 1 — разделяем строку на «подстроки» разделителем, указанным в флаге -d. (в данном примере указан пробел).
    Флаг -f 1 — показываем только поле с порядковым номером «1» (в данном случае это поле будет содержать IP, с которого идет запрос)

    logtop — считает количество одинаковых строк (в данном случае IP), сортирует их в порядке убывания и выводит списком, попутно добавляя статистику (в Debian ставится через aptitude из стандартного репозитория).

    2. grep "&key=" /var/log/nginx/nginx.access.log | cut -d ' ' -f 1 | sort | uniq -c | sort -n | tail -n 30 — покажет распределение какой-либо строки по IP в логе.

    В моем случае мне нужно было собрать статистику как часто один IP использует в запросе параметр &key=….

    Покажет что-то вроде такого:

    31 66.249.69.246
    47 66.249.69.15
    51 66.249.69.46
    53 66.249.69.30
    803 66.249.64.33
    822 66.249.64.25
    912 66.249.64.29
    1856 66.249.64.90
    1867 66.249.64.82
    1878 66.249.64.86


    • 1 — число вхождений строки (в данном случае IP)
    • 2 — собственно сам IP


    В данном случае мы видим, что с IP 66.249.64.86 суммарно пришло 1878 запросов (и потом, если посмотрим в Whois — увидим что этот IP принадлежит Google и не является «зловредным»)

    Разберем по частям:

    grep "&key=" /var/log/nginx/nginx.access.log — находим все строки в логе, содержащие подстроку "&key=" (не важно в какой части строки)
    cut -d ' ' -f 1 — (см. предыдущий пример), выведем IP
    sort — отсортируем строки (нужно для корректной работы следующей команды)
    uniq -c — покажем уникальные строки + подсчитаем количествово вхождений этих строк (флаг -с)
    sort -n — отсортируем используя числовой режим сортировки (флаг -n)
    tail -n 30 — выведем 30 строк с наибольшим количеством вхождений (флаг -n 30, можно указать произвольное число строк)

    Все запросы выше приведены для Debian или Ubuntu, но думаю в других Linux дистрибутивах команды будут иметь похожий вид.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 21

      +11
      Моя подборка, лет 5 назад откуда-то скопировал, часто выручают и логи не требуются:
      Cколько коннектов на 80 порт: netstat -na | grep ":80\ " | wc -l
      На какой домен чаще всего идут запросы: tcpdump -npi eth0 port domain
      С какого ip сколько запросов netstat -ntu | awk '{print $5}'| cut -d: -f1 | sort | uniq -c | sort -nr | more
      Нагрузка на канал ftop -i eth0 -B
        +1
        > Cколько коннектов на 80 порт: netstat -na | grep ":80\ " | wc -l

        Тут, наверное, еще и греп по ESTABLISHED нужно. А вообще, есть штуки вроде apachetop или HttpStubStatusModule.
        +4
        Cколько коннектов на 80 порт: netstat -na | grep ":80\ " | wc -l

        Если DDoS будет более-менее успешным, вы сервак добьёте этой операцией. Вот тут я приводил пример на ~40к соединениях. В таких случаях ss даёт фору.
          +1
          Спасибо за «наводочку» с ss — как говорится век живи — век учись.
          А не могли бы Вы разъяснить вот этот вывод (так сказать для более глубокого понимания):
          tcp LISTEN 0 128 :::80
          users:((«apache2»,26387,4),(«apache2»,10686,4),(«apache2»,10685,4),(«apache2»,10684,4),(«apache2»,10683,4),(«apache2»,10677,4),(«apache2»,10365,4),(«apache2»,10364,4),(«apache2»,10363,4),(«apache2»,10362,4),(«apache2»,10361,4))

          это означает, что порт 80 слушают несколько процессов(нитей)? Но к какому пойдёт следующий коннект?
          0
          wc -l не обязателен, у grep есть ключ "-с", который подсчитывает количество полученных строк.
          т.е. netstat -na | grep -c ":80\ "
          Сам раньше тоже везде считал с помощью wc -l :)
            0
            > На какой домен чаще всего идут запросы: tcpdump -npi eth0 port domain

            Правда? А вообще-то то же самое записывается как port 53 и всего лишь показывает DNS трафик.

            (Это называется script kiddies.)
            0
            Спасибо за наводку про logtop, актуально. Кстати, одного нашего клиента тоже последние две недели атакуют с юзер-агентом «Trident/4.0; SLCC2; .NET CLR 2.0.191602; .NET CLR 3.5.191602; .NET CLR 3.0.191602» и разными его вариациями.

            Делюсь своим скриптом, добавляющим правила в iptables по подсетям /24 по этому user-agent'у:

            #!/bin/bash
            while [ 1 ]; do
            cat /var/log/nginx/nginx_access.log | grep "Trident" | awk '{print $1}'| awk -F"." '{print $1"."$2"."$3".0/24"}' | sort | uniq -c | sort -nr > /root/trident.list
            cat /dev/null > /root/iptables_trident_ban.sh
            awk '{print "IP=" $2 "\nRULE=\"iptables -I INPUT 1 -p tcp --dport 80 -s " $2 " -j DROP\"\nif iptables-save | grep -- \"$IP\" ; then echo \"skip\"; else `$RULE`; fi" }' /root/trident.list | head -n 500 >> /root/iptables_trident_ban.sh
            bash /root/iptables_trident_ban.sh
            cat /dev/null > /var/log/nginx/nginx_access.log
            [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
            done
            

              0
              Кстати, довольно эффективно работает проверка по U-A в nginx (при правильной настройке самого nginx):
              if ($http_user_agent ~* "Trident") { return 403; }
                0
                Я не супер-спец, но разве это не забанит Internet Explorer?
                Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)
                  0
                  Верно, забанит, но в нашем случае клиенты — не обычные браузеры. Вместо Trident подставьте нужную маску.
                +1
                А fail2ban не пробовали? Настраивается легко и обладает довольно-таки большим функционалом (пару лет назад все было гораздо хуже у него, если мне память не изменяет).
                  +1
                  причем его можно настроить на конкретный url, используя в паре с nginx'овским ngx_http_limit_req_module. Недавно так отсек уйму нежелательно трафика. Причем бан гибкий на нужное время, с нужными условиями.
                0
                Ради тренеровки (и на будущее) напишите себе скрипт, читающий netstat и блокирующий в iptables айпишники, которые имеют более 50 конектов. Как бонус ведёт лог этих блокировок и через час, например, разблокирует айпишники.
                  +1
                  Полагаю, что DDoSом обычно называют атаку как минимум с сотни машин, и в этом случает 10 строчек logtop'а будет маловато. Нормальный же DDoS задействует десятки тысяч машин, и логи читать обычно уже поздно — входящий канал на 100 мбит переполняется одними SYN запросами (даже если они, вдруг, не поддельные)
                  Для владельцев одного-двух арендованых серверов с каналом 100Мбит/1Гбит проще воспользоваться CloudFlare, чем держать злой файрволл с неизбежными ложными срабатываниями
                  Замечу, что уже закончившие школу ддосеры осуществляют атаку с правильными юзерагентами (часто рандом по списку), и отличить их от легитимных пользователей по заголовкам запроса невозможно
                    +1
                    По поводу рандомных юзерагентов — Вы совершенно правы. Все так и есть.

                    Все юзерагенты «правильные» и рандомно выбранные по списку. Мало того, в $http_referer каждый раз указывается уникальный сгенерированный сайт (правда фейковый, вроде 6wwro6rq35muk.ru).

                    Для таких случаев использую доступ по ключу, сгенерированному с солью от IP, который ставится в cookie + если cookie отключены — каждый раз к запросу добавляется уникальный для IP параметр &key= через переадресацию.

                    Причем там тоже есть свои особенности. Сейчас боты уже научились парсить ответные заголовки (редирект и Cookie) и использовать вытащенную по regexp информацию (тот же уникальный key). Поэтому приходится изголяться. Например установку cookie и переадресацию делать в подключаемом через <script src="..." js-файле чтобы страница не содержала уникального ключа.

                    Возможно оформлю свои наблюдения в виде отдельной статьи.
                    0
                    а как посоветуете бороться со спаммерами, которые спамят через php-шный mail()?
                    в свое время для >=php5.3 я начал использовать лог вызовов
                    mail.add_x_header = On
                    mail.log = /var/log/sendmail-php.log
                    

                    потом, посредством ротации, я получаю на почту количество писем (вызовов mail()) каждым из скриптов
                    cat /var/log/sendmail-php.log | egrep -o '\/.+\.php'| sort | uniq -c | mail -s "sendmail-php log" my.mail.fetcher@domain.com
                    
                      +2
                      Не так давно писал пост на подобную тему — фаервол на lua_nginx. Это требует больше телодвижений по настройке, но результат сильно умнее разбора логов + перемалывает 10Г входящего http трафика.
                      • UFO just landed and posted this here

                        Only users with full accounts can post comments. Log in, please.