КСЗІ2010:Виступ на семінарі:Симчак Володимир:Захист інформації
Зміст
Анатомія DoS-атак
DoS-атаки поділяються на локальні і віддаленні. До локальних відносяться різні експлойти, форк-бомби і програми, що відкривають по мільйону файлів або запускають якийсь циклічний алгоритм, який зжирає пам'ять і процесорні ресурси. На всьому цьому ми зупинятися не будемо. А ось віддалені DoS-атаки розглянемо детальніше. Вони діляться на два види:
1.Віддалена експлуатація помилок в ПЗ з метою привести його в неробочий стан.
2.Flood - посилка на адресу жертви величезної кількості безглуздих (рідше – осмислених) пакетів. Метою флуда може бути канал зв'язку або ресурси машини. У першому випадку потік пакетів займає весь пропускний канал і не дає машині, що атакується, можливість обробляти легальні запити. У другому - ресурси машини захоплюються за допомогою багатократного і дуже частого звернення до якого-небудь сервісу, що виконує складну, ресурсоємну операцію. Це може бути, наприклад, тривале звернення до одного з активних компонентів (скрипту) web-сервера. Сервер витрачає всі ресурси машини на обробку запитів що атакує, а користувачам доводиться чекати.
У традиційного виконання (один атакуючий - одна жертва) зараз залишається ефективним лише перший вигляд атак. Класичний флуд даремний. Просто тому що при сьогоднішній ширині каналу серверів, рівні обчислювальних потужностей і повсюдному використанні різних анті-DoS прийомів в ПЗ (наприклад, затримки при багатократному виконанні одних і тих же дій одним клієнтом), що атакує перетворюється на докучливого комара, не здатного завдати якого б то не було збитку. Але якщо цих комарів наберуться сотні, тисячі або навіть сотні тисяч, вони легко покладуть сервер на лопатки. Натовп - страшна сила не лише в житті, але і на комп'ютерному світі. Розподілена атака типа "відмова в обслуговуванні" (DDoS), зазвичай здійснювана за допомогою безлічі зомбіфіціруваних хостів, може відрізувати від зовнішнього світу навіть найстійкіший сервер, і єдиний ефективний захист - організація розподіленої системи серверів (але це по кишені далеко не всім).
Методи боротьби
Небезпека більшості DDoS-атак – в їх абсолютній прозорості і "нормальності". Адже якщо помилка в ПЗ завжди може бути виправлена, то повне зжирання ресурсів - явище майже буденне. З ними стикаються багато адміністраторів, коли ресурсів машини (ширина каналу) стає недостатньо, або web-сайт піддається слешдот-ефекту. І якщо різати трафік і ресурси для всіх підряд, то врятуєшся від DDoS, но втратиш велику половину клієнтів.
Виходу з цієї ситуації фактично немає, проте наслідки DDoS-атак і їх ефективність можна істотно понизити за рахунок правильного налаштування маршрутизатора, брандмаузера і постійного аналізу аномалій в мережевому трафіку. У наступній частині статті ми послідовно розглянемо:
1. способи розпізнавання DDoS-атаки, що починається;
2. методи боротьби з конкретними типами DDoS-атак;
3. універсальні поради, які допоможуть підготуватися до DoS-атаки і понизити її ефективність.
В самому кінці буде дана відповідь на питання: що робити, коли почалася DDoS-атака.
Боротьба з flood-атаками
Отже, існує два типи DoS/DDoS-атак, і найбільш поширена з них заснована на ідеї флуда, тобто завалення жертви величезною кількістю пакетів. Флуд буває різним: ICMP-флуд, SYN-флуд, UDP-флуд і HTTP-флуд. Сучасні DoS-боти можуть використовувати всі ці види атак одночасно, тому слід заздалегідь поклопотатися про адекватний захист від кожної з них.
1. Icmp-флуд.
Дуже примітивний метод забивання смуги пропускання і створення навантажень на мережевий стек через монотонну посилку запитів ICMP ECHO (пінг). Легко виявляється за допомогою аналізу потоків трафіку в обидві сторони: під час атаки типа Icmp-флуд вони практично ідентичні. Майже безболісний спосіб абсолютного захисту заснований на відключенні відповідей на запити ICMP ECHO:
#sysctl net.ipv4.icmp_echo_ignore_all=1
Або за допомогою брандмаузера:
#iptables -A INPUT -p icmp -j DROP --icmp-type 8
2. SYN-флуд.
Один з поширених способів не лише забити канал зв'язку, але і ввести мережевий стек операційної системи в такий стан, коли він вже не зможе приймати нові запити на підключення. Заснований на спробі ініціалізації великого числа одночасних TCP-з'єднань через посилку SYN-пакету з неіснуючою зворотньою адресою. Після декількох спроб відіслати у відповідь ACK-пакет на недоступну адресу більшість операційок ставлять невстановлене з'єднання в чергу. І лише після n-ої спроби закривають з'єднання. Оскільки потік ACK-пакетів дуже великий, незабаром черга виявляється заповненою, і ядро дає відмову на спроби відкрити нове з'єднання. Найбільш розумні DoS-боти ще і аналізують систему перед початком атаки, щоб слати запити лише на відкриті життєво важливі порти. Ідентифікувати таку атаку просто: досить спробувати підключитися до одного з сервісів. Оборонні заходи зазвичай включають:
Збільшення черги "напіввідкритих" tcp-з'єднань:
# sysctl -w net.ipv4.tcp_max_syn_backlog=1024
Зменшення часу утримання "напіввідкритих" з'єднань:
# sysctl -w net.ipv4.tcp_synack_retries=1
Включення механізму TCP syncookies:
# sysctl -w net.ipv4.tcp_syncookies=1
Обмеження максимального числа "напіввідкритих" з'єднань з одного IP до конкретного порту:
# iptables -i INPUT -p tcp --syn --dport 80 -m iplimit --iplimit-above 10 -j DROP
3. UDP-флуд.
Типовий метод захаращення смуги пропускання. Заснований на безконечній посилці udp-пакетів на порти різних udp-сервісів. Легко усувається за рахунок відрізання таких сервісів від зовнішнього світу і установки ліміту на кількість з'єднань в одиницю часу до dns-сервера на стороні шлюзу:
# iptables -i INPUT -p udp --dport 53 -j DROP -m iplimit --iplimit-above 1
4. HTTP-флуд.
Один з найпоширеніших на сьогоднішній день способів флуда. Заснований на безконечній посилці http-повідомлень GET на 80-й порт з метою завантажити web-сервер настільки, щоб він виявився не в змозі обробляти всі останні запити. Часто метою флуда стає не корінь web-сервера, а один із скриптів, що виконують ресурсоємні завдання або що працює з базою даних. У будь-якому випадку, індикатором атаки, що почалася, служитиме аномально швидке зростання лігв web-сервера.
Методи боротьби з Http-флудом включають тюнинг web-сервера і бази даних з метою понизити ефект від атаки, а також відсіювання DoS-ботів за допомогою різних прийомів. По-перше, слід збільшити максимальне число з’єднань до бази даних одночасно. По-друге, встановити перед web-сервером Apache легкий і продуктивний nginx – він кешуватиме запити і видавати статику. Це рішення із списку "Must have", яке не лише понизить ефект DoS-атак, але і дозволить серверу витримати величезні нагрузки. Невеликий приклад:
# vi /etc/nginx/nginx.conf
# Збільшує максимальну кількість використовуваних файлів worker_rlimit_nofile 80000;
events {
# Збільшує максимальну кількість з’єднань
worker_connections 65536;
# Використовувати ефективний метод метод epoll для обробки з’єднань
use epoll;
}
http {
gzip off;
# Відключаеєм таймаут на закриття keep-alive з’єднань
keepalive_timeout 0;
# Не віддавати версію nginx в заголовку відповіді
server_tokens off;
# Зкидати з’єднання по таймауту
reset_timedout_connection on;
}
# Стандартні настройки для роботи в якості проксі
server {
listen 111.111.111.111 default deferred;
server_name host.com www.host.com;
log_format IP $remote_addr;
location / {
proxy_pass http://127.0.0.1/;
}
location ~* \.(jpeg|jpg|gif|png|css|js|pdf|txt|tar)$ {
root /home/www/host.com/httpdocs;
}
}
У разі потреби можна задіювати nginx-модуль ngx_http_limit_req_module, що обмежує кількість одночасних підключень з однієї адреси
(http://sysoev.ru/nginx/docs/http/ngx_http_limit_req_module.html). Ресурсоємні скрипти можна захистити від ботів за допомогою затримок, кнопок "Натискуй мене", виставляння кукисів і інших прийомів, направлених на перевірку "людяності".
Застосування кластера для вирішення проблеми атак на відмову
Рішення прийшло само-собою - у нас в том-же ДЦ що і веб-сервер-сервер коштують ще і файлові сервера, в яких дуже навантажені гвинти, але проц і пам'ять практично гуляє. Серед таких серверів знайшовся двохядерний оптерон з 4Гб оператіви, вирішили сайт перенести туди. Щоб не міняти запису в ДНС, не юзати забиті канали, які служать для роздачі файлів і т.д. ми зробили наступне: оптерон був налагоджений для праці backend сервером, на основному сервері в конфіге nginx прописали для домена fileshare.in.ua цей backend, а останні сайти (їх на тому сервері всього біля десятка, окрім файлшари, сумарною відвідуваністю порядку 15К хостів і 70К хітів в добу) залишити як є.
Рішення допомогло на якийсь час, сайт став нормально працювати і інші сайти теж пожвавіше стали відгукуватися. Десь через годин 6 після такого ось нововведення атака посилилася у декілька разів. Оптерон не витримав, файлшара знову просіла, проте останні сайти, які працювали не на оптероне, а на основному веб-сервері-сервері відмінно відгукувалися.
Цього разу я вирішив що файлшара важливіше і зробив кластер: файлшара працювала на обох серверах, балансування робив nginx, а останні сайти крутилися на основному. При чому для файлшари веб-сервер-сервер був прописаний як резервний (тобто на основному сервері скрипти файлшари виконувалися лише якщо оптерон помер), і, щоб довго не чекати, я встановив параметр чекання відповіді від backend 2 секунди. Все налагодилося, отперон не завжди витримував, був постійно завантажений на 100%, але другий сервер підхоплював сайт якщо оптерон падав і все більш-менш працювало.
Мабуть зловмисники стежили за розвитком подій тому, що буквально за годину, після того, як я розвів навантаження з файлшари на 2 сервери на атаку були кинута велика частина ресурсів. Вхідний трафік підріс в 3 рази в порівнянні із звичайним (далі йому просто вже нікуди зростати із-за обмежень провайдера), сайт впав і не піднімався, завантаження сервера (будь-якого) було на 100% вже відразу після рестарту апача, a на основному сервері підскочив до 60%, все було в ступорі небуло жодних шансів піднятися. Атака йшла не лише на файлшару але і останні сайти, навіть по ssh зайти було проблемою (не дивлячись на підвищений пріоритет) і я загасив nginx, щоб мати можливість щось зробити. Мабуть по маштабам атака була порівнянна з тими, від яких лежав 0day і progs не так давно. Не знаю вже кому ми так жити заважаємо, але думати про цей небуло часу, через 20 хвилин атака була повністю відбита;). Насамперед я додав в кластер ще 3 машини. По-друге залив на всі машини по nfs ісходники сайтів, подрехтовал конфіги апача і php і перевів сесію на mysql. Тепер всі сервера могли працювати як backend’и. Після цього я поставив на все сервера APC (php-акселератор), перевірив працездатність сайтів на кожному з серверів, прописав їх в конфіге nginx і знову його запустив. Атака, яка легко посадила 2 сервери, цього разу спасувала. Вхідний трафік не зменшився, атака йшла до ранку, але всім сайтам на хостингу це вже було по барабану. Навіть ab в 200 потоків, який я запустив паралельно з атакою нічого не змінив. Я боявся за базу - вона хоч і на потужній машині, але на одній, проте, мабуть за рахунок агресивного кешированія, база впоралася. А на веб-сервері-сервері опустився до 3, на сервері з'явився idle і тут-же взявся за справу антидос-скрипт. Запити валили шквалом, проте антидос знаходила час їх аналізувати і забанити найактивніших, тим самим понизивши навантаження десь на 40%. Підсумок: під час атаки сервера були завантажені не більше ніж на 60% (багато ресурсів віджирала роздача файлів), всі сайти (навіть на Вордпресі) відгукувалися швидко, атака йшла лісом. Сьогодні півдня довелося витратити на пошук багов, які з'явилися у зв'язку з такою зміною архітектури, проте в цілому результат хороший. Сподіватимемося, що сайт тепер захищений від ДДОС повністю. Чому повністю? тому що в ua-ix не буде достатньої кількості комп'ютерів, щоб його покласти, а ширина вхідного світу така, що сама стримає великий наплив ботів. Максимум, чого можна буде добитися, так це того, що сайт не буде доступний зі світу, проте і для цього треба буде сильно постаратися.
Принаймні це мій оптимістичний прогноз, думаю, що організатори атак не зупиняться на досягнутому і сайт ще не раз перевірять на міцність (та в і нас є ще гуляючі сервера+можно зібрати mysql кластер), проте те що якась кількість грошей вони вже спустили в унітаз (10 годин безрезультатної досить масованої атаки), це радує.
UDP та торенти
Очима фахівця, суть того, що відбувається така: з кінця січня (стабільна µTorrent версія 2.0 з µTP вийшла якраз 25 січня, офіційно доступна з 3 лютого) в статистичних звітах операторів зв'язку виявлено безперервне зростання UDP-трафіку і одночасне зменшення середньої величини пакетів, які істотно збільшували навантаження на мережеве устаткування. Спостереження показали, що чим сильніше завантажений канал клієнта, тим дрібніші пакети, довша черга і вище навантаження на роутерах.
У всіх випадках причиною що відбувається був названий МікроТоррент (µTorrent), з версії 1.8.1 що почав освоювати протокол обміну µTP (Micro Transport Protocol, до речі, що так не дістав схвалення IETF). І провайдерам просто повезло, що через низку обставин клієнти до версії µTorrent v2.0 не оновилися одномоментно. (У ній, за умовчанням, udp-завантаження стартує першим, а якщо не вийде, то лише тоді – по TCP). Інакше наростання проблем в мережі замість плавного носило б миттєвий характер і, можливо, відразу «повалило» до третини вітчизняних провайдерів. Останні могли б трактувати поведінку як ddos-атаки на провайдерське устаткування з відповідним недемократичним «закручуванням гайок» в аварійному порядку.
Остаточний аналіз ситуації був ускладнений тим, що у відкритому доступі повного опису протоколу, який став займати значну долю UDP трафіку, немає: цей опис застарілий і не дає повної картини, а стаття у Вікіпедії досить поверхневий описує характер проблем.
Реінженеринг дозволив не лише переконатися, що згідно з алгоритмами µTP в процесі обміну зменшується довжина пакету із зростанням завантаження каналу, але і передбачити, що для підтвердження використовуються udp-пакети квитування (з функцією, типа ACK) розміром в 2 десятки байт.
Логіка розробників протоколу і алгоритмів µTorrent може виправдовуватися тим, що вони не вважають розумними чекати TCP-ACK від доставки пакету. Адже tcp-потік формується послідовно, і якщо в стеку, наприклад, вже знаходиться 50 пакетів, але немає два, то передачу вони не здійснюватимуть, поки втрачені не прийдуть. А ось пірінгове застосування за своєю суттю якраз і не критично до строгої послідовності у вступі інформації, адже воно запрошує і збирає файли по шматочках.
І що виходить насправді? Додаток, відповідно, зменшує розмір пакету, тому що у нього зростає час між відсиланням пакету і приходом квитанції. Але зростає-то воно тому, що пакети стоять в переповненій черзі на «шейпері». І замість того що б спочатку зменшити кількість посланих, алгоритм ... далі зменшує їх розмір. В результаті, при даному агресивному алгоритмі використання udp-протоколу МікроТоррентом результуючий трафік (ємкість каналу) на клієнтові практично не міняється. Тобто вихідна мрія творців даного ПЗ – завантажити канал «під зав'язку» від цього ближче не стає. Міняється лише структура трафіку – з'являється більше дрібних пакетів, що для провайдера насправді небезпечніше чим зростання трафіку.
Давайте порахуємо: якщо в ходу пакети по 150 байт, то при швидкості 100 мегабіт операторові потрібно буде обробити в секунду ... 87 тисяч пакетів! Не всякий провайдер зможе оперативно відреагувати на виниклу проблему: замінити ті ж сервери доступа/роутери на високопродуктивних не всім по кишені. В результаті, багато провайдерів вимушено було для своїх клієнтів ввести на додаток до обмежень по Mbps, ще і по pps.
Але, навіть якщо провайдерське устаткування зможе впоратися з цим алогічним алгоритмом обміну, замість вичавлених з провайдера декількох зайвих відсотків смуги, клієнт ризикує втратити значно більше завдяки збільшеному пакетному навантаженню . на свій домашній шлюз і, можливо навіть – на свій не дуже сучасний ПК! А що він зробить, побачивши, що швидкість закачування знизилася? Правильно, без тіні сумніву звернеться в технічну підтримку і звалить свої проблеми на провайдера.
Оскільки локальна ситуація моделюється досить нескладно, я провів невеликий експеримент з наявним adsl-wifi-шлюзом, який можу запропонувати просунутим користувачам µTorrenta. Особливо вражаючим тест виглядатиме на древніх роутерах з Wifi. У моєму циклі випробувань пристрій почав «притормажувати» приблизно вже при 30-40 активних сесіях «звичайного» закачування, але при агресивній роботі по UDP (всього 5 роздач) втратило відразу майже третина смуги. Поза сумнівом, причина – в перевищення можливої кількості коректно оброблюваних пакетів за одиницю часу.