
Tunnélisez des données IPv4 à travers des serveurs DNS pour contourner les restrictions de pare-feu et fournir un accès réseau furtif pour les tests d'intrusion.
Ceci est un logiciel qui permet de tunnelliser des données IPv4 à travers un serveur DNS. Cela peut être utile dans différentes situations où l'accès à Internet est filtré par un pare-feu, mais où les requêtes DNS sont autorisées.
Iodine n'a pas de script configure. Il y a deux fonctionnalités optionnelles pour
Linux (le support SELinux et systemd) qui seront activées automatiquement si les
fichiers d'en-tête correspondants sont trouvés dans /usr/include.
(Voir le script dans ./src/osflags)
Exécutez make pour compiler les binaires du serveur et du client.
Exécutez make install pour copier les binaires et la page de manuel dans le
répertoire de destination.
Exécutez make test pour compiler et exécuter les tests unitaires. (Nécessite la
bibliothèque check)
Essayez-le sur votre propre LAN ! Suivez ces étapes simples :
./iodined -f 10.0.0.1 test.com.
Si vous utilisez déjà le réseau 10.0.0.0, utilisez un autre réseau interne
comme 172.16.0.0../iodine -f -r 192.168.0.1 test.com.
Remplacez 192.168.0.1 par l'adresse IP de votre serveur.10.0.0.2 et le serveur a 10.0.0.1.Note : le serveur et le client doivent parler exactement le même protocole. Dans la plupart des cas, cela signifie exécuter la même version d'iodine. Malheureusement, implémenter une compatibilité de protocole ascendante et descendante n'est généralement pas réalisable.
Pour utiliser ce tunnel, vous devez contrôler un vrai domaine (comme
mydomain.com), et disposer d'un serveur avec une adresse IP publique pour y
exécuter iodined. Si ce serveur exécute déjà un programme DNS, modifiez son
port d'écoute puis utilisez l'option -b d'iodined pour laisser iodined
transmettre les requêtes DNS. (Notez que cette procédure n'est pas conseillée en
environnement de production, car la transmission DNS d'iodined n'est pas
complètement transparente, par exemple les transferts de zone ne fonctionneront
pas.) Vous pouvez également transmettre le sous-domaine depuis votre serveur DNS
vers iodined, qui doit alors s'exécuter sur un port différent (-p).
Ensuite, déléguez un sous-domaine (par exemple, t1.mydomain.com) au serveur
iodined. Si vous utilisez BIND pour votre domaine, ajoutez deux lignes comme
celles-ci au fichier de zone :
t1 IN NS t1ns.mydomain.com. ; note the dot!
t1ns IN A 10.15.213.99
La ligne NS est tout ce qu'il faut pour router les requêtes pour le
sous-domaine t1 vers le serveur t1ns. Nous utilisons un nom court pour le
sous-domaine, afin de laisser le plus d'espace possible pour le trafic de
données. À la fin de la ligne NS se trouve le nom de votre serveur iodined.
Ce nom peut être n'importe quel nom pointant n'importe où, mais dans ce cas, il
est facilement conservé dans le même fichier de zone. Ce doit être un nom (pas
une adresse IP), et ce nom doit lui-même avoir un enregistrement A (pas un
CNAME).
Si votre serveur iodined a une IP dynamique, utilisez un fournisseur DNS
dynamique. Pointez simplement la ligne NS vers lui et laissez de côté la ligne
A :
t1 IN NS myname.mydyndnsprovider.com. ; note the dot!
Rechargez ou redémarrez ensuite votre programme de serveur de noms. Désormais,
toute requête DNS pour les domaines se terminant par t1.mydomain.com sera
envoyée à votre serveur iodined.
Enfin, démarrez iodined sur votre serveur. Le premier argument est l'adresse
IP à l'intérieur du tunnel, qui peut provenir de n'importe quelle plage que
vous n'utilisez pas encore (par exemple 192.168.99.1), et le second argument
est le domaine assigné (dans ce cas t1.mydomain.com). Utiliser l'option -f
maintient iodined au premier plan, ce qui est utile pour les tests. iodined
ouvrira une interface virtuelle (« tun device »), et commencera également à
écouter les requêtes DNS sur le port UDP 53. Saisissez un mot de passe soit en
ligne de commande (-P pass), soit après le démarrage du serveur. Tout est
maintenant prêt pour le client.
S'il y a un risque que vous utilisiez un tunnel iodine depuis des
environnements inattendus, démarrez iodined avec l'option -c.
Ligne de commande résultante dans cet exemple :
./iodined -f -c -P secretpassword 192.168.99.1 t1.mydomain.com
Toute la configuration est terminée, il suffit de lancer iodine. Il accepte
un ou deux arguments : le premier est le serveur DNS relais local (optionnel)
et le second est le domaine que vous avez utilisé (t1.mydomain.com). Si vous
ne spécifiez pas le premier argument, le réglage DNS actuel du système sera
consulté.
Si les requêtes DNS sont autorisées vers n'importe quel ordinateur, vous pouvez
directement donner l'adresse du serveur iodined comme premier argument (dans
l'exemple : t1ns.mydomain.com ou 10.15.213.99). Dans ce cas, il peut aussi
arriver que tout le trafic soit autorisé vers le port DNS (53 UDP) de
n'importe quel ordinateur. Iodine le détectera et passera en tunnel UDP brut si
possible. Pour forcer le tunnel DNS dans tous les cas, utilisez l'option -r
(particulièrement utile lors de tests sur votre propre réseau).
L'interface tunnel du client obtiendra une IP proche de celle du serveur (dans
ce cas 192.168.99.2 ou .3, etc.) et un MTU approprié. Saisissez le même mot
de passe que sur le serveur, soit en option de ligne de commande, soit après le
démarrage du client. Utiliser l'option -f maintient le client iodine au
premier plan.
Ligne de commande résultante dans cet exemple ; l'ajout de -r force le tunnel DNS même si le tunnel UDP brut serait possible :
./iodine -f -P secretpassword t1.mydomain.com
Depuis chaque côté, vous devriez maintenant pouvoir pinguer l'adresse IP à
l'autre extrémité du tunnel. Dans ce cas, ping 192.168.99.1 depuis le client
iodine, et 192.168.99.2 depuis le serveur iodine.
Les données à l'intérieur du tunnel sont uniquement en IPv4.
Par défaut, le serveur écoute à la fois en IPv4 et en IPv6 pour les requêtes
entrantes. Utilisez les options -4 ou -6 pour n'écouter que sur un seul
protocole. Le mode brut sera tenté sur le même protocole que celui utilisé pour
la connexion.
Le client peut utiliser des serveurs de noms IPv4 ou IPv6 pour se connecter à
iodined. Les serveurs de noms relais traduiront automatiquement entre les
protocoles si nécessaire. Utilisez les options -4 ou -6 pour forcer le
client à utiliser une version IP spécifique pour ses requêtes DNS.
Si votre serveur écoute en IPv6 et est accessible, ajoutez un enregistrement AAAA pour lui dans votre configuration DNS. En étendant l'exemple ci-dessus, cela donnerait :
t1 IN NS t1ns.mydomain.com. ; note the dot!
t1ns IN A 10.15.213.99
t1ns IN AAAA 2001:db8::1001:99
Il est possible de router tout le trafic à travers le tunnel DNS. Pour ce faire, ajoutez d'abord une route hôte vers le serveur de noms utilisé par iodine via l'interface filaire/sans fil avec la passerelle par défaut comme passerelle. Remplacez ensuite la passerelle par défaut par l'adresse IP du serveur iodined à l'intérieur du tunnel DNS, et configurez le serveur pour faire du NAT.
Cependant, notez que le trafic de données tunnelisé n'est pas chiffré du tout et peut être lu et modifié relativement facilement par des tiers. Pour une sécurité maximale, faites passer un VPN à travers le tunnel DNS (= double tunnel), ou utilisez un accès par shell sécurisé (SSH), éventuellement avec redirection de port. Cette dernière option peut également être utilisée pour la navigation web, si vous exécutez un proxy web (par exemple Privoxy) sur votre serveur.
Le serveur iodined répond aux requêtes NS envoyées pour les sous-domaines
du domaine du tunnel. Si votre sous-domaine iodined est t1.mydomain.com,
envoyez une requête NS pour foo123.t1.mydomain.com pour vérifier si la
délégation fonctionne. dig est un bon outil pour cela :
% dig -t NS foo123.t1.mydomain.com
ns.io.citronna.de.
De plus, le serveur iodined répondra aux requêtes commençant par « z » pour tous les types de requêtes pris en charge, par exemple :
dig -t TXT z456.t1.mydomain.com
dig -t SRV z456.t1.mydomain.com
dig -t CNAME z456.t1.mydomain.com
La réponse devrait ressembler à un texte incompréhensible dans tous ces cas.
Sur Mac OS X 10.6 et versions ultérieures, iodine prend en charge les
périphériques utun natifs intégrés au système d'exploitation - utilisez
-d utunX.
La taille des fragments de réponse DNS est normalement détectée automatiquement
pour obtenir une bande passante maximale. Pour forcer une valeur spécifique (et
accélérer les choses), utilisez l'option -m.
Les noms d'hôte DNS sont normalement utilisés jusqu'à leur longueur maximale de
255 caractères. Certains relais DNS se sont révélés répondre de manière plutôt
peu fiable aux requêtes de pleine longueur, donnant des résultats très variables
(et le plus souvent très mauvais) pour la détection automatique de la taille des
fragments lors d'essais répétés. Dans ces cas, utilisez l'option -M pour
réduire la longueur du nom d'hôte DNS à, par exemple, 200 caractères, ce qui rend
ces relais DNS beaucoup plus stables. Cela est également utile sur certains
relais DNS « dé-optimisants » qui remplissent la réponse avec deux copies
complètes de la requête, laissant très peu de place pour les données descendantes
(et qui ne sont pas non plus capables d'EDNS0). L'option -M peut échanger une
partie de la bande passante montante contre de la bande passante descendante.
Notez que la valeur minimale de -M est d'environ 100, car le protocole ne peut
diviser les paquets (1200 octets max) qu'en 16 fragments, ce qui nécessite au
moins 75 octets de données réelles par fragment.
Les données montantes sont envoyées compressées en gzip et encodées en Base32 ;
ou en Base64 si le serveur relais prend en charge les majuscules/minuscules et
le + dans les noms de domaine ; ou en Base64u si _ est pris en charge à la
place ; ou en Base128 si les caractères à valeur d'octet élevée sont pris en
charge. Cet encodage montant est détecté automatiquement. Le protocole DNS
autorise une requête par paquet, et une requête peut faire au maximum 256
caractères. Chaque partie de nom de domaine peut faire au maximum 63 caractères.
Votre nom de domaine et votre sous-domaine doivent donc être aussi courts que
possible pour permettre un débit montant maximal.
Plusieurs types de requêtes DNS sont pris en charge, les types NULL et
PRIVATE étant censés fournir la plus grande bande passante descendante. Le
type PRIVATE utilise la valeur 65399 dans la plage à usage privé. Les autres
types disponibles sont TXT, SRV, MX, CNAME et A (renvoyant CNAME),
par ordre décroissant de bande passante. Normalement, le « meilleur » type de
requête est détecté et utilisé automatiquement. Cependant, les relais DNS
peuvent imposer des limites, par exemple sur NULL et TXT, faisant de SRV ou MX
le meilleur choix en réalité. Cela n'est pas détecté automatiquement, mais peut
être forcé avec l'option -T. Il est conseillé d'essayer diverses alternatives,
surtout lorsque le type de requête détecté automatiquement fournit une taille de
fragment descendante inférieure à 200 octets.
Notez que les requêtes SRV, MX et A (renvoyant CNAME)
peuvent/entraîneront des recherches supplémentaires par des serveurs de noms
« intelligents » à cache pour obtenir une adresse IP réelle, ce qui peut
ralentir ou échouer complètement.
Les réponses DNS pour les requêtes autres que NULL/PRIVATE peuvent être
encodées avec le même ensemble de codecs que les données montantes. Cela est
normalement aussi détecté automatiquement, mais aucun test exhaustif n'est
effectué, donc certains problèmes peuvent ne pas être remarqués lors de la
sélection de codecs plus avancés. Dans ce cas, vous verrez des échecs/corruptions
dans la détection automatique de la taille des fragments. En particulier,
plusieurs relais DNS ont été trouvés qui ne mettent les réponses renvoyant des
noms d'hôte (SRV, MX, CNAME, A) en minuscules que lorsque ce nom d'hôte
dépasse environ 180 caractères. Dans ces cas et autres similaires, utilisez
l'option -O pour essayer d'autres codecs descendants ; Base32 devrait toujours
fonctionner.
Le fonctionnement normal consiste désormais pour le serveur à ne pas répondre
à une requête DNS tant que la requête DNS suivante n'est pas arrivée, autrement
dit à être « paresseux ». De cette façon, le serveur aura toujours une requête
DNS sous la main lorsque de nouvelles données descendantes devront être
envoyées. Cela améliore considérablement les performances (interactives) et la
latence, et permet de ralentir les requêtes ping au repos à des intervalles de
4 secondes par défaut, et éventuellement bien plus. En fait, le but principal
des pings est maintenant de forcer une réponse au ping précédent et d'éviter les
dépassements de délai du serveur DNS (généralement au moins 5 à 10 secondes
selon le RFC1035). Certains serveurs DNS sont plus impatients et renverront des
erreurs SERVFAIL (dépassements de délai) pendant les périodes sans trafic de
données tunnelisé. Toutes les données devraient tout de même passer dans ces cas,
mais iodine réduira l'intervalle de ping à 1 seconde quand même (-I1) pour
réduire le nombre de messages d'erreur. Cela peut ne pas aider pour les relais
DNS très impatients comme dnsadvantage.com (ultradns), qui expirent en
1 seconde ou même moins. Cependant, les données passeront quand même, et vous
pouvez ignorer les erreurs SERVFAIL.
Si vous êtes sur un réseau local sans serveur DNS intermédiaire, essayez -I 50
(iodine et iodined ferment la connexion après 60 secondes de silence). Le seul
moment où vous remarquerez un ralentissement est lorsque des paquets de réponse
DNS se perdent ; le serveur iodined doit alors attendre un nouveau ping pour
renvoyer les données. Vous pouvez accélérer cela en générant du trafic montant
(pression de touche, ping). Si cela arrive souvent, vérifiez les goulots
d'étranglement de votre réseau et/ou utilisez -I1.
La réponse différée en mode paresseux fera que certains relais DNS commerciaux
« carrier grade » renverront à plusieurs reprises la même requête DNS au serveur
iodined. Si le relais DNS est en réalité implémenté comme un pool de serveurs
parallèles, des requêtes dupliquées peuvent même arriver de sources multiples.
Cet effet ne sera visible que dans le trafic réseau au niveau du serveur
iodined et n'affectera pas la connexion du client. Iodined remarquera ces
doublons et enverra la même réponse (lorsque son heure sera venue) à la fois à la
requête d'origine et au dernier doublon. Après cela, la réponse complète est mise
en cache pendant un court moment. Les doublons retardés qui arrivent au serveur
encore plus tard reçoivent une réponse que le client iodine ignorera (si elle y
arrive jamais).
Si vous rencontrez des problèmes, essayez d'inspecter le trafic avec des outils
de surveillance réseau comme tcpdump ou ethereal/wireshark, et assurez-vous que
le serveur DNS relais n'a pas mis la réponse en cache. Un message d'erreur en
cache pourrait signifier que vous avez démarré le client avant le serveur.
L'option -D (et -DD) sur le serveur peut également afficher les requêtes
reçues et envoyées.
Si votre port 53 est occupé sur une interface spécifique par une application qui
ne l'utilise pas, utilisez -p sur iodined pour spécifier un port alternatif
(comme -p 5353) et utilisez par exemple iptables (sur Linux) pour rediriger le
trafic :
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353
(Envoyé par Tom Schouten)
Iodined rejettera les données des clients qui n'ont pas été actifs (données/pings) depuis plus de 60 secondes. De même, iodine se terminera si aucune donnée descendante n'a été reçue pendant 60 secondes. En cas de panne réseau prolongée ou similaire, redémarrez simplement iodine (re-connexion), éventuellement plusieurs fois jusqu'à récupérer votre ancienne adresse IP. Une fois cela fait, attendez un peu et vous verrez finalement le trafic TCP tunnelisé reprendre là où il s'était arrêté avant la panne.
Avec l'introduction de la file d'attente des paquets descendants dans le serveur, son utilisation mémoire a augmenté de plusieurs mégaoctets dans la configuration par défaut. Pour une utilisation dans des environnements à faible mémoire (par exemple sur votre routeur DSL), vous pouvez diminuer USERS et désactiver OUTPACKETQ_LEN dans user.h sans conséquence néfaste, en supposant qu'au plus un client sera connecté à la fois. Une petite valeur de DNSCACHE_LEN est toujours conseillée, de préférence 2 ou plus ; vous pouvez cependant aussi la désactiver pour économiser quelques kilo-octets de plus.
Un seul serveur iodine peut gérer plusieurs domaines. Configurez différents
enregistrements NS sur le même domaine pointant tous vers le même hôte, et
utilisez un joker au début de l'argument topdomain (exemple *.mydomain.com).
iodine acceptera le trafic du tunnel pour tous les domaines correspondant à ce
modèle. Le joker doit être au début de l'argument topdomain et être suivi d'un
point.
Cette section présente quelques mesures de performances. Pour un affichage correct, utilisez une police à largeur fixe comme Courier.
Les mesures ont été effectuées avec le protocole 00000502 en mode paresseux ;
encodage montant toujours en Base128 ; iodine -M255 ; iodined -m1130. Les
conditions réseau n'étaient pas extrêmement favorables ; les résultats ne sont
pas des benchmarks mais une indication réaliste des performances réelles que
l'on peut attendre dans des situations similaires.
Le débit montant/descendant a été mesuré en copiant via scp un fichier
préalablement lu depuis /dev/urandom (c'est-à-dire incompressible), et en
mesurant la taille avec ls -l ; sleep 30 ; ls -l sur une connexion séparée non
tunnelisée. Étant donné la grande taille de bloc scp de 16 ko, cela donne une
résolution de 4,3 kbit/s, ce qui explique pourquoi certaines valeurs sont
exactement égales.
Les temps d'aller-retour du ping ont été mesurés avec ping -c100 ; sont
présentés le rtt moyen et l'écart moyen (indiquant la dispersion autour de la
moyenne), en millisecondes.
Laptop -> Wifi AP -> Home server -> DSL provider -> Datacenter iodine DNS "relay" bind9 DNS cache iodined
downstr. upstream downstr. ping-up ping-down
fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev
-----------------------------------------------------------------------------
iodine -> Wifi AP :53
-Tnull (= -Oraw) 982 43.6 131.0 28.0 4.6 26.8 3.4
iodine -> Home server :53
-Tnull (= -Oraw) 1174 48.0 305.8 26.6 5.0 26.9 8.4
iodine -> DSL provider :53
-Tnull (= -Oraw) 1174 56.7 367.0 20.6 3.1 21.2 4.4
-Ttxt -Obase32 730 56.7 174.7*
-Ttxt -Obase64 874 56.7 174.7
-Ttxt -Obase128 1018 56.7 174.7
-Ttxt -Oraw 1162 56.7 358.2
-Tsrv -Obase128 910 56.7 174.7
-Tcname -Obase32 151 56.7 43.6
-Tcname -Obase128 212 56.7 52.4
iodine -> DSL provider :53
wired (no Wifi) -Tnull 1174 74.2 585.4 20.2 5.6 19.6 3.4
[174.7* : these all have 2frag/packet]
Laptop -> Wifi+vpn / wired -> Home server iodine iodined
downstr. upstream downstr. ping-up ping-down
fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev
-----------------------------------------------------------------------------
wifi + openvpn -Tnull 1186 166.0 1022.3 6.3 1.3 6.6 1.6
wired -Tnull 1186 677.2 2464.1 1.3 0.2 1.3 0.1
Les performances sont fortement liées à de faibles temps de ping, car iodine exige une confirmation pour chaque fragment de données avant de passer au suivant. Autoriser plusieurs fragments en vol comme TCP pourrait potentiellement augmenter les performances, mais cela provoquerait probablement une surcharge sérieuse pour les serveurs DNS intermédiaires. Le protocole actuel fait évoluer les performances en fonction de la réactivité du DNS, car les serveurs DNS traitent en moyenne au plus une requête DNS par client.
iodine a été testé sur Linux (arm, ia64, x86, AMD64 et SPARC64), FreeBSD (ia64, x86), OpenBSD (x86), NetBSD (x86), MacOS X (ppc et x86, avec http://tuntaposx.sourceforge.net/) et Windows (avec le pilote OpenVPN TAP32, voir le fichier readme win32). Il devrait être facile de le porter vers d'autres systèmes de type Unix disposant d'un support de tunneling TUN/TAP. Faites-nous savoir si vous arrivez à le faire fonctionner sur d'autres plateformes.
Le nom iodine a été choisi car il commence par IOD (IP Over DNS) et parce que l'iode a le numéro atomique 53, qui se trouve être le numéro du port DNS.
Copyright (c) 2006-2014 Erik Ekman [email protected], 2006-2009 Bjorn Andersson [email protected]. Également des contributions majeures d'Anne Bezemer.
La permission d'utiliser, copier, modifier et/ou distribuer ce logiciel à des fins quelconques, avec ou sans frais, est accordée par la présente, à condition que l'avis de droit d'auteur ci-dessus et cet avis de permission apparaissent dans toutes les copies.
LE LOGICIEL EST FOURNI « EN L'ÉTAT » ET L'AUTEUR DÉCLINE TOUTE GARANTIE CONCERNANT CE LOGICIEL, Y COMPRIS TOUTES LES GARANTIES IMPLICITES DE QUALITÉ MARCHANDE ET D'ADÉQUATION. EN AUCUN CAS L'AUTEUR NE SAURAIT ÊTRE TENU RESPONSABLE DE DOMMAGES SPÉCIAUX, DIRECTS, INDIRECTS OU CONSÉCUTIFS, NI D'AUCUN DOMMAGE QUEL QU'IL SOIT RÉSULTANT D'UNE PERTE D'UTILISATION, DE DONNÉES OU DE PROFITS, QUE CE SOIT DANS LE CADRE D'UNE ACTION CONTRACTUELLE, D'UNE NÉGLIGENCE OU D'UN AUTRE DÉLIT, DÉCOULANT DE OU LIÉ À L'UTILISATION OU À LA PERFORMANCE DE CE LOGICIEL.
Implémentation MD5 par L. Peter Deutsch (licence et source dans src/md5.[ch])
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. Tous droits réservés.