Ein Programm, das über (e)BPF eine Verbindung zum XDP-Hook des Linux-Kernels herstellt, um eine schnelle Paketverarbeitung zu ermöglichen und eine grundlegende Schicht-3/4-Weiterleitung durchführt. Dieses Programm führt eine Quellportzuordnung ähnlich wie IPTables und NFTables für die Verarbeitung von Verbindungen durch. Bestehende Verbindungen werden basierend auf den Paketen der Verbindung pro Nanosekunde priorisiert. Das bedeutet, dass bei Porterschöpfung die Verbindungen mit den wenigsten Paketen pro Nanosekunde ersetzt werden. Ich glaube, das ist das Beste, da Verbindungen mit höheren Paketen pro Nanosekunde empfindlicher sind.
Wenn die Netzwerkkonfiguration oder Netzwerkschnittstellenkarte (NIC) des Hosts den XDP-DRV-Hook (auch bekannt als nativ; tritt vor der SKB-Erstellung auf) nicht unterstützt, versucht das Programm außerdem, eine Verbindung zum XDP-SKB-Hook (auch bekannt als generisch; tritt nach SKB auf) herzustellen Erstellung, bei der IPTables und NFTables über das netfilter
Kernelmodul verarbeitet werden). Sie können Überschreibungen über die Befehlszeile verwenden, um SKB- oder Offload-Modi zu erzwingen.
Vor diesem Hintergrund können die folgenden Gründe dafür vorliegen, dass die Netzwerkkonfiguration eines Hosts den DRV-Hook von XDP nicht unterstützt.
Ich hoffe, dass dieses Projekt bestehenden Netzwerkingenieuren/Programmierern hilft, die an der Nutzung von XDP interessiert sind, oder allen, die daran interessiert sind, in diese Bereiche einzusteigen! Hochleistungsfähige Router/Paketweiterleitung und (D)DoS-Abwehr/Prävention sind so wichtige Bestandteile der Cybersicherheit, und das Verständnis des Netzwerk- und Paketflusskonzepts auf einem niedrigen bis mittleren Niveau würde sicherlich denjenigen helfen, die eine Karriere in diesem Bereich anstreben?
ACHTUNG : An diesem Projekt müssen noch viele Dinge erledigt werden, und derzeit unterstützt es nur IPv4. IPv6-Unterstützung wird vor der offiziellen Veröffentlichung hinzugefügt. Derzeit kann das Programm Fehler enthalten und Weiterleitungsfunktionen sind noch nicht verfügbar.
Der standardmäßige maximale Quellport, der pro Bindungsadresse verwendet werden kann, beträgt 21 und wird hier festgelegt (Sie können diese bei Bedarf anpassen). Wir verwenden standardmäßig den Portbereich 500–520 , dies kann jedoch konfiguriert werden.
Zuerst habe ich versucht, die meisten verfügbaren Ports (1 - 65534) zu verwenden. Aufgrund der Einschränkungen des BPF-Verifizierers musste ich jedoch einige Konstanten im Linux-Kernel erhöhen und den Kernel neu kompilieren. Ich habe dafür Patches erstellt und habe alles hier dokumentiert. Ich kann das Programm mit maximal 65534 Ports pro Bindungsadresse ohne Probleme mit dem benutzerdefinierten Kernel ausführen, den ich mit den von mir erstellten Patches erstellt habe. Bedenken Sie jedoch: Je mehr Quellports verfügbar sind, desto mehr Verarbeitung muss das XDP-Programm durchführen, wenn es nach verfügbaren Ports sucht.
Wenn Sie planen, dies für die Produktion zu verwenden, würde ich Ihnen dringend empfehlen, Ihren eigenen Kernel mit den oben genannten Konstanten zu kompilieren. 21 maximale Quellports pro Bindungsadresse sind nicht viel, aber leider erlauben uns die standardmäßigen BPF-Verifizierungseinschränkungen derzeit nicht, weiter zu gehen.
Der Hauptcode, der diese Einschränkungen verursacht, befindet sich hier und tritt auf, wenn wir versuchen, den besten Quellport für eine neue Verbindung zu finden. Es gibt wirklich keine andere Möglichkeit, mit der Flexibilität, die wir haben, nach dem besten verfügbaren Quellport zu suchen, da wir meines Wissens nach alle Quellports durchlaufen und den Paket-pro-Nanosekunden-Wert überprüfen müssen (BPF-Maps-Suche nach Schlüssel).
Sie benötigen make
, clang
, libelf
und llvm
, da wir diese Pakete zum Erstellen des Projekts verwenden. Darüber hinaus benötigen Sie auch libconfig
( libconfig-dev
ist das Paket auf Ubuntu/Debian-Systemen) zum Parsen der Konfigurationsdatei.
Für Ubuntu/Debian sollte Folgendes funktionieren.
apt install build-essential make clang libelf-dev llvm libconfig-dev
Ich gehe davon aus, dass die Paketnamen in anderen Linux-Distributionen ähnlich sind.
Um xdpfwd-add
und xdpfwd-del
verwenden zu können, müssen Sie das BPF-Dateisystem mounten, da das XDP-Programm die BPF-Zuordnungen an /sys/fs/bpf/xdpfwd
anheftet. Es besteht eine hohe Wahrscheinlichkeit, dass dies bereits über iproute2
oder etwas Ähnliches für Sie erledigt wurde. Ist dies jedoch nicht der Fall, können Sie den folgenden Befehl verwenden.
mount -t bpf bpf /sys/fs/bpf/
Die grundlegende Verwendung der Befehlszeile umfasst Folgendes.
-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.
Das Auslagern Ihres XDP/BPF-Programms auf die Netzwerkkarte Ihres Systems ermöglicht die schnellste Paketverarbeitung, die Sie erreichen können, da die Netzwerkkarte die Pakete mit ihrer Hardware verarbeitet/weiterleitet. Es gibt jedoch nicht viele NIC-Hersteller, die diese Funktion unterstützen , und Sie sind auf den Speicher/die Verarbeitung der NIC beschränkt (z. B. sind Ihre BPF-Kartengrößen extrem begrenzt). Darüber hinaus gelten in der Regel strengere BPF-Verifizierungsbeschränkungen für ausgelagerte BPF-Programme. Sie können jedoch versuchen, sich an den Hersteller der Netzwerkkarte zu wenden, um zu erfahren, ob er Ihnen eine spezielle Version seines Netzwerkkartentreibers zur Verfügung stellt, die diese Einschränkungen erhöht (das habe ich bei einem Hersteller gemacht). Ich habe verwendet).
Zum jetzigen Zeitpunkt ist mir kein NIC-Hersteller bekannt, der dieses Tool aufgrund seiner BPF-Komplexität und Schleifenanforderungen vollständig auf die NIC auslagern könnte. Ehrlich gesagt glaube ich, dass es im aktuellen Netzwerkzeitalter am besten ist, ausgelagerte Programme der Suche nach BPF-Karten und einer minimalen Paketprüfung zu überlassen. Zum Beispiel eine einfache BPF-Layer-2-Routentabellenzuordnungssuche und anschließendes Senden der Pakete zurück aus der Netzwerkkarte. Allerdings ist XDP noch sehr neu und ich kann mir vorstellen, dass diese Einschränkungen in den nächsten Jahren gelockert oder aufgehoben werden. Aus diesem Grund habe ich diesem Programm Unterstützung für den Offload-Modus hinzugefügt.
Die ausführbare Datei xdpfwd-add
die bei der Installation über /usr/bin
zum $PATH
hinzugefügt wird, akzeptiert die folgenden Argumente.
-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.
Dadurch wird eine Weiterleitungsregel hinzugefügt, während das XDP-Programm ausgeführt wird.
Die ausführbare Datei xdpfwd-del
, die bei der Installation über /usr/bin
zum $PATH
hinzugefügt wird, akzeptiert die folgenden Argumente.
-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.
Dadurch wird eine Weiterleitungsregel gelöscht, während das XDP-Programm ausgeführt wird.
Die Standardkonfigurationsdatei befindet sich unter /etc/xdpfwd/xdpfwd.conf
und verwendet die libconfig
Syntax. Hier ist eine Beispielkonfiguration mit allen aktuellen Funktionen.
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).
},
...
);
Vorausgesetzt, Sie haben alle erforderlichen Pakete heruntergeladen, sollte die Erstellung dieses Projekts unkompliziert sein. Sie können die folgenden Shell- und Bash-Befehle verwenden!
# 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