Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
![](https://habrastorage.org/getpro/habr/upload_files/76b/ac6/d82/76bac6d82dc84a054d11bb27636f3058.png)
Примечание автора: это пост многолетнего разработчика сетевых технологий ядра Linux и создателя проекта Cilium Томаса Графа.
Сообщество разработчиков ядра Linux недавно анонсировало bpfilter, который заменит давно существующую внутриядерную имплементацию iptables на высокопроизводительную сетевую фильтрацию на базе Linux BPF, гарантируя при этом переход без сбоев для пользователей Linux.
Из скромной системы фильтрации пакетов, лежащей в основе таких популярных инструментов, как tcpdump и Wireshark, BPF превратился в насыщенную основу для расширения возможностей Linux чрезвычайно гибким образом, без ущерба таким ключевым свойствам, как производительность и безопасность. Это мощное сочетание привело к тому, что такие перспективные пользователи технологии ядра Linux, как Google, Facebook и Netflix, выбрали BPF для использования в самых разных случаях — от сетевой безопасности и балансировки нагрузки до мониторинга производительности и устранения неполадок. Брендан Грегг из Netflix изначально назвал BPF Superpowers (суперсилой) для Linux. В этой заметке мы расскажем о том, как эти «суперспособности» делают ненужными давно существующие подсистемы ядра, такие как iptables, и одновременно позволяют создавать новые внутриядерные сценарии использования, которые мало кто мог себе представить раньше.
Проведя последние 15 лет в сообществе разработчиков ядра Linux за написанием кода для многих подсистем, включая стек TCP/IP, iptables и многих других, я имел возможность наблюдать за развитием BPF вблизи. Вскоре понял, что BPF — это не просто очередная функция, а фундаментальный технологический сдвиг, который со временем изменит почти все аспекты сетевой работы и безопасности в Linux. Я внес свой вклад и стал одним из самых больших сторонников этой технологии вместе с Алексеем Старовойтовым и Даниэлем Боркманном, которые сейчас поддерживают BPF. С этой точки зрения, переход от iptables к bpfilter является лишь следующим логическим шагом на пути BPF к обновлению сетевого стека Linux для современной области. Чтобы понять, почему этот переход так интересен, позвольте мне совершить небольшой экскурс по истории iptables в ядре.
iptables и основы последовательной фильтрации
iptables был основным инструментом для реализации брандмауэров и пакетных фильтров в Linux в течение многих лет. iptables и его предшественник ipchains являлись частью моего личного пути в Linux с самого начала. Сперва в качестве пользователя, затем как разработчика ядра. За эти годы iptables был благом и проклятием: благом за его гибкость и быстроту решений. А проклятием — во время отладки настройки iptables с 5K правилами в среде, где несколько компонентов системы борются за право устанавливать те или иные правила iptables.
Джером Петаццони однажды подслушал цитату, которая как нельзя лучше соответствует действительности:
Подслушано: "В любой команде вам нужен танк, лекарь, дэмэдж дилер, кто-то со способностями контроля толпы и еще один, кто знает iptables"
— Jérôme Petazzoni (@jpetazzo) 27 июня 2015 г.
Когда 20 лет назад iptables начал свое существование, заменив предшественника ipchains, функциональность брандмауэра была прописана очень просто:
Защита локальных приложений от получения нежелательного сетевого трафика (цепочка INPUT)
Защита локальных приложений от отправки нежелательного сетевого трафика (цепочка OUTPUT)
Фильтрация сетевого трафика, пересылаемого/маршрутизируемого системой Linux (цепочка FORWARD).
Скорость сети в те времена была низкой. Помните звук, который издавал модем при наборе номера? Это была эпоха, когда iptables был первоначально разработан и спроектирован. Стандартной практикой применения списков контроля доступа (ACL), как это реализовано в iptables, было использование последовательного списка правил, т.е. каждый полученный или переданный пакет сопоставляется со списком правил, один за другим.
Однако у линейной обработки есть очевидный крупный недостаток: издержки на фильтрацию пакета могут увеличиваться линейно с количеством добавляемых правил.
Промежуточный обходной путь: ipset
Прошло некоторое время, скорость сети увеличилась, и наборы iptables выросли с десятка до тысяч правил. Последовательный просмотр списков iptables стал просто невыносимым с точки зрения производительности и времени ожидания.
Сообщество быстро определило самое узкое место: длинные списки правил, отклоняющих или разрешающих отдельные комбинации IP-адресов и портов. Это привело к появлению ipset. ipset позволяет сжать список правил, соответствующих IP-адресам и/или комбинациям портов, в хэш-таблицу, уменьшая общее количество правил iptables. С тех пор такое решение служит обходным путем.
К сожалению, ipset не является ответом на все проблемы. Ярким примером является kube-proxy, компонент Kubernetes, который использует правила iptables и -j DNAT для обеспечения балансировки нагрузки на сервисы. Он устанавливает несколько правил iptables для каждого бэкенда, к которому обращается служба. Для каждого сервиса, добавляемого в Kubernetes, список правил iptables, которые необходимо пройти, растет экспоненциально.
В недавнем выступлении на KubeCon производительность kube-прокси была рассмотрена во всех деталях. В докладе представлены результаты измерений, показывающие непредсказуемые задержки и снижение производительности по мере роста числа сервисов. Кроме того, был выявлен еще один серьезный недостаток iptables: отсутствие инкрементных обновлений. Весь список приходится заменять каждый раз, когда в него добавляется новое правило. В результате общая продолжительность установки 160K правил iptables, представляющих 20K сервисов Kubernetes, составляет 5 часов.
Использование механизмов, основанных на IP/портах, в целом имеет много других очевидных недостатков, особенно в эпоху контейнеров приложений. Контейнеры часто разворачивают и сворачивают. Это может привести к короткому лайфтайму отдельных IP-адресов. IP-адрес может использоваться одним контейнером в течение нескольких секунд, а затем повторно использоваться другим через пару секунд. Это создает нагрузку на системы, которые полагаются на использование IP-адресов для обеспечения фильтрации безопасности, поскольку все узлы в кластере должны постоянно знать о последнем маппинге IP-адресов и контейнеров. Если в пределах одного кластера это не представляет особой сложности, то между кластерами это становится невероятно трудной задачей. Подробное рассмотрение этого вопроса выходит за рамки данной статьи, поэтому мы оставим его на будущее.
Развитие BPF
В последние годы BPF развивается с бешеной скоростью, открывая то, что раньше было недоступно ядру. Это стало возможным благодаря невероятно мощной и эффективной программируемости, которую обеспечивает BPF. Задачи, которые раньше требовали создания кастомного ядра и его перекомпиляции, теперь могут быть решены с помощью эффективных BPF-программ в безопасных границах "песочницы" BPF.
Ниже приведен список, демонстрирующий использование BPF в различных проектах и компаниях:
Cilium раскрывает возможности BPF в мире контейнеров и предоставляет мощные и эффективные сети, безопасность и балансировку нагрузки на уровне L3-L7. Прочитайте введение в Cilium, чтобы начать знакомство с Cilium.
“То, что @ciliumproject делает с eBPF и XPD - это самый чистый сетевой плагин, который я видел, большой респект”
— jessie frazelle (@jessfraz) 16 августа 2017 г.
Facebook представила интересную работу по балансировке нагрузки на основе BPF/XDP для замены IPVS, которая также включает логику смягчения DDoS. Хотя IPVS является привлекательным следующим шагом по сравнению с iptables, Facebook уже перешел от IPVS к BPF, заметив примерно 10-кратное улучшение производительности.
“Производительность eBPF поражает воображение! Простой ингресс-брандмауэр, который я написал, используя XDP, обрабатывает 11 миллионов пакетов/с. Время для новых оптимизаций!”
— Diptanu Choudhury (@diptanu) 21 августа 2017 г.
Netflix, в частности Брендан Грегг, использовали возможности BPF для профилирования и трассировки производительности. Проект bcc предоставляет пользователям доступ к возможностям BPF, например, для создания удивительных флеймграфов:
![](https://habrastorage.org/getpro/habr/upload_files/856/316/663/856316663dbd7ee2654c63f0677f7fa1.png)
Более подробную информацию, включая множество примеров использования BPF для трассировки приложений, можно найти в блоге Брендана Грегга.
“Как я уже говорил многим людям, ищущим работу в области системной инженерии: опыт работы с BPF очень популярен, и он становится все более популярным.”
— Брендан Грегг (@brendangregg) 20 мая 2017 г.
Google работает над bpfd, который обеспечивает мощную трассировку Linux для удаленных задач с использованием eBPF. Основываясь на активном взаимодействии с BPF, они также, похоже, рассматривают возможность миграции различных внутренних проектов на BPF.
Cloudflare использует BPF для смягчения DDoS-атак и опубликовала несколько сообщений в блоге, а также представила несколько публичных выступлений на эту тему.
Suricata — это IDS, которая начала использовать BPF и XDP для замены nfqueue, которая представляет собой инфраструктуру для перехвата пакетов на основе iptables. Более подробную информацию можно найти в этом докладе Kernel Recipes.
Open vSwitch работает над использованием datapath с поддержкой eBPF.
Существует слишком много примеров, чтобы перечислить их все в этом блоге. Более полный список проектов, использующих BPF, представлен в справочнике BPF.
Один BPF, чтобы управлять всем
Самым последним достижением в эволюции BPF является захватывающее предложение полностью заменить часть ядра iptables на BPF таким образом, чтобы это было полностью прозрачно для пользователя, т. е. существующие бинарные файлы и библиотеки клиента iptables продолжат работать.
Ознакомиться с ходом дискуссии можно в рассылке Kernel. Авторами предложения являются Дэниел Боркманн (Covalent), специалист по работе с сетями Дэвид Миллер (Red Hat) и Алексей Старовойтов (Facebook). Предложение было освещено в статье LWN, в которой дается отличное резюме первоначального обсуждения.
Следующий график, представленный Квентином Монне на FRnOG 30, показывает несколько первоначальных измерений bpfilter в сравнении с iptables и nftables. Здесь показана как программная реализация BPF, так и тест с аппаратной разгрузкой:
![](https://habrastorage.org/getpro/habr/upload_files/690/ca8/384/690ca8384d594617b442bf2f10a842bd.png)
Эти первые показатели производительности выглядят многообещающе и свидетельствуют о мощности BPF. Следует отметить, что bpfilter и сам BPF не решат проблемы производительности, связанные с использованием iptables последовательных списков. Для этого потребуется использование BPF на нативном уровне, как это сделано в проекте Cilium.
Как отреагировало сообщество разработчиков ядра?
Некоторые из участников списков рассылки ядра Linux известны своими горячими баталиями. Вспыхнули ли эти войны в данном случае? Нет, на самом деле, сразу же появились предложения от основных мэйнтейнеров iptables, направленные в сторону BPF.
Флориан Вестфал предложил фреймворк, который будет работать поверх bpfilter и конвертировать nftables в BPF. Это позволит сохранить язык nftables, специфичный для конкретной области, но получить все преимущества среды выполнения BPF с ее JIT-компилятором, аппаратной разгрузкой и инструментарием.
Пабло Нейра Аюсо, похоже, работал над аналогичным предложением и опубликовал серию статей, в которых также переводит nftables на BPF. Основное различие в подходах, похоже, заключается в том, что Пабло намеревался выполнять перевод в ядре. С тех пор сообщество согласилось, что любая инъекция BPF-программ должна происходить через адресное пространство пользователя и BPF-верификатор, чтобы гарантировать безопасное поведение BPF.
Резюме
Я считаю BPF самой захватывающей разработкой Linux за последние годы. Мы лишь слегка прикоснулись к его потенциалу, а он еще продолжает развиваться. Замена части ядра iptables на BPF — это логичный первый шаг. Фактический переход будет заключаться в создании собственных инструментов BPF, а также в отходе от традиционных конструкций, ориентированных на IP-адреса/порты.
Материал подготовлен в рамках специализации "Administrator Linux".
Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.