Захист від syn flood атак, блокнот звичайного адміна)

Власне, мова піде про захист від SYN flood атак:

Дуже популярна DoS атака полягає в посилці великого числа SYN пакетів на ваш сервер. При цьому установка TCP зв'язку не доводиться до кінця. Черга напіввідкритих запитів з'єднань швидко заповнюється, що заважає встановленню нормальних з'єднань. Так як з'єднання не повинно бути обов'язково завершено, така атака не вимагає великих ресурсів від атакуючої машини, тому її легко реалізувати і контролювати.


Визначити SYN атаку просто - команда netstat видає величезний список напіввідкритих підключень:

Чи можемо просто підрахувати кількість:

Для початку - перевіряємо параметр tcp_syncookies - він повинен бути дорівнює 1:

Так і залишаємо. За замовчуванням в нових дистрибутивах цей параметр завжди включений.

Якщо параметр tcp_syncookies встановлений (доступний тільки коли ядро ​​зібрано з CONFIG_SYNCOOKIES), тоді ядро ​​обробляє SYN пакети TCP в звичайному режимі до тих пір, поки черга не заповниться. Після заповнення черги включається механізм SYN cookies.

Включення механізму SYN cookies є дуже простим способом боротьби проти атаки SYN флуд. При цьому трохи більше завантажується процесор через необхідність створювати і звіряти cookie. Так як альтернативним рішенням є відхиляти всі запити на з'єднання, SYN cookies є хорошим вибором.

Також потрібно збільшити чергу напіввідкритих з'єднань - tcp_max_syn_backlog (в Debian Lenny за замовчуванням 1024 з'єднання):

Крім того, можемо зменшити час очікування з'єднання tcp_synack_retries:

Цілочисельне значення (1 байт) tcp_synack_retries визначає число спроб повтору передачі пакетів SYNACK для пасивних з'єднань TCP. Число спроб не повинно перевищувати 255. Що Використовується за замовчуванням значення 5 відповідає приблизно 180 секундам на виконання спроб організації з'єднання.

Зменшуємо до 1 (це приблизно 9 секунд):

Ціле число в файлі tcp_fin_timeout визначає час збереження сокета в стані FIN-WAIT-2 після його закриття локальної стороною. Партнер може не закрити це з'єднання ніколи, тому слід закрити його за власною ініціативою після закінчення тайм-ауту. За замовчуванням тайм-аут становить 60 секунд. В ядрах серії 2.2 зазвичай використовувалося значення 180 секунд і ви можете зберегти це значення, але не слід забувати, що на завантажених WEB-серверах ви ризикуєте витратити багато пам'яті на збереження полуразорванних мертвих з'єднань. Сокети в стані FIN-WAIT-2 менш небезпечні, ніж FIN-WAIT-1, оскільки поглинають не більше 1,5 Кбайт пам'яті, але вони можуть існувати довше.

Цілочисельна змінна tcp_keepalive_probes задає число передач проб keepalive, після якого дзвінки вважається розірваним. За замовчуванням передається 9 проб.

Цілочисельна змінна tcp_keepalive_intvl визначає інтервал передачі проб. Твір tcp_keepalive_probes * tcp_keepalive_intvl визначає час, після якого дзвінки буде розірвано при відсутності відгуків. За замовчуванням встановлений інтервал 75 секунд, тобто час розриву з'єднання при відсутності відгуків складе приблизно 11 хвилин.

Тут вказується максимальна кількість пакетів в чергу на обробку якщо інтерфейс отримує пакети швидше, ніж ядро ​​може їх обробити.

Максимальне число відкритих сокетів, що чекають з'єднання.

Так як подібні зміни параметрів ядра не будуть збережені після перезавантаження - додаємо в /etc/rc.local:

Крім того, можна додати обмеження числа SYN пакетів в одиницю часу в iptables:

Число нових SYN пакетів - максимум 500 в секунду, при перевищенні порога в 1500 - нові пакети блокуються:

Більш наочно цей критерій можна уявити собі як деяку ємність з випускним отвором, через яке проходить певна кількість пакетів за одиницю часу (тобто швидкість «витікання»). Швидкість «витікання» якраз і визначає величина --limit. Величина --limit-burst задає загальний «обсяг ємності». А тепер уявімо собі правило --limit 3 / minute --limit-burst 5, тоді після надходження 5 пакетів (за дуже короткий проміжок часу), ємність «наповниться» і кожний наступний пакет буде викликати «переповнення» ємності, тобто «Спрацьовування» критерію. Через 20 секунд «рівень» в ємності буде знижений (відповідно до величини --limit), таким чином вона готова буде прийняти ще один пакет, не викликаючи «переповнення» ємності, тобто спрацьовування критерію.

Сподобалося це: