
Injecteur d'options DHCP
Avez-vous déjà voulu intercepter des requêtes DHCP et y insérer quelques options DHCP supplémentaires, à l'insu de l'expéditeur ? Probablement pas. Cependant, si le besoin se présentait, dhcpoptinj vous aidera (espérons-le).
Il peut y avoir de nombreuses raisons de modifier des requêtes DHCP, même s'il est probable que vous deviez chercher une méthode bien meilleure pour résoudre votre problème. Peut-être n'avez-vous pas accès au serveur/aux clients DHCP et devez-vous modifier leurs options DHCP, peut-être le logiciel DHCP est-il difficile à configurer (ou ne prend-il pas en charge ce que vous voulez faire), peut-être avez-vous une configuration très complexe et/ou particulière, ou peut-être voulez-vous simplement expérimenter l'envoi d'options exotiques ou malformées ? Il y a une petite chance que dhcoptinj puisse réellement être utile.
dhcpoptinj attend que des paquets arrivent dans une file d'attente netfilter. Il vérifie que le paquet est bien un paquet BOOTP/DHCP, et si c'est le cas, il procède à l'injection d'options. Il recalcule la somme de contrôle de l'en-tête IPv4, désactive la somme de contrôle UDP (pour une implémentation plus simple) puis rend le paquet à netfilter.
Vous avez besoin d'une règle iptables pour intercepter les paquets et les envoyer à dhcpoptinj. Supposons que vous ayez deux interfaces reliées par un pont, eth0 et eth1. Supposons que vous souhaitiez intercepter toutes les requêtes BOOTP provenant de eth0 et injecter l'option d'informations de l'agent relais (82/0x52). Inventons une charge utile idiote : une sous-option d'ID de circuit d'agent avec la valeur "Fjas".
Ajoutez une règle à la table mangle d'iptables :sudo iptables -t mangle -A PREROUTING -m physdev --physdev-in eth0 -p udp --dport 67 -j NFQUEUE --queue-num 42.
Exécutez ensuite dhcpoptinj (exécutons-le en premier plan avec une sortie de débogage supplémentaire) : sudo dhcpoptinj -d -f -q 42 -o'52 01 04 46 6A 61 73'. Notez que dhcpoptinj doit être exécuté par un utilisateur disposant de la capacité CAP_NET_ADMIN. Vous n'avez pas besoin d'exécuter dhcpoptinj en tant que root, et vous ne devriez vraiment pas le faire. Au lieu de cela, vous pouvez par exemple accorder la capacité CAP_NET_ADMIN au binaire (en utilisant setcap) et limiter les droits d'exécution à un utilisateur ou groupe spécifique. C'est une méthode utilisée pour exécuter wireshark sans être root, vous trouverez donc plusieurs guides pour vous aider à y parvenir.
Envoyez maintenant un paquet DHCP à l'interface eth0 et observez-le (à l'aide d'un outil comme wireshark) après avoir été modifié lorsqu'il atteint l'interface pontée. Il devrait avoir l'option injectée à la fin de la liste des options. Si vous capturez le paquet DHCP entrant avec Wireshark, il apparaîtra non modifié bien qu'il soit en réalité modifié.
Notez le format de l'argument de l'option -o : il doit s'agir d'une chaîne hexadécimale commençant par le code de l'option DHCP suivie de la charge utile de l'option. La longueur de l'option (l'octet qui suit normalement le code de l'option) est calculée automatiquement et ne doit pas être spécifiée. La chaîne hexadécimale peut être délimitée par des caractères non hexadécimaux pour plus de lisibilité. Toutes les options doivent avoir une charge utile, à l'exception de l'option de bourrage spéciale (code 0).
La disposition de l'option absurde utilisée dans cet exemple (d'abord la disposition des options DHCP, puis la disposition de la sous-option d'informations de l'agent relais) est la suivante :
| Code | Longueur | Données |
|---|---|---|
| 52 | (auto) | 01 04 46 6A 61 73 ("Fjas") |
| Sous-opt. | Longueur | Données |
|---|---|---|
| 01 | 4 | 46 6A 61 73 ("Fjas") |
Notez que dhcpoptinj ne se soucie pas de ce que vous écrivez dans les charges utiles des options, ni ne vérifie si votre code d'option existe. Il vous interdit cependant d'utiliser le code d'option 255 (l'option de fin de terminaison). dhcpoptinj insère cette option comme dernière option automatiquement.
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 est dans Debian/Ubuntu. Le paquet deb est sous contrôle de version sur salsa. L'installation de dhcpoptinj à partir du paquet deb est recommandée par rapport à la procédure d'installation manuelle suivante, car elle inclut également une page de manuel, des règles de complétion bash, des fichiers d'exemple, etc.
Vous avez besoin de cmake et de libnetfilter_queue (ainsi que d'un compilateur C supportant C99). Espérons que vous utilisez un système de type Debian, auquel cas vous pouvez exécuter la commande suivante pour les installer : sudo apt-get install cmake libnetfilter-queue-dev.
git clone git://github.com/misje/dhcpoptinjcd dhcpoptinjmkdir build && cd buildcmake .. (ou cmake -DCMAKE_BUILD_TYPE=Debug .. si vous voulez une compilation de débogage)make -j4sudo make installsudo make uninstall depuis votre répertoire de constructionLe répertoire de construction avec tout son contenu peut être supprimé en toute sécurité. Si vous n'avez pas utilisé de répertoire de construction, vous pouvez vous débarrasser de tous les déchets de cmake en exécutant git clean -dfx. Notez cependant que cela supprime tout dans le répertoire du projet qui n'est pas sous contrôle de version.
dhcptopinj tentera d'analyser /etc/dhcpoptinj.conf ou le fichier passé avec -c/--conf-file. La syntaxe du fichier de configuration est :
Les espaces sont optionnels. Tout ce qui suit et inclut le caractère # est considéré comme un commentaire. Les options DHCP sont listées une par une sous la forme option=01:02:03. Les guillemets autour de la chaîne hexadécimale de l'option sont optionnels, et les octets peuvent être séparés par n'importe quel nombre de caractères non hexadécimaux.
Les options version, help et conf-file ne sont pas acceptées dans un fichier de configuration.
Exemple :
# Run in foreground:
foreground
# Enable debug output:
debug
# Override hostname to "fjasehost":
option = '0C 66 6A 61 73 65 68 6F 73 74'
# Send agent ID "Fjas":
option = "52:01:04:46:6A:61:73"
# Override address request to ask for 10.20.30.40:
option=320A141E28
# Use queue 12:
queue = 12
remove-existing-opt # Remove options before inserting
Ce README devrait vous avoir permis de démarrer. Consultez également la page de manuel (dans le paquet deb) et la sortie d'aide (dhcpoptinj -h), qui devrait couvrir tout ce que l'utilitaire a à offrir.
Pour les bogues et suggestions, veuillez créer un problème (issue).
dhcpoptinj est simple et, espérons-le, le restera. Néanmoins, voici les fonctionnalités manquantes qui, espérons-le, seront ajoutées un jour :
Failed to bind queue handler to AF_INET: Operation not permitted
Il est très probable que vous n'ayez pas la capacité CAP_NET_ADMIN ou qu'un autre processus (peut-être une autre instance de dhcpoptinj ?) soit lié au même numéro de file d'attente netfilter.
Fuite de mémoire en cas de sortie non normale.
Ce n'est pas considéré comme une fuite. Cependant, il ne devrait y avoir aucune fuite de mémoire lors d'une sortie normale (capture de SIGTERM, SIGINT ou SIGHUP).
Lors de la création de règles iptables à utiliser avec dhcpoptinj, les options suivantes peuvent être utiles :
--queue-bypass
Ne pas abandonner les paquets, mais les laisser passer si dhcpoptinj n'est pas en cours d'exécution (ou n'écoute pas sur le bon numéro de file d'attente).
Si vous avez des suggestions, veuillez laisser un problème (issue) et je vous répondrai. Vous êtes les bienvenus pour contribuer et les pull requests sont très appréciées.
Si vous trouvez dhcpoptinj utile, j'aimerais savoir à quoi vous l'utilisez. Mettez à jour la page wiki et décrivez votre utilisation.
J'ai choisi d'utiliser GPL pour ce projet. Si cela ne vous convient pas, contactez-moi et nous pourrons convenir d'une licence différente.