Cloudflare, Netflix, Google, Meta — все они переписали часть своей сетевой инфраструктуры на eBPF. Объясняю, что это такое, как работает и почему это важно даже если вы никогда не напишете ни строчки BPF-кода.
Несколько лет назад коллега показал мне как Cloudflare обрабатывает DDoS-атаки. Я ожидал увидеть кластер специализированного железа, FPGA, что-то дорогое. Вместо этого — обычные x86-серверы и несколько строчек кода, которые дропали миллионы пакетов в секунду до того, как они вообще доходили до ядра Linux. Это был eBPF.
С тех пор я не могу перестать думать о том, насколько незаметно произошла эта революция.
Представьте, что у вас есть операционная система — большая, сложная, написанная тысячами людей за десятки лет. Чтобы изменить её поведение, нужно написать модуль ядра: скомпилировать, загрузить, молиться что ничего не упадёт. Один баг — и система висит.
eBPF делает другое: позволяет запускать ваш код прямо внутри ядра Linux, при этом гарантируя что он безопасен. Перед запуском специальный верификатор проверяет каждую инструкцию — нет бесконечных циклов, нет выхода за границы памяти, нет краша.
eBPF-программы цепляются к «хукам» — точкам в ядре, где происходят интересные события. Для сетевого стека самые важные:
Вот реальные замеры с одного из наших серверов (Intel E5-2690v4, 10GbE NIC):
Разница в 10-12 раз. На одном и том же железе. Без каких-либо аппаратных ускорителей.
Когда пакет приходит и обрабатывается через iptables, он проходит через весь сетевой стек Linux: выделение skb (socket buffer), обработку в netfilter, прохождение через все цепочки правил. Это сотни функций и тысячи инструкций.
XDP-программа запускается до всего этого — пакет ещё в DMA-буфере сетевой карты. Программа смотрит на него, принимает решение (PASS/DROP/REDIRECT), и всё. Если DROP — пакет не существует с точки зрения ядра.
Cloudflare — фильтрация DDoS на XDP. Когда на вас летит 1 Тбит/с мусора, iptables просто не успевает. XDP успевает.
Meta (Facebook) — Katran, L4-балансировщик на eBPF. Заменил IPVS. Обрабатывает весь трафик Facebook на входе.
Google — Calico с eBPF в Kubernetes, замена kube-proxy. Меньше латентность, больше throughput.
Netflix — bpftrace для отладки латентности в продакшне без перезапуска сервисов.
Скорее всего нет. Большинство практических кейсов уже решены готовыми инструментами:
Если хотите потрогать руками — вот самый быстрый путь:
Первая команда — и вы уже видите каждое сетевое соединение на машине, в реальном времени, без tcpdump, без прав на запись пакетов. Это eBPF.
eBPF — не хайп и не академическая концепция. Это production-технология, которая уже работает в инфраструктуре компаний обслуживающих миллиарды пользователей. Она меняет то, как мы думаем о сетевом стеке, observability и безопасности.
Если вы работаете с Linux-инфраструктурой и ещё не разобрались с eBPF — это пробел который стоит закрыть. Не потому что модно. Потому что это реально меняет что возможно сделать.
BGP — протокол который решает куда идут пакеты в интернете. Он не выбирает кратчайший путь. Он выбирает путь по правилам, которые придумали люди. И иногда эти правила приводят к абсурду.
Однажды мне написал разработчик: «Почему мой запрос от сервера в Амстердаме до сервера в Москве идёт 180ms? Это же рядом!» Я попросил сделать traceroute. Трафик шёл через Лондон, Нью-Йорк и обратно.
Это не баг. Это BGP.
Физически интернет — это тысячи отдельных сетей (их называют автономными системами, AS), которые соединены между собой. Провайдеры, университеты, датацентры, крупные компании — у каждого свой AS с уникальным номером.
BGP (Border Gateway Protocol) — это язык, на котором эти сети общаются между собой. Каждый AS говорит соседям: «Я умею доставлять трафик вот в эти IP-адреса». Соседи передают эту информацию своим соседям. Так строится глобальная таблица маршрутизации.
Когда у BGP есть несколько путей до одного и того же адреса, он выбирает лучший по 13 критериям. Первые три — самые важные:
1. Local Preference (локальное предпочтение). Каждый AS может сказать «этот путь мне нравится больше» — через атрибут local-pref. Кто поставил выше — тот и победил, независимо от физического расстояния.
2. AS Path Length (длина пути). Сколько автономных систем нужно пройти. Меньше — лучше. Но это количество AS, не километров.
3. MED (Multi-Exit Discriminator). Подсказка от соседнего AS: «входи через этот интерфейс, он ближе к получателю».
И вот в чём проблема: нигде в этих критериях нет физического расстояния или задержки. BGP не знает про миллисекунды.
Вернёмся к нашему примеру. Провайдер в Амстердаме мог купить транзит у крупного tier-1 оператора с хорошим local-pref. Этот оператор имеет поп (point of presence) в Лондоне и Нью-Йорке, но его BGP-сессия с российским провайдером настроена через Нью-Йорк — потому что там исторически стоит оборудование, потому что контракт, потому что «так сложилось».
BGP увидел: путь через этого оператора имеет высокий local-pref → выбрал его → физика стала неважна.
185ms вместо ~25ms которые были бы при прямом маршруте. В 7 раз медленнее.
Если вы управляете своим AS — у вас есть инструменты:
Если вы просто пользователь чужой инфраструктуры — вы зависите от решений провайдера. Можно только переехать к тому у кого пиринг лучше.
BGP-маршруты определяются коммерческими договорами, историческими решениями и техническими конфигурациями — а не географией. Это одновременно его слабость (субоптимальные пути) и сила (гибкость, устойчивость, возможность traffic engineering).
В следующий раз когда сделаете traceroute и увидите странный маршрут — знайте: где-то между двумя NOC-командами есть контракт, который объясняет почему ваши пакеты летят через другой континент.
Это не технический пост. Это про то, что происходит с человеком, который годами встаёт по ночам когда что-то падает. И про то, почему лучшие инженеры всегда выглядят спокойными.
Первый серьёзный инцидент я помню до деталей. 2011 год, 2:47 ночи, BGP-сессия с аплинком упала и не поднялась. Я паниковал. Руки тряслись. Я делал одно и то же по три раза — рестартил демон, смотрел логи, снова рестартил. Прошло 40 минут прежде чем я сел, выдохнул, и начал думать системно.
Оказалось — MTU mismatch на новом линке провайдера. Сессия устанавливалась но BGP OPEN-пакеты были больше 1500 байт и дропались по дороге. Три команды и пять минут после того как я успокоился.
С тех пор прошло 15 лет и сотни инцидентов. Вот что я понял.
Когда падает продакшн и вы в ответе — адреналин выбрасывается независимо от вашего опыта. Это нормально. Проблема не в том что вы паникуете, а в том что делаете во время паники.
Неопытный инженер начинает действовать: что-то рестартить, менять конфиги, «попробовать вот это». Опытный инженер первые три минуты собирает данные: что именно упало, с каких мониторов, когда началось, что менялось за последние часы.
Действие без данных в 80% случаев удлиняет инцидент.
«Оно само упало». Не бывает. Всегда есть причина. «Само» означает что причину не нашли.
Инцидент в 3 ночи почти всегда связан с изменением в 17:00. Деплой, ребут, обновление конфига. Что-то поменяли перед уходом домой, и это всплыло ночью под нагрузкой или после истечения таймера.
Первый симптом — не причина. Упал nginx — причина не в nginx. Смотрите глубже: память, сеть, зависимый сервис, ядро.
После трёх лет постоянного oncall я заметил: я стал медленнее. Не технически — реакция на стресс притупилась. Я мог сидеть на инциденте два часа и не заметить очевидного, потому что мозг был просто истощён.
Хронический oncall без нормального сна — это не героизм. Это деградация качества работы в тихом режиме. Компания которая не ротирует oncall и не даёт восстановление после тяжёлых инцидентов — тратит деньги: следующий инцидент будет дольше и дороже.
Я работал с десятками сетевых инженеров. Лучшие из них не самые умные — они самые методичные. У них есть процесс на любой тип инцидента, и они следуют ему даже в 4 утра.
Они также умеют делать одну вещь которая кажется контринтуитивной: они говорят «я не знаю» быстро. Не тратят 40 минут на угадывание — сразу эскалируют, привлекают нужных людей, признают что нужна помощь.
Инциденты не делают вас хорошим инженером. Хорошим инженером вас делает то, что вы делаете после инцидентов: постмортем без поиска виноватых, исправление системных проблем, улучшение мониторинга.
Компания которая наказывает за инциденты — это компания которая учится медленнее конкурентов. Это стратегический проигрыш.
И последнее: если вы читаете это в 3 ночи пока что-то горит — выдохните. Вы справитесь. Соберите данные. Думайте медленно.
XDP позволяет обработать пакет раньше чем ядро Linux его «увидит». Это делает фильтрацию в 10-15 раз быстрее iptables. Показываю как это работает на практике — с кодом, числами и объяснением каждого шага.
Во время DDoS-атаки мощностью 80 Гбит/с наш сервер с iptables держал примерно 1.2 миллиона пакетов в секунду. При 2 миллионах — ядро начинало захлёбываться, CPU уходил в 100%, latency для легитимного трафика улетала в секунды.
После переезда на XDP тот же сервер обрабатывал 14 миллионов пакетов в секунду. Атака продолжалась, но сервис работал.
Когда пакет приходит на сетевую карту, ядро Linux делает много работы прежде чем его «увидят» iptables-правила:
Это сотни операций и несколько переходов между уровнями. При миллионах пакетов в секунду — это огромная нагрузка.
XDP (eXpress Data Path) — хук в самом начале пути пакета, сразу после получения данных от NIC, до выделения sk_buff. Ваша программа получает прямой доступ к сырым байтам пакета и должна вернуть одно из трёх решений:
Вот и всё. Это программа на C которая компилируется в eBPF bytecode и загружается в ядро. Она дропает весь UDP-трафик со скоростью которую ограничивает только NIC.
Во время атаки вы часто знаете список источников. XDP-карта позволяет хранить IP-адреса для блокировки и обновлять её из userspace без перезагрузки программы:
Lookup в BPF hash map — это O(1), порядка 50-100 наносекунд. 100 тысяч заблокированных IP — не проблема.
XDP — не замена всему сетевому стеку. Это инструмент для конкретной задачи: очень быстрое решение «пустить или нет» на входе. Если нужна сложная логика, statefull inspection, NAT — смотрите на TC или работайте в userspace.
Но если у вас DDoS и вам нужно дропать мусор со скоростью линка — XDP это ваш ответ.
Честный постмортем. Без героизации, без «наша команда справилась с любым вызовом». Что сломалось, что сработало случайно, что мы сделали правильно, и что изменили после.
Вторник, 14:23. Мониторинг начинает кричать. Входящий трафик на наш аплинк вырос с обычных 8 Гбит/с до 40 Гбит/с за две минуты. К 14:30 — 180 Гбит/с. В 14:41 провайдер написал что видит 400 Гбит/с и собирается заблокировать наш /24 целиком.
У нас было примерно 15 минут до полного blackhole от провайдера.
UDP amplification через CLDAP (Connectionless LDAP, порт 389). Атакующие отправляли маленькие запросы на уязвимые LDAP-серверы по всему миру, подделывая source IP на наши адреса. Серверы отвечали пакетами в 70-80 раз больше — прямо к нам. Amplification ratio ~70x.
ACL на нашем оборудовании. Бессмысленно — трафик доходит до нашего железа уже насытив аплинк. 400 Гбит/с в канале 10 Гбит/с означает что 390 Гбит/с дропается провайдером, но канал всё равно полностью забит мусором.
Звонок в NOC провайдера. Они предложили заблокировать весь /24. Это «спасение» которое убивает нас вместо атаки. Мы отказались.
Надежда что само закончится. Это наивность. DDoS-атаки не заканчиваются сами — их либо прекращают атакующие, либо их останавливают жертвы.
Remote Triggered Blackhole — мы попросили провайдера заблокировать трафик до конкретных /32-адресов (отдельных IP внутри нашего /24), которые принимали основную нагрузку атаки. Остальной /24 продолжал работать.
Провайдер видит этот анонс с BLACKHOLE community и начинает дропать трафик до этого IP на своём оборудовании — до того как он попадает в наш канал. Через 4 минуты 340 Гбит/с исчезло.
60 Гбит/с продолжали приходить на другие IP. Мы использовали BGP Flowspec — это расширение BGP которое позволяет передавать правила фильтрации провайдеру. Правило: дропать UDP порт 389 с пакетами больше 300 байт идущими к нашим адресам.
Провайдер поддерживал Flowspec. Ещё 55 Гбит/с исчезло в течение 2 минут.
5 Гбит/с мусора продолжали доходить — провайдер фильтровал не всё. Мы подняли XDP-программу дропающую UDP/389 паттерны прямо на входе. CPU при этом не превысил 8%.
Самое важное — не «как мы победили», а что мы сделали чтобы следующий раз был лучше:
iptables работает на миллионах серверов прямо сейчас. Он не исчезнет завтра. Но как primary tool для нового проекта в 2026 году — это архитектурная ошибка. Разбираем почему и что использовать вместо.
iptables появился в Linux 2.4 в 2001 году. Ему 25 лет. Это не проблема — SSH тоже старый и отлично работает. Проблема в том, что iptables проектировался для другого мира: меньших скоростей, меньших таблиц, меньших требований к динамике изменений.
Линейный поиск правил. iptables проходит правила последовательно — сверху вниз, пока не найдёт совпадение. 1000 правил означает в среднем 500 сравнений на пакет. 10 000 правил в Kubernetes — катастрофа.
Нет атомарных обновлений. Чтобы изменить одно правило, iptables-restore выгружает всю таблицу и загружает заново. В Kubernetes при каждом изменении сервисов — это может быть тысячи правил каждые несколько секунд.
Нет observability. Вы не можете легко узнать почему конкретный пакет был принят или отброшен. Только `iptables -L -n -v` с счётчиками — и то не всегда информативно.
nftables — официальная замена iptables от тех же разработчиков (Netfilter project). Работает через тот же netfilter framework в ядре, но с современным синтаксисом и атомарными обновлениями.
Плюсы: нативно в любом современном Linux, поддержка sets (хэш-таблицы правил — O(1) вместо O(n)), атомарные транзакции, читаемый синтаксис.
Минусы: всё ещё работает через netfilter — пакет проходит тот же путь в ядре. Скорость ограничена архитектурой.
Вместо работы внутри netfilter — работа до него. XDP перехватывает пакет сразу после NIC, до любого ядерного стека. Максимальная скорость, минимальный overhead.
Когда использовать: высокая нагрузка, DDoS mitigation, кастомная логика, нужна максимальная производительность. Когда не использовать: нужен statefull NAT, сложная логика, небольшой трафик (iptables достаточно).
Если вы в Kubernetes — Cilium это отдельная история. Он полностью заменяет kube-proxy (который использует iptables) на eBPF-реализацию. Результат:
Простое правило:
Вы нажали Enter. Браузер отправил запрос. Через 50 миллисекунд сервер начал отвечать. Что произошло за эти 50мс? Пройдём весь путь — от электрона в вашем кабеле до TCP-сессии на сервере.
50 миллисекунд — это мало. За это время звук проходит около 17 метров. Процессор делает 150 миллионов операций. А ваш пакет успевает облететь полмира и вернуться.
Проследим за одним TCP SYN-пакетом от вашего браузера до сервера в другом городе.
Браузер знает доменное имя, но не IP. Сначала — DNS. Проверяем кэш браузера → кэш ОС → запрос к DNS resolver провайдера. Если домен уже в кэше — мгновенно. Если нет — ещё один round-trip к DNS-серверу.
Предположим IP уже известен. Браузер создаёт TCP SYN: пакет с флагом SYN, случайным sequence number, параметрами окна. Передаёт в сетевой стек ОС.
ОС смотрит в таблицу маршрутизации: куда отправить этот пакет? Если адрес в другой подсети — к шлюзу (default gateway). ОС проверяет ARP-кэш для MAC-адреса шлюза. Если нет — ARP запрос, ещё задержка.
Пакет получает Ethernet-заголовок с MAC-адресами источника и назначения. Передаётся в очередь сетевой карты.
NIC берёт пакет из очереди, преобразует в электрические сигналы (медь) или световые импульсы (оптика). Скорость распространения сигнала в оптоволокне — около 200 000 км/с (⅔ скорости света).
Расстояние 1000 км по оптике — минимум 5мс только на физическую передачу. Плюс задержки на промежуточном оборудовании.
Пакет попадает на первый маршрутизатор вашего провайдера. Роутер смотрит в FIB (Forwarding Information Base) — таблицу которая говорит в какой порт отправить пакет для данного destination IP. Это происходит в специализированном чипе (ASIC) за наносекунды.
Пока пакет летит, маршрутизаторы уже знают куда его отправить — это решение принято заранее BGP-протоколом. BGP постоянно обменивается информацией о достижимости сетей между автономными системами. FIB — это результат этих вычислений, закэшированный в железе.
NIC сервера получает пакет, делает DMA в память. Прерывание ядра. Сетевой стек обрабатывает Ethernet → IP → TCP заголовки. Видит SYN — создаёт половинчатое соединение, отправляет SYN-ACK обратно.
SYN-ACK проходит тот же путь обратно. Ещё ~25мс.
И только после трёхстороннего handshake (SYN → SYN-ACK → ACK) браузер может отправить HTTP-запрос. Это одна из причин почему QUIC (UDP-based протокол HTTP/3) так важен: 0-RTT или 1-RTT вместо 1.5-RTT у TCP+TLS.
Физика — не оптимизируется. Скорость света постоянна. Но остальное — можно:
Если вы не можете объяснить концепцию простыми словами — вы её не поняли. Аналогия которая работает для BGP, plus бонус: как это применять на технических интервью.
Мама спросила чем я занимаюсь. Я сказал «настраиваю BGP». Она кивнула с видом человека который ничего не понял но не хочет расстраивать. Я решил попробовать иначе.
Представь что есть тысячи городов и в каждом — своя курьерская компания. Каждая компания умеет доставлять посылки внутри своего города, и ещё знает несколько соседних компаний с которыми работает.
Автономная система (AS) — это одна курьерская компания со своим городом (набором IP-адресов).
Чтобы доставить посылку в незнакомый город, твоя компания спрашивает соседей: «Вы знаете как добраться до города X?» Сосед говорит: «Да, через меня — я знаю путь». Сосед спрашивает своих соседей. Так информация о маршрутах распространяется по всей сети компаний.
BGP — это язык на котором курьерские компании говорят друг другу «через меня можно доставить в такие-то города».
Мама сказала: «А, как навигатор но для посылок». Близко. Очень близко.
Продолжаем аналогию. Ваша компания работает с двумя соседями. Первый — старый партнёр, надёжный, хорошие условия. Второй — новый, возможно быстрее, но контракт только начинается.
По умолчанию вы будете отправлять посылки через старого партнёра — не потому что он быстрее, а потому что вы ему доверяете и у вас хороший договор. Это local preference в BGP.
Посылка может ехать дольше. Но компания выбрала этот маршрут по своим бизнес-соображениям. BGP — про бизнес, не про физику.
BGP основан на доверии: если сосед говорит «через меня можно доставить в город X» — вы верите. Нет встроенной проверки что это правда.
Именно поэтому route leaks и BGP hijacking так опасны: кто-то говорит «через меня быстрее до всего интернета» — и часть интернета начинает посылать трафик через него. Случайно или намеренно.
«Как мошенники которые говорят что они почта», — сказала мама. Именно.
На технических интервью часто спрашивают объяснить сложную концепцию. Проблема не в том что кандидат не знает — проблема в том что он говорит на языке документации RFC вместо языка понятных моделей.
Простое правило: сначала аналогия, потом технические детали. «BGP — это как курьерские компании которые договариваются о маршрутах. Технически это EGP протокол работающий поверх TCP, использующий path vector для предотвращения петель...»
Интервьюер видит: человек понимает суть, а не просто выучил термины. Это редкость.
Попробуйте объяснить эти концепции человеку без технического образования:
Если объяснение занимает больше трёх предложений — вы ещё не нашли правильную аналогию. Продолжайте искать.
Мама теперь рассказывает друзьям что её сын «настраивает маршруты для интернет-посылок». Я считаю это успехом.
Linux не настроен для высокой сетевой нагрузки по умолчанию. Дефолтные значения — это разумные значения для среднего сервера 2005 года. Вот 7 параметров которые меняют всё.
Нам позвонил клиент: «У нас сервер 32 ядра, 128GB RAM, 10GbE — и nginx упирается в 12 000 RPS». Я попросил прислать вывод `ss -s` и `sysctl -a | grep net`. Диагноз был поставлен за три минуты.
Проблема не в nginx. Проблема в ядре Linux.
Сетевой трафик в Linux проходит через несколько очередей и буферов. Каждый из них имеет размер. Когда размер недостаточен — пакеты дропаются или блокируются. CPU тратит время на управление переполненными очередями вместо обработки данных.
Маленький буфер = TCP окно не может вырасти = низкий throughput на линках с задержкой. На WAN-соединениях это критично.
Дефолтный somaxconn = 128. При 10 000 RPS даже кратковременный spike может переполнить очередь. Соединения начинают дропаться с ECONNREFUSED. nginx пишет ошибки, клиенты видят 502.
При высоком RPS быстро заканчиваются ephemeral порты и накапливаются TIME_WAIT соединения. Симптом: `ss -s` показывает тысячи TIME-WAIT, новые соединения начинают фейлиться.
На многосокетных серверах NIC часто подключена к одному NUMA-узлу. Если прерывания обрабатываются CPU с другого узла — каждый доступ к памяти пакета стоит дорого (cross-NUMA latency ~100нс против ~10нс локально).
Не курсы Udemy. Не YouTube-туториалы. То что читают люди, которые строят сети на миллионы пользователей — и откуда они узнают об этом первыми.
Меня часто спрашивают: откуда брать информацию о сетях, если хочется расти быстрее? Не основы (для этого есть книги), а то что происходит прямо сейчас на переднем крае.
Вот что я читаю каждую неделю.
Cloudflare Blog (blog.cloudflare.com) — лучший технический блог в индустрии по сетям. Они публикуют детальные разборы своей инфраструктуры: как работает их anycast, как они обрабатывают DDoS, как реализован их Workers runtime. Каждая статья — это заглянуть внутрь системы которая обрабатывает 20% интернет-трафика.
Meta Engineering Blog — разборы инфраструктуры масштаба которого нет нигде ещё. Статьи про Katran (L4 балансировщик на eBPF), про их BGP-архитектуру, про инцидент 2021 года когда весь Facebook пропал из интернета — это обязательное чтение.
Netflix Tech Blog — особенно всё что связано с CDN и оптимизацией TCP. Их статьи про BBR congestion control и про то как они работают с ISP изменили мой взгляд на управление трафиком.
NANOG (nanog.org) — North American Network Operators Group. Архив презентаций с их конференций — это золото. Здесь операторы крупнейших сетей мира делятся реальными проблемами и решениями. Не теория — живая практика.
RIPE Labs (labs.ripe.net) — исследования о состоянии глобальной маршрутизации, BGP-аномалиях, IPv6 adoption. Если хотите понять как работает интернет на макро-уровне — здесь.
Julia Evans (jvns.ca) — объясняет сложные концепции ядра Linux с редкой ясностью. Её посты про strace, tcpdump и сетевой стек — образец того как надо писать технически.
Jessie Frazelle — containers, kernel, networking. Глубокие технические посты от человека который работал в Docker, Microsoft и других местах где сеть — это не абстракция.
Большинство RFC написаны сухо и для специалистов. Но несколько — настоящее удовольствие и фундамент понимания:
BGPlay (bgplay.massimocandela.com) — визуализация BGP-событий в реальном времени. Запустите во время любого крупного инцидента — видно как маршруты появляются и пропадают.
RIPE RIS Live — стрим BGP-обновлений со всего мира в реальном времени. Когда кто-то делает route leak — видно буквально за секунды.
«TCP/IP Illustrated, Vol. 1», W. Richard Stevens. Написана в 1994 году. Устарела в деталях, но не устарела в понимании. Если вы читали её давно — перечитайте. Если не читали — это пробел.
Главный принцип: читайте первоисточники, а не пересказы. Когда компания пишет о своей инфраструктуре — это знание из первых рук. Когда блогер пересказывает — это всегда потеря точности.
И ещё: лучший способ усвоить прочитанное — написать о нём своими словами. Именно этим я и занимаюсь здесь.