• Авторизация


Затрахали вопросами, как справится с DDoS... 10-07-2011 18:27 к комментариям - к полной версии - понравилось!


Защита от DDoS. Нет веб-сервера, кроме nginx, и Сысоев пророк его.

И действительно, если у вас по каким-то причинами стоит что-то, кроме nginx, можете сразу ползти на кладбище, так как помочь вам уже никак не получится. В частности, если у вас стоит apache, то вас реально можно положить с мобильного телефона, безо всякого ботнета и так далее. Не верите? Подождите, а вы вообще чем занимались все то время, прежде, чем прочесть этот текст? Click here, motherfucker... => http://ha.ckers.org/slowloris/. Это же касается истории, если у вас стоит какое-то дикое извращение, вроде IIS. Вообще, если у вас на production-серверах стоит windows - убейте себя об стену, так как вы безнадежны и говорить с вами не о чем.

Но если у вас стоит nginx на intel Atom на домашнем кинотеатре, то даже если, у вас ничего не настроено и вы толком не понимаете, что надо подкрутить и в какую сторону, то у вас уже все значительно лучше, чем долбоебов, у которых стоит cisco asa 5580 + checkpoint firewall + load balancer + ферма серверов на IIS. И это святая правда, поскольку вы можете сделать хорошее логгирование, а именно:

log_format mainext
'$remote_addr [$http_x_real_ip] - $remote_user($cookie_auth) [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" ua:"$http_user_agent" '
'gz:"$gzip_ratio" ae:"$http_accept_encoding" c:("$http_cookie") rb:("$request_body") ($request_time)';

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

После того, как вы настроили свой замечательный nginx и начали видеть нормальные логи, все что, реально остается сделать, это написать простенький perl скрипт, который будет смотреть, кто к вам лезет и зачем, и если вы обнаруживаете, что с сайта www.you-tube.com к вам приходит “POST //” да еще и при этом браузер Chrome делает соединение, но при этом не желает принимать ответ сжатый gzip ($http_accept_encoding), то это - бот. Все, что остается после этого - добавить этот ip в ваш firewall. Если ботов мало - вполне прокатит iptables.

Кстати, при добавлении адресов в iptables, не переусердствуйте, и не добавляйте один и тот же адрес дважды, запоминайте что уже добавлено, а что - нет. И не стоит вызывать iptables слишком часто - он расстроится, делайте паузу:)

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

Так или иначе, insight:

my %iplist;

sub blackList {
my $bot = shift;
if (!defined($iplist{$bot})) {
system(“iptables -A INPUT -s $bot/32 -j DROP”);
$iplist{$bot}++;
}
}

while(my $logLine = ) {
my ($ip) = ($logLine =~ /^(\d+\.\d+\.\d+\.\d+)/);
if (defined($ip)) {
my ($ae) = ($logLine =~ /ae:”([^)]+)”/);
my ($ua) = ($logLine =~ /ua:”([^)]+)”/);
if ($ua =~ /chrome|firefox/i && $ae eq “-”) {
blackList($ip); # chrome/ff without compression
}
}
}

Совсем правильно - использовать BerkeleyDB для хеша %iplist, это позволит безболезненно выключать и включать скрипт. Правила можно подобрать более точные, и подбор этих правил уже зависит от структуры защищаемого ресурса, но сделав это однажды, можно уже больше никогда не заботиться о DDoS.

Но вообще, если готовиться за ранее, то я бы написал себе скрипт на twisted python, для чтения логов и проверки того, что к чему. Вот что-то в этом роде:

from __future__ import nested_scopes
import twisted.internet.reactor, os, stat, sys

def checkIfBot(logLine):
pass

def file_identity(struct_stat):
return struct_stat[stat.ST_DEV], struct_stat[stat.ST_INO]

def followtail(filename, callback, freq=1, fileobj=None, fstat=None):
if fileobj is None:
fileobj = open(filename)
fileobj.seek(0, 2)
callback(fileobj.read())
if fstat is None: fstat = os.fstat(fileobj.fileno())
try: stat = os.stat(filename)
except: stat = fstat
if file_identity(stat) != file_identity(fstat):
fileobj = open(filename)
fstat = os.fstat(fileobj.fileno())

twisted.internet.reactor.callLater(freq, lambda:
followtail(filename, callback, freq,
fileobj, fstat))

if __name__ == '__main__':
followtail(sys.argv[1], checkIfBot)
twisted.internet.reactor.run()

Несколько хуже дела, если ботов много. Ядро linux, при всем уважении к современным процессорам, все же начинает притормаживать, когда в ядре набирается много правил, скажем ~7000, и времени на проверку каждого пакета уходит довольно много. В таком случае - Cisco вам в помощь, синтаксис простой, как три копейки - shun ip. Самый разумный способ - накапливать адреса в iptables, и сбрасывать на cisco эпизодически, уже большими блоками. Если вам нужно quick and dirty solution, как обычно и бывает во время DDoS, то можно сделать так:

shun.pl:
#!/usr/bin/perl -w
use strict;
use Net::SSH::Perl;

my $ssh = Net::SSH::Perl->new("ciscoHost", debug=>0);
$ssh->login("ciscoUser", "ciscoPassword");
$ssh->shell;

Это нечто просто просто открывает shell, и дает нам возможность что-нибудь писать прямо в шелл, не вводя пароля. А что писать.... ну например, если список адресов ботов в файле iplist, то:

(echo login; echo ciscoUser; echo ciscoPassword; tail -n `iptables-save | wc -l ` iplist | sed 's/^/shun /'; sleep 60) | ./shun.pl
iptables -F

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

Совсем дело хреново, если ботов много, но Cisco нет - тут необходимо компилировать правила firewall, сделать reduce - запрещать по общей маске, по моему опыту, так можно сократить список на 20-30%. Идея такая, что можно для каждого адреса посмотреть из какого он диапазона: whois ip | grep inetnum, и оставить только уникальные диапазоны. В маску для iptables этот интервал адресов можно превратить с помощью ipcalc, как-то так:

# whois 31.3.244.146 | grep inetnum
inetnum: 31.3.244.144 - 31.3.244.151

# ipcalc 31.3.244.144 - 31.3.244.151
deaggregate 31.3.244.144 - 31.3.244.151
31.3.244.144/29

Это, конечно не решит всех вопросов, но это даст вам еще какое-то время и кто знает, может за это время вы сподобитесь поставить cisco:)

Но это все хорошо тогда, когда атака уже идет, а всегда нужно время среагировать, при том, что хорошо бы было, если бы небольшие DDoS атаки вообще проходили незаметно. Для этого надо сделать так, чтобы все, кто не похож на реальных пользователей сходу не проходил к веб-приложению. И сделать это просто - боты не следуют по редиректам, и боты не цепляют cookie. Средствами nginx это можно сделать так:
server {
default_type text/html;
listen yourserver:80;
location = / {
add_header Set-Cookie "thatsfine=yes$remote_addr";
rewrite ^/(.*) http://yourserver/login;
}
location = /login {
if ($cookie_thatsfine != "yes$remote_addr") {
return 503;
}
root /webroot/login;
index login.html;
}
}

Страницу login.html увидят только те, кто получает cookie и следует редиректам, убийственно просто. И только таких пользователей следует пускать к скриптам, реализующим сложную логику.

В конечном итоге, DDoSеры, обнаружив, что ничто не помогает и ваш сайт работает, как работал начнут искать новые варианты, часто они прибегают к icmp и udp flood. Тут рецепт простой - на внешнем файрволле надо просто отрубить напрочь и то и другое, оставив, быть может, только udp до вашего DNS сервера. Так как для работы вебсервера ни то, ни другое - просто не нужно. Don’t forget to disable name resolution in your ssh config:)

Но это все - лирика. На самом деле, если софт исполнен правильно, то DDoS - пустая затея. А правила просты:
не считайте статистику в клиентских скриптах - select sum(whatever) from … - запрещено!
не надо использовать сложносочиненных запросов к БД вообще, а в клиентских скриптах в особенности - лучше выдернуть, все, что надо и обработать процессором в скрипте - это будет быстрее в любом случае;
не стоит вообще обращаться к mysql без надобности, если ваш скрипт начинается с того, что соединяется с БД - он написан неправильно, надо сначала проверить все аргументы, выяснить все, что можно выяснить без SQL, и только в том случае, если нужных данных нет в memcached, соединяться с mysql;
вообще надо все кешировать, на всех уровнях - memcached - в помощь;
не надо делать счетчики и аутентификацию пользователей на mysql - это идиотизм, используйте redis, например - это более подходящая вещь;
если угораздило использовать php, используйте php-fpm + eaccelerator - других вариантов в этом мире просто нет;
hiphop php - даст вам преимущество только, если вы делаете действительно сложную обработку данных в php, во всех остальных случаях он просто усложнит процесс внедрения и отладки;
не используйте frameworks для php - они все без исключения тяжелые, и в случае чего вы не сможете их оптимизировать;
обрабатывайте максимум данных на клиенте, не надо строить HTML-таблицу на сервере в php, надо сформировать json и построить табличку javascriptом на клиенте - это сэкономит траффик и процессорное время;
и если у вас какие-то данные отдаются в течение какого-то времени всем одинаковые - используйте статику, напишите скрипт на удобном языке и обновляйте статику, пусть nginx занимается своим делом, он сделает это лучше, чем вы в компании php-fpm.

И самое главное - не ебите мозги! Если вы писали софт для web, вы уже должны были действовать так или аналогичным способом, если вы действовали иначе, но все же читаете эти строки - самое время начать работать по-новому.
вверх^ к полной версии понравилось! в evernote
Комментарии (12):
eugene20237 10-07-2011-19:26 удалить
Большое спасибо за полезнейшую статью!
eugene20237 11-07-2011-21:04 удалить
Я уже растаскал статью на цитаты, потому что они прекрасны
d0rc, эта... а я вот фигурные скобочки несколько иначе размещаю...
d0rc 12-07-2011-17:54 удалить
eugene20237, спасибо на добром слове:) но правда жизни в том, что я заебался сам разруливать ddosы и всем рассказывать, как их разруливать...
d0rc 12-07-2011-17:54 удалить
Юрий_Мишенев, мало нас осталось, размещающих фигурные скобки....
eugene20237 12-07-2011-20:38 удалить
Дима говорил, что обычно при дедосах кладут не сервер, а канал. Таким образом, ни один нормальный пользователь не может достучаться до сервера, потому что канал забит паразитным трафиком. Допустим, если сервер подключен к каналу в 100 Мбит, то забить его наверное реально.
P.S.: сам никогда с дедосом напрямую не сталкивался - не приходилось.
SARGANC 30-07-2011-09:44 удалить
С днём рождения!
eugene20237 30-07-2011-15:46 удалить
Дима, с Днём Рождения тебя!!! Желаю построить большую scifi лабораторию и получать удовольствие!
Я желаю счастья и тепла,
Пусть мечты чудесные сбываются,
Будет жизнь прекрасна и светла,
Все легко, как в сказке, получается!
А еще хочу я пожелать
Ярких встреч, удачи и везения,
Чтобы утро каждое встречать
В радостном хорошем настроении!
[640x527]
02-08-2011-18:39 удалить


Добрый день, друзья!


Я очень люблю узнавать что-то новое и на просторах глобальной сети неоднократно задавался вопросом о том, как можно зарабатывать в Интернете? Я нашел способ заработка, которому доверяю и хочу рассказать о нем Вам! Уделите пожалуйста пару минут для изучения материала и Ваша жизнь изменится к лучшему уже сегодня!



Зайти в гости!


Заранее благодарю!



Комментарии (12): вверх^

Вы сейчас не можете прокомментировать это сообщение.

Дневник Затрахали вопросами, как справится с DDoS... | d0rc - Дневник d0rc | Лента друзей d0rc / Полная версия Добавить в друзья Страницы: раньше»