Пожалуй, лучший облачный хостинг в России
15,90
рейтинг
9 августа 2012 в 10:44

Разное → Доступные методы борьбы с DDoS-атаками для владельцев vds/dedicated серверов с Linux

image

Начать свое присутствие на Хабре мы решили с материала, подготовленного для Конференции уральских веб-разработчиков, в котором описаны проверенные на собственной практике и оказавшиеся вполне успешными методы борьбы с DDoS-атаками. Целевая аудитория данной статьи — это программисты, имеющие в распоряжении vds или dedicated. Статья не претендует на полноценное руководство и многие сисадминские нюансы в ней намеренно опущены. Мы рассматриваем только DDoS типа http flood как наиболее распространенный тип DDoS и наиболее дешевый для заказчика.

Целевая аудитория данной статьи – это программисты, имеющие в распоряжении VDS или Dedicated.

Связка nginx – apache – fastcgi/wsgi. Узкие места


Типовая схема организации работы веб-приложения состоит из 3х уровней: это reverse proxy-сервер (например nginx), apache (web-сервер) и какое-то fastcgi/wsgi/… приложение. На практике имеют место вырожденные случаи, когда нет apache или при использовании mod_php/mod_python, когда нет выделенного приложения (оно встроено в веб-сервер), но суть работы схемы при этом не меняется, меняется только количество уровней в ней.

Fcgi сервер может запустить несколько десятков процессов, параллельно обрабатывающих входящие запросы. Увеличить это значение можно только до определенного предела, пока процессы помещаются в памяти. Дальнейшее увеличение приведет к swapping'у. При DDoS-атаке или при высокой посещаемости, когда все текущие процессы fcgi уже заняты обработкой поступивших запросов, вновь поступающие запросы apache ставит в очередь, пока либо не освободится какой-то из fcgi процессов, либо не возникнет таймаут нахождения в очереди (в этом случае возникает ошибка 503).

Apache точно также имеет лимит на количество коннектов, как правило несколько сотен (на порядок больше, чем fcgi). После того, как все коннекты к apache исчерпаны, запросы в очередь уже ставит nginx.
Nginx, в силу своей асинхронной архитектуры, может спокойно держать несколько тысяч коннектов при очень скромном расходе памяти, поэтому типовые DDoS-атаки не доходят до уровня, когда nginx не в состоянии принимать новые коннекты, если nginx настроен соответствующим образом.

Фильтрация трафика на nginx. Разбор логов nginx


Предлагаемая нами методика сводится к тому, чтобы лимитировать общее количество запросов к сайту определенным значением (например, 1500 в минуту, в зависимости от того, сколько максимум хитов может выдержать движок сайта при текущих серверных мощностях). Все, что будет превышать это значение, мы первоначально будем фильтровать с помощью nginx (limit_req_zone $host zone=hostreqlimit:20m rate=1500r/m;).
Затем мы будем смотреть в логи nginx и вычислять там те IP-адреса, которые были отфильтрованы более определенного количества раз за определенный промежуток времени (например, более 100 раз за 5 минут) и запрещать доступ к нам этим IP-адресам с помощью firewall.

Почему мы не используем традиционный и часто рекомендуемый лимит по подключениям с одного и того же ip адреса (limit_req_zone $binary_remote_addr ...)? Во-первых, под этот лимит попадут клиенты провайдеров, сидящие за nat'ом. Во-вторых, установить универсальное значение порога невозможно, потому что есть сайты с ajax и большим количеством js/css/картинок, у которых в принципе на загрузку одной страницы может требоваться несколько десятков хитов, и использовать такой порог можно только индивидуально для каждого сайта. В-третьих, для так называемых «вялотекущих» DDoS-атак боты вообще не будут попадать под этот порог – ботов будет много, но каждый из них в отдельности будет делать немного запросов за короткий период времени, в результате мы ничего не сможем отфильтровать, а сайт при этом работать не будет.

Для того чтобы воспользоваться нашим методом, конфигурационный файл nginx, при работе nginx в качестве reverse proxy для apache, должен выглядеть примерно следующим образом:
http {
     limit_req_zone $host zone=hostreqlimit:20m rate=1500r/m;
     ...
     server {
               listen       1.2.3.4;
               server_name  domain.ru www.domain.ru;
               limit_req zone=hostreqlimit burst=2500 nodelay;
               location /
               {
                    proxy_pass http://127.0.0.1:80;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header Host $host;
               }
     }
}

В этом конфиге также подразумевается, что apache у нас слушает на loopback интерфейсе на 127.0.0.1:80, а nginx на 80-м порту на нашем внешнем ip-адресе (1.2.3.4) и на порту 8080 на 127.0.0.1.

Отфильтрованные nginx'ом хиты будут сопровождаться такой записью в error.log nginx'а:
2012/01/30 17:11:48 [error] 16862#0: *247484 limiting requests, excess: 2500.200 by zone "hostreqlimit", client: 92.255.185.237, 
server: domain.ru, request: "GET / HTTP/1.1", host: "domain.ru", referrer: "http://www.yahoo.com/"

Чтобы получить из error.log список всех блокировавшихся ip-адресов мы можем выполнить следующее:
cat error.log | awk '/hostreqlimit/ { gsub(", ", " "); print $14}' | sort | uniq -c | sort -n

Но мы с вами помним, что в этом случае мы блокируем всех, кто обратился к сайту после того, как счетчик обращений насчитал 1500 раз в минуту, поэтому не все заблокированные – боты. Ботов же можно выделить, если провести какую-то условную черту по количеству блокировок. Как правило, для черты выбирается значение в несколько сотен раз за 5-15 минут. Например, мы пополняем список ботов раз в 5 минут и считаем что все, кого nginx заблокировал более 200 раз – боты.

Теперь перед нами стоит две проблемы:
  1. Как выбрать из лога период «последние 5 минут»?
  2. Как отсортировать только тех, кто был заблокирован более N раз?

Первую проблему решаем при помощи tail -c +OFFSET. Идея сводится к тому, что после разбора error.log мы записываем во вспомогательный файл его текущий размер в байтах (stat -c '%s' error.log > offset), а при следующем разборе отматываем error.log на последнюю просмотренную позицию (tail -c +$(cat offset)). Таким образом, запуская разбор логов раз в 5 минут, мы будем просматривать только ту часть лога, которая относится к последним 5 минутам.

Вторую проблему решаем при помощи скрипта на awk. В итоге получим (THRESHOLD — это тот самый лимит по количеству блокировок, после которого соответствующий IP-адрес считается принадлежащим атакующему нас боту):
touch offset; (test $(stat -c '%s' error.log) -lt $(cat offset) 2>/dev/null && echo 0 > offset) || echo 0 > offset; \
tail -c +$(cat offset) error.log | awk -v THRESHOLD=200 '/hostreqlimit/ { gsub(", ", " "); a[$14]++; } \
END { for (i in a) if (a[i]>THRESHOLD) printf "%s\n", i; }' ; stat -c '%s' error.log > offset

Подразумевается, что этот набор команд выполняется в той директории, где лежит error.log от nginx, то есть как правило это/var/log/nginx. Полученный в результате список мы можем отправить в firewall на блокировку (об этом ниже).

Как просто можно построить список сетей для бана


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

Первое, что нам может помочь, это список сетей Рунета на сайте NOC masterhost. В настоящий момент в этом списке насчитывается почти 5000 сетей. Большинство российских сайтов ориентированы на посетителей из России, поэтому отсечь всех заграничных посетителей, а вместе с этим и всех заграничных ботов, выглядит вполне логичным решением. Однако, в последнее время внутри Российских сетей возникает все больше и больше самостоятельных ботнетов, поэтому такое решение хоть и обосновано, но очень часто не спасает от атаки.

Если сайт имеет устоявшееся community (ядро), то мы можем выбрать список IP адресов постоянных посетителей из логов веб-сервера за последние 3-4 недели. Хотя новые посетители на время атаки на сайт попадать не смогут, но зато старые активные пользователи скорее всего даже не заметят никакой атаки. Кроме того, среди постоянных посетителей вряд ли будут боты, поэтому такой метод может в принципе сам по себе остановить атаку на какое-то время.

Если сайт местного значения, то можно забанить на firewall всех, кроме сетей местных провайдеров и сетей поисковых систем (Яндекс).

Введение в iptables, пример простейшего firewall


В ОС Linux firewall работает на базе iptables. Фактически суть работы iptables сводится к тому, чтобы для каждого пакета трафика, принимаемого снаружи или отправляемого с сервера, был применен определенный набор правил, которые могут повлиять на судьбу данного пакета. В самом простом случае правила просто говорят, что пакет нужно либо принять (ACCEPT), либо отбросить (DROP). Правила подразделяются на цепочки (chains). Например, принимаемые сервером из Интернета пакеты попадают в цепочку INPUT, где для каждого пакета с самого начала правил в цепочке проверяется, подходит ли данный пакет под описанные в правиле условия и если подходит, то к пакету применяется это правило, а если нет, то пакет передается следующему правилу. Если ни одно из правил для пакета не было применено, то к пакету применяется политика по-умолчанию (policy).

В качестве простого примера напишем правила firewall, которые разрешают подключение к серверу по ssh только из нашего офиса (с ip-адреса 1.2.3.4), а всем остальным доступ по ssh блокируют:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -s 1.2.3.4/32 -m comment --comment "our office" -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j DROP
COMMIT

Эти строки можно записать в текстовый файл и загрузить в firewall с помощью: iptables-restore < firewall.txt, а сохранить текущее состояние firewall в файл: iptables-save > firewall.txt.

Работают эти правила следующим образом. Первая строка — разрешаем весь трафик для всех соединений, которые уже открыты (процедура handshake пройдена). Вторая строка — разрешаем любой трафик с ip-адреса 1.2.3.4 и помечаем комментарием, что это наш офис. На самом деле сюда доходят только пакеты, устанавливающие какое-либо соединение, то есть пакеты типа syn и ack, все остальные пакеты проходят только первую строку. Третья строка – запрещаем всем подключение по tcp на 22-й порт. Сюда доходят попытки подключения (syn, ack) по ssh от всех, кроме нашего офиса.

Интересно, что первую строчку можно смело удалить. Плюс наличия такой строки в том, что для уже открытых соединений в firewall отработает всего одно правило, а пакеты в рамках уже открытых соединений – это подавляющее большинство принимаемых нами пакетов, то есть firewall с такой строкой в самом начале практически не будет вносить никаких дополнительных задержек в работу сетевого стека сервера. Минус — эта строка приводит к активации модуля conntrack, который держит в памяти копию таблицы всех установленных соединений. Что затратнее – держать копию таблицы соединений или необходимость обрабатывать несколько правил firewall на каждый пакет? Это индивидуальный нюанс каждого сервера. Если firewall содержит всего несколько правил, на наш взгляд правильнее строить его правила так, чтобы модуль conntrack не активизировался.

В iptables можно создавать дополнительные цепочки, задаваемые пользователем. В каком-то смысле это выглядит как аналог вызова функций в языках программирования. Создаются новые цепочки просто: iptables -N chain_name. Используются создаваемые таким образом цепочки для того, чтобы разделять firewall на разные логически блоки.

Рекомендуемая структура firewall для противодействия DDoS


Рекомендуемая нами структура для противодействия DDoS состоит из следующих логических блоков:
  1. Разрешаем трафик по уже установленным соединениям.
  2. Прописываем разрешения для «своих» ip-адресов.
  3. Таблица whitelist – это исключения.
  4. Таблица DDoS – это идентифицированные нами боты.
  5. Таблица friends – это сети РуНета, которым мы разрешаем доступ, если пакет дошел до этого уровня.
  6. Всем остальным – -j DROP.

В терминах iptables это выглядит так:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:ddos - [0:0]
:friends - [0:0]
:whitelist - [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -s 1.2.3.4/32 -m comment --comment "our office" -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j DROP
-A INPUT -j whitelist
-A INPUT -j ddos
-A INPUT -j friends
-A INPUT -j DROP
-A whitelist -s 222.222.222.222 -j ACCEPT
-A whitelist -s 111.111.111.111 -j ACCEPT
-A ddos -s 4.3.2.0/24 -j DROP
-A friends -s 91.201.52.0/22 -j ACCEPT
COMMIT

Опять же, целесообразность наличия второй строки под вопросом и в зависимости от полного размера firewall она может как ускорять его работу, так и тормозить.

Заполняем таблицу friends:
for net in $(curl -s http://noc.masterhost.ru/allrunet/runet); do iptables -A friends -s $net -j ACCEPT; done

Проблема такого firewall в его монстроидальности: таблица friends в случае Рунета будет содержать порядка 5000 правил. Таблица DDoS в случае более-менее среднего DDoS'а будет содержать еще 1-2 тысячи записей. Итого firewall будет состоять из 5-7 тысяч строк. При этом все пакеты, прилетающие от заграничных отправителей, которые должны быть просто отброшены, на самом деле будут проходить все 5-7 тысяч правил, пока не доберутся до последнего: -A INPUT -j DROP. Сам по себе такой firewall будет отъедать огромное количество ресурсов.

Ipset – решение для монстроидальных firewall'ов


Ipset полностью решает проблему с монстроидальными firewall, в которых присутствуют тысячи строк с описанием того, что делать с пакетами с разными адресами отправителей или получателей. Ipset представляет собой утилиту по управлению специальными set'ами (наборами однотипных данных), где для нескольких заранее определенных типов данных сделаны специальные hash-таблицы, позволяющие очень быстро устанавливать факт наличия или отсутствия определенного ключа в этой таблице. В каком-то смысле это аналог memcached, но только гораздо более быстрый и позволяющий при этом хранить только несколько конкретных типов данных. Создадим новый набор данных для хранения информации об ip-адресах DDoS-ботов:
ipset -N ddos iphash

Здесь последним параметром указывается тип создаваемой таблицы: nethash – это set для списка сетей, iphash – для отдельных ip адресов. Есть разные варианты таблиц, подробности в man ipset. Соответственно whitelist и friends – это таблицы типа nethash, а DDoS — iphash.
Чтобы воспользоваться созданной таблицей ipset в firewall, достаточно одного правила (строки firewall), например:
-A INPUT -m set --match-set whitelist src -j ACCEPT
-A INPUT -m set --match-set ddos src -j DROP

Добвить какой-то ip-адрес во вновь созданную таблицу можно так:
ipset -A ddos 1.2.3.4

Таким образом, весь наш firewall при использовании ipset сводится к:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -s 1.2.3.4/32 -m comment --comment "our office" -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j DROP
-A INPUT -m set --match-set whitelist src -j ACCEPT
-A INPUT -m set --match-set ddos src -j DROP
-A INPUT -m set --match-set friends src -j ACCEPT
-A INPUT -j DROP
COMMIT

Заполняем set friends (тип nethash):
for net in $(curl -s http://noc.masterhost.ru/allrunet/runet); do ipset -A friends $net; done

Заполняем set ddos из показанной ранее команды:
touch offset; (test $(stat -c '%s' error.log) -lt $(cat offset) 2>/dev/null && echo 0 > offset) || echo 0 > offset; \
for ip in $(tail -c +$(cat offset) error.log | awk -v THRESHOLD=300 \
'/hostreqlimit/ { gsub(", ", " "); a[$14]++; } END { for (i in a) if (a[i]>THRESHOLD) printf "%s\n", i; }' ; \
stat -c '%s' error.log > offset); do ipset -A ddos $ip; done

Используем модуль TARPIT


Модуль iptables под названием tarpit представляет собой так называемую «ловушку». Принцип работы tarpit такой: клиент присылает syn-пакет для попытки установки handshake (начало установки tcp-соединения). Tarpit отвечает ему syn/ack пакетом, о котором тут же забывает. При этом никакое соединение на самом деле не открывается и никакие ресурсы не выделяются. Когда от бота приходит конечный ACK-пакет, модуль tarpit отправляет назад пакет, устанавливающий размер окна для передачи данных на сервер равным нулю. После этого любые попытки закрыть это соединение со стороны бота tarpit'ом игнорируются. Клиент (бот) считает, что соединение открыто, но «залипло» (размер окна 0 байт) и пытается закрыть это соединение, но он ничего не может сделать вплоть до истечения таймаута, а таймаут, в зависимости от настроек – это порядка 12-24 минут.

Использовать tarpit в firewall можно следующим образом:
-A INPUT -p tcp -m set --match-set ddos src -j TARPIT --tarpit
-A INPUT -m set --match-set ddos src -j DROP

Собираем xtables-addons


К сожалению, модули ipset и tarpit в стандартном наборе современных дистрибутивов отсутствуют. Их нужно установить дополнительно. Для более-менее свежих дистрибутивов Debian и Ubuntu это делается просто:
apt-get install module-assistant xtables-addons-source
m-a a-i xtables-addons

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

Тюнинг ядра


Как правило, разговоры о борьбе с DDoS-атаками начинаются с рекомендаций по тюнингу ядра ОС. Однако, на наш взгляд, если ресурсов в принципе мало (например, при наличии менее одного Гб памяти), то тюнинг ядра смысла не имеет, так как почти ничего не даст. Максимум полезного в этом случае будет — включить так называемые. syncookies. Включение syncookies позволяет эффективно бороться с атаками типа syn flood, когда сервер забрасывается большим количеством syn-пакетов. Получая syn-пакет сервер должен выделить ресурсы на открытие нового соединения. Если за syn-пакетом не последует продолжение процедуры установки соединения, сервер выделит ресурсы и будет ждать, пока не произойдет таймаут (несколько минут). В конечном итоге, без syncookies, при достаточном количестве отправленных серверу syn-пакетов, он не сможет более принимать соединения, потому что система израсходует на хранение информации о полуоткрытых соединениях все свои ресурсы.

Параметры ядра, о которых пойдет речь, правятся с помощью команды sysctl:
sysctl [-w] option

Опция -w означает, что вы хотите записать новое значение в какой-то параметр, а ее отсутствие – что вы хотите прочитать текущее значение этого параметра. Рекомендуется поправить следующие параметры:
net.ipv4.tcp_syncookies=1
net.ipv4.ip_local_port_range = 1024 65535
net.core.netdev_max_backlog = 30000 
net.ipv4.tcp_max_syn_backlog = 4096
net.core.somaxconn = 4096
net.core.rmem_default = 124928
net.core.rmem_max = 124928
net.core.wmem_max = 124928

  • Параметр net.ipv4.tcp_syncookies отвечает за включение механизма syncookies; net.core.netdev_max_backlog определяет максимальное количество пакетов в очереди на обработку, если интерфейс получает пакеты быстрее, чем ядро может их обработать.
  • net.ipv4.tcp_max_syn_backlog определяет максимальное число запоминаемых запросов на соединение, для которых не было получено подтверждения от подключающегося клиента.
  • net.core.somaxconn максимальное число открытых сокетов, ждущих соединения.
  • Последние строки – это различные буферы для tcp-соединений.

Мы надеемся, что эта статья будет полезна для владельцев VDS или Dedicated серверов. Просим оставлять свои комментарии и замечания.
Автор: @NetAngels
NetAngels
рейтинг 15,90
Пожалуй, лучший облачный хостинг в России

Комментарии (116)

  • +5
    Очень интересно, но хотелось бы видеть отформатированные правила.
    • 0
      Вы правы, сейчас исправимся.
  • +2
    Все хорошо и интересно, правда по своему опыту борьбы с атаками пришел к выводу что все же бороться с ддосом нужно начинать не на уровне nginx, а раньше, на уровне iptables. Темболее что там есть весь необходимый для этого инструментарий. Тюнинг же nginx и php должен делаться просто под большую нагрузку и возможность держать как можно большее число прорвавшихся запросов.
    Вышеперечисленный в статье функционал по отбитию аттак можно также реализовать при помощи таких инструментов как: limit, connlimit, ipset, geoip…
    Я например как-то делал нечто похожее описанному в статье, только подозреваемых ботов я не наглухо блокировал а заносил в определенный ipset список, по которому ставилось ограничение по числу коннектов 1 в сек (серый список). В случае если он продолжал свою бурную деятельность, заносил уже в черный.
    Все лимиты настраивал в обычных условиях с запасом в 20-30%, обычно жалоб небыло.
  • –1
    Статья отличная! Но скажу с другой колокольни и не холивара ради — как владелец бизнеса для себя выяснил, что пока идет DDoS и компания теряет деньги, в итоге эксперименты с самостоятельной настройкой защиты обходятся дороже, чем сразу обратиться к профильным компаниям по защите от DDoS.

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

    Потом уже, с набитыми шишками, обратились в швейцарскую компанию по защите от DDoS. В отличие от нас, ситуацию исправили за 10 минут раз и навсегда. Дороговато, но это контролируемые и прогнозируемые расходы.
    • 0
      Не могли бы вы привести свой шортлист компаний, которым вы бы доверили такую работу? Занесу в избранное.
      • +1
        Сначала пытался обращаться к русским, но они грубили, тормозили с ответами, что никак не устраивало за ту цену, которую они выставляли.
        Начал писать иностранцам, остановился на dragonara.net
    • 0
      Совершенно верно говорите. Подобный тюнинг сайтов нужен только для того, чтобы не отвлекаться на всякую мелочевку. Хотя, порой, можно добиться вполне неплохих результатов и своими силами.
      При любом ддосе главное правило «устоять в начале любой ценой». Пусть сайт открывается через раз, тормозит, главное он должен работать. Эдакий психологический эффект, он демотивирует ддосеров.
      Посему идеальный вариант своя защита рассчитанная на n коннектов + какой-то балансировщик, который переключает нагрузку на антиддос тоннель.
    • 0
      Безусловно, специализированные компании предоставляют за те деньги, что они просят, значительно более продвинутые методики защиты от DDoS, чем то, что описано в статье. Однако, статья все равно может быть полезна если DDoS не очень сильный, либо даже если приличный, чтобы что-то сделать на время пока Вы договариваетесь о защите сайта со специализированной компанией и перенаправляете на них свои А-записи в DNS. А это может занять несколько часов.
  • 0
    Это точно ваша статья?
    • +2
      Это точно наша статья. Более того, это не просто статья, это конспект нашего доклада на UWDC-2012, который нагло сперт сайтом mannix.ru
      • 0
        Манникс эту статью позаимствовал 6 марта (дата видна сверху), а UWDC-2012 прошла в конце февраля.
      • 0
        Устроим DDoS атаку на сервер mannix.ru в виде хабрэффекта, и узнаем читает ли администрация сайта материал который тырит ))
      • 0
        Тогда никаких претензий. Интересные товарищи, однако.
    • +1
      Спасибо тебе, добрый человек ;)
      Там форматирование нормальное и глаза в узел не завязываются…
  • 0
    Спасибо, очень неплохая подборка методов. В мемориз, однозначно.
  • +8
    Статья ниочём! Бред полный, это не защита от DDOS атак, а самоубийство своего сайта/сервера. Не дай бог кому-то так свой сервер настроить и использовать всё что здесь понаписано! Одно net.core.somaxconn = 4096 чего стоит, а если сделать как нам говорит автор: limit_req_zone $host zone=hostreqlimit:20m rate=1500r/m;, то я вообще смогу положить его сайт с одного компьютера в вечный DDOS и все посетители будут получать ошибку 503, пока он не удалит это идиотское правило.

    Если как тут пишут, это не статья, а стыренный чей-то доклад, то могу поздравить докладчиков — ваш доклад полная лажа!

    Видимо на Хабре проблема с реальными качественными статьями на эту тему, надо будет на днях выложить качественные рекомендации используемые на боевых серверах.
    • +3
      > Видимо на Хабре проблема с реальными качественными статьями на эту тему, надо будет на днях > выложить качественные рекомендации используемые на боевых серверах.

      Не откладывайте в долгий ящик…
      Можно еще про балансировку нагрузки и прочую отказостойчивость.

      Сравним насечку на напильниках…
    • 0
      Если Вы так считаете, то, вероятно, у Вас есть и обоснование? Поделитесь с общественностью чем именно Вас не устраивает приведенная методика, кроме того что она «ниочём»? Дело в том, что в реальном мире эта методика работает и спасла уже не один сайт, но возможно это была случайность?
      • +2
        Кхм, всё что написано в статье по определению не может «устраивать» и вообще хоть как-то использоваться на серверах под DDOS атакой. Мне нечего даже перечислять, здесь всё в корне неправильно. Спасти множество сайтов ваши методики ну никак не могли, они могли только наоборот побыстрее «прибить» несчастные сайты, поскольку предложенные решения только усугубляют действие DDOS атаки, а не борются с ней.

        Статью надо бы срочно убрать в черновики подальше с глаз долой и больше никому не показывать. Вы даёте вредные рекомендации которые убивают сайты при любой мало-мальской DDOS атаке, а народ бездумно копирует всё это в свои конфиги и ставит плюсы (вижу уже более 30 несчастных). Не знаю почему статья в плюсах, видимо все грамотные сисадмины в отпусках.

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

        Если кто из администрации Хабра упрочитает — уберите пожалуйста статью, она даёт вредные рекомендации читателям. Не знаю как-кому, но я рискну предположить что автор занимается DDOS атаками и пустил эту дезу в массы для хомячков. Хомячки не глядя вносят эти настройки на свои дедики, хостинги, сайты и как результат их можно с лёгкостью ддосить. Учитывая посещаемость Хабра, эффект от такой липовой борьбы с DDOS может быть большим, конечно в пользу ддосеров :-)
        • +2
          То есть аргументов у Вас нет? Отлично.
          • 0
            Аргументы? Т.е. вы предлагаете чтобы я вам сейчас перечислял каждую вашу рекомендацию и описывал почему она вредная? Боже упаси меня в комментариях целую статью переписывать с пояснениями и опровержениями… Хватает уже того, что вы поисковики блокируете, даете возможность положить сайт с одного компьютера и делаете так, чтобы машина захлебнулась своим же файерволом.
        • –1
          Где-то пол года назад здесь же на Хабре была статья от highloadlab, они советовали аналогичную методику, но несколько иную. Они тоже не умеют с ddos бороться?
          • +3
            Не верю что они такой бред могли насоветовать, дайте ссылку. Уверен они давали верное направление. Вы решили видимо переплюнуть ребят из highload, а случился фэйл. Да, надо тюнить ядро, нужно использовать limit_conn (про который вы даже не упомянули), limit_req и т.д. но не так как вы, а совершенно иначе.
            • +2
              У нас иное мнение, но Вы, к сожалению, даже не попытались понять почему.
        • +2
          Для наглядности было бы все же красиво обпровергнуть парочку тезисов автора…
          Жду вашей статьи.
          • +1
            Раз вам так уж нужно парочку, то пожалуйста, начнем с начала:

            1) Он говорит не нужно банить по $binary_remote_addr и правильно говорит, только вместо того чтобы банить по динамической perl_set переменной $host.md5($uri+аргументы).$binary_remote_addr, он банит тупо по адресу сайта $host. Т.е. если к сайту во время ddos за минуту отправили больше 1500 запросов (конечно больше отправят) — сайт висит. Автор не понимает что это за правило вообще или специально хочет сайт убить.

            2) Дальше идём по статье, следующее у него — бан после 200 запросов за 15 минут. Т.е. он банит все поисковики (900 запросов / 15 минут), оставляя только Яндекс и может быть Google, путем добавления в белый лист мифических подсетей этих поисковых систем (где он взял такие списки, а если и взял, с чего решил что они полные?). На остальные поисковики ему плевать. А если атака не 2 дня, а 2 недели — все равно плевать. Можно вылетать из индекса, закрывать бизнес и вешаться.

            Ну и далее по статье можно описывать в том же духе… ниже в комментах уже отметили предложенный «супертюнинг ядра».
            • 0
              В (1) под «сайт висит» подразумевается, что если с одного IP на сайт пришло больше 1500 запросов за минуту, IP попадет в бан?

              Спасибо, жду вашу статью.
              • 0
                Нет, 1500 запросов с любого адреса. Причем это мегаограничение установлено даже не на отдельный специальный location/ который ведет к Apache, а на весь сервер. Т.е. если сайт со множеством картинок, CSS и JS скриптов + высокая посещаемость, то он даже без DDOS просто напросто ляжет от этого правила. В статье приведены правила «как отключить свой сайт», а не как его защитить.

                Свою статью постараюсь написать, надо только время найти. Не собирался, но видя такое понимаю что надо…
              • 0
                Вы зря его спрашиваете, он не понял сути. Ниже я написал все подробно.
            • 0
              Спасибо за комментарий! Наконец-то я понял, зачем вели учет по $host, хотя я и не считаю, что это хорошая затея. Однако если использовать $host.md5($uri+аргументы).$binary_remote_addr, то почему тогда ботам не посылать каждый раз разный uri+аргументы?

              По поводу (2). Из текста статьи мне показалось, что в бан попадет только тот, кто будет 100 раз отфильтрован за 15 минут. А для каждого «отфильтровывания» нужно подать более 1500 запросов в минуту (допустим, учет ведем всё-таки по $binary_remote_addr). Поисковик не подает запросы так часто, поэтому он не должен «отфильтроваться» nginx'ом ни разу. Кажется, суть тут в том, что бот, в отличие от пользователя, не успокоится после отфильтровывания nginx'ом и быстро наберет необходимые 100 отфильтрованных запросов. Хотя бота можно сделать и умного. Как, к примеру, отличить пользователя от бота, имитирующего неторопливое хождение по ссылкам, заполнение форм и нажатие кнопок?
              • 0
                1) Это как пример было показано конечно. Я бы предложил такую комбинированную переменную:

                $combined
                perl_set $combined '
                sub {
                use Digest::MD5 qw(md5_hex);
                my $r = shift;
                my $uri = $r->uri;
                return md5_hex($r->remote_addr.$r->header_in("Host").$uri);
                }';
                


                т.е. по сути это md5($ip$host$uri).

                2) Сколько раз будет отфильтрован бот там вообще не имеет значения н и к а к о г о. Само правило не даёт сделать более 1500 запросов к сайту за минуту (вообще любых запросов и к статике и к динамике и с любого ip). Т.е. сайт будет лежать.
                • 0
                  1) То есть разные uri дают разные значения переменной. Тогда приходим к той же проблеме: что, если бот посылает каждый раз новый uri?

                  2) Допустим, от этого отказались. То есть считают не для $host, а для $binary_remote_addr, например. Пусть статику считают отдельно, с более мягкими ограничениями. Мне кажется, при таких условиях имеет смысл считать, сколько раз «попался» потенциальный бот. Если 100 раз за 5 минут, это явный бот, так как человек не будет тыкаться, если его временно заблокировали. Но опять же это спасет только от простых ботов. Стоит им добавить капельку «интеллекта», и они смогут это обходить. Если Вы напишете статью, было бы интересно узнать про способы борьбы с «умными» ботами.
                  • 0
                    Зачем обсуждать вымышленные вами ситуации? При определённых обстоятельствах всё имеет смысл, а мы же обсуждаем ту ересь, которая нам предлагается в этой статье.

                    Что касается фильтрации, то описанная мною переменная предназначена для фильтрации ботов долбящихся по одинаковому адресу. Если боты долбятся по разным URL, то для этого делается отдельный счётчик md5($host$ip), но никак не $host!
            • +5
              Похоже вся проблема сводится к тому, что Вы ничего не поняли, а сразу бросились критиковать. Методика, на которой строится статья, сводится к следующему:

              1. У любого сайта есть порог посещаемости, свыше которой он не тянет. В данном случае он установлен в 1500 хитов в минуту, хотя это индивидуально и понятно как настраивается. Когда на сайт налетает постоянная высокая посещаемость, то очевидно выше этого порога сайт начинает всем выдавать ошибки. Здесь, установив в nginx порог по посещаемости, те, кто создаст первые 1500 хитов, увидят именно сайт, а не ошибки. Далее все, кто пришел после 1500 хитов, начинают получать ошибку от nginx и их ip пишется в логи. Пока что всё просто: пока сайт тянет, он работает, дальше мы принудительно отключаем поток входящих запросов.

              2. По прошествии 5-15 минут у нас уже есть пачка записей в логах о том, что кто-то был зафильтрован nginx'ом. Боты, в отличие от людей, долбятся постоянно, поэтому всегда можно найти тот самый THRESHOLD, выше которого кол-во банов в логе nginx будет означать, что это постоянно долбящийся бот, а ниже которого — человек.

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

              На случай ложных срабатываний введен whitelist

              Поэтому Ваши выпады в адрес статьи строятся на том, что Вы методику просто не поняли, Вы докапываетесь до деталей не понимая сути того, зачем они здесь.

              В пункте (1) Вы ошибаетесь. Во-первых, сайт «висит» только до конца этой минуты, а потом работает снова. Во-вторых, в любом случае более 1500 (подставьте свое значение) хитов в минуту сайт все равно упадет, но только не до конца минуты, а вообще.

              В пункте (2) Вы ошибаетесь еще больше. Допустим, поисковый робот делает 900 запросов за 15 минут. Кто сказал, что все 900 запросов попадут в отлуп на nginx? 900 запросов за 15 минут это 60 запросов в минуту (1 запрос в секунду). Сколько из них получат ошибку зависит от интенсивности атаки, но точно не 100%. Кроме того, понятно же что роботы ходят с одних и тех же сетей. Соберите статистику по этим сетям заранее и обновляйте списки сетей поисковиков. Что тут сложного? Ничего.
              • +2
                А если один атакующий сделает 1500 запросов за 50 секунд и перестанет атаковать? Сайт будет недоступен какое-то время и часть хороших пользователей может попасть в «вечный» бан, а он не попадет, так как не будет заходить следующую минуту. Выждав минуту, он сделает то же самое и т.д. Это можно делать в одиночку, без ботнета. Мне кажется, что загонять всех под один счетчик опасно.
                • 0
                  Почему же часть хороших пользователей попадет в вечный бан? Во-первых, для того, чтобы воспользоваться Вашим методом атакующему нужно точно знать методику защиты. Очевидно что заранее он ее знать не будет никаким образом. Во-вторых, даже в такой ситуации «хорошие» пользователи в бан не попадут. В-третьих, на то у сервера и должен быть админ, чтобы такие ситуации мог вычислить по логам, если методика защиты от атаки не работает.

                  Никто же не говорит что здесь описана серебрянная пуля. Это всего лишь одна из методик. Она не безгрешна, но она реально работает.
              • –2
                1. У любого сайта есть порог посещаемости, свыше которой он не тянет. В данном случае он установлен в 1500 хитов в минуту, хотя это индивидуально и понятно как настраивается. Когда на сайт налетает постоянная высокая посещаемость, то очевидно выше этого порога сайт начинает всем выдавать ошибки. Здесь, установив в nginx порог по посещаемости, те, кто создаст первые 1500 хитов, увидят именно сайт, а не ошибки. Далее все, кто пришел после 1500 хитов, начинают получать ошибку от nginx и их ip пишется в логи. Пока что всё просто: пока сайт тянет, он работает, дальше мы принудительно отключаем поток входящих запросов.

                image

                Вы правда верите в то, что сайт будет более или менее сносно работать, с таким вот limit_req_zone $host zone=hostreqlimit:20m rate=1500r/m; правилом? Первая же серия из 3000 одновременных запросов от одного бота положит ваш сайт намертво в первую же секунду. Кому он будет открываться? Господу богу? Будет открываться не сайт, а ошибка 503 всегда, всем и постоянно. Вы просто отключаете свой сайт этим правилом. Устанавливать порог посещаемости по $host это бред! Фух… ну простите, не могу я больше что-либо писать в этом топике, пусть хомячки дальше плюсуют вашу статью, а вы будете их новым проповедником своих заповедей, правил и т.д. :-)

                На сим откланиваюсь и снимаю шляпу :/
                • +2
                  Первая же серия из 3000 запросов от бота положит сайт на 1 минуту. Через 5 минут этот бот будет навечно забанен на firewall. Вот если вся атака будет строиться на том, что каждый бот (и только один одновременно) будет делать 3000 запросов и замолкать на минуту, тогда да, тогда эта методика не сработает. Но вот я не видел атак с таким паттерном ни разу, а всего разных атак мы видели множество.
                  И против такого паттерна можно еще проще написать защиту, тут даже nginx не понадобится. Достаточно в firewall считать кол-во коннектов в минуту с ip и банить тех, кто в минуту делает больше 120 коннектов, например.
                • –1
                  Кстати, установка порога посещаемости по $host всего лишь ограничивает кол-во хитов в минуту на один сайт. Это в принципе полезно делать, когда сайтов на сервере несколько, чтобы атака на один из сайтов не положила вообще всё.
                • 0
                  «все картинки я буду заливать только через хабрасторедж». «все картинки я буду заливать только через хабрасторедж». «все картинки я буду заливать только через хабрасторедж». «все картинки я буду заливать только через хабрасторедж». «все картинки я буду заливать только через хабрасторедж». «все картинки я буду заливать только через хабрасторедж». «все картинки я буду заливать только через хабрасторедж». «все картинки я буду заливать только через хабрасторедж». «все картинки я буду заливать только через хабрасторедж». «все картинки я буду заливать только через хабрасторедж».
      • –2
        Скажите, вы хоть понимаете, что ваши правила даже поисковики банят??? Поисковый робот делает 1 запрос в секунду, т.е. за 15 минут он сделает 900 запросов, а вы баните всех кто обратился к хосту более 200 раз! Этоже ж ппц, простите меня за такое слово. Скройте статью если уважаете себя и читателей.
        • +1
          Простите, а Вы статью читали? Там и про whitelist было, и методика-то вами понята не правильно совершенно.
          • +1
            whitelist? Для поисковиков? Ух ты… это как? Методом поглаживания магического шара? Или может быть у вас есть список всех IP адресов гугла, с которых он может придти? Или вы заносите googlebot в whitelist по строке с user agent? Ну тогда я дам команду ботам прикинуться googlebot и ваш фильтр успешно занесет весь мой ботнет в белый лист.

            Или я может опять чего-то не так понял? Тогда расскажите, растолкуйте…
            • –1
              Очень не сложно найти список сетей, откуда ходят роботы Гугла и/или Яндекса. Буквально за 5 минут гуглится.

              Никто не говорит, что все описанные в статье действия нужно делать в момент, когда атака уже началась. Все whitelist и прочее надо готовить заранее
              • +1
                Кем составлены эти списки и откуда они? Сомневаюсь что поисковики список своих сетей выкладывают (хотя конечно было бы полезно). Что насчет WebAlta, Rambler, Yahoo, Bing, Alexa, Mailru и прочих пауков, у вас тоже есть полные списки их сетей? Подумайте, зачем вам вообще эти списки… они же абсолютно не нужны, надо просто грамотно и правильно фильтрацию настраивать, а не так, как сделали вы.

                Не подумайте что я злой и наезжаю на вас, просто статься реально вредна, я опасаюсь за неопытных хабровчан, ну а вы защищаете свою стаью ибо уверены в её правильности. Эх, это уже философия…
                • 0
                  Лично я, как частное лицо, считаю что достаточно пускать на сайт роботов Яндекса и, может еще Гугля. Сети Я. и Г. выделить очень просто. Остальных на время ddos, а это обычно пара дней, можно просто не пускать, ничего страшного не случится. Ну это в общем случае.

                  Наша идея в том, чтобы предоставить инструмент для защиты, а не комплексное решение. Комплексные решения на рынке много кто предлагает за деньги, welcome.
                • –1
                  RIPE вам в помощь. Не сложно написать скрип, парсящий периодически базу RIPE выковыривая подсети, анонсирующиеся на AS поисковиков и других заведомо благоверных компаний.
              • –1
                >Очень не сложно найти список сетей, откуда ходят роботы Гугла и/или Яндекса. Буквально за 5 >минут гуглится.

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

                То что вы гуглите за 5 минут, давно не актуальное старье, выложенное «бывшими сеошниками».
    • 0
      Ну и где статья?
  • 0
    Самдоельный анализатор логов… мне кажется лучше использовать уже готовые решения.

    Для себя решил проблему со школьным ддосом вполне штатными средствами:

    fail2ban смотрит лог nginx, слишком часто обращающихся отправляет в blackhole (iptables даже не задействуется, можно держать огромный список ипшников в черном списке)

    конфиги fail2ban:

    filter: pastebin.com/NiR1E0qj
    action: pastebin.com/k4BxrAeG
    jail.conf: pastebin.com/n7eAhbxD

    за 5 мин такая защита настраивается на любом сервере :)
    • НЛО прилетело и опубликовало эту надпись здесь
      • +3
        1. ставим fail2ban (например yum install fail2ban)
        2. создаем файл nginxaccess.conf в /etc/fail2ban/filter.d (содержимое из pastebin.com/NiR1E0qj)
        3. создаем файл blackhole.conf в /etc/fail2ban/action.d (содержимое из pastebin.com/k4BxrAeG)
        4. редактируем файл /etc/fail2ban/jail.conf в самый конец записываем содержимое из pastebin.com/n7eAhbxD, редактируем параметр logpath — должен указывать путь к access логу nginx, нормально обрабатывает ситуации с ротацией логов.
        Ну и смотрим вначале файла jail.con строчку ignoreip = 127.0.0.1 — добавляем в нее свои ip адреса на всякий случай.

        Последним пунктом перезапускаем fail2ban: service fail2ban restart

        И идем пить чай ,) и через некоторое время смотрим в /var/log/fail2ban.log — сообщения о банах или смотрим список командой: ip route show | grep blackhole

        Можно поиграться параметрами findtime и maxretry — задают жесткость критериев по которым определяются ддосеры (150 запросов к бэкендну на протяжении 60 секунд — критерий в примерах)

        fail2ban демон достаточно гуманно потребляет ресурсы CPU и памяти даже на высокопосещаемых проектах. (в отличие от awk/grep/скриптов) А бан через blackhole работает хорошо с большим списокм ip в бане (в отличие от бана по iptables, который начинает есть много CPU на больших таблицах)
    • –1
      Если Вы с awk не на «Вы», то написать на awk скрипт проще, чем конфиги к fail2ban или еще чему-то узкоспециализированному.
      • +1
        А вот тут можно долго спорить.
        Свои правила для F2B пишутся на раз, по примерам соседних натсроек.
        Использовать cat | awk — весьма накладно по ресурсам сервера,
        а он, бедный под атакой…
        А потом еще и | sort | uniq -c | sort -n, что не самым лучшим образом сказывается на производительности…

        Тут бы отдельный лог завести, и в него складывать только адреса для блокировки, но этого вы не предусмотрели.
        В этом случае можно было бы развести по location разные правила по числу обращений…

        Нет у вас комплексног оподхода к проблеме…
        Хотя awk вы освоили на достаточно высоком уровне.
        • –1
          Не могу согласиться с Вами. У нас есть примеры как эта методика отлично отрабатывала защищая от DDoS интернет-магазины на vds с 768 мб памяти. sort/uniq/awk не так много ресурсов потребляют, тем более запускаясь раз в 5 минут, а не постоянно.
          • +1
            Можете не соглашаться, ваше право…
            А можете провести эксперименты по оптимизации настроек Nginx с выдачей адресов атакующих сразу в файл…

            Типа:
            server {

            log_format IP '$remote_addr';
            location = / {

            if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) {
            access_log /var/log/nginx/for_ban.log IP;
            return 403;
            }

            }

            И сразу банить…
            Ни каких grep|sed|awk…
            И посмотреть, как под атакой живет сервер…

            P.S.
            Это только один из фрагментов. Ни как не полноценная система.
            • –1
              Вы, конечно, сэкономите так какое-то количество ресурсов, но полноценных логов иметь не будете. И речь ведь не о том, что если нашу методику заменить на Вашу, то нагрузка на сервере упадет в 2 раза. Мы говорим о разнице в несколько процентов, не более.
              • +2
                Похоже, мистер, Вы не в теме…
                Nginx позволяет вести отдельные логи для какждой location помимо полноценного лога.
                В силу этой полезной особенности я получаю и _полноценные_ логи, и список адресов для последующего бана…
                И этот список не нужно обрабатывать как-то еще…

                А о «нескольких процентах» разговор ведете Вы… При этом, абсолютно не обосновано, потому как без численных аргументов.

                Я же предпочитаю заранее планировать поведение сервера под атакой и изначально не допускать неоправданных расходов ни памяти, ни тактов процессора, ни iops носителя.

                Дальнейшее обсуждение вашей «методики» считаю безполезной…

                Лучше дождаться статьи ArhMax…
                • –1
                  На основании чего Вы делаете вывод, что я «не в теме»? Я говорю глядя на предлагаемый Вами конфиг, в нем упоминания другого лога нет, только одного.

                  Несколько процентов я называю исходя из того, что запуск раз в 5 минут связки awk/sort/uniq никак не может по потреблению ресурсов быть сопоставим с работой движка сайта. Возможно Ваш метод в 10 раз меньше ресурсов потребит, но в целом это будет 1% или 0,1%. А идея заключается в том, чтобы сервер не тащил на себе нагрузку от ddos, а очень быстро с ней справился.
                  • +1
                    > На основании чего Вы делаете вывод, что я «не в теме»?
                    Теперь я делаю вывод, что Вы и читать не умете…

                    Русским же ж по белому написано было:
                    Это только один из фрагментов. Ни как не полноценная система.

                    Проценты нужно не фантазировать, в потолок глядя, а считать и мерять…

                    О том, что каждый пайп (|) порождает subshell, Вы, вероятно, даже не подозреваете…
                    А, судя по коду (так и не отформатированного) скрипта, там не обдегченный /bin/sh, а гораздо более тяжеловесный /bin/bash…

                    • –1
                      Я думаю Вы достаточно хамоваты, чтобы продолжать эту дискуссию, к сожалению. Она могла бы быть интересной, если бы Вы не переходили на личности.
                    • 0
                      JFYI:

                      ls -l /bin/sh
                      lrwxrwxrwx 1 root root 4 авг. 1 14:32 /bin/sh -> dash
                      • 0
                        ;)
                        Это от дистрибутива зависит…
                        Бывает сильно урезанный bash, исключительно ради быстродействия.
                        А бывает симлинк на полноценный bash…
          • +1
            Похвастайтесь своим максимальным достижением.

            Интернет-магазин на vds с 768M оперативы наверное кто-то у себя на телефоне его хостит =) Даже любопытно, кому вздумалось такое DDoS'ить — или у вас DDoS — забытый siege или ab в фоне? Что означает первая «D» в «DDoS» надеюсь вы знаете?
            • –1
              Давайте уж Вы тогда первый похвастайтесь, чтобы было с чем сравнивать.
    • 0
      Если вы зануляете маршруты к ботам, то это надо делать через BGP blackhole.
      В вашем случае, сервер будет принимать запросы от ботов, обрабатывать их, а потом еще тратить ресурсы на отсылку пакетов в никуда.
      • 0
        Дело в том, что эта статья не о том, как бороться с ddos на провайдерском уровне, а о том, как бороться с ddos для vds/dedicated. У таких людей нет возможности использовать такие методы как bgp blackhole
        • 0
          А вы не боретесь.
          У вас как была высокая нагрузка, так она и остается, даже немного растет.
          • 0
            Если атакующий больше не может соединиться с сервером, то почему от него останется какая-то нагрузка? Максимум — несколько пакетов по сети. Любой ботнет имеет конечный размер и за вполне конкретное время весь ботнет попадет в -j DROP
            • 0
              Атакующий знает маршрут к вашему ip и продолжает слать запросы.
              Обработкой ответов занимается только командный центр, а не рядовые ячейки бот-нета.
            • 0
              Вы посмотрите свои action. Где там -j DROP?
              • 0
                -A INPUT -m set --match-set ddos src -j DROP
  • 0
    ipset, кстати, уже почти с год как в ядре.
    • –4
      В Debian Squeeze — нет. В wheezy тоже.
      • +1
        ipset 6.12 есть в wheezy.
        • 0
          Он идет в составе пакета с ядром или все так же через module-assistant устанавливается?
          • 0
            Видимо, с ядром.

            ii ipset 6.12.1-1
            ii libipset2:amd64 6.12.1-

            lsmod:
            ip_set 26700 0
            nfnetlink 12906 1 ip_set
            • 0
              Ясно, не знал.
  • 0
    Наверное несовсем в тему вопрос, но все-таки озвучу.
    Имеется VDS с 2Гб, lighttpd,fcgi-php,mysql.
    Если просто даю нагрузку на сайт, то все нормально. А если начинаю сканировать чем-то типа Acunetix Web Vulnerability, то, насколько я понимаю, у mysql заканчиваются сокеты и он на пару минут впадает в ступор.
    В какую сторону лучше копать кроме игры с timeout'ом сессий mysql?
  • 0
    Интересно, но у меня просьба — не советуйте тюнить другим те параметры TCP, которые сами не понимаете.

    Вот, например, зачем вы это предложили?

    net.ipv4.tcp_rmem = 4096 8192 87380
    net.ipv4.tcp_wmem = 4096 8192 65536

    Для тех, кто не знает, что это такое: это параметры настройки буфферов TCP (на чтение и запись соотв): min, default, max.

    Значение по-умолчанию — 4к, 16к, 64к/4M.

    Вы зачем-то взяли и порезали размер буфера по-умолчанию. Меньше буфер — меньше максимальная скорость WAN сети (где RTT, то бишь пинг, большой).

    Меньше скорость — больше коннектов (если вам нужно обслужить 100 запросов по 100кб в секунду, то если вы будете отдавать их со скоростью 1Мб/с каждому, то будете иметь 10 одновременных коннектов, если со скоростью 5Мб/с, то всего 2).

    И вы взяли зачем-то и уменьшили буфер. Нафига? И нафига было так сурово резать максимум?
    • 0
      Это не единственный ляп в приведенном «рукоблудстве» по защите сервера от DDoS…
      К огромному сожалению…
      • +2
        Я думаю, что если каждый напишет про область своего знания, итогом будет увеличение общего знания у всех читающих/обсуждающих.

        Я вот не сильно гуру в веб-сервисах, мне написанное показалось вполне разумным.

        В чём тут проблемы?
        • +1
          Я к тому, чтоб время не терял.
          Тут уже отметили, что ценность данного опуса крайне низкая, аж до отрицательных значений.

          Ну и кое-кто по паре ляпсусов высветил.

          Ваш комментарий только подтвердил коллективный вывод.

          ArhMax намерен в обозримом будущем опубликовать более правильный вариант,
          в котором и вижу смысл сброситься своими наработками и, может быть, сделать общеупортебимый вариант. Комплексный, на всех возможных уровнях…
          Начиная с тюнинга ядра, дисковой подсистемы, сетвого стека
          и собстенно nginx+(apache|lighttpd)…

          А этот винигрет из понадерганных наколенных решений в пристальном внимании не нуждается. Времени жаль только…
          • 0
            Я представляю что он напишет, с учетом того, что он даже не понял о чем идет речь тут. Он своими словами попытался описать суть и написал полную ахинею, не имеющую ничего общего с методикой, описанной в статье.
            • +4
              Гораздо более одного человека указали вам на разнообразные ошибки…
              Как в алгоритме построения защиты, так и в реализации этого алгоритма.
              Вы не поняли ни ошибочности первого, ни ущербности второго.
              И продолжаете упорствовать…

              А когда и если появится статья, тогда мы и будем обсуждать её содержание,
              а не ваши представления о возможном содержании.

              P.S.
              Уже не один раз приходилось слышать обиженные всхлипывания в стиле
              «Я такую мегахрень выродил, а меня ни кто не понимает»…
              С возрастом проходит… Но не у всех.
              У тех, кто старательно ищет рациональное зерно в любой критике, проходит быстрее.
              • 0
                В алгоритме построения защиты ошибки есть только если строить атаку очень специализированным образом, атакуя именно слабые места алгоритма. Для этого нужно знать какой именно алгоритм применяется, а атакующий этого не знает. Против типового http flood ddos эта методика работает и глупо отрицать очевидное.
                Выпады в адрес того, что fail2ban быстрее чем awk, либо что можно писать отдельно логи — это, знаете те ли, не ошибки. Ошибки — это когда что-то делается не правильно. А когда что-то делается и в результате все работает, это не может быть ошибкой, это может быть лишь не эффективной реализацией. Но и это спорно, потому что никто не привел цифр, которые бы с разгромным счетом показали растрату ресурсов сервера нашим методом против какого-то иного, все голосновно.
                • +1
                  Вы абсолютно необосновано отказываете атакующему в знании алгоритмов защиты…
                  Чаще всего это заказные атаки, несущие явный финансовый интерес.
                  Атаки заказываются и хорошо оплачиваются, следовательно специалисты там привлекаются весьма и весьма грамотные.

                  Атаки, в отражении которых мне приходилось принимать участие, трудно назвать типовыми, потому как были они комплексные.
                  И алгоритмы атаки менялись несколько раз в течение 4-5 суток…
                  И защиту приходилось адаптировать на лету, под изменившиеся алгоритмы.

                  То, что вы предожили на всеобщее обсуждение, работает скорее, вопреки, а не потому, что грамотно и правильно спроектировано.

                  Если вы считаете допустимым положить сайт на одну минуту, а потом думаете, что он поднимется, то остается только позавидовать вашей наивности.

                  Смею утверждать, что атака, в ходе которой в течение минуты ловится 2-3К адресов, а в следующую минуту еще столько же, но уже других, уложит ваш сайт гарантированно.
                  Такая атака может иметь явно выраженный региональный характер, когда в течение суток к атаке подключаются новые регионы, на смену тем, боты в которых отключаются. И каждую минуту сотни и/или тысячи новых адресов будут исчерпывать установленные вами лимиты и укладывать сайт.
                  И указанные вами интервалы проверки «улова» для формирования правил в iptables явно подсмотрены через розовые очки…

                  А потом только представьте себе, что все те адреса, которые вы «успешно» забанили, чихать хотели на все ваши -j DROP и входящий канал будут забивать аж по самое не балуйся ;)
                  Вы банально, по SSH на свой сервер зайти не сможете,
                  чтоб как-то подправить конфиги…

                  Ну и дальше жонглируйте уже без меня…
                  • –2
                    Вот с одной стороны Ваш комментарий, с другой успешная практика использования этой и других методик в течение нескольких последних лет. По Вашему, я должен поверить что Вы — мега-спец (кстати, а где пруф? Ваш коллега так и вовсе программист на php, а Вы даже ни одной статьи не написали), и тогда я должен признать что весь наш опыт борьбы с ddos — это результат случайного везения. Но очевидно, что на одном везении с ddos не поборешься, отсюда возникают вопросы в Ваш адрес, уж извините.
                  • –1
                    > «только представьте»

                    Вот и вся аргументация: только представьте что на Землю упадет Луна… В статье явно написано что это борьба с http flood. Откуда возьмется то, что Вы предлагаете представлять? Почему обычно не берется? Может потому что Вы сами реально с атаками только на картинках знакомы?
                    • +1
                      Я то и делаю, что представляю, как будет работать система в тойи или иной ситуации, и как она будет из этой ситуации выходить ;)
                      При чем, я не падение Луны на Землю представляю, или, к примеру, бабу голую, а реальное поведение системы на всех уровнях OSI…

                      При этом, не считаю себя (Мега|Гига|Супер)-спецом…
                      Даже вас в этом не пытаюсь убедить…

                      И количеством статей не меряюсь (кстати, качественный показатель важнее, IMHO)…

                      Я просто описал вам практическую ситуацию, в которой ваш алгоритм защиты тихо пукнет в лужу…

                      Я просто предпочитаю не попадать в ситуации, из которых вы, с некоторой долей вероятности, выкрутитесь…
                      С некоторой, весьма скромной, долей…

                      И, обратите внимание, не возвращаю вам же,
                      слегка перефразированный, ваш вопрос.

                      Если мне не изменяет мой склероз, то это один из признаков профессионального троллинга…

                      Кормить больше не буду.
                      Dixi.
                      • –2
                        Смотрите, вот несколько цитат из последней статьи highloadlab:

                        > Преступники отдают предпочтение высокоуровневым атакам транспортного и прикладного уровня (82%)
                        > Не менее 50% атак Layer 7 – это «долбежка» в один URI

                        Думаю процент чисто http flood атак Вы сможете посчитать сами. Отсюда Ваше высказывание «А потом только представьте себе, что все те адреса, которые вы «успешно» забанили, чихать хотели на все ваши -j DROP и входящий канал будут забивать аж по самое не балуйся ;)» уже под боооольшим вопросом, точнее его актуальность. Причем HLL считают статистику по атакам, с которыми обращаются к ним, а у нас есть статистика по атакам, с которыми обращаются к нам. У нас расклад иной и еще больше не в пользу Вашей точки зрения. Из последних 4 десятков атак кроме http flood другой трафик мы наблюдали только в одном (!) случае.

                        Теперь прикиньте каков реальный процент атак, против которых эта методика будет эффективна и Вам поплохеет.
                      • –3
                        > И количеством статей не меряюсь (кстати, качественный показатель важнее, IMHO)…

                        конечно, Вы правы. Только когда показатель, любой причем, умножается на ноль, он все равно равен нулю. Что такое «ноль»? Ноль — это количество Ваших статей.
    • +1
      Кажется, это первая обоснованная критика. Спасибо
  • 0
    Про $host в limit_req_zone вам уже много написали. Я считаю, что это имеет смысл, особенно на слабых VPS. Но значение burst должно быть в разы больше, и без nodelay.

    Для равномерного ограничения нагрузки на железо можно было бы и $pid использовать (речь ведь о VPS, а не о кластере).

    Кстати, зачем мы резервируете под такую маленькую зону целых 20 Мб?

    Ёще надо иметь в виду, что без $binary_remote_addr под нагрузкой часть клиентов могут получать 503 на часть запросов (например, им не отдастся css), что вообще-то еще хуже чем лежащий сайт.
    • 0
      Основная идея сводится к тому, чтобы в достаточно короткое время выделить ботнет и зафильтровать его. Понятно что при этом будут какие-то потери для нормальных посетителей. Но если речь о том, что они не допустимы, то лучше сразу идти договариваться с профильными компаниями о защите.
  • +1
    Срач разгорелся нешуточный. А давайте кто-нибудь поднимет тестовый сайт, прикрутит к нему описанную выше защиту, а затем проверит ее DDOS'ом? И увидим все плюсы и минусы предлагаемого решения.
    • 0
      А самый умный — платит. На самом деле, если наберется пара десятков желающих — возьмем в аренду хетцнер и заDDOSим его до кровавых соплей. На хабре же есть способные превратить всю эту экзекуцию в вебинар. Вон, тут на днях за 50000 с лица предлагали балаган по сетевым технологическим новинкам провести и ничего, кто-то купил себе знаний.
    • +3
      Тогда уж давайте сперва скинемся по рекомендации на каждом уровне, начиная с ядра, сетевого стека, оптимизации самого софта, и т.д.
      А потом поставим и натсроим. Ну и погоняем под нагрузкой…
      И красиво всё это дело задокументируем и прокомментируем каждый значащий параметр.
      Типа, если «тут» написать «так», то «там» вылезет «это».
      Примерно, как amarao пояснил смысл тюнинга net.ipv4.tcp_*…

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

      Зная смысл каждого действия, уже можно самостоятельно принимать решение о целесообразности той или иной настойки.

      А через тупое повторение чужих «степ_бай_степ» уже ни одно поколение начинающих админов вспотыкалось.

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

      Я готов приняь участие в этом проекте.
      Есть немного времени, кой-какой практический опыт и теоретические знания.
      • НЛО прилетело и опубликовало эту надпись здесь
        • +2
          Я вообще-то ожидал не «собереТЕСЬ», а «собереМСЯ» ;)
          • НЛО прилетело и опубликовало эту надпись здесь
            • НЛО прилетело и опубликовало эту надпись здесь
              • +2
                < :) >
                Так, народ… За хостинг для тестов нам уже платят… ;)

                Будем холиварить по базовому дистрибутиву?
                FreeBSD или Linux? Вынь не предлагать…

                Ставим штатно, из пакетов официальных репозиториев,
                типа «обычные пользователи»,
                или как взрослые дядьки, ./configure && make && make install?
                </ :)>

                :|
                Если кто действительно готов за базар отвечать, то стучите в личку,
                будем думать вместе.
                • 0
                  По сути требуется не мега-защита, а что-то любительского уровня (иначе проще нанять конторы которые занимаются такими проблемами и потратиться на железо). Т.е. общедоступное. А следовательно, и дистрибутив должен быть массовый. Например Linux (Ubuntu Server, Debian, Fedora, etc.).
                  • 0
                    Ошибочное суждение.
                    Есть атаки, с которыми можно справиться своими силами, и есть атаки, которые можно отбивать только на более дальних подступах.

                    А «любительского» уровня тут нет и быть не может.

                    Дистрибутив — согласен. Опытному админу это без разницы.
                    Где-то привычнее, где уже все грабли вытоптаны, где-то нужно сперва осмотреться…
                • НЛО прилетело и опубликовало эту надпись здесь
                • 0
                  Считайте что я вам написал в личку, что бы «ответить за базар» деньгой.
                  Интересует LAMP-стэк на Debian/CentOS 64 и KVM/Xen виртуализация.
                  • +1
                    Специоалисты по виртуализации всяко приветствуются.
                    Иначе можем получить некорректный тест…
  • +2
    Хабр как он есть, все хотят показать себя большими молодцами по сравнению с остальными))

    Большинство комментирующих почему-то никак не хотят принимать во внимание тот факт, что алгоритм из топика предназначен для простых vds/dedicated server, где по определению мощность всей системы не столь высока. Раз мощность не столь высока, то и сайт не настолько популярен (тем более, что автор пишет о нескольких сайтах на одном vps/ds). А раз сайт не настолько популярен, то и алгоритмы ddos-атак будут на них весьма примитивные (не будут платить большие деньги за качественный ddos, а если и будут, то скорее всего и много других защит захлебнется, остальные ddos-атаки проводят всякие школьники). Для защиты именно от таких атак и написан конфиг. Алгоритм не так плох в плане скорости работы/эффективности/сложности/etc для своих нужд, хоть и не без недостатков. Имхо)
    • 0
      Спасибо :) Именно это мы и пытались донести.
  • 0
    Холивар, хорошо с утра почитать.
    Копошатся и петушаться друг перед другом…
    А давайте просто затестим этот скрипт на указанном автором сервере, желателньо чтобы он был не продакшн — чтобы никому не навредить. :)

    потом почитаем логи и посчитаем uptime сервиса.

    Автор ты ЗА?
    • 0
      И в чем, простите, глубокий смысл этой затеи? Описанная методика опробована на нескольких десятках реальных ddos-атак. Она не идеальна, но она работает. Разумеется, завалить защищаемый ею сайт можно, но в большинстве случаев реальным атакующим это не удается.
      • 0
        Это против? — Голос принят.

        Я в реальной жизни полагаюсь на аппаратные решения, согласен что они дороже — но надежнее.

        Мысли у вас изложены может и верные — а админов гоните в шею за реализацию и не знание предметной области.
  • 0
    Интересная статья, про ipset и tarpit не знал.
    Хотелось бы подробнее про sysctl, поскольку почти нигде не объясняется, на что конкретно влияют параметры и какие причины ставить большие или меньшие значения, но статья вроде не об этом :)
    С реальными ддос-атаками не сталкивался, поведения ботов не знаю, но общая идея мне нравится, я бы тоже пытался думать в таком направлении, если бы возникли проблемы с маленьким сервером с сотней малобюджетных сайтов.
    Конечно, это не подойдет для толстых java-rich сайтов, которые не поднимаются сами при пропадании нагрузки.
    Еще можно прикрутить proxy_cache, если специфика сайта это позволяет.
    • +2
      Я думаю параметры sysctl стоит начать изучать с документации по ядру.
  • 0
    sprinthost.ru/support/personal-apache.html — это хорошая основа для того, чтобы строить превентивные меры от заддосивания или маловато?

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

Самое читаемое Разное