Все ленты — последние статьи

*Защита Linux-сервера от SYN flood:

http://habrahabr.ru/post/185322/


Защита Linux-сервера от SYN flood: основы и методы из песочницы tutorial
Песочница
Disclaimer 1: прошу простить мне тот факт, что статья довольно скомкана, и многие темы не раскрыты полностью. Не стесняйтесь задавать вопросы в комментариях. Я, в свою очередь, постараюсь раскрыть наиболее интересные темы в дальнейших статьях.

 

Disclaimer 2: в сети есть множество статей с заголовками “Как защитить сервер от SYN-атак” или “Защита Linux от DDoS”. Должен предупредить, что многим из них ни в коем случае нельзя слепо верить! Они зачастую написаны людьми, которые плохо понимают, что происходит во время атаки, и рекомендуют делать сумасшедшие вещи — кто-то “оптимизирует” sysctl так, что на сервер перестает проходить даже нормальный трафик, а большинство советуют еще и включить syncookies, чего делать категорически нельзя при большей части реальных атак!

Этой статьей я преследую 3 цели:

1) Дать Вам понимание специфики SYN-атак и того, как они осуществляются;
2) Научить Вас эффективно защищать Linux-сервер от SYN-атаки;
3) Поделиться некоторыми своими наработками.

Что такое SYN-атака?

SYN-флуд или SYN-атака — это метод вызова отказа в обслуживании, влияющий на хосты, выполняющие серверные процессы TCP. Атака используется тот факт, что TCP хранит состояние сессии после получения SYN-сегмента на порту, находящемся в состоянии LISTEN. Основная идея — эксплуатировать это поведение, заставляя хост хранить столько состояний для ложных полуоткрытых сессий, что у него не остается ресурсов для установки новых соединений (RFC4987).

С SYN-флудом относительно сложно бороться, поэтому атаки этого типа так популярны. Почему же?

1) Обычно используются случайные Source IP, которые бесполезно банить, потому что они заново генерируются в каждом пакете;
2) SYN-атака потребляет мало ресурсов на стороне атакующего и очень много на стороне жертвы;
3) Защита от этого типа атак довольно комплексная, полна нюансов и требует времени, чтобы понять и внедрить ее.

Я считаю, что серверы, которые потенциально подвержены атакам (по сути, все серверы, которые имеют публичные IP-адреса, в особенности Web-серверы) должны быть защищены от SYN-атак заранее.


Рисунок 1: SYN-атака

Как производятся SYN-атаки?

Пример утилиты, которая часто используется для осуществления атак — hping3. Вы можете использовать ее для того, чтобы устроить стресс-тест своего сервера до того, как злоумышленники сделают это за Вас.

hping3 — это богатая возможностями утилита, которая может проделывать множество типов атак с различными параметрами. Я не буду давать мастер-класс по ее использованию, покажу только пример того, как можно проверить свой сервер на уязвимость к небольшой SYN-атаке:

# hping3 -S <--fast --faster --flood> -p 80 xx.xx.xx.xx

80 (HTTP) в этом примере — это порт назначения. Обратите внимание на другие параметры (hping3 --help), чтобы понять, как атаки могут отличаться друг от друга.

Пользуйтесь этой утилитой аккуратно и только в целях тестирования собственных ресурсов! Если быть честным, большая часть Интернета уязвима к этим простым операциям, даже если у атакующего канал значительно меньше, чем у атакуемого.

Как определить и измерить SYN-атаку?

1) Во время SYN-атаки атакующий открывает множество подключений к Вашему серверу, но никогда не завершает их, и подключения продолжают висеть в состоянии SYN_RECV. Их можно подсчитать вот так:

# netstat -anutp grep SYN_RECV wc -l

Если это число заметно выше, чем число ESTABLISHED-соединений ( grep ESTABLISHED) — Вы, вероятно, под SYN-атакой.

Кстати, я не рекомендую использовать netstat для автоматизированного мониторинга — во время реальной атаки он может выполняться очень долго и впустую тратить ценные ресурсы CPU.

2) Вы можете мониторить текущую нагрузку на сеть с помощью vnstat:

# vnstat -l -i eth0

Это очень полезная утилита, которая поможет понять, насколько сильная идет атака.

3) Также я рекомендую установить “продвинутый” аналог top — htop и также смотреть, как атака влияет на ресурсы процессора. Запустите htop:

# htop

Нажмите F2, зайдите в 'Display options' и выберите 'Display threads in a different color'. Розовым цветом можно будет увидеть нагрузку от системных прерываний.

4) Просмотрите SYN-сегменты, которые получает сервер — что в них общего? '-c 100' говорит tcpdump ограничиться 100 пакетами.

# tcpdump -i eth0 -nn 'tcp port 80' and 'tcp[13] == 2' -c 100

И наконец, помните, что многие SYN-атаки не “равномерны”, у них есть пики и провалы, которые нужно учитывать в процессе анализа.


Рисунок 2. Динамика типичной атаки

Сначала — главное

Сетевая карта, прерывания, очереди…

Первая вещь, над которой нужно поработать — это драйвер сетевой карты. Когда на сетевую карту приходит фрейм, она должна инициировать системное прерывание, которое говорит процессору приостановить выполнение текущей задачи и обработать пришедшую порцию трафика. Однако если бы каждый фрейм вызывал незамедлительное прерывание и “отвлекал” CPU от текущих задачи, заметную деградацию производительности можно было бы наблюдать даже на простейших сетевых операциях, таких как передача файла по FTP. Поэтому эти прерывания организованы в очередь, которая скапливается на сетевой карте и обрабатывается процессором за один раз. Обычно это происходит 250-1000 раз в секунду, чем реже — тем меньше загрузка CPU, тем выше задержка.

С другой стороны, большинство современных десктопов и серверов имеют насколько процессорных ядер. Поскольку каждое из них работает для ОС как отдельный процессор, мы можем равномерно распределить между ними нагрузку от прерываний. Есть 2 способа это сделать.

1) Первый и рекомендуемый — использовать аппаратные очереди. Современные сетевые карты имеют несколько очередей прерываний, обычно 4-16. По какой-то причине, в Linux они часто отключены по умолчанию. Нам нужно их включить, а затем равномерно распределить их по процессорам.

2) Второй способ называется RPS — Receive Packet Steering. Это довольно новый механизм ядра, который автоматически распределяет нагрузку между всеми ядрами, неважно, есть на карточке несколько аппаратных очередей или нет. Используйте этот способ только если у Вас больше ядер, чем аппаратных очередей (кстати, рассмотрите возможность отключения SMT/HyperThreading — во время атаки это будет весьма кстати).


Рисунок 3. Intel 10Gb NIC

Шаги, которые нужно предпринять:

1) Определите производителя и модель сетевой карты (лучше бы это был Intel)

# ethtool -i eth0

2) Установите последние драйверы. Зайдите на сайт производителя чипа для сетевой карты и скачайте последнюю версию драйвера под Linux (чтобы его собрать, понадобятся исходники текущего ядра)

3) Настройте аппаратные очереди. Для этого Вам понадобится воспользоваться документацией от драйвера сетевой карты, которая идет вместе с ним.

4) Распределите загрузки прерываний равномерно между ядрами.
Нужно будет определить, какие номера прерываний использует карточка (в нашем случае eth0).

# cat /proc/interrupts grep eth0

Здесь Вы можете увидеть все номера прерываний, которые использует Ваша NIC, и то, как они по факту сейчас распределяются по ядрам. Запишите эти числа. Теперь нам нужно поменять SMP affinity, чтобы назначить каждому прерыванию свое ядро (interrupt 1 > cpu 1, interrupt 2 > cpu 2 и т.д.). Вот как это делается:

# echo <affinity> > /proc/irq/xx/smp_affinity

5) ОПЦИОНАЛЬНО: Включите RPS (это может не понадобиться, см. выше)

# echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus

Выберите соответствующее устройство (если это не eth0) и все очереди приема, которые оно поддерживает (rx-0..n).

Sysctl

Следующая вещь называется sysctl. Это программный интерфейс, позволяющий Вам настраивать множество параметров системы “на лету”. Однако в рамках данной статьи мы воздержимся от обсуждения того, как с их помощью защититься от SYN-атак — об этом в Интернете и так написано слишком много.

В отличие от того, как думает большинство “советчиков”, НЕ СУЩЕСТВУЕТ “универсальных оптимизаций”, которые подошли бы каждому, у кого есть сервер. Каждая так называемая оптимизация влечет за собой последствия, такие как повышенное потребление памяти или уменьшение доступности/функциональности. Безусловно, определенные изменения должны применяться, но эта тема заслуживает отдельной статьи, более обширной, чем эта.

Единственное, что хочется отметить как важное и зачастую неправильно применяемое — так называемые syncookies. Вкратце, это системный механизм борьбы с SYN-атаками путем отправки cookies отправителю для подтверждения легитимности соединения при переполнении очереди соединений. Факт в том, что это может быть действительно полезно, если скорость атаки составляет 40% от эффективной пропускной способности сервера или меньше (под эффективной я имею в виду такую пропускную способность, которую сервер по факту способен обработать). В остальных случаях использование syncookies ведет к повышению нагрузки на сеть, CPU и, таким образом, к отказу в обслуживании.

Лично я в большинстве случаев отключаю syncookies.

Базовые техники защиты с помощью iptables

Не забудьте “укрепить” свой файрвол: блокируйте весь входящий трафик, кроме того, который ДЕЙСТВИТЕЛЬНО нужен на Вашем сервера. Разрешите управление только из доверенных сетей.

Самый простой случай — это атака с 1 IP без подмены адресов (спуфинга). С такими бороться просто:

# iptables -A INPUT -p tcp -m state --state NEW -m recent --update --seconds 60 --hitcount 20 -j DROP
# iptables -A INPUT -p tcp -m state --state NEW -m recent --set -j ACCEPT

Эти правила ограничивают количество SYN-пакетов с одного адреса до 20 в минуту. Только не пользуйтесь этим на постоянной основе! Вы можете заблокировать легитимный трафик, идущий из-за NAT. Еще одно предостережение. Это правило использует модуль conntrack, который, как справедливо заметили в комментариях, при сильной атаке может вызвать DoS. Это может спасти от небольшого SYN flood с одного адреса, но во время реальной атаки толку мало, т.к. IP-адреса все равно генерируются.

Многие SYN-атаки можно отфильтровать по “необычным” и повторяющимся параметрам TCP-заголовка, которыми “грешат” атакующие утилиты.

Первый такой параметр — это MSS (Maximum Segment Size) — максимальный размер сегмента, который хочет разрешить хост, инициирующий соединение. Большинство атакующих утилит (включая hping) не задействуют эту опцию по умолчанию. С другой стороны, я еще не видел легитимных клиентов, которые бы ее не ставили. “Нормальные” значения находятся в диапазоне от 536 до 65535, давайте это использовать:

# iptables -t mangle -I PREROUTING -p tcp -m tcp --dport 80 -m state --state NEW -m tcpmss ! --mss 536:65535 -j DROP

Кстати, таблица mangle быстрее, чем filter, потому что обрабатывается раньше, однако через нее проходит ВЕСЬ трафик, и нет возможности разделить INPUT, OUTPUT и FORWARD.

Еще один крайне полезный параметр — это размер окна TCP (window size). Большинство атакующих не генерируют его каждый раз, и он остается одинаковым в течение всей атаки. Чтобы отфильтровать и заблокировать сегменты по window size, понадобится модуль u32 для iptables. После того, как Вы узнаете размер окна, с которым идет атака, преобразуйте его в hex и выполните следующую команду:

# iptables -t mangle -I PREROUTING -d xx.xx.xx.xx -p tcp -m u32 --u32 "6&0xFF=0x6 && 32&0xFFFF=0x200" -j DROP

Но будьте осторожны! Не блокируйте well-known размеры окон, используемые популярными операционными системами.

Наконец, упомянем параметр TTL (Time To Live). Я хочу, чтобы это был самый последний параметр, на котором основываются Ваши проверки, поскольку диапазон значений невелик и Вы практически наверняка заблокируете не того, кого надо. Но когда вы видите множество пакетов атаки, и совпадает у них только TTL — это может помочь.

# iptables -A FORWARD -p tcp -m ttl --ttl-eq=55 -m state --state NEW -j DROP

Если ничего не помогает

Обратитесь к профессионалам! Я серьезно. То, что описано здесь — это только верхушка айсберга. Помните, есть две стратегии защиты, которые должны использоваться вместе:

1) Наращивание/оптимизация вычислительных/сетевых ресурсов для обработки большего числа запросов;
2) Отделение нежелательного трафика от легального с целью его дальнейшей блокировки.

Таким образом, у Вас есть 3 причины попросить помощи со стороны:
1) У Вас недостаточно полосы пропускания или же вычислительных ресурсов для отделения нежелательного трафика от легального;
2) Атака сложная, и нежелательные пакеты не отличаются или почти не отличаются от легальных. Профессионалы используют более продвинутые методы фильтрации, а иногда дорогостоящее специализированное оборудование и ПО.

И наконец,

DDoS
, SYN-атака
, SYN flood
, Linux
, защита от SYN-атак


2115
202
netracer 2,0
комментарии (15) отслеживать новые: в почте в трекере
0
bugaga0112358, 2 июля 2013 в 16:24 (комментарий был изменён) #
Мне кажется, что в данном случае корректнее использовать таблицу raw вместо таблицы mangle. Она обрабатывается еще раньше raw, но не дает такую нагрузку на процессор, которую генерирует mangle.
+1
T0R, 2 июля 2013 в 19:18 #
&#8629;
&#8593;
На самом деле преимущество размещения правил в таблице raw (у автора подгружен модуль conntrack) только в том, что правила отрабатывают до connection tracking подсистемы. В данной же ситуации сервер будет уничтожен от десятков-пары сотен kpps спуфленного синфлуда в зависимости от конфигурации. Уничтожит ресурс cpu как раз таки модуль conntrack, не прерывания.
Автор зря пренебрегает синкуками, ребята из HLL показали на конференции PHDays простейший способ перелопатить 2.5Mpps честного флуда. Призываю в тред flx.
+2
catharsis, 2 июля 2013 в 16:59 #
я бы не ставил жесткую планку SYN_RECV > 30 = syn flood.
Зависит от производительности и профиля использования системы.
Бывает SYN_RECV > 1000 и в других ситуациях :)

Расскажите больше про syn cookies, почему они повышают загрузку системы?
Кажется, linux начинает посылать syn cookies автоматически (с дефолтным sysctl) при достижении некоторого состояния.

–1
netracer, 2 июля 2013 в 21:27 #
&#8629;
&#8593;
Согласен :) Сразу приходит на ум сервер, массово обслуживающий клиентов мобильного Интернета. Поправил.

При включенном Syncookies в случае переполнении очереди SYN сервер вместо того, чтобы дропать подключение, отправляет в ответ SYN+ACK и помещает в таблицу успешные соединения. Если syncookies отключены, этого не произойдет. Знаю, что в RHEL6 они включены по умолчанию.

Загрузку системы они повышают, вероятно, потому, что во время атаки запускаются дополнительные проверки. Видел, как при включении syncookies во время атаки сервер просто «вешался».
+1
T0R, 2 июля 2013 в 21:37 #
&#8629;
&#8593;

При включенном Syncookies в случае переполнении очереди SYN сервер вместо того, чтобы дропать подключение, отправляет в ответ SYN+ACK и помещает в таблицу успешные соединения.


Что за ад я сейчас прочитал?
Не вводите читателей в заблуждение, вы и близко не понимаете сути процессов, о которых пишете.
Пр работе syncookies не выделяется ни бита памяти.
Второй момент, вы же сами и пишете, что без syncookies сервер будет банально дропать все входящие SYN пакеты, сервис не работает для новых легитимных пользователей, чего и добивался атакующий.
–1
netracer, 2 июля 2013 в 21:54 #
&#8629;
&#8593;
Ну вот Вы, как человек, хорошо понимающий механизм работы syncookies, объясните пожалуйста, почему во время атаки включение syncookies ведет к отказу в обслуживании? При правильно настроенном sysctl, разбросанных прерываниях и пр.

Я вот этот документ cr.yp.to/syncookies.html (на него ссылка в RFC) прочитал 3 раза и до конца не понял :)
+1
vaara, 2 июля 2013 в 22:12 #
&#8629;
&#8593;
у вас версия ядра < 3.6?
+1
T0R, 3 июля 2013 в 00:25 #
&#8629;
&#8593;
Сперва что вы понимаете под термином «отказ в обслуживании». Как я писал уже выше, не включая syncookies, сервис доступен не будет, даже не смотря на то, что у вас ssh не отвалился и сервер выглядит живым. Включение syncookies заставляет сервер «бороться», а не тупо пасовать в первую же секунду.
Следующий момент. Он называется блокировки. Не важно сколько на сколько у вас ядер распределен трафик есть узкие места. Нужно больше информации по этому поводу? Я выше привет ссылку на доклад от HLL, там все расписано, ядерный код приводить здесь не буду.
Надеюсь ответил. Теперь и вы будьте добры ответить.
1.

зачастую написаны людьми, которые плохо понимают, что происходит во время атаки, и рекомендуют делать сумасшедшие вещи


Вы сами то как оцениваете свой материал?
2.

Многие SYN-атаки можно отфильтровать по “необычным” и повторяющимся параметрам TCP-заголовка, которыми “грешат” атакующие утилиты.


Что будете делать, если придет честный син флуд?
3. Как вы оцениваете процент false positive?
4.

прочитал 3 раза и до конца не понял :)


Зачем тогда все это?
–1
stavinsky, 2 июля 2013 в 18:00 #
Спасибо, очень позновательно. Хотелось бы серию статей. Например опыт подбора правильных параметров sysctl, способы анализа трафика, возможно о мониторринге сетевой активности, о других видах атак, о средствах защиты на сетевом оборудовании (типа bgp blackholing ). Добавил в избранное, и в ближайшее время буду изучать подробнее!
0
flx, 2 июля 2013 в 19:21 #
призвался.
теперь у меня глаза вот такие:
image

Даже не знаю что написать.
0
flx, 2 июля 2013 в 19:26 #
&#8629;
&#8593;
Нашелся что спросить.

Уважаемый автор, а можно как-то осветить вопрос бенчмарков предлагаемого решения?
Особенно увлекательно это будет при включенном conntrack ;)

0
netracer, 2 июля 2013 в 21:36 #
&#8629;
&#8593;
Действительно, стоило написать про прожорливость conntrack, поправил
0
EvilMan, 3 июля 2013 в 10:09 #
&#8629;
&#8593;
В этих правилах нет необходимости учитывать состояние соединения через коннтрак. Просто проверяйте флаг syn в заголовке tcp.
0
EvilMan, 3 июля 2013 в 10:12 #
Кстати, после последнего Netfilter Workshop (конференция разработчиков Netfilter), началась работа над реализацией механизма syn-proxy, который так же является очень эффективным при syn-флуде.