Эта статья подготовлена командой STE системного отдела ByteDance.
Для Linux iptables/nftables является основным сетевым решением ACL (список управления доступом). В связи с быстрым развитием технологии eBPF в последние годы, bpfilter также был включен в повестку дня и, как ожидается, заменит iptables/nftables и станет сетевым ACL-решением нового поколения.
Эта статья следует по стопам bpfilter, использует технологию XDP+eBPF для устранения узких мест производительности iptables/nftables и предоставляет техническое решение для высокопроизводительного сетевого ACL.
Узкое место производительности iptables/nftables
Поскольку технологии iptables и nftables схожи, но iptables относительно прост, мы используем iptables в качестве примера для анализа:
O(N) соответствие
Стиль правил для iptables:
# iptables -A INPUT -m set --set black_list src -j DROP
# ......省略N条规则
# iptables -A INPUT -p tcp -m multiport --dports 53,80 -j ACCEPT
# ......省略N条规则
# iptables -A INPUT -p udp --dport 53 -j ACCEPT
Как показано выше, если пакет запроса DNS (пакет udp порта назначения 53) совпадает, все правила необходимо пройти по очереди, чтобы найти совпадение. Среди них элементы соответствия, такие как ipset/multiport, могут только уменьшить количество правил, но не могут изменить метод сопоставления O(N).
Потеря пакетов стека протоколов
Iptables часто используется в сочетании с ipset для настройки некоторых черных списков IP-адресов для защиты от сетевых атак DDOS (распределенный отказ в обслуживании). Для сетевых атак, таких как DDOS, чем раньше происходит потеря пакетов, тем лучше можно снизить нагрузку на ЦП. Однако использование iptables в качестве средства предотвращения DDOS-атак часто оказывается неэффективным. Это связано с тем, что iptables реализован на основе структуры netfilter.Даже если пакет атаки отбрасывается в точке перехвата PREROUTING структуры netfilter (самая ранняя точка перехвата на пути получения пакета), он уже прошел множество процессов обработки. стека сетевых протоколов Linux. В интернете есть сравнительные данные, и скорость потери пакетов по технологии XDP примерно в 4 раза выше, чем у iptables:
- Предустановленное условие: один поток UDP, обработка одним процессором
- CPU: i7-6700K CPU @ 4.00GHz
- NIC: 50Gbit/s Mellanox-CX4
- правила iptables: iptables -t raw -I PREROUTING -m set --set black_list src -j DROP
- Скорость потери пакетов iptables: 4 748 646 пакетов в секунду
- XDP: карта eBPF типа PERCPU_HASH, хранящая черный список IP-адресов
- Скорость потери пакетов XDP: 16 939 941 пакетов в секунду
XDP
XDP (eXpress Data Path) — это высокопроизводительная программируемая технология плоскости данных, основанная на eBPF. Базовая архитектура программного обеспечения показана на следующем рисунке:
XDP расположен на уровне драйвера сетевой карты.После того, как пакет данных сохранен в кольцевом буфере через DMA, он может быть обработан XDP до выделения skb. После того, как пакет данных проходит через XDP, есть 4 пункта назначения:
- XDP_DROP: потеря пакетов
- XDP_PASS: загрузить стек протоколов
- XDP_TX: отправлено с текущей сетевой карты
- XDP_REDIRECT: отправлено с другой сетевой карты
Поскольку XDP находится в нижней части всего стека сетевого программного обеспечения ядра Linux, он может идентифицировать и отбрасывать пакеты атак очень рано и с высокой производительностью. Это дает нам отличное решение для устранения узкого места в производительности, связанного с потерей пакетов стека протоколов iptables/nftables.
eBPF
BPF (Berkeley Packet Filter) — это технология динамического внедрения, основанная на байт-коде BPF, предоставляемом ядром Linux (часто используется в tcpdump, фильтрации необработанных сокетов и т. д.). eBPF (расширенный пакетный фильтр Беркли) — это усовершенствование расширения для BPF, которое обогащает набор инструкций BPF и обеспечивает структуру хранения KV карты. Мы можем использовать системный вызов bpf() для инициализации программы и карты eBPF, а также использовать сообщение netlink или системный вызов setsockopt() для внедрения байт-кода eBPF в определенный процесс ядра (например, XDP, фильтр сокетов и т. д.). . Как показано ниже:
До сих пор техническое направление нашего высокопроизводительного ACL было уточнено, то есть использование технологии XDP для фильтрации пакетов в нижней части стека программного обеспечения.
Общая структура
Как показано на рисунке ниже, плоскость управления ACL отвечает за создание программы и карты eBPF и их внедрение в поток обработки XDP. Программа eBPF хранит логику обработки, такую как сопоставление пакетов и потерю пакетов, а карта eBPF хранит правила ACL.
алгоритм сопоставления
Чтобы повысить эффективность сопоставления, мы предварительно обрабатываем все правила ACL и сохраняем связанные правила отдельно. Когда правила совпадают, мы обращаемся к алгоритму планирования O(1) ядра и быстро выбираем правило с высоким приоритетом среди нескольких правил сопоставления.
Предварительная обработка правил
Давайте возьмем предыдущее правило iptables в качестве примера, чтобы увидеть, как его можно разделить и сохранить. Во-первых, все правила нумеруются в соответствии с приоритетом. Например, правила в примере пронумерованы: 1 (0x1), 16 (0x10), 256 (0x100). Во-вторых, совпадения всех правил классифицируются и разделяются. Например, совпадения в примере можно классифицировать как: исходный адрес, порт назначения, протокол. Наконец, номер правила и конкретные совпадающие элементы классифицируются на карте eBPF.
# ipset create black_list hash:net
# ipset add black_list 192.168.3.0/24
# iptables -A INPUT -m set --set black_list src -j DROP
# ...... 省略15条规则
# iptables -A INPUT -p tcp -m multiport --dports 53,80 -j ACCEPT
# ...... 省略240条规则
# iptables -A INPUT -p udp --dport 53 -j ACCEPT
Например:
Исходный адрес совпадает только с правилом 1. Мы используем исходный адрес 192.168.3.0/24 в качестве ключа и номер правила 0x1 в качестве значения и сохраняем его в карте src.
Правило 16 имеет 2 совпадающих элемента порта назначения и протокола.Мы используем 53 и 80 в качестве ключа и номер правила 0x10 в качестве значения, которое хранится в карте dport, протокол tcp номер 6 используется в качестве ключа, и номер правила 0x10 используется как значение, которое хранится в proto на карте.
Правило 256 имеет 2 соответствующих элемента порта назначения и протокола.Мы используем 53 в качестве ключа и номер правила 0x100 в качестве значения и сохраняем его в карте dport; используем номер протокола udp 17 в качестве ключа и номер правила 0x100 в качестве значение и сохраните его в протокарте.
Мы последовательно используем номера правил 1, 16 и 256 в качестве ключа, а действие в качестве значения и сохраняем их в Карте действий.
перекресток
Следует отметить, что правила 16 и 256 совпадают с портом назначения 53. Мы должны выполнить побитовую операцию ИЛИ над номерами правил 16 и 256, а затем сохранить их, то есть 0x10 | 0x100 = 0x110.
подстановочный знак
Кроме того, порт назначения и протокол правила 1 являются элементами подстановки, и мы должны добавить количество правила 1 к существующим сопоставленным элементам по BITWICE или (подчеркнутое значение на рисунке: 0x111, 0x11 и т. Д.). Точно так же, что число правил правил 16 и 256 побито или добавлено к существующему списку исходного адреса (подчеркнутое значение на рисунке: 0x111, 0x110). На данный момент наше предварительное обработка правила завершено, а матчи и действия всех правил разделены и хранятся на 6 картах EBPF, как показано на рисунке выше.
соответствие класса O(1)
Когда сообщение совпадает, 5-кортеж (источник, адрес назначения, источник, порт назначения, протокол) нашего сообщения по очереди используется в качестве ключа, и выполняется поиск соответствующей карты eBPF для получения 5 значений. Мы выполняем побитовую операцию И над этими 5 значениями, чтобы получить растровое изображение. Каждый бит этого битового массива представляет соответствующее правило; бит, установленный в 1, указывает, что соответствующее правило успешно сопоставляется.
Например:
При использовании в качестве ключа 5-кортежа сообщения (192.168.4.1:10000 -> 192.168.4.100:53, udp) после поиска в карте eBPF получены следующие значения: src_value = 0x110, dst_value = NULL, sport_value = NULL, dport_value = 0x111, proto_value = 0x101. Выполните побитовую операцию И над значением, отличным от NULL, чтобы получить растровое изображение = 0x100 (0x110, 0x111 и 0x101). Поскольку только один бит битовой карты установлен в 1 (успешно сопоставлено только одно правило, то есть правило 256), используйте битовую карту в качестве ключа, чтобы найти карту действия и получить значение ACCEPT. Это согласуется с результатом сопоставления правил iptables.
Точно так же, когда в качестве ключа используется 5-кортеж пакета (192.168.4.1:1000 -> 192.168.4.100:53, tcp), после поиска на карте eBPF поток обработки такой же, как и выше, и, наконец, правило 16 соответствует.
Точно так же, когда в качестве ключа используется 5-кортеж пакета (192.168.3.1:1000 -> 192.168.4.100:53, udp) и выполняется поиск карты eBPF, процесс обработки такой же, как описано выше. Отличие в том, что полученный битмап = 0x101, так как два бита битмапа установлены в 1 (правило 1, 256), то в качестве ключа для поиска карты действия следует взять номер правила с наивысшим приоритетом. Здесь мы опираемся на идею алгоритма планирования ядра O(1) и выполняем следующие операции:
bitmap &= -bitmap
Вы можете получить бит с наивысшим приоритетом, например, 0x101 & = - (0x101) наконец равно 0x1. Мы используем 0x1 в качестве ключа, посмотрите на карту действий и получите значение в качестве падения. Это согласуется с результатом сопоставления правил iptables.
Суммировать
В этой статье, основанной на механизме XDP ядра Linux, предлагается схема ACL для повышения производительности iptables/nftables. В настоящее время технология eBPF очень популярна в сообществе с открытым исходным кодом и имеет очень богатые возможности, и мы можем использовать эту технологию, чтобы делать много интересных вещей. Заинтересованные друзья могут присоединиться к нам для обсуждения и общения.
Ссылаться на
- ACL. https://en.wikipedia.org/wiki/Access-control_list
- BPF comes to firewalls. https://lwn.net/Articles/747551/
- XDP — путь к данным eXpress, используемый для защиты от DDoS-атак. http://people.netfilter.org/hawk/presentations/OpenSourceDays2017/XDP_DDoS_protecting_osd2017.pdf
Команда STE отдела ByteDance Systems
Команда Biode Tooth System STE занимается ядром и виртуализацией операционной системы, базовым программным обеспечением системы, созданием базовой библиотеки и оптимизацией производительности, созданием стабильности и надежности сверхбольших центров обработки данных, совместным проектированием нового аппаратного и программного обеспечения и другими основами НИОКР и инжиниринга. в технической области, с комплексными базовыми возможностями разработки программного обеспечения, сопровождая байт превосходный бизнес. В то же время команда активно следит за трендами технологий сообщества, поддерживает открытый исходный код и стандарты. Вы можете присоединиться, если хотите отправить свое резюме на sysRecruitment@bytedance.com.
Добро пожаловать в техническую команду ByteDance