какие методы позволяют предотвратить переполнение приемных буферов коммутаторов или маршрутизаторов
Управление потоком кадров (проблема переполнения выходного буфера)
Трафик неравномерно распределяется между выходными портами коммутатора, легко представить ситуацию, когда в какой-либо выходной порт будет направляться трафик с суммарной средней интенсивностью большей, чем протокольный максимум.
На рис. … изображена как раз такая ситуация, когда в порт 3 коммутатора направляется трафик от портов 1,2,4 и 6. Естественно, что когда кадры поступают в буфер порта со скоростью превышающей скорость ухода, то внутренний буфер выходного порта начинает неуклонно заполняться необработанными кадрами. Какой бы ни был объем буфера порта, он в какой-то момент времени обязательно переполнится. Для того чтобы избежать потери кадров необходимо заставить узлы, которые шлют кадры вызывающие переполнение, прекратить их передачу. При этом нельзя менять существующие протоколы работы оборудования на физическом и канальном уровне.
Рисунок 4‑11. Переполнение буфера порта из-за несбалансированности трафика
Если порты коммутатора работают в обычном, то есть в полудуплексном режиме, то у коммутатора имеется возможность оказать некоторое воздействие на конечный узел и заставить его приостановить передачу кадров, пока у коммутатора не разгрузятся внутренние буферы. Эта возможность основана на воздействии порта на конечный узел с помощью механизмов алгоритма доступа к среде, который конечный узел обязан отрабатывать. Т.е. каждый входной порт оказывает воздействие на узел находящийся в сегменте, который к нему подключен.
Обычно применяются два основных способа управления потоком кадров — обратное давление на конечный узел и агрессивный захват среды.
Метод обратного давления (backpressure) состоит в создании искусственных коллизий в сегменте, который чересчур интенсивно посылает кадры в коммутатор. Для этого коммутатор обычно использует специальную последовательность (jam-последовательность), отправляемую в выход порта, к которому подключен сегмент (или узел), чтобы приостановить его активность. Т.е. в ответ на передачу узлом своего кадра коммутатор сразу начинает свою передачу, которая вызывает коллизию и тем самым прерывает передачу узла.
Второй метод «торможения» конечного узла в условиях перегрузки внутренних буферов коммутатора основан на так называемом агрессивном поведении порта коммутатора при захвате среды либо после окончания передачи очередного пакета, либо после коллизии. Т.е. коммутатор сам начинает передачу нового кадра после передачи предыдущего, не дожидаясь окончания технологической паузы. Компьютер не может захватить среду, так как он выдерживает стандартную паузу и обнаруживает после этого, что среда уже занята.
Если коммутатор работает в полнодуплексном режиме, то уже не существует возможности воздействовать на узел с помощью механизмов доступа к разделяемой среде, и протокол работы конечных узлов, и его портов должен меняется. В соответствии со стандартом IEEE 802.3x для поддержки полнодуплексного режима работы коммутаторов протоколы взаимодействия узлов были модифицированы, путем встраивания в них явного механизма управления потоком кадров.
Процедура управления потоком кадров в полнодуплексном режиме подразумевает две команды — «Приостановить передачу» и «Возобновить передачу», которые направляются от порта коммутатора узлу. Эти команды реализуются на уровне символов кодов физического уровня, таких как 4В/5В, а не на уровне команд, оформленных в специальные управляющие кадры. (Напомним, что в результате логического кодирования 4В/5В мы получаем 16 «запрещенных» 5 битных символов, которые не могут использоваться для передачи данных, среди этих запрещенных символов и выбираются указанные две команды.) Сетевой адаптер или порт коммутатора поддерживающий стандарт 802.3х и получивший команду «Приостановить передачу», должен прекратить передавать кадры впредь до получения команды «Возобновить передачу».
Основы коммутации
Управление потоком в полудуплексном и дуплексном режимах
Механизм управления потоком (Flow Control) позволяет предотвратить потерю данных в случае переполнения буфера принимающего устройства.
Для управления потоком в полудуплексном режиме обычно используется метод обратного давления (Backpressure). Принимающее устройство ( порт коммутатора) в случае переполнения его буфера отправляет искусственно созданный сигнал обнаружения коллизии или отправляет обратно устройству-отправителю его кадры.
Общая схема управления потоком показана на рис. 1.22.
Дуплексный режим работы и сопутствующее ему управление потоком являются дополнительными режимами для всех МАС-уровней Ethernet независимо от скорости передачи. Кадры-паузы идентифицируются как управляющие МАС-кадры по уникальным значениям полей » Длина /тип» (88-08) и «Код операции управления МАС» ( 00-01 ).
Заголовок | Признак начала кадра | Адрес назначения | Адрес источника | Длина/ тип | Код операции управления MAC (00-01) | Параметры управления MAC (от 00-00 до FF-FF) | Зарезервировано | Контрольная последовательность кадров |
---|---|---|---|---|---|---|---|---|
7 байт | 1 байт | 6 байт | 6 байт | 2 байта | 2 байта | 2 байта | 42 байта | 4 байта |
Правильно сконфигурированная функция управления потоком на устройствах позволяет повысить общую производительность сети за счет уменьшения потери данных и повторных передач. Управление потоком данных IEEE 802.3х большинства интерфейсных сетевых карт и встроенных сетевых карт включено по умолчанию. Коммутаторы D-Link имеют разные настройки функции IEEE 802.3х по умолчанию:
Поэтому для корректной работы функции IEEE 802.3х на порте коммутатора должна быть активизирована функция управления потоком.
Технологии коммутации и модель OSI
Несмотря на преимущества коммутации 2-го уровня, она все же имеет некоторые ограничения. Наличие коммутаторов в сети не препятствует распространению широковещательных кадров по всем сегментам сети.
Коммутаторы уровня 3 осуществляют маршрутизацию пакетов аналогично традиционным маршрутизаторам. Они поддерживают протоколы маршрутизации RIP ( Routing Information Protocol ), OSPF ( Open Shortest Path First ), BGP ( Border Gateway Protocol ) для обеспечения связи с другими коммутаторами уровня 3 или маршрутизаторами и построения таблиц маршрутизации, осуществляют маршрутизацию на основе политик, управление многоадресным трафиком.
Какие методы позволяют предотвратить переполнение приемных буферов коммутаторов или маршрутизаторов
Узкие места сетевой подсистемы Linux. Тюнинг сети в Linux. Настройка производительности сети в модели NAPI и с прерываниями.
Создано 22.11.2016 11:53
Опубликовано 22.11.2016 11:53
Узкие места сетевой подсистемы Linux. Тюнинг сети в Linux. Настройка производительности сети в модели NAPI и с прерываниями.
Кольцевой буфер
Кольцевые буферы, совместно используются драйвером устройства и сетевой картой. TX – есть передача данных, а RX – получение данных в кольцевом буфере. Как следует из названия, переполнение буфера просто перезаписывает существующие данные. Есть два способа переместить данные от сетевой карты до ядра: аппаратные прерывания и программные прерывания, названные SoftIRQs.
Кольцевой буфер RX используется, чтобы сохранить входящие пакеты, пока они не могут быть обработаны драйвером устройства. Драйвер устройства опустошает буфер RX, обычно через SoftIRQs, который помещает входящие пакеты в структуру данных ядра, названную sk_buff или «skb», чтобы начать свой путь через ядро и до приложения, которому принадлежит соответствующий сокет. Кольцевой буфер TX используется для хранения исходящих пакетов, которые предназначенные для отправки по проводам.
Эти кольцевые буферы находятся у основания стека и являются критическим моментом, в который может произойти удаление (drop) пакетов, что негативно влияет на производительность сети.
Прерывания и обработчики прерываний
Прерывания от аппаратных средств известны как прерывания «top-half».
Жесткие прерывания можно увидеть в /proc/interrupts, где у каждой очереди есть vector прерывания в 1-м столбце. Каждой очереди RX и TX присвоен уникальный vector, который сообщает обработчику прерываний, относительно какого NIC/queue пришло прерывание. Столбцы представляют количество входящих прерываний:
#egrep «CPU0|eth1» /proc/interrupts
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
45: 28324194 0 0 0 0 0 0 0 PCI-MSI-edge eth1
SoftIRQs
Иизвестны как прерывания «bottom-half», запросы программного прерывания (SoftIRQs), являются подпрограммами ядра, которые планируется запустить в то время, когда другие задачи не должны быть прерваны. Цель SoftIRQ состоит в извлечении данных из кольцевых буферов. Эти подпрограммы, выполненные в форме процессов ksoftirqd/cpu-number и, вызывают специфичные для драйвера функции кода.
После перемещения данных от драйвера к ядру, трафик двигатется вверх к сокету приложения.
SoftIRQs можно контролировать следующим образом. Каждый столбец есть ЦП:
NAPI Polling
Поиск узкого места
Для примера вывод статистики ethtool:
Существуют различные инструменты, доступные для поиска проблемной области. Следует исследовать:
• Уровень встроенного ПО адаптера
• Уровень драйвера адаптера
• Ядро Linux, IRQs или SoftIRQs
— Проверяем /proc/interrupts и /proc/net/softnet_stat
• Уровни протокола IP, TCP, UDP
Вот некоторые типичные примеры узких мест:
# egrep “CPU0|eth2” /proc/interrupts
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5
105: 1430000 0 0 0 0 0 IR-PCI-MSI-edge eth2-rx-0
106: 1200000 0 0 0 0 0 IR-PCI-MSI-edge eth2-rx-1
107: 1399999 0 0 0 0 0 IR-PCI-MSI-edge eth2-rx-2
108: 1350000 0 0 0 0 0 IR-PCI-MSI-edge eth2-rx-3
109: 80000 0 0 0 0 0 IR-PCI-MSI-edge eth2-tx
0073d76b 00000000 000049ae 00000000 00000000 00000000 00000000 00000000 00000000 00000000
000000d2 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0000015c 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Настройка производительности
SoftIRQ
Если выполнение программных прерываний не выполняются достаточно долго, то темп роста входящих данных может превысить возможность ядра опустошить буфер. В результате буферы NIC переполнятся, и трафик будет потерян. Иногда, необходимо увеличить длительность работы SoftIRQs (программных прерываний) с CPU. За это отвечает netdev_budget. Значение по умолчанию 300. Параметр заставит процесс SoftIRQ обработать 300 пакетов от NIC перед тем как отпустить CPU:
Это значение может быть удвоено, если 3-й столбец в /proc/net/softnet_stat увеличивается, что указывает, на то, что SoftIRQ не получил достаточно процессорного времени. Маленькие инкременты нормальны и не требуют настройки.
0073d76b 00000000 000049ae 00000000 00000000 00000000 00000000 00000000 00000000 00000000
000000d2 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0000015c 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0000002a 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
IRQ Balance
Прерывания также можно раскидать по ядрам вручную.
#CPU0
echo 1 > /proc/irq/57/smp_affinity
echo 1 > /proc/irq/66/smp_affinity
#CPU1
echo 2 > /proc/irq/58/smp_affinity
echo 2 > /proc/irq/67/smp_affinity
#CPU2
echo 4 > /proc/irq/59/smp_affinity
echo 4 > /proc/irq/68/smp_affinity
#CPU3
echo 8 > /proc/irq/60/smp_affinity
echo 8 > /proc/irq/69/smp_affinity
Для того, чтобы при старте системы прерывания сами настраивались, можно сделать скрипт и настроить его запуск /etc/rc.d/rc.local.
Ethernet flow control
Однако, важно понимать, что этот уровень контроля потока только между коммутатором и адаптером. Если пакеты отброшены, более высокие уровни, такие как TCP или приложение в случае UDP и/или многоадресно переданы, должен инициировать восстановление.
Важно! Фреймы паузы и flow control (управление потоком) должны быть включены и на NIC и на порте коммутатора.
Pause parameters for eth3:
Pause parameters for eth3:
Interrupt Coalescence (отложенные прерывания)
Отложенные прерывания рассказывают нам о количестве трафика, который будет получать сетевой интерфейс, или времи, которое проходит после приема трафика, перед выдачей жесткого прерывания. Слишком ранние прерывания или слишком частые приводят к снижению производительности системы, так как ядро останавливается (или «перебивает») запущенное задание для обработки запроса прерывания от аппаратного обеспечения. Слишком поздее прерывание может привести к тому, что пакеты достаточно долго не будут обработаны ядром с сетевой карты. Большие объемы трафика могут переписать предыдущие пакеты трафика, т.е. потеря пакетов.
Coalesce parameters for eth3:
Adaptive RX: on TX: off
Следующая команда выключает адаптивный IC, и говорит адаптеру о прерывании ядра
сразу после приема любого трафика:
Очередь адаптера (The Adapter Queue)
0073d76b 00000000 000049ae 00000000 00000000 00000000 00000000 00000000 00000000 00000000
000000d2 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0000015c 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0000002a 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
В текущем выводе netdev_max_backlog не нуждается в тюнинге, т.к. очередь не переполняется и нет потерь соответственно. Если же наблюдаются приащения в второй колонке, тогде увеличиваем значение очереди и снова смотрим в этот файл. Если увеличения этого значения мы видим что скорость приращений в втором столбце уменьшается то можно еще увеличить значение backlog. Повторяем этот процесс пока перестанет расти цифры в столбце 2.
Backlog изменить можно такой командой:
Adapter RX and TX Buffer
Буфер адаптера по умолчанию обычно установлен в меньшем размере, чем максимальный. Часто, увеличить размер буфера приема RX вполне достаточно, чтобы предотвратить потери пакетов, так как это может приводит к тому, что у ядра будет немного больше времени, чтобы опустошить буфер. В результате, это может предотвратить возможные потери пакетов.
Буферы можно посмотреть так:
Ring parameters for eth3:
Current hardware settings:
Тут видим что кольцевой буфер RX входящих пакетов равен 1024 дескрипторам в оперативной памяти, и можно увеличить до 8192.
Очередь передачи (Adapter Transmit Queue Length)
Увеличить длину очереди можно так:
# ip link set dev em1 txqueuelen 2000 |
TCP Window Scaling (масштабирование окна TCP)
Размер TCP окна (TCP Window Size) – количество октетов (начиная с номера подтверждения), которое принимающая сторона готова принять в настоящий момент без подтверждения. На стадии установления соединения рабочая станция и сервер обмениваются значениями максимального размера TCP окна (TCP Window Size), которые присутствуют в пакете. Например, если размер окна получателя равен 16384 байта, то отправитель может отправить 16384 байта без остановки. Принимая во внимание, что максимальная длина сегмента (MSS) может быть 1460 байт, то отправитель сможет передать данный объем в 12 фреймах, и затем будет ждать подтверждение доставки от получателя и информации по обновлению размера окна. Если процесс прошел без ошибок, то размер окна может быть увеличен. Таким образом, реализуется размер скользящего окна в стеке протокола TCP. В современных версиях операционных систем можно увеличить размер окна TCP Window Size и включить динамическое изменение окна в зависимости от состояния канала связи. Динамическое увеличение и уменьшение размера окна является непрерывным процессом в TCP и определяет оптимальный размер окна для каждого сеанса. В очень эффективных сетях размеры окна могут стать очень большими, потому что данные не теряются.
Масштабирование Окна TCP включено по умолчанию:
# sysctl net.ipv4.tcp_window_scaling net.ipv4.tcp_window_scaling = 1 |
TCP буфер
После того, как сетевой трафик обрабатывается от сетевого адаптера, предпринимается попытка приема трафика непосредственно в приложение. Если это не представляется возможным, данные ставятся в очередь на буфер сокета приложения. Есть 3 структуры очереди в сокете:
sk_rmem_alloc – очередь получения
sk_wmem_alloc – очередь передачи
Существует также sk_rcvbuf переменная, которая является пределом, измеренный в байтах, что сокет может получить. В этом случае sk_rcvbuf = 125336.
Из приведенного выше вывода можно вычислить, что очередь получения почти полна. Когда sk_rmem_alloc > sk_rcvbuf то буфер начинает рушится, т.е. наблюдаются потери пакетов. Выполните следующую команду, чтобы определить, происодит это или нет:
17671 packets pruned from receive queue because of socket buffer overrun
18671 packets pruned from receive queue because of socket buffer overrun
Если счетчик обрезки пакетов растет, то требуется тюнинг.
tcp_rmem: У настраиваемой памяти сокета есть три значения, описывающих минимальное, значение по умолчанию и максимальное значения в байтах. Чтобы просмотреть эти настройки и увеличить:
4096 87380 4194304
# sysctl net.core.rmem_max 4194304
После изменения максимального размера, требуется перезапуск приложения.
Новости
Сегодня перед специалистами, отвечающими за информационную безопасность корпоративных ресурсов, очень остро стоит проблема атак на сеть путем переполнения буфера. Практически каждую неделю, а иногда и несколько раз в течение одной недели консультанты LiveSecurity (служба сервиса компании WatchGuard) предупреждают о новых уязвимостях, связанных с переполнением буфера.
События, связанные с безопасностью, переполнение буфера, как ни прискорбно встречаются везде, даже в коде, в котором по заверениям разработчиков все потенциальные возможности этой встречи исследованы и устранены. Возможно, вы слышали о таких вариантах переполнения буфера, как формат строки или атаки на хип. В этой статье, используя аналогии из повседневной жизни, я попытаюсь объяснить, как работают эти атаки. Я позаимствую идею, почерпнутую мною из книги Брюса Шнеера Секреты и ложь (Bruce Schneier “Secrets and Lies”), хотя, как типичный хакер, эту идею разовью и обобщу.
Глупый продавец
Шнеер объясняет переполнение буфера, сравнивая компьютерную память с перекидным ежедневником, содержащим инструкции для продавца круглосуточного магазина. На каждой странице написана одна инструкция, например: «Поприветствовать посетителя», «выбить чек», «принять деньги». Предположим, что продавец глуп и может работать, только дослов-но выполняя инструкции.
Все это делает наш магазин уязвимым для простой атаки. Атакующий подходит к стойке и, пока продавец роется в инструкциях, вставляет в них листок, на котором написано: «Взять все деньги из кассы и передать их покупателю». Единственное на что в подобном случае можно надеяться, так это то, что, если продавец точно выполняет все инструкции, то он должен был их запомнить, и, наверное, заметит, что здесь что-то неладно.
По страницам моей памяти…
В отличие от продавцов, компьютеры точно выполняют инструкции и, при этом, вообще лишены чувств. Если атакующий сможет подсунуть компьютеру дополнительные инструкции, он выполнит эти инструкции один в один. Это является основой для нападения, связанного с переполнением буфера.
Существует три разновидности атак, основанных на переполнении буфера: атаки на стек, атаки на формат строки и атаки на хип. Эти разновидности одинаковы по сути, но каждая направлена на разные части памяти компьютера. Для того, чтобы понять различия между этими атаками, я вкратце обрисую как работает компьютерная память.
Когда программа начинает выполняться, операционная система выделяет для нее виртуальную память большого размера. Можно рассмотреть эту память как разграфленную тетрадь, в которой написана программа, начиная со страницы один, где хранятся инструкции и заканчивая данными программы. После того, как программа записана, остается много чистых страниц.
Пустые страницы, находящиеся сразу же за данными программы называются хипом (куча, heap), а те, которые находятся в самом конце тетради, называются стеком. Точно так-же, как если бы вы использовали тетрадь с двух сторон, хип будет расти в сторону конца тетради, а стек – в сторону начала. А тетрадь (то есть виртуальная память) настолько велика, что хип никогда не достигнет стека и наоборот.
Атаки на стек
В стеке хранятся временные данные. Вновь мы можем проиллюстрировать это примером из книги Шнеера. Предположим, что вы пишете заметки по проекту, над которым вы работаете, когда звонит телефон. Звонящий сообщает некую информацию, которую вы у него запрашивали, следовательно, вы берете новый листок бумаги, кладете его поверх первого и записываете эту информацию. Прежде чем вы успеваете завершить разговор, в комнату входит начальник, привлекает ваше внимание и просит вас сделать кое-что по окончании звонка. Вы берете еще один листок бумаги и записываете на него просьбу начальника. Теперь у вас есть небольшая стопка (стек) листков бумаги, с написанными на них инструкциями и данными. Как только вы выполняете очередное задание, вы сминаете листок и бросаете его в мусорную корзину. Вы используете стек таким же образом, как и в случае с атакой, направленной на переполнение буфера.
Если мы будем говорить о компьютерах, то там, конечно, нет листков бумаги, а есть просто память (RAM). Данные действительно добавляются в стек сверху и потом извлекаются. При атаке «переполнение буфера», направленной на стек, нарушитель добавляет в него больше данных, чем предусмотрено, при этом лишняя часть перезаписываются поверх данных, для которых разработчик программы не предусмотрел такой вариант.
Например, давайте пред-положим, что при исполнении программы она дошла то такой стадии, на которой необходимо использовать почтовый индекс из Web формы, заполненной пользователем. Длина даже самого длинного почтового индекса не превышает двенадцати символов. Но в нашем примере Web форму заполняет нарушитель. Вместо того, чтобы ввести почтовый код он 256 раз вводит букву «А», а за ней пишет определенные команды. После того, как программа получает эту сверхдлинную строку, бессмысленные данные переполняют буфер, выделенный для постового индекса (как вы помните, буфер – это область памяти, зарезервированная для ввода данных) и команды атакующего попадают в стек.
В идеале, программисты защищаются от атак, связанных с переполнением буфера путем проверки размерности всех данных, поступающих в программу, и того, что они не превысят тот размер памяти, который для них предусмотрен. (В приведенном выше примере с почтовым индексом, программа должна быть написана так, чтобы не вводить больше двенадцати символов).
На практике же программисты часто забывают о том, что программу могут атаковать или что данные могут поступать из «ненадежных» источников. Чем больше и сложнее становится программа, тем больше вероятность того, что произойдет атака.
Атаки на формат строки
Атаки на формат строки также используют стек, но требуют гораздо меньше изменений, чем переполнение буфера стека, которое мы обсуждали ранее. Форматирование означает подготовку каких-либо данных к отображению или печати. Однако, инструкции форматирования так гибки, что некоторые нарушители нашли способы использовать их для записи в память. Атаки на формат строки обычно добавляют в память адрес, указывающий на другую ссылку, по которой нарушитель добавляет свои исполнимые инструкции.
Используя нашу аналогию с «глупым продавцом», предположим, что его книга с инструкциями содержит 25 страниц. Предположим также, что после страницы с инструкцией, гласящей «возьми у покупателя деньги и открой кассу», вор вставил инструкцию «Перейди на страницу 26». Вор мог подготовить несколько страниц с инструкциями типа «Отдай покупателю все деньги», «Дай ему уйти и не поднимай тревоги» и поместить их в конец книги. Если глупый продавец будет следовать этим указаниям, это будет аналогично программе, которая перешла по указанному адресу в памяти и выполнила все найденные там инструкции.
Кучи проблем
Защита: о жуках и канарейках
Мы уже знаем, что является наилучшей защитой от подобного вида атак – это грамотное программирование. В идеале, каждое поле в каждой программе должно позволять только заданное число символов (концепция, известная как «проверка границ») заданного типа (почему, например, программа должна позволять вводить буквы или метасимволы типа % для телефонного номера). Также мы знаем, что программы несовершенны, они содержат ошибки, а некоторые из этих ошибок позволяют проводить атаки. Поскольку программы несовершенны, программисты придумали схемы защиты от атак, связанных с переполнением буфера.
Простейшая схема основана на том, что в стеке и хипе должны быть только данные, компьютер никогда не должен выполнять найденные там инструкции. Этот подход прекрасно работает во многих UNIX-системах, однако, он не может использоваться в Windows. Более того, эта схема заставляет UNIX-администраторов изменять параметры конфигурации на каждом сервере. Легче всего это сделать на неинтеловских процессорах (например Sun Microsystem\’s Sparc).
«Канарейка» в стеке защищает его будучи помещенной в критические места памяти (около адресов возврата, которые являются критическими местами в стеке, указывая компьютеру какие команды выполнять после завершения текущей функции). Перед использованием адресов возврата программа проверяет в порядке ли «канарейка». Если «канарейка» уничтожена, программа завершает работу, сообщая об ошибке.
Идея использования «канареек» принадлежит группе разработчиков Linux, создавших версию Linux (Immunix.com), использующую Stackguard для встраивания «канареек» в операционную систему и прилагающиеся программы. Новый компилятор Microsoft для среды Visual C тоже имеет возможность добавлять «канареек» в стек.
«Канарейки», конечно, помогают, но не могут полностью защитить от атак на хип. Атаки на хип совершенно не затрагивают стек и обходят «канареек». Таким образом, программисты должны создавать такой код, который позволяет копировать в буфер только то количество данных, на которое он был рассчитан (или, другими словами, писать программы правильно). Этот способ является наиболее эффективной защитой.
Что вы можете сделать с переполнением буфера
Проблему переполнения буфера сегодня можно попытаться решить, используя специализированные аппаратные или программные решения. Довольно таки хорошо с подобными проблемами можно справиться используя межсетевые экраны, в том числе и включенные в UTM-устройства WatchGuard Firebox. Пользователи этих устройств имеют дополнительный рубеж обороны, который заключается в следующем.
Когда Вы настраиваете свой межсетевой экран на использование служб прокси, это ПО отслеживает использование чрезвычайно длинных входных данных для защищаемых сервисов: электронной почты, HTTP, FTP и DNS. Не являясь идеальной защитой, прокси, тем не менее, могут остановить многие атаки, на-правленные на переполнение буфера. Если вы используете пакетные фильтры, даже с динамическим анализом, вы лишаетесь этого преимущества.
Службы прокси WatchGuard функционируют следующим образом: они аккуратно исследуют протоколы, которые призваны наблюдать. Если пакеты или команды, отличаются от обычных, правомерных, используемых наблюдаемым протоколом, то служба прокси разорвет соединение с источником несоответсвия. При включенной службе обнаружения аномалии протокола, служба прокси сделает больше, чем в обычном случае – она не только разорвет соединение, но и добавит адрес клиента в список блокированных источников. Попытки соединения этого клиента с системой будут игнорироваться, пока не истечёт время автоматического блокирования.
Во время FTP-сеанса клиент и сервер общаются при помощи коротких сообщений. Клиент обращается к серверу, выясняя, готов ли тот обмениваться бинарными файлами, после чего, в случае положительного ответа, клиент аутентифицируется и может использовать другие команды для взаимодействия с файлами. Служба FTP прокси следит за тем, чтобы от клиента исходили только правомерные команды. Она также устанавливает ограничения на длину командных аргументов с целью защиты от возможного переполнения буфера, если со стороны клиента исходят слишком длинные команды.
При взаимодействии с DNS сервером, клиент посылает запрос, сервер его выполняет, тем самым отвечая клиенту. Служба DNS прокси следит за тем, чтобы форма запроса была заполнена корректно, проверяя длину запроса. Слишком короткие или чересчур длинные запросы вызывают ошибки переполнения буфера в DNS серверах. Кроме того, DNS прокси удостоверяется в корректности заполнения остальных частей формы.
Служба SMTP прокси проверяет, что бы все строки, полученные при использовании этого протокола, являлись его частью. Служба также следит за тем, чтобы ни одна строка не была длиннее, чем заранее задано. Количество символов можно изменить при помощи WatchGuard Policy Manager, по умолчанию оно равно 1000. По длине адреса документом RFC 2822 рекомендовано ограничение в 256 символов. Чем больше это ограничение, т.е. чем короче адрес, тем сложнее произвести атаку.
Также служба прокси проверяет и содержимое электронного письма на наличие запрещённого содержимого и определенных расширений файлов.
Хочется надеяться на то, что эта маленькая статья помогла вам понять, что такое атаки направленные на переполнение буфера, каковы разновидности этих атак, каковы применяемые контрмеры и почему даже эти контрмеры не всегда работают. Но помните, что вы не беззащитны. Если ваш межсетевой экран поддерживает шлюзы приложений или прокси, используйте их. Когда служба информирования LiveSecurity предупреждает вас о критичных уязвимостях, связанных с переполнением буфера, используйте заплатки для приложений. Используйте эти меры, Ваши новые знания о переполнениях буфера и все будет в порядке.
Материал подготовлен специалистами компании Rainbow Technologies и WatchGuard Technologies на основании публикаций автора Rik Farrow, специалиста по компьютерной безопасности.