Информационные технологииStfw.Ru 🔍

Предотвращение DoS атак в FreeBSD

Авлин Виг
🕛 11.08.2006, 11:52
onlamp.com Методы описанные здесь одинаково применимы как для 4-ой, так и для 5-ой ветки FreeBSD.

Различные виды атак

Целью атак DoS (Denial of Service - отказ в обслуживании) является отказ сервиса в функциональном обслуживании своих клиентов. Веб сервера прекращают обслуживание вебстраниц, почтовые сервера не принимают и не отправляют почту, роутеры отключаются - и все вместе обрывают вашу связь с Интернетом.

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

В течение последних лет атакующие постоянно совершенствуют свои методы. Так как девелоперы создают софт более надежным и более устойчивым к DoS, атаки теперь направлены на те части сервисов, которые трудно защитить. Мы обсудим первый вид атак, а также что требуется сделать , чтобы защитить наши сервисы от них.

Выжмите все из своих сервисов

Защита ваших сервисов от атак это практически то же самое, что и их настройка на максимальную производительность. Чем большую нагрузку вы сможете выдерживать, тем гибче вы будете. Все происходит немного по другому, когда атака действует иначе, чем предполагает настройка вашего сервиса.
Например, если у вас есть веб сервер, настроенный на передачу больших файлов, а атака проводится при помощи большого количества маленьких, коротких транзакций, то вы увидите, что буферы сетевой памяти закончатся очень быстро. Я рекомендую сначала прочитать «Настройка FreeBSD для различных приложений» (http://silverwraith.com/papers/freebsd-tuning.php). В ней хорошо описано, с чего начать оптимизацию производительности ваших серверов. Также tuning(7) (http://www.freebsd.org/cgi/man.cgi?query=tuning) - отличное справочное руководство по улучшению производительности.

Анализ и блокировка DoS

Первое, что вы должны сделать для своей защиты, - это научиться понимать сущность различных видов атак. Как было сказано раньше, атаки, поглощающие ресурсы, нацелены в вашей системе на места, которые могут оказаться для вас «узкими». Самые частые цели атак - пропускная способность сетевого канала, системная память, память сетевого стека, I/O дисковой подсистемы, ограничения операционной системы такие, как лимит на число открытых файловых дескрипторов и ЦПУ. Эти «узкие» места могут присутствовать в вашей системе или в вашем сетевом оборудовании.

Атаки на полосу пропускания

Атаки на ваш сетевой канал очень трудно отразить. То, как вы должны от них защищаться, сильно зависит от вашей сетевой топологии и от того, какую помощь может предоставить вам ваш провайдер. Начните, задавая следующие вопросы:
- Это атака против одного хоста или против нескольких?
- Атака охватывает маленькое количество портов или случайно поражает много портов?
- Состоит ли атака из протоколов, которые обычно не используются с атакуемым сервером?

Нам повезло, что большинство атак сегодня просты по своей природе. Они выбирают один или два вида атаки и в большинстве случаях малое количество IP-адресов. В этом есть смысл - ширину канала атакующим так же трудно захватить, как и нам ее защитить. Если ваш Интернет-канал не заблокирован, то приемлемым решением будет блокировать трафик к атакуемым хостам на вашем шлюзе.

Еще хорошо было бы запустить tcpdump на атакованных серверах, если есть такая возможность, чтобы увидеть, какой тип атаки используется. Проверьте наличие большого количества одинаковых пакетов - все TCP SYN, UDP или ICMP. Проверьте на наличие пакетов, все из которых направлены на определенный порт. Если вы увидите, что количество исходящих IP адресов достаточно невелико, то можно блокировать пакеты с этих адресов.

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

С современными мультигигабитными сетями довольно обычно, что канал с Интернетом имеет большую полосу пропускания, чем локальная сеть, так что становиться возможным блокировать атаку на вашем Интернет-шлюзе. Хотя в большинстве случаев это не помогает. Когда ваш Интернет канал забивают - это очень раздражает. Самое время позвонить вашему провайдеру и узнать, готовы ли они помочь вам с этими проблемами.

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

Если для публикации IP-пространства в Интернет на своем Интернет-шлюзе вы используете пограничный межсетевой протокол (Border Gateway Protocol, BGP), вы можете выбрать третий вариант. Этот вариант позволяет пользователям UUNet, C&W, XO и многих Интернет-провайдеров экспортировать небольшие маршруты (например, /32) со специальной общественной строкой, которая указывает на то, что пограничным маршрутизаторам надо сбрасывать все входящие на этот маршрут пакеты. Это очень эффективный метод отражения атаки с минимальными последствиями для вас и вашего провайдера. Конечно, этот способ хорошо работает с малым количеством атакованных хостов и если ваш провайдер обеспечивает такую функциональность. Свяжитесь с ним, чтобы это выяснить. Очевидный недостаток этого способа - ваши IP адреса, которые вы экспортируете описанным образом, полностью потеряют связь с Интернетом.

В общем случае лучше всего держать свою сеть в чистоте - позволять только тот трафик, который необходим вашим сервисам для работы. Откройте доступ TCP пакетам на порты 80 и 443 ваших серверов и откройте UDP для ваших игровых серверов. Откройте SSH только для проверенных хостов (комм. перевод. - это необходимо только в случае, если у вас функционирует веб сервера и игровые сервера, здесь приведено в качестве иллюстрации). Все это ограничит выбор инструментов для атакующего, когда он заглянет к вам.

Атаки на системы и сервисы

Если ваш канал не забивают, то значит атака проводится на ваши системы и сервисы, которые на них подняты, а не на всю вашу сеть. И опять лекарство зависит от типа атаки. Вы можете обнаружить, что любая система может содержать много потенциально уязвимых «узких» мест. Атаки на системы и сервисы в основном попадают под следующие категории -
- ограничение сетевой подсистемы (очень большое количество пакетов в секунду)
- ограничение памяти ОС или приложения (поглощение памяти)
- ограничения дисковой подсистемы и ЦПУ (большое количество корректных запросов)

Атаки, направленные на системы, могут очень раздражать, так как от них тяжело защититься. Тем менее FreeBSD обладает некоторой защитной магией.

По умолчанию каждый раз, когда ваша сетевая карточка получает пакет, она генерирует прерывание процессору со своим IRQ. ЦПУ получает его и выделяет небольшое количество времени для получения этого пакета с интерфейса. С нормальной загрузкой это происходит несколько тысяч раз в секунду - это нормально даже с возможностями маломощных процессоров. Со старыми процессорами производительность начнет падать, начиная с 25-50 тысяч пакетов в секунду. С размером пакета в 1500 байт это составит где-то от 40 до 75 мегабайт в секунду, достаточно много для обработки большинством старых процессоров. Большинство систем с 1 Ггц начнут испытывать проблемы при 75 тысячах пакетов в секунду. Два фактора усложняют проблему:
- TCP SYN пакеты требуют полной обработки прежде чем система может ответить SYN ACK пакетом адресу-источнику. TCP и UDP пакеты, посланные на закрытые порты так же, как и ICMP пакеты в целом, требуют похожую обработку и ответы. Не будучи таким ресурсоемким, как обработки SYN пакетов, это все же занимает время и исходящий канал.
- Размер пакета также играет большую роль. Ваш канал может вместить больше маленьких пакетов, чем больших. Чем больше пакеты, тем больше процессорного времени требуется на их обработку независимо от их типа.

Как было сказано раньше - каждое прерывание съедает определенное количество процессорного времени. С достаточным числом сгенерированных IRQ у ЦПУ не будет времени ни на что другое, кроме обработки этих прерываний. Входящие пакеты остаются необработанными, приложения не получают процессорного времени и ваша система практически мертва. Это известно как Live-lock. Ваша система все еще жива, так как она не упала, она не может делать ничего полезного. Как только пакеты перестают поступать на интерфейс, ЦПУ начнет обработку всех еще необработанных принятых пакетов. Это может занять несколько минут, а может и несколько часов.

Есть несколько вещей, которые можно сделать, чтобы предотвратить или уменьшить эффект от большого количества пакетов без покупки дополнительного оборудования. Все эти способы используют sysctl(8) (http://www.freebsd.org/cgi/man.cgi?query=sysctl) FreeBSD. Вот параметры, которые надо добавить в ваш /etc/sysctl.conf:

- net.inet.tcp.msl=7500
net.inet.tcp.msl определяет максимальное время жизни сегмента (Maximum Segment Life - MSL). Это максимальное количество времени ожидания ACK в ответ на SYN-ACK или FIN-ACK в миллисекундах. Если в течение этого времени компьютер не получает ACK, то он считает, что сегмент потерян и освобождает сетевое подключение.
Это имеет два следствия. Когда вы пытаетесь закрыть соединение, то если последний ACK потерян или задерживается, то сокет закроется быстрее. Тем не менее, если клиент пытается открыть соединение с вами и его ACK задерживаются более чем на 7500 миллисекунд, то соединение не установится. RFC 753 определяет MSL равным 120 секундам. Но оно было написано в 1979, с тех пор временные рамки немного изменились. Сегодня во FreeBSD по умолчанию установлено 30000 миллисекунд. Это в общем приемлемо, но для более эффективной защиты от DoS можно понизить параметр до 7500 или даже меньше.

- net.inet.tcp.blackhole=2
net.inet.tcp.blackhole определяет, что должно происходить, когда система получает TCP пакет на закрытый порт. Когда эта переменная установлена в 1, SYN пакеты на закрытый порт будут отклоняться без отсылки отправителю RST пакета. Когда она установлена в 2, все пакеты на закрытый порт отбрасываются без отсылки RST. Это бережет время ЦПУ, потому что пакеты практически не требуют обработки, а также освобождает исходящий канал, потому ответные пакеты не отсылаются.

- net.inet.udp.blackhole=1
net.inet.udp.blackhole схоже с net.inet.tcp.blackhole по своей функциональности. Так как протокол UDP не устанавливает соединение, как TCP, то при сбросе UDP пакетов есть только одна опция. Когда эта переменная установлена в 1, система отбрасывает все UDP пакеты, которые адресованы закрытым портам.

- net.inet.icmp.icmplim=50
Название это переменной вводит в заблуждение. Она контролирует максимальное количество пакетов ICMP «Недостижимо», а также количество отсылок TCP RST пакетов в секунду. Она помогает уменьшить урон от атак, при которых генерируется большое количество ответных пакетов.

- kern.ipc.somaxconn=32768
kern.ipc.somaxconn ограничивает максимальное количество одновременно открытых сокетов. Значение по умолчанию - 128. Если атакующий сможет завалить вас достаточно большим количеством SYN пакетов за короткий период времени, то он может задействовать все возможные сетевые соединения, успешно ограничив ваших пользователей в доступе к сервисам.

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

Наконец, если у вас есть одна из следующих сетевых карточек, то вы можете включить в ядро опцию DEVICE_POLLING:
- dc
- em
- fxp
- nge
- rl
- sis

DEVICE_POLLING меняет обработку прерываний, со включенным DEVICE_POLLING ядро совсем их не обрабатывает!!! Вместо этого ЦПУ будет опрашивать сетевую карточку для приема пакетов, ожидающих обработку. Это заметно уменьшит объем процессорного времени, используемого при обработке входящего трафика. Данный прием работает только с перечисленными выше сетевыми карточками, поскольку только их драйвера поддерживают DEVICE_POLLING.

Карты FXP лучше работают с этой функцией, так как их драйвера и железо очень хорошо разработаны. Качество сетевых карт RL гораздо хуже - без ЦПУ с достаточной тактовой частотой (обычно около 1 Ггц), они редко достигают скорости в 100 Мб/с. Помните об этом, когда будете выбирать новую сетевую карточку.

Мы можете узнать подробнее про DEVICE_POLLING (http://info.iet.unipi.it/%7Eluigi/polling/) на домашней странице автора. Там есть хорошие инструкции по установке и настройке, а также сравнительные тесты со включенной и выключенной функцией DEVICE_POLLING.

Отслеживаем источник атаки

Атаки могут проводиться снаружи и изнутри вашей сети. Очевидно, что первую легче изолировать, чем вторую. Отслеживание источника атак требует некоторых знаний по работе с инструментами сниффинга пакетов такими, как tcpdump, ngrep и ethereal. До тех пор, пока вы не проведете несколько месяцев, тщательно изучая ваш сетевой трафик, и установите мониторинг, который бы сообщал вам об аномалиях, шансы обнаружения, что вы подвергаетесь атаке DoS очень малы. Гораздо чаще жалобы типа «Интернет медленный» или «Я не могу получить свою почту» укажут вам на истину. Важно понимать две вещи:
- Атаки могут проводится как изнутри сети, так и снаружи
- Не все случаи отказа сервисов свидетельствует об атаке DoS и не все атаки DoS вызывают отказ сервиса.

Что это значит для вас? Это означает, что когда вы начнете выяснять, почему Интернет медленный или почему люди не могу закачать свою почту, то помните, что источником проблемы может быть любая машина в вашей сети и в Интернете. Этот отказ может быть случайным.

Анализ следует начать с «узких» мест. Ими могут быть ЦПУ на вашем прокси сервере или на вашем Интернет шлюзе. Если ваше «узкое» место - это системный процесс, такой как например прокси сервер, посмотрите его логи. Требует ли один или несколько процессов больше ресурсов, чем обычно, или производят ли они большое количество запросов?

Если ваше «узкое» место - ваш Интернет шлюз ( на котором мы предполагаем, что стоит FreeBSD), можно использовать следующую команду для просмотра IP пакетов, проходящих через ваш шлюз:
router# tcpdump -n -i <interface> -c 100

Эта команда покажет информацию о первых 100 пакетах (-c 100) , которые прошли через указанный интерфейс (-i <interface>), и не будет ресолвить IP адреса в имена хостов (-n), так как это может отнять дополнительное время или окончиться неудачно, если у вас проблемы с коннектом. Пример строки вывода команды:

04:59:53.915324 192.168.0.3.2327 > 192.168.0.10.1214:
S 3199611726:3199611726(0) win 16384 <mss 1460,nop,nop,sackOK> (DF)

Давайте взглянем на первую часть этого вывода, которая может быть нам полезна.
- 04:59:53.915324
Это временная метка того, когда был обработан этот пакет.
- 192.168.0.3.2327
Это IP адрес источника. Число после последнего октета, 2327, указывает на порт источника пакета.
- 192.168.0.10.1214
Это IP адрес получателя. Число после последнего октета, 1214, указывает на порт, на который пришел пакет.
- S
Это тип пакета, в данном случае SYN пакет. Обратитесь к Daryl's TCP/IP Primer (http://www.ipprimer.com/), чтобы узнать больше об обработке и жизни TCP соединения и типе используемых в нем пакетов.

Трудно предсказать, что вы увидите в процессе реальной атаки, так как атака DoS может проводиться огромных количеством способов. Типичная атака заваливает порт вашего сервера SYN пакетами. Цель состоит в том, чтобы максимально занять вашу систему создаваемыми подключениями, чтобы у нее больше ни на что не оставалось ресурсов. В данном случае вы увидите большое количество SYN пакетов. В рядовых условиях количество пакетов разных типов примерно одинаково.

Ссылки

Эти ссылки я нашел, когда писал данную статью. Практически все они содержат гораздо больше информации, чем я представил. Надеюсь, что они пригодятся вам так же, как пригодились мне.

The FreeBSD handbook. (http://www.freebsd.org/handbook/)
Великолепный источник информации о FreeBSD. Почитайте, если хотите узнать о FreeBSD что-нибудь новое.
Google Groups. (http://groups.google.com/)
Я использовал их для поиска в USENET статей, опубликованных в прошлом. Вам тоже бы не помешало!

Unix   Теги:

Читать IT-новости в Telegram
Информационные технологии
Мы в соцсетях ✉