DDoS защита пользователей на хостинге: почему это важно для сайта

DDoS и хостинг

Хостинг представляет из себя комплекс, состоящий из внутренней сети (автономной системы), пограничных маршрутизаторов и распределенных каналов связи с различными операторами связи. 

Если упрощенно показать это на схеме, то получится следующее:

  1. Операторы связи, обеспечивающие связь сети хостинга с внешним миром
  2. Каналы связи с операторами
  3. Пограничные маршрутизаторы
  4. Каналы связи внутренней сети
  5. Серверы хостинга (например, виртуального)

Целью DDoS-атаки является прекращение доступности какого-либо сервиса, будь то один сайт, сервер или даже целый хостинг. Что такое доступность сервиса? В контексте нашей темы это возможность конечного сервера хостинга получать весь легитимный трафик от пользователей, обрабатывать его за адекватное время и отдавать пользователям ответы. Поэтому для упрощения можно сказать, что мы должны обеспечивать хождение легитимного трафика в направлении 1-5-1. 

PS: На самом деле, де-факто наша ответственность перед пользователями не заканчивается на том, что мы отдаем трафик операторам связи, т.к. бывают случаи, что даже при этом ответ до пользователя не доходит, но мы пока оставим эти кейсы за рамками нашей статьи.

Почему хостинг не может взять и полностью передать защиту от DDoS специализированным компаниям?

Передача данных в современной сети Internet построена на многоуровневой архитектуре, где каждый уровень несет свое определенное предназначение. Для передачи данных, используется стек протоколов TCP/IP, который построен по принципу эталонной модели OSI. Концепция этой модели заключается в разбиении процесса передачи данных на уровни, где каждый уровень отвечает за свой функционал.

В случае с DDoS атаками, их принято делить по уровням модели OSI, несмотря на то что стек протоколов TCP/IP состоит всего из 4х уровней.

Сами DDOS атаки происходят только на уровнях L3,L4,L7 по модели OSI.

Для защиты на уровне L3-L4 мы 24/7 работаем через специализированный сервис защиты, который постоянно отбивает сотни атак в день, в последнее время достаточно больших. По объему трафика они приближаются к терабиту. Весь наш трафик поступает к магистральным провайдерам через него.

А что с 7-м уровнем? В случае с хостингом - на 7-м уровне предполагается использование протоколов TLS и HTTPS. Они нужны для защиты передаваемых данных с повышенными требованиями к безопасности. 

Соответственно, учитывая все вышенаписанное и отвечая на изначальный вопрос — при атаках на уровне L7, нам было бы необходимо постоянно передавать подрядчику сертификаты пользователей (сотни тысяч сертификатов ежемесячно, десятки тысяч каждый день). Скажем прямо — это не очень удобно и потенциально является дополнительной точкой отказа.

Второй причиной является то, что мы как хостинг-провайдер работаем с очень разнообразными сайтами: на разных фреймворках, с разными правилами маршрутизации, разными куками и т.п.. У кого-то на сайте много видео, у кого-то одни картинки, кто-то публикует новости. У кого-то частота запросов большая, у кого-то — маленькая. И так далее. Именно поэтому без понимания нашей специфики неизбежно возникает множество ложно-положительных срабатываний защиты: настроить ее универсально просто невозможно. А объяснять пользователям “Ну вы поймите: мы вас защищали, хотели как лучше, но вот система посчитала ваш трафик невалидным. Простите”, — это не наш метод (хотя и такие кейсы бывают, чего уж там). 

Ну и третьей причиной является то, что какая бы хорошая защита не была — она не бывает идеальна. А по-настоящему эффективные средства защиты являются многоуровневыми, работающими в несколько “эшелонов”, каждый из которых работает на своем уровне: от каналов связи, до конечного веб-сервера.

Именно поэтому передать полностью защиту специализированным компаниям будет недостаточно. Не получится “просто заплатить и расслабиться” 🙂 

Как отбиваются атаки

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

UDP/TCP Flood

Это один из наиболее частых видов атак, которые мы отбиваем. Он представляет из себя большой объем трафика, который летит в нашу сторону. Смысл атаки — создать такой объем трафика на входе сети, который, по задумке атакующего, нельзя обработать без отбрасывания валидных пакетов.

Таким образом, на схеме мы можем заметить несколько уязвимых мест:

  • Каналы связи с операторами (2).
  • Пограничный маршрутизатор (3)
  • Операторы связи (1) (сюрприз!)

На графиках с трафиком на границе сети такая атака как правило имеет характерный вид:

В зависимости от силы атаки у нас есть несколько вариантов действий:

А. Забить и ничего не делать

Самый простой вариант. Подходит, когда атака слабая и у нас есть большой запас по каналам связи как снаружи сети, так и внутри сети. В этом случае просто смотрим на самый “узкий” канал связи (как правило, это канал до конечного сервера хостинга(5)) и, если укладываемся в него с кратным запасом, то просто следим и ничего не делаем.

Б. Порезать трафик на пограничном маршрутизаторе

Главный критерий для применения такого способа защиты — остался запас емкости в каналах до операторов связи (2). В противном случае сразу переходим к пункту “В”. Данный вариант чуть посложнее, т.к. тут уже требуется анализ поступающего трафика. Обычно есть смысл обращать внимание на следующие параметры:

  • src/dst IP
  • dst порт
  • протокол
  • длина пакета
  • тело пакета

Для анализа трафика просто отливаем информацию о нем с маршрутизатора при помощи netflow/ipfix или настраиваем port mirroring на сервер с толстым каналом и анализируем трафик вместе с телом пакета на нем.

Чем более “однородный” вредоносный трафик, тем проще его заблокировать без последствий. Часто прилетают атаки на заранее закрытые порты или с 5-10 IP-адресов, или с очень большим размером пакета. Поэтому увидеть закономерность и настроить фильтрацию достаточно просто.

Само-собой, делать это вручную не очень удобно. Поэтому тут подойдут различные системы анализа и визуализации трафика, чтобы было проще и быстрее выявить закономерности. В самом простом случае это связка Prometheus + Grafana с парой дашбордов. Для лучшей аналитики можно использовать что-то вроде Fastnetmon или самописные решения. В идеале нужно добиться того, чтобы правила для блокировки трафика на маршрутизаторе по ряду критериев добавлялись автоматически.

Также не забывайте, что на пограничном маршрутизаторе по умолчанию должны быть закрыты все протоколы и порты, которые не используются для легитимного трафика. Это автоматически отобьет 90% мелких атак =) Например, на виртуальном хостинге у нас практически не используется UDP. Это очень помогает: для всех сетей хостинга можно поставить очень жесткий лимит на объем такого трафика.

В. Бороться с атакой за пределами нашей сети

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

FlowSpec имеет свои ограничения:

  • Не все операторы связи поддерживают эту технологию. А те, кто поддерживает, как правило берут за неё дополнительную плату.
  • Набор правил, которые можно передать, обычно ограничен, и в случае очень сложной распределенной атаки, в которой нельзя выделить явные паттерны, заблокировать весь вредоносный трафик не получится.

В любом случае всегда полезно иметь несколько аплинков с FullView (то есть полной связностью со всеми сетями в интернете), и FlowSpec, которые покрывают весь объем легитимного трафика. В этом случае можно просто отключиться от остальных и передать правила для блокировки нежелательного трафика через них.

Интересный случай: пару раз у нас были атаки, от которых в принципе падали сами операторы связи. Например, в марте, когда после падения (или может быть нас просто отключили?) одного из магистральных операторов в результате DDoS’а на наши сети, мы потеряли связность с Европой. Пользователям это не понравилось, хотя формально мы ничего сами не отключали =)

Г. Blackhole

Наверное, это самый печальный вариант отбития атаки, потому что, по сути, мы просто жертвуем атакуемым ресурсом ради того, чтобы остальные ресурсы продолжили работу. Метод равносилен признанию победы атакующего и единственная его цель — минимизация ущерба для остальных клиентов. Осуществляется через специальное BGP Community у операторов связи. Метод не подходит в случае атаки на множество адресов (например, когда пытаются положить сразу весь хостинг).

К счастью, прибегать к этому методу приходится очень редко.

Атаки на уровне приложения (L7)

Атаки на уровне приложения (в случае с виртуальным хостингом это как правило HTTP(S)-флуд) с одной стороны редко когда приносят глобальные проблемы, т.к. целью атаки почти всегда является конкретный сайт пользователя, конечный сервер хостинга (5), и редко когда мы упираемся в каналы связи. С другой стороны, они происходят, буквально, постоянно и непрерывно, поэтому и средства борьбы с ними должны быть максимально экологичными и универсальными.

Суть атаки заключается в флуде HTTP(S)-запросами к сайту/на ip-адрес пользователя с целью:

  • Превысить лимиты хостинга на количество одновременных запросов/процессорное время с целью спровоцировать отключение сайта. По факту мы видим либо большой объем запросов к сайту, либо запросы к “тяжелым страницам” сайта, генерация которых требует много процессорного времени. 
  • Использовать уязвимости в CMS/фреймворках, чтобы выполнить какой-либо произвольный код. Чаще всего так запускают различные майнеры или флудеры (тут у нас появляется интересная тема про исходящие ddos-атаки, о которой мы можем рассказать отдельно). 

Методы борьбы с такими атаками достаточно разнообразные:

А. Блокировка подозрительных запросов по-умолчанию

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

Так, например, мы по умолчанию блокируем запросы от уникальных User-Agent, которые были замечены в массовом флуде, блокируем ряд ботов и сканеров, которые ведут себя неадекватно: не считают нужным смотреть robots.txt, ходят по сайтам в несколько потоков и прочими способами увеличивают нагрузку на сервер, не принося никакой пользы. Таких ботов в интернете довольно много и список постоянно расширяется.

Также иногда на длительное время блокируются целые подсети, с которых практически нет легитимного трафика, но зато есть массовые автоматические запросы: привет друзьям из поднебесной и сопредельных стран!

Как ни странно, без этих мер, количество паразитных запросов к серверам было бы просто огромным. Зачастую различные сканеры работают по принципу: если сервер что-то вменяемое ответил, то начинаем активно его исследовать; иначе - просто забиваем на него на некоторое время и прекращаем запросы. Поэтому, по нашей практике, если вы начали отвечать на мусорные запросы - дальнейший их поток будет только возрастать.

Б. Слежение за процессами пользователей (MCPU)

Зачастую проблемы на сервере может создать не миллион http-запросов к одному сайту, а всего пару десятков, но очень “точных”. К таким запросам относятся различные уязвимые страницы на сайте, скрипты (как правило, в админках/плагинах), которых при определенных входных данных начинают “творить дичь”: уходить в бесконечные циклы с запросами к БД, генерацию превьюшек из полноразмерных картинок товаров, сбросу кеша. В конце концов, есть множество уязвимостей, результатом эксплуатации которых будет майнер крипты, работающий от вашего имени на хостинге (и, к сожалению, майнить он будет не в ваш кошелек).

В итоге сервер загибается под бесполезной нагрузкой.

Бороться с этим достаточно сложно, если мы не хотим вводить драконовские ограничения на время выполнения скриптов пользователей или потребляемое CPU. 

Мы пошли по пути активного мониторинга процессов на сервере. У нас есть свой демон на Rust, который постоянно следит за всеми процессами пользователей и имеет постоянно пополняющийся набор правил для выставления ограничений (вплоть до убийства), для тех процессов, которые мы считаем неуместными. Он умеет смотреть на:

  • Различные атрибуты процесса (uid, gid, cmdline, cgroup и т.п.).
  • Объем потребляемой памяти.
  • Затраченное процессорное время.
  • Содержимое исполняемого файла.

В случае совпадения, в зависимости от конкретной задачи, он может выполнять различные действия:

  • Логирует событие (для дальнейшего анализа).
  • Убивает процесс.
  • Помещает в cgroup с заданными параметрами.
  • Настраивает OOM Killer для этого процесса.
  • … любое другое действие, которое нам потребуется.

Вот кусочек такого конфига:

# kill all binaries with miner cmdline patterns
- match:
	- proc.group: newcustomers
	- proc.exe: ^/home/\w/\w+/
	- proc.cmdline: zcash\.flypool\.org
  action:
	- log
	- kill
	- last

Иногда пользователи добровольно хотят запускать валидный процесс convert для того же самого ресайза картинок в своих интернет-магазинах. Как правило, он хочет потреблять довольно много ресурсов и надо, с одной стороны, дать ему выполниться, с другой стороны, — не мешать другим пользователям:

- match:  
	- proc.group: newcustomers
	- proc.command: convert
  action:
	- log
	- adjust_oom: 1000
	- cgroup:
    	    name: convert
    	    memory:
      	    memory.limit_in_bytes: 40543505612 # лимит памяти по умолчанию для других процессов меньше
      	    memory.move_charge_at_immigrate: 0
     	    blkio:
      	    blkio.weight: 100
	- last

Помимо прочего этот демон выставляет нужные нам cgroup для ряда служебных процессов в случае их появления.

В. Анализ и слежение за запросами к сайтам в реальном времени

Безусловно, выявить зловредные запросы только по атрибутам вроде User-Agent или характерного URL невозможно: часто флудят вполне валидными на вид запросами к разным страницам с разными адресами.

Чтобы работать с такими атаками можно использовать несколько уровней защиты:

На сервере (5)

Полезно будет анализировать лог входящих запросов, искать подозрительные паттерны, характерные тайминги и автоматически выставлять ограничения/rate-limit для тех src ip, user-agent, которые кажутся нам подозрительными. Подойдет против простых атак, которые может переварить сервер без ущерба для остальных. Но на самом деле простых атак —большинство и именно на этом уровне выполняется большая часть блокировок.

Внутри сети (4)

Если сервер не справляется, то уместно будет проксировать трафик к сайту/серверу через специальные серверы, которые могут переварить множество tls-хендшейков и отделить невалидные запросы от валидных, и выполнить еще какую-либо дополнительную фильтрацию. На сервер при этом прилетает уже только валидный HTTP-трафик. Подойдет, если флуд состоит из множества невалидных https-запросов и атака нацелена на перегрузку CPU.

В качестве заключения

Увы, нет какого-то единственно верного способа защитить всех, навсегда и от всего. 

Нельзя ни делегировать защиту на подрядчика (по крайней мере полностью), ни настроить 1 раз правила фильтрации.

Более того, под DDoS порой попадают даже самые безобидные сайты, а общий объём атак поистине огромен и в последние месяцы их интенсивность только возрастает. 

По сути, ключевой способ защиты для любого хостинга — это накопленная экспертиза админов, которые систематизируют и внедряют защиту: где-то с помощью внешних решений, где-то с помощью “креатива и творчества” — например, иногда полезно вместо закрытия соединения отправить в ответ пару килобайт мусора, чтобы атакующая вас взломанная веб-камера надолго уходила в раздумья перед тем, как отправить следующий запрос =) 

Благодаря всему этому пользователи хостинга чувствуют последствия атак лишь изредка.

Да пребудет с нами аптайм!

Опубликовано: 19.09.2022
4
5327