
DHCP-Option-Injektor
Haben Sie jemals DHCP-Anfragen abfangen und ein paar zusätzliche DHCP-Optionen einschleusen wollen, ohne dass der Absender etwas davon merkt? Wahrscheinlich nicht. Sollte dieser Bedarf jedoch jemals aufkommen, wird dhcpoptinj Ihnen (hoffentlich) helfen.
Es kann viele Gründe geben, DHCP-Anfragen zu manipulieren, auch wenn die Wahrscheinlichkeit hoch ist, dass Sie eine viel bessere Methode zur Lösung Ihres Problems suchen sollten. Vielleicht haben Sie keinen Zugriff auf den DHCP-Server/die DHCP-Clients und müssen deren DHCP-Optionen ändern, vielleicht ist die DHCP-Software schwer zu konfigurieren (oder unterstützt nicht, was Sie tun möchten), vielleicht haben Sie eine sehr komplexe und/oder ungewöhnliche Einrichtung, oder vielleicht möchten Sie einfach nur exotische oder fehlerhafte Optionen ausprobieren. Es besteht eine geringe Chance, dass dhcpoptinj tatsächlich nützlich sein könnte.
dhcpoptinj wartet darauf, dass Pakete in einer Netfilter-Warteschlange ankommen. Es stellt sicher, dass ein Paket tatsächlich ein BOOTP/DHCP-Paket ist, und injiziert dann gegebenenfalls Optionen. Es berechnet die IPv4-Header-Prüfsumme neu, deaktiviert die UDP-Prüfsumme (für eine einfachere Implementierung) und gibt das Paket dann an Netfilter zurück.
Sie benötigen eine iptables-Regel, um Pakete abzufangen und an dhcpoptinj zu senden. Nehmen wir an, Sie haben zwei Schnittstellen, eth0 und eth1, die in einer Brücke verbunden sind. Angenommen, Sie möchten alle von eth0 kommenden BOOTP-Anfragen abfangen und die Relay-Agent-Information-Option (82/0x52) injizieren. Lassen Sie uns eine sinnlose Nutzlast erfinden: Eine Agent-Circuit-ID-Suboption mit dem Wert "Fjas".
Fügen Sie eine Regel zur iptables-Mangle-Tabelle hinzu: sudo iptables -t mangle -A PREROUTING -m physdev --physdev-in eth0 -p udp --dport 67 -j NFQUEUE --queue-num 42.
Führen Sie dann dhcpoptinj aus (lassen Sie es im Vordergrund mit zusätzlicher Debug-Ausgabe laufen): sudo dhcpoptinj -d -f -q 42 -o'52 01 04 46 6A 61 73'. Beachten Sie, dass dhcpoptinj von einem Benutzer mit der CAP_NET_ADMIN-Fähigkeit ausgeführt werden muss. Sie müssen dhcpoptinj nicht als root ausführen, und Sie sollten es auch nicht. Stattdessen können Sie dem Binärprogramm beispielsweise die CAP_NET_ADMIN-Fähigkeit gewähren (mit setcap) und die Ausführungsrechte auf einen bestimmten Benutzer oder eine bestimmte Gruppe beschränken. Dies ist eine Methode, die auch zum Ausführen von Wireshark als Nicht-Root verwendet wird. Sie werden also mehrere Anleitungen finden, die Ihnen dabei helfen.
Senden Sie nun ein DHCP-Paket an die Schnittstelle eth0 und beobachten Sie es (mit einem Tool wie Wireshark), wie es am gebrückten Interface modifiziert ankommt. Es sollte die injizierte Option am Ende der Optionsliste haben. Wenn Sie das eingehende DHCP-Paket mit Wireshark erfassen, wird es unverändert erscheinen, obwohl es tatsächlich manipuliert wurde.
Beachten Sie das Format des Arguments für die Option -o: Es sollte ein hexadezimaler String sein, der mit dem DHCP-Optionscode gefolgt von der Optionsnutzlast beginnt. Die Optionslänge (das Byte, das normalerweise dem Optionscode folgt) wird automatisch berechnet und darf nicht angegeben werden. Der Hex-String kann zur Lesbarkeit durch nicht-hexadezimale Zeichen getrennt werden. Alle Optionen müssen eine Nutzlast haben, außer der speziellen Pad-Option (Code 0).
Das Layout der unsinnigen Option, die in diesem Beispiel verwendet wird (zuerst das DHCP-Optionslayout, dann das spezifische Suboptionslayout der Relay-Agent-Information-Option), ist wie folgt:
| Code | Länge | Daten |
|---|---|---|
| 52 | (auto) | 01 04 46 6A 61 73 ("Fjas") |
| Sub-Opt. | Länge | Daten |
|---|---|---|
| 01 | 4 | 46 6A 61 73 ("Fjas") |
Beachten Sie, dass dhcpoptinj sich nicht darum kümmert, was Sie in die Optionsnutzlasten schreiben, und auch nicht prüft, ob Ihr Optionscode existiert. Es verbietet Ihnen jedoch, den Optionscode 255 (die abschließende Ende-Option) zu verwenden. dhcpoptinj fügt diese Option automatisch als letzte ein.
dhcpoptinj -f -d -q42 -r -o'0C 66 6A 61 73 65 68 6F 73 74' -o'52 01 04 46 6A 61 73' -o 320A141E28
3 DHCP option(s) to inject (with a total of 25 bytes): 12 (0x0C) (Hostname), 82 (0x52) (Relay Agent Information), 50 (0x32) (Address Request)
Existing options will be removed
Initialising netfilter queue
Initialising signal handler
Initialisation completed. Waiting for packets to mangle on queue 42
Received 416 bytes
Inspecting 328-byte DHCP packet from B6:40:FE:41:30:DC to 255.255.255.255:67
Mangling packet
Found option 53 (0x35) (DHCP message type) DHCPREQUEST (copying)
Found option 54 (0x36) (DHCP Server Id) with 4-byte payload 0A 14 1E 01 (copying)
Found option 50 (0x32) (Address Request) with 4-byte payload 0A 14 1E 28 (removing)
Found option 12 (0x0C) (Hostname) with 12-byte payload 33 31 36 64 65 39 31 34 64 61 62 34 (removing)
Found option 55 (0x37) (Parameter List) with 13-byte payload 01 1C 02 03 0F 06 77 0C 2C 2F 1A 79 2A (copying)
Found END option (removing)
Injecting option 12 (0x0C) (Hostname) with 9-byte payload 66 6A 61 73 65 68 6F 73 74
Injecting option 82 (0x52) (Relay Agent Information) with 6-byte payload 01 04 46 6A 61 73
Injecting option 50 (0x32) (Address Request) with 4-byte payload 0A 14 1E 28
Inserting END option
Padding with 10 byte(s) to meet minimal BOOTP payload size
Sending mangled packet
dhcpoptinj ist in Debian/Ubuntu verfügbar. Das Deb-Paket wird unter salsa versioniert. Die Installation von dhcpoptinj aus dem Deb-Paket wird gegenüber der folgenden manuellen Installationsprozedur empfohlen, da es auch eine Manpage, Bash-Vervollständigungsregeln, Beispieldateien usw. enthält.
Sie benötigen cmake und libnetfilter_queue (sowie einen C-Compiler, der C99 unterstützt). Hoffentlich verwenden Sie ein Debian-ähnliches System, in diesem Fall können Sie Folgendes ausführen, um sie zu installieren: sudo apt-get install cmake libnetfilter-queue-dev.
git clone git://github.com/misje/dhcpoptinjcd dhcpoptinjmkdir build && cd buildcmake .. (oder cmake -DCMAKE_BUILD_TYPE=Debug .., wenn Sie einen Debug-Build wünschen)make -j4sudo make installsudo make uninstall aus Ihrem Build-Verzeichnis ausDas Build-Verzeichnis mit seinem gesamten Inhalt kann sicher entfernt werden. Wenn Sie kein Build-Verzeichnis verwendet haben, können Sie den ganzen cmake-Müll mit git clean -dfx entfernen. Beachten Sie, dass dies alles im Projektverzeichnis entfernt, was nicht unter Versionskontrolle steht.
dhcptopinj versucht, /etc/dhcpoptinj.conf oder die mit -c/--conf-file übergebene Datei zu parsen. Die Syntax der Konfigurationsdatei ist:
Leerzeichen sind optional. Alles nach und einschließlich des Zeichens # gilt als Kommentar. DHCP-Optionen werden einzeln als option=01:02:03 aufgelistet. Anführungszeichen um den Options-Hex-String sind optional, und die Bytes können durch eine beliebige Anzahl nicht-hexadezimaler Zeichen getrennt sein.
Die Optionen version, help und conf-file werden in einer Konfigurationsdatei nicht akzeptiert.
Beispiel:
# Im Vordergrund ausführen:
foreground
# Debug-Ausgabe aktivieren:
debug
# Hostname auf "fjasehost" setzen:
option = '0C 66 6A 61 73 65 68 6F 73 74'
# Agent-ID "Fjas" senden:
option = "52:01:04:46:6A:61:73"
# Adressanfrage überschreiben, um 10.20.30.40 anzufordern:
option=320A141E28
# Warteschlange 12 verwenden:
queue = 12
remove-existing-opt # Vorhandene Optionen vor dem Einfügen entfernen
Diese Readme sollte Ihnen den Einstieg erleichtern. Schauen Sie sich auch die Manpage (im Deb-Paket) und die Hilfeausgabe (dhcpoptinj -h) an, die alles abdecken sollte, was das Dienstprogramm zu bieten hat.
Für Fehler und Vorschläge erstellen Sie bitte ein Issue.
dhcpoptinj ist einfach und wird es hoffentlich auch bleiben. Dennoch fehlen folgende Funktionen, die hoffentlich eines Tages hinzugefügt werden:
Failed to bind queue handler to AF_INET: Operation not permitted
Höchstwahrscheinlich haben Sie nicht die CAP_NET_ADMIN-Fähigkeit oder es gibt einen anderen Prozess (vielleicht eine weitere dhcpoptinj-Instanz?), der an dieselbe Netfilter-Warteschlangennummer gebunden ist.
Speicherleck bei nicht normalem Beenden.
Dies wird nicht als Leck betrachtet. Es sollte jedoch kein Speicherleck bei normalem Beenden (Abfangen von SIGTERM, SIGINT oder SIGHUP) geben.
Beim Erstellen von iptables-Regeln für die Verwendung mit dhcpoptinj können die folgenden Optionen nützlich sein:
--queue-bypass
Pakete nicht verwerfen, sondern durchlassen, wenn dhcpoptinj nicht läuft (oder nicht auf der richtigen Warteschlangennummer hört).
Wenn Sie Vorschläge haben, hinterlassen Sie bitte ein Issue, und ich werde mich bei Ihnen melden. Sie sind herzlich eingeladen, beizutragen, und Pull-Requests werden sehr geschätzt.
Wenn Sie dhcpoptinj nützlich finden, würde ich gerne hören, wofür Sie es verwenden. Aktualisieren Sie die Wiki-Seite und beschreiben Sie Ihre Anwendung.
Ich habe mich für die GPL für dieses Projekt entschieden. Wenn Ihnen das nicht zusagt, kontaktieren Sie mich, und wir können eine andere Lizenz vereinbaren.