Post on 12-Jul-2015
10/23/12
Механика DDoS
Крижановский Александрak@natsys-lab.com
«Механика»
● Чем в среднем отличается DdoS от flash crowd (не исчерпывающее описание и без специальных случаев)
● Процессы, происходящие с HTTP-акселератором под DdoS
● Как не надо и как лучше отражать HTTP DDoS
● Пример — Nginx, но говорим «в целом»
Нормальный HTTP трафик
● Запросы достаточно большие за счет Cookie и URL (~1KB, часто больше)
● Ответ — Web-страница (десятки килобайт), считанная из файла
● Сотни или тысячи Keep-Alive соединений (к одному HTTP-акселератору), каждое из которых генерирует умеренное число запросов
HTTP DDoS трафик
● Запросы часто сильно меньше (десятки или сотни байт)
● Ответов сервера сильно меньше, чем получаемых запросов
● Десятки или сотни тысяч соединений
● много запросов в каждом соединении● или постоянная переустановка соединений с каждого хоста
Nginx, netstat, grep, fail2ban и др.
● Посмотреть netstat'ом соединения и добавить правила в Iptables
● Погрепать access.log и/или error.log и добавить правила в ipset
● Fail2ban
● Лимитирование на сервере (limit zone для Nginx)
● Iptables connlimit и hashlimit
=> HTTP-акселератор + Firewall
Чтение логов – не самая быстрая операция, особенно в условиях высокой нагрузки
Обработка лимита (Nginx)
epoll_wait(12, {{EPOLLIN, ....}}, 512, 500) = 1
recvfrom(3, "GET / HTTP/1.1\r\nHost: ....", 1024, 0, NULL, NULL) = 327
// parse HTTP
write(11, “...limiting requests, excess...", 176) = 176
writev(3, [{"HTTP/1.1 503 Service Temporarily Una....", 200}], 1) = 200
sendfile(3, 7, [0], 383) = 383
recvfrom(3, 0xa1bac0, 1024, 0, 0, 0) = -1 EAGAIN
epoll_wait(12, {{EPOLLIN, ....}}, 512, 500) = 1
recvfrom(3, "", 1024, 0, NULL, NULL) = 0
close(3) = 0
Горячая точка (Nginx, без логов)
samples % image name symbol name
496099 1.5719 nginx ngx_vslprintf
325148 1.0303 nginx ngx_http_parse_header_line
219699 0.6961 vmlinux cfq_set_request
202023 0.6401 libc-2.12.so memcpy
183268 0.5807 libpthread-2.12.so recv
162710 0.5156 nginx ngx_linux_sendfile_chain
157504 0.4990 nginx ngx_http_limit_req_handler
Nginx и DDoS
● Логировать запросы от ботов дорого
● Парсить логи тоже дорого
● Вместо логирования лимитов – простой модуль, добавляющий правило в netfilter
Обработка пакетов
● Параллельность: MSI-X, irq round-robin
● RPS (Receive Packet Steering) позволяет «разбрасывать» пакеты по softirq на разных ядрах если MSI-X недостаточно (или железо вообще не может параллелить прерывания)
● RFS (Receive Flow Steering) позволяет отправлять пакеты на CPU прикладного процесса
● Улучшают параллельность, но ухудшают кэширование
User space vs Kernel
● Более 15 context switch
● Kernel/userspace копирования запросов и ответов
● Zero-copy network IO (splice(2)) не работает в общем случае на чтение из сокета
● Проблема с очередями сокетов все равно остается (парсить HTTP нужно синхронно в skb)
Kernel HTTP-акселераторы
● Первая половина 2000x: TUX (Linux), OpenKETA (FreeBSD), khttpd (Linux) и комерческие прокеты
=> Основное узкое место, которое может решить kernel-based HTTP-сервер – копирование на отправке файла – решается в user space через sendfile().
L7 DDoS-mitigation HTTP-акселератор: специальный случай
● Нужно минимизировать накладные расходы на обработку запросов от ботов
● Более тесная интеграция с Netfilter
● Возможность держать до 1 млн. Cоединений:
● Обработка TCP in-order данных сразу, не откладывая в очередь (лучше cache hit, меньше расход памяти)
● Per-connection и per-host resource management/QoS● Желательно блокировать не по IP, а содержимому HTTP запроса
Спасибо!
ak@natsys-lab.com