Программа, которая подключается к XDP-перехватчику ядра Linux через (e)BPF для быстрой обработки пакетов и выполняет базовую пересылку на уровне 3/4. Эта программа выполняет сопоставление исходных портов, аналогично IPTables и NFTables, для обработки соединений. Приоритет существующих соединений определяется исходя из количества пакетов соединения в наносекунду. Это означает, что при исчерпании портов соединения с наименьшим количеством пакетов в наносекунду будут заменены. Я считаю, что это лучший вариант, поскольку соединения с большим количеством пакетов в наносекунду будут более чувствительными.
Кроме того, если сетевая конфигурация хоста или сетевая карта (NIC) не поддерживают перехватчик XDP DRV (собственный вариант KA; возникает перед созданием SKB), программа попытается подключиться к перехватчику XDP SKB (общий вариант AKA; возникает после SKB). создание, в котором IPTables и NFTables обрабатываются с помощью модуля ядра netfilter
). Вы можете использовать переопределения через командную строку, чтобы принудительно включить режимы SKB или разгрузки.
С учетом вышесказанного, причины, по которым конфигурация сети хоста не поддерживает перехватчик DRV XDP, могут быть следующими.
Я надеюсь, что этот проект поможет существующим сетевым инженерам/программистам, заинтересованным в использовании XDP, или всем, кто заинтересован в освоении этих областей! Высокопроизводительные маршрутизаторы/пересылка пакетов и (D) смягчение/предотвращение DoS являются такими важными частями кибербезопасности, и понимание концепции сети и потока пакетов на низком и среднем уровне, безусловно, поможет тем, кто делает карьеру в этой области.
ВНИМАНИЕ . С этим проектом еще многое предстоит сделать, и на данный момент он поддерживает только IPv4. Поддержка IPv6 будет добавлена до официального релиза. На данный момент программа может содержать ошибки, а функции переадресации пока недоступны.
Максимальное количество исходных портов по умолчанию, которое можно использовать для каждого адреса привязки, равно 21 и устанавливается здесь (вы можете настроить их, если хотите). По умолчанию мы используем диапазон портов 500–520 , но это можно настроить.
Сначала я пытался использовать большинство доступных портов (1 – 65534). Однако из-за ограничений верификатора BPF мне пришлось поднять пару констант внутри ядра Linux и перекомпилировать ядро. Я сделал для них патчи и все задокументировал здесь. Я могу запустить программу с максимальным количеством портов 65534 на каждый адрес привязки без каких-либо проблем с собственным ядром, которое я собрал с использованием сделанных мной патчей. Однако имейте в виду, что чем больше исходных портов доступно, тем больше обработки программе XDP придется выполнять при проверке доступных портов.
Если вы планируете использовать это в производстве, я настоятельно рекомендую скомпилировать собственное ядро с константами, указанными выше. Максимальное количество исходных портов 21 на адрес привязки — это немного, но, к сожалению, ограничения верификатора BPF по умолчанию не позволяют нам идти дальше.
Основной код, вызывающий эти ограничения, находится здесь и возникает, когда мы пытаемся найти лучший исходный порт для нового соединения. На самом деле не существует другого способа проверить лучший доступный исходный порт с той степенью гибкости, которую мы имеем, насколько я понимаю, поскольку мы должны пройти через все исходные порты и проверить пакеты на значение наносекунды (поиск карт BPF по ключу).
Вам понадобятся make
, clang
, libelf
и llvm
поскольку мы используем эти пакеты для сборки проекта. Кроме того, вам также понадобится libconfig
( libconfig-dev
— это пакет в системах Ubuntu/Debian) для анализа файла конфигурации.
Для Ubuntu/Debian должно работать следующее.
apt install build-essential make clang libelf-dev llvm libconfig-dev
Я предполагаю, что имена пакетов в других дистрибутивах Linux аналогичны.
Чтобы использовать xdpfwd-add
и xdpfwd-del
, вам необходимо смонтировать файловую систему BPF, поскольку программа XDP закрепляет карты BPF в /sys/fs/bpf/xdpfwd
. Велика вероятность, что это уже сделано за вас через iproute2
или что-то подобное, но если это не так, вы можете использовать следующую команду.
mount -t bpf bpf /sys/fs/bpf/
Базовое использование командной строки включает в себя следующее.
-o --offload => Attempt to load XDP program with HW/offload mode. If fails, will try DRV and SKB mode in that order.
-s --skb => Force program to load in SKB/generic mode.
-t --time => The amount of time in seconds to run the program for. Unset or 0 = infinite.
-c --config => Location to XDP Forward config (default is /etc/xdpfwd/xdpfwd.conf).
-l --list => List all forwarding rules.
-h --help => Print out command line usage.
Выгрузка вашей программы XDP/BPF на сетевой адаптер вашей системы обеспечивает максимально быструю обработку пакетов, которую вы можете достичь, благодаря обработке/пересылке пакетов сетевым адаптером с помощью своего оборудования. Однако не так много производителей сетевых карт поддерживают эту функцию , и вы ограничены объемом памяти/обработкой сетевой карты (например, размеры вашей карты BPF будут чрезвычайно ограничены). Кроме того, обычно существуют более строгие ограничения верификатора BPF для выгруженных программ BPF, но вы можете попробовать обратиться к производителю сетевой карты и узнать, предоставят ли они вам специальную версию своего драйвера сетевой карты, повышающую эти ограничения (это то, что я сделал с одним производителем). Я использовал).
На данный момент мне неизвестен ни один производитель сетевых карт, который сможет полностью переложить этот инструмент на сетевой адаптер из-за его сложности BPF и требований к контуру. Честно говоря, в нынешнюю эпоху сетевых технологий я считаю, что лучше оставить разгруженные программы поиску по карте BPF и минимальной проверке пакетов. Например, простой поиск карты маршрутов уровня 2 BPF и последующая передача пакетов обратно из сетевого адаптера. Однако XDP все еще очень нов, и я предполагаю, что в ближайшие годы мы увидим ослабление или отмену этих ограничений. Именно поэтому я добавил в эту программу поддержку режима разгрузки.
Исполняемый файл xdpfwd-add
, который добавляется в $PATH
через /usr/bin
при установке, принимает следующие аргументы.
-b --baddr => The address to bind/look for.
-B --bport => The port to bind/look for.
-d --daddr => The destination address.
-D --dport => The destination port.
-p --protocol => The protocol (either "tcp", "udp", "icmp", or unset for all).
-a --save => Save rule to config file.
Это добавит правило пересылки во время работы программы XDP.
Исполняемый файл xdpfwd-del
, который добавляется в $PATH
через /usr/bin
при установке, принимает следующие аргументы.
-b --baddr => The address to bind/look for.
-B --bport => The port to bind/look for.
-p --protocol => The protocol (either "tcp", "udp", "icmp", or unset for all).
-a --save => Remove rule from config file.
Это приведет к удалению правила переадресации во время работы программы XDP.
Файл конфигурации по умолчанию находится в /etc/xdpfwd/xdpfwd.conf
и использует синтаксис libconfig
. Вот пример конфигурации, использующей все ее текущие функции.
interface = "ens18"; // The interface the XDP program attaches to.
// Forwarding rules array.
forwarding = (
{
bind = "10.50.0.3", // The bind address which incoming packets must match.
bindport = 80, // The bind port which incoming packets must match.
protocol = "tcp", // The protocol (as of right now "udp", "tcp", and "icmp" are supported). Right now, you must specify a protocol. However, in the future I will be implementing functionality so you don't have to and it'll do full layer-3 forwarding.
dest = "10.50.0.4", // The address we're forwarding to.
destport = 8080 // The port we're forwarding to (if not set, will use the bind port).
},
...
);
Предполагая, что вы загрузили все необходимые пакеты, сборка этого проекта должна быть простой. Вы можете использовать следующие команды оболочки и Bash!
# Clone respository and its sub-modules such as LibBPF.
git clone --recursive https://github.com/gamemann/XDP-Forwarding
# Change directory.
cd XDP-Forwarding
# Make project using all cores.
make -j $( nproc )
# Install binaries to PATH as root so you may use 'xdpfwd', 'xdpfwd-add', 'xdpfwd-del'.
sudo make install