Для того, чтобы понять что такое SYN атака необходимо иметь базовые понятия о том, как вообще происходит образование TCP-соединения. Как мы знаем, в ходе “рукопожатия” серверу отправляется пакет с выставленным SYN флагом, на который он должен ответить пакетом с флагами SYN, ACK. С этой
секунды сервер находится в состоянии ожидания от клиента пакета с флагом ACK, что означало бы установленное соединение. Сам сервер при этом находится в состояние SYN RECEIVED (SYN_RECV в *nix).
Наблюдать состояние установленных соединений можно посредством netstat (как в Linux, так и в Windows).
Проблема в том, что некоторые клиенты умышленно не посылают подтверждение ACK, заставляя сервер тратить ресурсы на поддержание “недооткрытых” сессий. Это и называется SYN атака. Вообще, атака SYN носит характер DDoS. При этом речь идёт именно о переполнении очереди соединений, а не о забивании канала трафиком.
Что же можно сделать, чтобы уменьшить негативное влияние такого “забивания” ресурсов нашего сервера?
Уменьшить размер очереди недооткрытых соединений;
Уменьшить таймаут, по которому соединение будет висеть и ожидать окончательной установки;
Конечно эти меры не могут служить панацеей от всех бед, но существенно увеличат вероятность не потерять легитимного клиента.
Модель атаки:
Для совершения атаки используются фиктивные IP адреса, с которых посылаются пакеты с выставленными флагами SYN. Сервер, получая эти пакеты, периодически посылает на каждый адрес подтверждение SYN+ACK. Недооткрытое соединение может висеть в памяти компьютера 180 секунд, пока, наконец, не будет выброшено из очереди. Ну а размер очереди тоже ограничен. Системы Windows (на примере 2000) имеют очередь в 100, RHEL 7.3 – в 256. Не такая уж большая очередь, верно? Хоть и на каждый порт. Достаточно просто
посылать два раза в секунду такой пакет и редхатовский сервер перестанет отвечать на этом порту. А это вполне под силам даже простой рабочей машинке.
Механизм расширения очереди
В OS Windows нам нужен параметр в разделеHKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters с именем SynAttackProtect:DWORD и значением 1 или 2.
При значении равном 1 уменьшается количество повторных передач и до организации полноценного сеанса не работает маршрутизация содержимого кэша. При значении равном 2 не происходит установка флага соединения с WinSock до создания полноценного сеанса связи. На что реагирует операционная система в таком случае?
Защита от SYN-флуда срабатывает, когда происходит превышение значений, указанных в параметрах TcpMaxHalfOpen (максимальное количество полуоткрытых соединений, которые могут быть обработаны прежде, чем сработает защита. Рекомендуемое значение 100 для Win2k Server и 500 для Win2k advanced server), TcpMaxHalfOpenRetried (максимальное количество полуоткрытых соединений, для которых уже выполнена хотябы одна повторная передача SYN+ACK, рекомендуемое значение 80 и 400
соответственно) и TcpMaxPortsExhausted (число отклоненных SYN запросов, рекомендуемое значение 5) того же раздела реестра.
В ОС Linux существует механизм SYN cookies, включить который можно установкой в единицу значение в /proc/sys/net/ipv4/tcp_syncookies.
Увеличить размер очереди соединений
Прежде всего, хочу предупредить, что увеличение размера очереди влечет за собой резервирование ресурсов системы и может привести к проблемам другого рода.
В Windows динамической очередью соединений занимается драйвер AFD. Глобальный параметр реестра EnableDynamicBacklog = 1 отвечает за формирование динамической очереди сообщений. Расположен этот (и следующие) параметры в разделе:
Кроме того, есть параметр, который отвечает за минимальное количество свободных соединений, формируя некоторый “запас” – MinimumDynamicBacklog, который рекомендуется выставить в значение 20. В случае, если свободных соединений в динамической очереди окажется меньше, чем значение этого параметра, новые будут добавлены в очередь автоматически.
Сумма активных полуоткрытых соединений и максимального количества свободных соединений определяется параметром MaximumDynamicBacklog. При превышении этого значения система не будет создавать новые соединения. Рекомендуется выставить в 20000.
Следующий параметр – DynamicBacklogGrowthDelta, рекомендуется выставить в 10. Это количество свободных соединений, создаваемых за один раз в случае необходимости. Так сказать, при недостатке соединений они создаются не по одному, а сразу некоторой “пачкой”, размер этой пачки регламентируется в этой переменной.
Все ключи имеют тип DWORD!
В операционной системе Linux для этого есть переменная tcp_max_syn_backlog, выставить которую можно, например, так:
# sysctl -w net.ipv4.tcp_max_syn_backlog=”2048″
Уменьшение таймаутов ожидания “недосоединения” в очереди
Как я уже говорил, при получении пакета с SYN флагом, сервер незамедлительно посылает ответ SYN+ACK. Но так как отправитель у нас с фиктивным IP, ответ мы никогда не получим и, как следствие, пакет будет висеть в очереди некоторое время (около трёх минут). В этом случае рекомендуется уменьшить таймаут, чтобы очередь скорее очищалась от ненужных соединений.
Кроме того есть ещё такой временной параметр, как время повторной передачи SYN+ACK пакетов, если не получен ACK ответ. Так вот, первая перепередача осуществляется через 3 секунды.
Лучше бы нам уменьшить это время, чтобы побыстрее разобраться с непонятной TCP сессией (выявить то, что это SYN атака, а не проблемы с каналом). Для этого выставляем значение TcpInitialRtt = “2000” (мсек) в разделеHKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters.
А само количество повторных перепередач определяется параметром TcpMaxConnectResponseRetransmissions в этом же разделе реестра.
Параметр принимает четырезначения:
0 (в очереди 3 секунды, повторно не перепередает);
1 (в очереди хранится 9 секунд, перепередача на 3-ей секунде);
2 (в очереди хранится 21 секунду, перепередача на 3 и 9 секундах);
3 (в очереди – 45 секунд, перепередача на 3, 9 и 21-ой секундах);
В ОС Linux это переменная Tcp_synack_retries, которая по умолчанию на многих ОС равна 5 (удаление полуоткрытого соединения через 3 минуты). А вообще принимаются те же самые значения, что и для Windows.