XDP и eBPF: фильтрация пакетов нового поколения для игровых серверов

XDP и eBPF: фильтрация пакетов нового поколения для игровых серверов

Когда на ваш Minecraft сервер прилетает DDoS в 50 миллионов пакетов в секунду, iptables не поможет. Не потому что он плохой. А потому что он работает слишком высоко в сетевом стеке Linux, чтобы справиться с таким потоком. Каждый пакет проходит через десятки слоёв ядра, прежде чем iptables вообще его увидит. К этому моменту ресурсы CPU уже потрачены.

Есть другой подход. XDP (eXpress Data Path) позволяет перехватить пакет на уровне драйвера сетевой карты, до того как ядро Linux начнёт его обрабатывать. А eBPF (extended Berkeley Packet Filter) позволяет написать программу, которая решит судьбу этого пакета за наносекунды. Пропустить, дропнуть, перенаправить.

Эта технология уже используется в продакшене у Cloudflare, Meta, Netflix для защиты от DDoS. И именно её мы используем в MineGuard для фильтрации трафика к игровым серверам.

Что такое eBPF

eBPF - это технология, позволяющая запускать пользовательские программы прямо внутри ядра Linux. Не модули ядра (которые могут уронить систему при ошибке), а программы в специальной песочнице. Ядро верифицирует каждую eBPF-программу перед загрузкой: проверяет, что нет бесконечных циклов, выходов за границы памяти, деления на ноль.

Если программа не прошла верификацию - она не загрузится. Если прошла - работает со скоростью нативного кода ядра, потому что JIT-компилятор (Just-In-Time) переводит её в машинные инструкции конкретного процессора.

По сути, eBPF превратил ядро Linux в программируемую платформу. Раньше, чтобы добавить логику обработки пакетов в ядро, нужно было писать kernel module на C, компилировать его под конкретную версию ядра и рисковать kernel panic при каждой ошибке. С eBPF вы пишете маленькую программу, ядро гарантирует её безопасность, и она выполняется с минимальными накладными расходами.

Ключевые свойства eBPF:

  • Безопасность. Верификатор ядра проверяет каждую инструкцию перед загрузкой
  • Скорость. JIT-компиляция в нативный машинный код
  • Гибкость. Программу можно обновить без перезагрузки системы
  • Изоляция. Крах eBPF-программы не роняет ядро

Что такое XDP

XDP (eXpress Data Path) - это хук (точка перехвата) в Linux, расположенный на самом нижнем уровне сетевого стека, в драйвере сетевой карты. Когда сетевая карта получает пакет, XDP позволяет обработать его ДО того, как ядро создаст структуру sk_buff, ДО netfilter, ДО conntrack, ДО iptables.

Почему это принципиально? Потому что большая часть CPU-затрат при обработке пакетов приходится именно на верхние уровни стека. Создание sk_buff, прохождение через цепочки netfilter, обновление таблиц conntrack - всё это занимает сотни наносекунд на каждый пакет. При DDoS-атаке в миллионы пакетов в секунду эти "сотни наносекунд" превращаются в 100% загрузку CPU.

XDP работает там, где пакет - это ещё просто набор байтов в буфере DMA. Никаких аллокаций памяти, никакого conntrack. Программа XDP получает указатель на сырые данные пакета и принимает одно из четырёх решений:

  • XDP_DROP - отбросить пакет. Самое быстрое действие, пакет никогда не попадёт в ядро
  • XDP_PASS - передать пакет дальше в стек ядра для обычной обработки
  • XDP_TX - отправить пакет обратно через тот же интерфейс (полезно для SYN cookies)
  • XDP_REDIRECT - перенаправить пакет на другой интерфейс или в другую программу

Вот упрощённый пример XDP-программы на C:

SEC("xdp")
int xdp_filter(struct xdp_md *ctx) {
    void *data = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;

    struct ethhdr *eth = data;
    if ((void *)(eth + 1) > data_end)
        return XDP_DROP;

    if (eth->h_proto != htons(ETH_P_IP))
        return XDP_PASS;

    struct iphdr *ip = (void *)(eth + 1);
    if ((void *)(ip + 1) > data_end)
        return XDP_DROP;

    // Проверяем блоклист
    __u32 src_ip = ip->saddr;
    if (bpf_map_lookup_elem(&blocklist, &src_ip))
        return XDP_DROP;

    // Проверяем rate limit
    struct rate_info *rate = bpf_map_lookup_elem(&rate_counters, &src_ip);
    if (rate && rate->pps > MAX_PPS_PER_IP)
        return XDP_DROP;

    return XDP_PASS;
}

Этот код выполнится за 50-100 наносекунд. Для сравнения: прохождение пакета через полный стек iptables занимает 2000-5000 наносекунд.

Почему iptables слишком медленный

Чтобы понять преимущество XDP, нужно посмотреть на путь пакета при использовании iptables.

Когда пакет приходит на сетевую карту, происходит следующее:

  1. NIC кладёт пакет в ring buffer через DMA
  2. Ядро получает прерывание, запускает NAPI polling
  3. Создаётся структура sk_buff (аллокация памяти)
  4. Пакет проходит через ingress qdisc (traffic control)
  5. netfilter: таблица raw, цепочка PREROUTING
  6. conntrack: поиск в хеш-таблице соединений, создание новой записи
  7. netfilter: таблица mangle, цепочка PREROUTING
  8. Routing decision (определение маршрута)
  9. netfilter: таблица filter, цепочка INPUT
  10. iptables: проверка КАЖДОГО правила по порядку

Только на шаге 10 iptables решает: DROP или ACCEPT. Но к этому моменту ядро уже потратило CPU на шаги 1-9. При DDoS-атаке 90% пакетов - мусор, и тратить на каждый из них полный путь через стек бессмысленно.

XDP работает между шагами 1 и 2. Пакет перехватывается до создания sk_buff, до conntrack, до netfilter. Если его нужно дропнуть - он дропается мгновенно, без единой аллокации памяти.

Числа

Реальные тесты показывают разницу в порядках:

МетодПакетов/сек (1 ядро)Задержка
iptables~1 млн2-5 мкс
nftables~2 млн1-3 мкс
XDP (generic)~5 млн0.5-1 мкс
XDP (native)~14 млн0.05-0.1 мкс

XDP в native-режиме (поддерживается драйвером NIC) обрабатывает в 14 раз больше пакетов, чем iptables. На сервере с 8 ядрами это теоретически 100+ миллионов пакетов в секунду. Для сравнения: большинство DDoS-атак на Minecraft серверы генерируют от 5 до 50 миллионов pps.

BPF maps: состояние для фильтрации

Одного дропа по IP недостаточно. Реальная защита требует состояния: счётчики пакетов, блоклисты, информация о сессиях. В eBPF для этого есть BPF maps - структуры данных, разделяемые между eBPF-программой в ядре и user-space приложением.

Основные типы map:

Hash map - классическая хеш-таблица. Идеально для блоклистов IP:

struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 100000);
    __type(key, __u32);         // IP address
    __type(value, __u64);       // timestamp
} blocklist SEC(".maps");

LRU hash - хеш-таблица с автоматическим вытеснением старых записей. Хорошо подходит для rate limiting:

struct {
    __uint(type, BPF_MAP_TYPE_LRU_HASH);
    __uint(max_entries, 1000000);
    __type(key, __u32);            // IP address
    __type(value, struct rate_info); // packets count, timestamp
} rate_counters SEC(".maps");

Per-CPU array - массив с отдельной копией для каждого ядра CPU. Нет блокировок, максимальная скорость:

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __uint(max_entries, 1);
    __type(key, __u32);
    __type(value, struct stats);
} packet_stats SEC(".maps");

User-space приложение может в реальном времени обновлять блоклист, читать статистику, менять пороги rate limiting. eBPF-программа в ядре подхватывает изменения без перезагрузки. Это ключевое отличие от iptables, где добавление 10 000 правил занимает секунды и блокирует обработку пакетов.

Режимы работы XDP

XDP может работать в трёх режимах, и разница между ними значительна.

Native XDP (XDP_FLAGS_DRV_MODE). eBPF-программа выполняется внутри драйвера сетевой карты, до создания sk_buff. Это самый быстрый режим, дающий те самые 14M+ pps на ядро. Но требует поддержки в драйвере NIC. Поддерживают: Intel i40e/ice, Mellanox mlx4/mlx5, Broadcom bnxt, Amazon ENA, virtio-net. Если ваш сервер использует один из этих драйверов, вы получите максимальную производительность.

Generic XDP (XDP_FLAGS_SKB_MODE). eBPF-программа выполняется после создания sk_buff, но до netfilter. Работает на любом сетевом интерфейсе без специальной поддержки драйвера. Производительность ниже native (около 5M pps), но всё равно в 5 раз выше iptables. Это fallback-режим для NIC без нативной поддержки.

Offloaded XDP (XDP_FLAGS_HW_MODE). eBPF-программа загружается прямо на SmartNIC и выполняется аппаратно, без участия CPU сервера вообще. Поддерживается Netronome NFP и некоторыми Mellanox ConnectX-6. Скорость фильтрации ограничена только пропускной способностью сетевого порта, а CPU полностью свободен для обработки легитимного трафика.

Проверить, поддерживает ли ваш NIC native XDP, можно так:

ethtool -i eth0 | grep driver
# Если driver: i40e, mlx5_core, bnxt_en - native XDP доступен

Как работает традиционная DDoS-защита

Большинство сервисов защиты от DDoS для Minecraft до сих пор используют iptables или nftables в качестве основного инструмента фильтрации. Схема простая: трафик проходит через прокси-сервер, на котором набор правил iptables фильтрует "плохие" пакеты.

Проблемы этого подхода:

Линейная проверка правил. iptables проверяет правила по порядку. 1000 правил в блоклисте = 1000 проверок на каждый пакет. С ipset лучше (O(1) поиск), но всё равно через conntrack и netfilter. А при DDoS-атаке каждый лишний цикл проверки - это потерянные микросекунды, которые складываются в миллисекунды, а затем в пропущенные пакеты легитимных игроков.

Conntrack overhead. Каждое новое соединение создаёт запись в conntrack. Стандартная таблица conntrack вмещает 65536 записей (можно увеличить через nf_conntrack_max), но при SYN-флуде она заполняется за секунды и начинает дропать легитимные соединения. Ядро пишет в dmesg: "nf_conntrack: table full, dropping packet". Мы подробно разбирали эту механику в статье про SYN-флуд атаки на Minecraft.

Context switches. iptables работает в контексте softirq, но каждое действие с правилами (добавление, удаление) требует блокировок xtables lock. При высокой нагрузке, когда user-space приложение пытается обновить правила, а ядро одновременно обрабатывает миллионы пакетов, возникает contention. Обновление блоклиста из 10 000 IP через iptables может занять несколько секунд, в течение которых фильтрация работает непредсказуемо.

Ограниченная логика. Сложная фильтрация (анализ payload Minecraft-пакетов, stateful rate limiting, адаптивные пороги) в iptables либо невозможна, либо требует костылей с модулями u32/string match. Попробуйте написать правило iptables, которое проверяет, что incoming TCP-пакет содержит валидный Minecraft handshake с корректным protocol version. Это невозможно без дополнительных модулей ядра.

XDP/eBPF решает все эти проблемы. Блоклист в BPF hash map - O(1) поиск без conntrack, даже для миллиона IP. Rate limiting на per-CPU counters - без блокировок, каждое ядро CPU работает со своей копией счётчиков. Анализ Minecraft protocol в eBPF - полный доступ к данным пакета на уровне байтов. Обновление правил через BPF map - атомарное, без перезагрузки и без блокировки обработки.

Почему игровым серверам нужен XDP

Игровые серверы, особенно Minecraft, имеют специфические требования к DDoS-защите.

Низкая задержка. Каждая миллисекунда задержки ощущается игроком. Если фильтр добавляет 5 мс на обработку пакета, игроки заметят лаги. XDP добавляет менее 0.1 мс, что незаметно даже при 100+ онлайне.

Высокий pps при атаках. Современные DDoS-атаки на Minecraft генерируют десятки миллионов пакетов в секунду. Это не объёмный флуд (Gbps), а packet rate flood, рассчитанный на перегрузку CPU сервера. iptables при таком потоке физически не справляется. Про разницу между volumetric и packet rate атаками мы писали в статье про TCP и UDP атаки на Minecraft.

Бот-атаки на протокол. Атакующие имитируют Minecraft handshake, отправляя валидные SYN, затем login-пакеты. iptables не умеет анализировать содержимое Minecraft-пакетов. eBPF-программа может разобрать payload на уровне ядра и дропнуть фейковый handshake до того, как он дойдёт до userspace.

Быстрое переключение правил. Во время атаки профиль трафика меняется каждые секунды. Новые IP, новые паттерны, адаптивные ботнеты. BPF maps позволяют обновлять блоклисты и счётчики мгновенно, без перезагрузки фильтра.

В MineGuard мы используем XDP/eBPF как первый уровень фильтрации. Пакеты, не прошедшие проверку на уровне XDP, дропаются ещё до создания sk_buff. Только легитимный трафик передаётся выше по стеку, где проходит дополнительную валидацию протокола Minecraft.

Конкретный пример: при атаке в 30M pps на один из защищённых серверов, XDP-фильтр дропает 99.7% пакетов на уровне драйвера. На верхние уровни стека проходит менее 100 000 пакетов в секунду - обычный легитимный трафик от реальных игроков. CPU сервера при этом загружен на 15-20%, игроки не замечают атаку вообще. При использовании iptables такая же атака вызвала бы 100% загрузку CPU и полную недоступность сервера.

Реальное применение: кто использует eBPF

XDP/eBPF - не экспериментальная технология. Крупнейшие компании используют её в продакшене.

Cloudflare обрабатывает eBPF-программами весь входящий трафик на своих edge-серверах. Их Magic Firewall полностью построен на XDP, обрабатывая десятки терабит в секунду DDoS-атак.

Meta (Facebook) использует XDP для балансировки нагрузки (Katran) и DDoS-защиты. Их решение обрабатывает миллиарды пакетов в секунду на продакшен-серверах.

Netflix применяет eBPF для сетевой аналитики и защиты своей CDN-инфраструктуры.

Cilium - сетевой плагин для Kubernetes, полностью построенный на eBPF. Заменяет iptables для маршрутизации и фильтрации в контейнерных средах.

Тренд очевиден: eBPF заменяет iptables везде, где нужна высокая производительность. Игровая индустрия - не исключение. Актуальные данные по DDoS-атакам на Minecraft и используемым методам защиты мы собрали в обзоре трендов DDoS-атак на Minecraft в 2026 году.

Ограничения XDP/eBPF

Было бы нечестно говорить только о плюсах. У технологии есть реальные ограничения.

Версия ядра. XDP требует Linux 4.8+, а многие полезные функции (BPF_MAP_TYPE_LRU_HASH, bpf_fib_lookup) появились только в 5.x. Большинство VPS хостеров для Minecraft до сих пор используют ядра 4.x или даже 3.x. На таких ядрах XDP либо не работает, либо работает в ограниченном generic-режиме.

Поддержка драйвера. Для полной скорости XDP нужна поддержка в драйвере NIC (native XDP). Не все драйверы это поддерживают. Без native-режима XDP работает в generic mode, который быстрее iptables, но не даёт максимальных 14M+ pps.

Сложность разработки. Написать eBPF-программу для фильтрации пакетов - нетривиальная задача. Нужно знать:

  • C (eBPF программы пишутся на подмножестве C)
  • Сетевой стек Linux на уровне ядра
  • Структуры пакетов (Ethernet, IP, TCP/UDP)
  • Ограничения верификатора eBPF (нет циклов произвольной длины, ограниченный размер стека)
  • Специфику BPF maps и their concurrency model
  • Протоколы игровых серверов (Minecraft protocol для анализа payload)

Ограничения верификатора. Верификатор eBPF строг. Нет бесконечных циклов, ограниченный размер стека (512 байт), каждый доступ к памяти должен быть проверен на границы. Это хорошо для безопасности, но усложняет написание сложной логики.

Дебаг. Отладка eBPF-программ значительно сложнее обычного кода. printk в eBPF ограничен, а ошибки часто проявляются как "verifier rejected program" с криптичным сообщением длиной в 200 строк. Инструменты вроде bpftool и libbpf помогают, но кривая обучения крутая.

Размер программы. Верификатор ограничивает размер eBPF-программы (до 1 миллиона инструкций в ядрах 5.2+, 4096 в более старых). Для сложной логики фильтрации приходится разбивать программу на несколько частей, связанных через tail calls.

Почему нельзя просто установить XDP самому

Теоретически XDP - открытая технология, и любой может написать eBPF-программу для фильтрации. На практике это требует:

  1. Подходящего ядра (5.10+ для комфортной работы)
  2. NIC с поддержкой native XDP (Intel i40e, Mellanox mlx5, virtio в некоторых конфигурациях)
  3. Глубокого знания сетевого стека Linux
  4. Понимания протокола Minecraft (для application-level фильтрации)
  5. Мониторинга и аналитики (чтобы понимать, что фильтр делает)
  6. Постоянного обновления (атаки эволюционируют, фильтры должны адаптироваться)

Написать базовый XDP rate limiter - полдня работы. Написать production-ready DDoS фильтр с анализом Minecraft протокола, адаптивными порогами, BPF map rotation, graceful reload и мониторингом - месяцы разработки.

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

Гораздо эффективнее использовать защиту от DDoS, в которой XDP/eBPF уже настроен и оптимизирован. Базовая настройка iptables по-прежнему нужна как последняя линия обороны на вашем сервере, но первичную фильтрацию трафика стоит доверить специализированным решениям.

Будущее: программируемые сети

XDP и eBPF - это не просто замена iptables. Это фундаментальный сдвиг в подходе к сетевой безопасности. Вместо статических правил ("блокируй этот IP", "ограничь rate до N/s") появляется возможность запускать произвольную логику прямо в ядре на скорости передачи данных.

Что это означает для DDoS-защиты:

Адаптивная фильтрация. eBPF-программа может в реальном времени анализировать паттерны трафика и менять стратегию фильтрации без участия userspace. Обнаружила рост SYN-пакетов с определённой подсети? Автоматически включила stricter rate limit для неё.

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

Hardware offload. Некоторые NIC (SmartNIC) позволяют загружать eBPF-программы прямо на карту. В этом случае пакеты фильтруются вообще без участия CPU сервера. Скорость фильтрации - 100+ Gbps на одном порту.

Composable datapath. Несколько eBPF-программ можно соединять в цепочку (tail calls), создавая модульную систему фильтрации. Один модуль проверяет IP, другой анализирует rate, третий разбирает протокол игры.

Для игровой индустрии это означает, что DDoS-атаки, которые сегодня кажутся неотразимыми (100M+ pps), через пару лет будут отфильтровываться одной SmartNIC за десятые доли микросекунды. А сложные application-level атаки будут детектироваться ML-моделями прямо в ядре, без задержек на передачу данных в userspace.

XDP/eBPF - не серебряная пуля. Это инструмент, который при грамотном использовании даёт на порядок лучшую производительность фильтрации, чем традиционные методы. И в защите игровых серверов от DDoS, где каждая микросекунда задержки и каждый лишний пакет имеют значение, этот порядок - разница между падением сервера и стабильным 20 TPS под атакой.


Sunucunuzu DDoS Saldırılarından Koruyun

5 dakikada kurulumla ücretsiz koruma. 1 TB bant genişliği dahil.

Ücretsiz Deneyin


İlgili Makaleler