Материал просмотрен 647 раз(а)

Для того, чтобы понять что такое SYN атака необходимо иметь базовые понятия о том, как вообще происходит образование TCP-соединения. Как мы знаем, в ходе “рукопожатия” серверу отправляется пакет с выставленным SYN флагом, на который он должен ответить пакетом с флагами SYN, ACK. С этой секунды сервер находится в состоянии ожидания от клиента пакета с флагом ACK, что означало бы установленное соединение. Сам сервер при этом находится в состояние SYN RECEIVED (SYN_RECV в *nix).

SYN_flood1

Бриф:

SynAttackProtect,
TcpMaxHalfOpen,
TcpMaxHalfOpenRetried,
TcpMaxPortsExhausted,
MinimumDynamicBacklog,
MaximumDynamicBacklog,
DynamicBacklogGrowthDelta,
TcpInitialRtt,
TcpMaxConnectResponseRetransmissions

Наблюдать состояние установленных соединений можно посредством netstat (как в Linux, так и в Windows).

Проблема в том, что некоторые клиенты умышленно не посылают подтверждение ACK, заставляя сервер тратить ресурсы на поддержание “недооткрытых” сессий. Это и называется SYN атака. Вообще, атака SYN носит характер DDoS. При этом речь идёт именно о переполнении очереди соединений, а не о забивании канала трафиком.

Что же можно сделать, чтобы уменьшить негативное влияние такого “забивания” ресурсов нашего сервера?

  1. Уменьшить размер очереди недооткрытых соединений;
  2. Уменьшить таймаут, по которому соединение будет висеть и ожидать окончательной установки;

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

Модель атаки:

Для совершения атаки используются фиктивные 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 отвечает за формирование динамической очереди сообщений. Расположен этот (и следующие) параметры в разделе:

HKLM\System\CurrentControlSet\Services\ AFD\Parameters

Кроме того, есть параметр, который отвечает за минимальное количество свободных соединений, формируя некоторый “запас” – 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.

Выставляем её:

# sysctl -w net.ipv4.Tcp_synack_retries=”0″