Mettre en place un résolveur DNS sur un WRT54GL équipé d’OpenWRT

Table des matières

Pour suivre cet article, je vous conseille de connaitre les bases de l'administration sous OpenWRT (GNU/Linux quoi) et les bases du DNS. Pour le Domain Name System, je vous recommande Wikipédia et un cours vidéo sur lalitte.com.

Pourquoi vouloir un résolveur DNS à la maison ?

Il y a plusieurs raisons qui peuvent amener à mettre en place un résolveur DNS at home. Je vais vous donner les miennes :

  • le "défi" technique.
  • éviter les DNS menteurs.
  • améliorer la réactivité de vos applications internet : les réponses étant mises en cache sur un périphérique à l'intérieur du réseau local, les temps de réponses sont excellents lorsque vous demandez plusieurs fois la même résolution (1 à 2 msec(s)).

Avec quel logiciel ?

Le facteur limitant sera ici la taille du logiciel : il doit loger dans l'espace libre (233 kb) qui reste sur mon routeur (il faudra que je vois pour ajouter une carte MMC/SD). Faisons le tour des logiciels que je connais :

  • Bind : un standard de fait. Mais je voulais quelque chose de plus exotique. De plus, le paquetage nécessite 1868kb pour être installé : il est donc trop gros pour mon WRT54GL.
  • MaraDNS : lui aussi est trop lourd : 612kb sont réclamés.
  • Dnsmasq : il est installé par défaut sur OpenWRT. Mais comme l'indique son man : "Dnsmasq is a DNS query forwarder: it it not capable of recursively answering arbitrary queries starting from the root servers but forwards such queries to a fully recursive upstream DNS server which is typically provided by an ISP.". En clair : ça va pas être possible.
  • DjbDNS. Celui-là répond à tous les critères. Après son installation sur mon routeur, il reste encore 188kb d'espace libre.

Avant l'installation

Comme nous l'avons vu, le paquetage dnsmasq est installé par défaut sous OpenWRT. C'est un logiciel multi-fonctions : DHCP, TFTP et "résolveur" DNS (enfin ... pas tout à fait puisqu'il se contente de transférer les requêtes DNS vers un vrai résolveur DNS sur internet).

Rappel : il ne peut pas y avoir deux logiciels qui utilisent un même port sur une même interface réseau.

Il va donc falloir soit désinstaller dnsmasq et donc se priver d'un serveur DHCP, soit lui demander d'abandonner uniquement sa fonction de "résolveur" DNS. Réponse 2, Jean-Pierre !

Nous allons donc installer dnscache, le configurer puis désactiver la fonctionnalité dns de dnsmasq.

Installation de dnscache

Rien de compliqué ici :

root@OpenWRT:~# opkg update
root@OpenWRT:~# opkg install djbdns-dnscache

Configuration de dnscache

Si vous lancez dnscache maintenant et que vous faisez un netstat -lep, vous verrez que dnscache écoute sur le port 53 en UDP et TCP mais sur l'interface WAN. Or, ce que nous voulons, c'est un résolveur qui écoute uniquement sur le réseau local. Il va donc falloir configurer dnscache.

C'est ici que j'ai pas mal galéré. En effet, si vous cherchez de la documentation sur internet, vous trouverez qu'il faut créer des comptes utilisateur, ajouter ou modifier des fichiers dans /etc/dnscache. J'ai essayé : ça ne fonctionne pas. J'ai donc décidé de lire le readme qui se trouve dans le paquetage. Il est disponible à cette adresse : https://dev.openwrt.org/browser/packages/net/djbdns/README. Tout devient alors clair : il faut utiliser uci pour configurer dnscache.

Allons-y pour la configuration :

root@OpenWRT:~# uci set djbdns.@dnscache[0].interface=lan
root@OpenWRT:~# uci set djbdns.@dnscache[0].defaultallowif=lan
root@OpenWRT:~# uci set djbdns.@dnscache[0].forwardonly=0
root@OpenWRT:~# uci set djbdns.@tinydns[0].interface=lan
root@OpenWRT:~# uci set djbdns.@axfrdns[0].interface=lan
root@OpenWRT:~# uci set djbdns.@rbldns[0].interface=lan
root@OpenWRT:~# uci set djbdns.@walldns[0].interface=lan

Commentons un peu ces lignes. Dans l'ordre :

  • on demande à dnscache d'écouter que sur le réseau local.
  • on demande à dnscache de ne répondre qu'à des périphériques membres du réseau local
  • on demande à dnscache de résoudre lui-même les noms de domaine en partant des serveurs qui gèrent la racine.
  • on demande aux autres composants de djbdns d'écouter que sur sur le réseau local. Même si nous ne les avons pas installés, cela est plus prudent : si vous souhaitez les installer, vous pourrez les configurer tranquillement sans les exposer directement sur internet. Il vaut mieux prévoir le coup plutôt que de s'en remettre à la bonne configuration du firewall.

Note : pour voir l'intégralité des variables de configuration propres à djbns présentent dans le système, vous pouvez taper :

root@OpenWRT:~# uci show | grep "djbdns"

Test de la configuration

Comme nous l'avons dit, on ne peut pas avoir deux logiciels qui écoutent sur le même port. Donc on arrête dnsmasq temporairement :

root@OpenWRT:~# /etc/init.d/dnsmasq stop

Lançons dnscache :

root@OpenWRT:~# /etc/init.d/dnscache start

Pour tester le serveur, il suffit de lui envoyer une requête. Sous GNU/Linux, je préfère utiliser dig alors que sous Windows, nslookup fera l'affaire.

Sous GNU\Linux :

dig @192.168.1.1 www.guiguishow.info.

Vous devez obtenir une réponse dont le status est "NOERROR".

Sous Windows :

nslookup www.guiguishow.info. 192.168.1.1

Vous devez obtenir aucune erreur.

Note : 192.168.1.1 est à remplacer par l'adresse IP LAN de votre routeur.

Ensuite, vous pouvez vous demandez "comment être sûr que mon serveur ne se contente pas de transférer ma requête à un autre DNS ?" Il y a manière simple de vérifier cela.

Il suffit de capturer le trafic réseau qui sort du routeur sur l'interface WAN (eth0.1).

Si vous avez encore assez d'espace libre dans la mémoire de votre routeur, vous pouvez installer tcpdump (660kb) ou tcpdump-mini dessus. Il suffit alors de lancer le sniffer :

tcmpdump -n -i eth0.1 port 53

Sinon, vous pouvez brancher un autre ordinateur sur le port WAN du WRT54GL et capturer le trafic réseau avec un logiciel comme Wireshark. Pour que cela fonctionne, l'ordinateur que vous avez branché au port WAN doit prendre la même adresse IP que le modem qui est habituellement branché à votre routeur (ou redéfinir la route pas défaut sur le routeur, mais c'est une autre histoire). Si vous ne la connaissais pas, regardez la capture réseau : vous verrez des trames ARP "Who has x.x.x.x tell y.y.y.y". Il vous suffit de donner à votre ordinateur l'adresse IP x.x.x.x . Vous pouvez ensuite lancer la capture.

Dans tous les cas, une fois cela fait, revenez sur l'ordinateur qui est toujours connecté sur un des ports LAN du routeur. Lancez un dig/nslookup en direction de votre résolveur personnel. Dans la capture réseau, vous devez voir des adresses IP qui appartiennent à l'un des serveurs qui gèrent la racine DNS ou les TLD comme 192.26.92.30 ou 192.54.112.30.

Pour savoir si une adresse IP appartient à l'un des serveurs en charge de la racine ou des TLD, vous pouvez utiliser la commande host sous GNU/Linux ou nslookup sous Windows. Dans le cas de 192.54.112.30, nous obtenons "30.112.54.192.in-addr.arpa domain name pointer h.gtld-servers.net.". Il s'agit donc d'un des serveurs qui gère le domaine de premier niveau .net. .

Si tout va bien, vous pouvez passer à l'étape suivante.

Changer l'adresse du résolveur DNS sur les machines grâce à DHCP et sur le routeur

Les Unixiens se seront précipités pour éditer le fichier /etc/resolv.conf 😉 . C'est un bon réflexe en temps normal mais, dans le cas présent, ce fichier est généré à chaque démarrage du routeur, ou plus précisément à chaque démarrage de dnsmasq.

Il faut donc éditer le script de démarrage : /etc/init.d/dnsmasq. A la 5éme ligne, vous pouvez lire :

DNS_SERVERS= ""

Saisissez ici l'adresse ip LAN de votre routeur.

Note : dnsmasq ajoutera le résolveur 127.0.0.1 automatiquement à la fin de la liste. Si vous trouvez ça inconcevable, que ça vous empêche de dormir la nuit, supprimez la 5eme ligne du fichier puis cherchez cette ligne dans la fonction start :

DNS_SERVERS= "$DNS_SERVERS 127.0.0.1"

Enlevez tout ce qu'il y a entre guillemets et mettez la ou les adresse(s) IP de votre(vos) résolveurs, séparés par un espace.

Il ne reste plus qu'a redémarrer dnsmasq :

root@OpenWRT:~# /etc/init.d/dnsmasq restart

Notez que les modifications ne prendront effet sur vos périphériques que lors du renouvellement du bail DHCP. Vous pouvez le forcer (ipconfig /renew sous windows, désactiver/activer l'interface réseau, reboot, etc.).

Désactiver la fonctionnalité DNS de dnsmasq

A présent, nous pouvons désactiver la partie DNS de dnsmasq. Le man de dnsmasq nous dis ("Listen on <port> instead of the standard DNS port (53). Setting this to zero completely disables DNS function, leaving only DHCP and/or TFTP.") qu'il suffit de configurer le port à 0 pour désactiver la fonction DNS. Pour mettre cela en application, il suffit d'aller dans l'interface web, dans "Services", "Dnsmasq", d'ajouter un champ "port DNS", de le configurer à 0 et d'appliquer les changements.

Pour les True Warrior qui veulent le faire depuis le shell, ça donne :

root@OpenWRT:~# uci set dhcp.@dnsmasq[0].port=0
root@OpenWRT:~# /etc/init.d/dnsmasq restart

Mettre en place durablement notre résolveur

En effet, dans l'état actuel, djbdns ne se relancera pas au prochain reboot du routeur et les paramètres seront perdus 🙁 .

Pour que le serveur se lance tout seul au démarrage du routeur vous pouvez créer un lien de /etc/init.d/dnscache vers /etc/rc.d/Sxxdnscache (ou xx représente l'ordre de boot) avec la commande ln ou plus simplement taper la commande :

root@OpenWRT:~# /etc/init.d/dnscache enable

Pour enregistrer les paramètres que nous avons donnés à uci, il faut taper ceci dans ash (le shell par défaut d'OpenWRT) :

root@OpenWRT:~# uci commit network.lan
root@OpenWRT:~# uci commit dhcp
root@OpenWRT:~# uci commit djbdns
root@OpenWRT:~# uci commit

Détaillons un peu, toujours dans l'ordre :

  • On enregistre le changement de serveur DNS pour le réseau local.
  • On enregistre le fait que dnsmasq ne doit plus faire office de résolveur DNS ainsi que le changement de serveur DNS pour le réseau local, le cas échéant.
  • On enregistre toutes les modifications faites à djbdns.
  • On enregistre tout. Pas utile mais je le fais par mesure de précaution.

Et voila, votre résolveur DNS personnel est en place sur votre routeur équipé avec OpenWRT.

Si dnscache plante lorsqu'une déconnexion survient sur l'interface WAN (ÉDIT du 08/08/2011 à 14h00 )

J'ai rédigé un billet à ce sujet : OpenWRT : relancer automatique dnscache en cas de déconnexion du net

La magie des liens sous Windows Vista/7

Table des matières

Les liens, dans les systèmes de gestion de fichiers j'entends, tout le monde connait. Pourtant, nous allons quand même revenir sur deux cas, sous Windows, dans lesquels ils peuvent s'avérer utiles : avec Squid et avec Daemon Tools/Y.A.S.U. Pour aborder cet article, je vous conseille de savoir la différence qu'il y a entre un lien symbolique et un hard link (lien matériel en français).

Cas pratique n°1 : Squid

Pour télécharger une version de Squid pour Windows (et en même temps avoir les instructions d'installation 😀 ), je vous conseille ce site : Acme Consulting - Squid 2.7 for Windows. Suivons les instructions ensembles :

Extract the binary archive in the desired directory (default c:\squid)

Hum ... Je sais pas pour vous mais moi j'aime bien que mes programmes soient bien rangés. Ainsi je vais mettre Squid dans "C:\Program Files (x86)\Squid".

Copy and rename the follwing files:

Rien de compliqué ici ... Je vous attends pour passer à la suite 🙂

Edit the squid.conf and change if needed the c:/squid path (use path with '/' char, NOT '\')

Ça ne sert à rien de suivre cette consigne puisque, comme préciser plus bas sur le site :

Paths with spaces (like C:\Programs Files\Squid) are NOT supported by Squid

Continuons :

Manually create ALL the directories specified in squid.conf, except the contents of the cache directory

En fait, il n'y a qu'un seul dossier à créer : /var/cache. Mais au cas où cela changerai à l'avenir, je vous conseille de lire le fichier de configuration. Ce fichier contient beaucoup de commentaires. Qu'à cela ne tienne : voici un script PHP fait il y quelques années par Dodo et que je viens d'améliorer, qui affiche les lignes du fichier de configuration qui ne sont ni commentées ni vides :

<?php
	$fichierDeConfiguration = fopen('squid.conf', 'r');

	while ($ligne = fgets($fichierDeConfiguration))
	{
		if (($ligne[0] != '#') AND (bin2hex($ligne[0]) != '0a'))
		{
			$tableau[] = $ligne;
		}
	}

	foreach($tableau as $ligneOK)
	{
		echo $ligneOK . '<br /><br />';
	}

	fclose($fichierDeConfiguration);
?>

Ce script est sans prétention. Oui, nous aurions pu utiliser une regex pour chercher tous les répertoires mentionnés dans le fichier de configuration puis exclure les répertoires commentés. Mais nous avons fait autrement 😀

squid -i [-f configfile] [-n servicename] (installs the servicename Squid service using the configfile configuration file, default configfile is "c:/squid/etc/squid.conf", default servicename is "Squid")

Rien de spécial ici.

squid -z [-f configfile] (creates the cache directories)

C'est là que commence les ennuis puisque nous obtenons un joli message :

FATAL: MIME Config Table c:/squid/etc/mime.conf: (2) No such file or directory
Squid Cache (Version 2.7.STABLE8): Terminated abnormally.
CPU Usage: 0.016 seconds = 0.000 user + 0.016 sys
Maximum Resident Size: 5732 KB
Page faults with physical i/o: 1523

abnormal program termination

Squid cherche le fichier mime.conf dans C:\Squid. Si nous modifions la variable mime_table dans le fichier de configuration, Squid la refusera car elle contiendra des espaces. En attendant, nous ne pouvons pas lancer Squid.

La solution est de créer un lien réel de C:\Squid vers C:\Program Files (x86)\Squid (dans la terminologie Windows/NTFS, on appelle cela une jonction de répertoire) :

c:\>mklink /D /H /J Squid "C:\Program Files (x86)\Squid"
Jonction créée pour Squid <<===>> C:\Program Files (x86)\Squid

Ce coup-là, Squid fonctionne :

2010/08/17 17:41:07| Creating Swap Directories

La fin de l'installation, à savoir la création d'un service, ne pose pas de problèmes particuliers. Je vous laisse donc continuer tout seul.

Nous avons donc bien rangé notre programme dans le répertoire prévu à cet effet. Seul un lien traine dans C:\ .

Cas pratique n°2 : Daemon Tools et Y.A.S.U.

Avant de commencer, je rappelle à tous les bien-pensants que Y.A.S.U. n'est pas utilisable que dans des activités illégales 😉 . Il peut par exemple servir à contourner les protections Securom et Safedisc dans le cas où l'on utilise des mini-images afin de ne pas avoir à insérer le CD/DVD dans le lecteur à chaque fois que l'on souhaite jouer, dans le but de préserver la durée de vie du CD/DVD original du jeu et de notre lecteur CD/DVD.

Depuis les versions postérieurs à la version 4.30 de Daemon Tools, Y.A.S.U. ne semble plus fonctionner en mettant un message "Unable to locate the file "daemon.exe" or "dtpro.exe". Please copy "YASU.exe" to your DAEMON Tools Lite/Pro directory, then run the application again."

La première solution est de renommer le fichier DTLite.exe en daemon.exe. Je sais pas ce que vous en pensez, mais cette solution manque de piment 😉 .

La deuxième solution est de créer un lien. Mais plutôt que de le faire depuis l'interface graphique, faisons le depuis la ligne de commande :

C:\Program Files (x86)\DAEMON Tools Lite>mklink daemon.exe DTLite.exe
Lien symbolique créé pour daemon.exe <<===>> DTLite.exe

ÉDIT du 14/05/2011 à 17h20 : Pour créer un lien réel sous XP, il faut utiliser la commande fsutil. Ainsi, pour l'exemple précédent, il suffit de faire :

C:\Program Files (x86)\DAEMON Tools Lite>fsutil hardlink create daemon.exe DTLite.exe

Mise au point à propos des destructeurs

La programmation orientée objet introduit le concept de destructeur. Pour résumer, il s'agit d'une unique méthode de classe (dans le sens où une classe peut implémenter plusieurs constructeurs mais un seul destructeur) qui est exécutée lors de la destruction d'un objet de la classe afin de récupérer les ressources, mémoire notamment, empruntées lors de la création de l'objet.

Sur le net, on peut parfois lire qu'il ne sert à rien d'écrire soit-même le code du destructeur ou qu'il faut écrire le destructeur que lorsque l'on utilise des pointeurs. Parfois, c'est encore pire : on peut lire qu'un destructeur ne sert à rien. Faisons une petite mise au point.

La première chose à savoir est que l'on n'a pas besoin de destructeur dans les langages de programmation (Java, PHP, etc. ) qui implémentent un système de ramasse-miettes (en anglais, juste pour épater les filles : garbage collector) car la libération de la mémoire est alors automatique. Certains vont dire : dans ce cas, à quoi sert la méthode java.lang.object.finalize() en Java ?

La réponse est simple : d'une part, la méthode finalize() ne détruit pas l'objet : elle permet au programmeur de réaliser une action avant la destruction à proprement parlé de l'objet par le ramasse-miettes. D'autre part, elle n'est pas à utiliser, même pour fermer un descripteur de fichier car Java ne peut ni garantir que cette méthode sera bien exécutée ni quand elle le sera. De plus cela ruine la portabilité de l'application, ce qui est un peu dommage vu que c'est un des principaux objectifs de Java. Ce n'est pas moi qui le dit mais Joshua Bloch dans son livre "Effective Java: Programming Language Guide". Vu les antécédents de cette personne dans le domaine Java, on peut, peut-être, lui faire confiance.

Prenons un exemple rapide : réaliser un close() sur un objet de la classe FileOuputStream à l'intérieur d'une méthode finalize() redéfinie est une mauvaise méthode en plus d'être inutile. Le close() doit être fait dans le bloc finally (vous savez : try ... catch ... finally) qui suit le try dans lequel vous avez ouvert le fichier. Plus précisément, elle doit être faite dans un bloc try ... catch à l'intérieur d'un bloc finally car cette méthode peut soulever une exception de type IOException.

Pour lever tout ambiguïté concernant mes propos :
En PHP, la méthode magique __destruct permet de personnaliser le processus de destruction d'un objet (exemple : supprimer une ligne dans une table de la base de donnée lors de la destruction d'une instance d'une classe donnée). Néanmoins, PHP implémente un mécanisme de libération automatique de la mémoire. Avant PHP 5.3, il était basé sur un compteur de référence : dès qu'une variable n'est plus référencée, elle est supprimée. Depuis PHP 5.3, le mécanisme a été amélioré et on obtient un garbage collector qui, en plus de faire la même chose que le mécanisme du compteur de référence, permet d'éviter les problèmes liés aux références circulaires. C'est pour cela que je pense que, comme en Java, il n'est pas nécessaire de redéfinir un destructeur sauf à vouloir personnaliser la destruction d'un objet comme évoqué précédemment.

Ensuite, pour les langages orientés objet sans ramasse-miettes (C++ par exemple) :

- Pour tout ce qui est allocation statique (int, double, array, objet) à l'intérieur d'une classe et qui sera donc stocké sur la pile, vous n'avez pas besoin d'un destructeur. Même avec un pointeur (un tableau est un pointeur), tout sera supprimé automatiquement par le destructeur par défaut. C'est pour ça qu'il est faux de dire qu'il faut écrire soit-même le code du destructeur dès que l'on utilise un pointeur. Le must c'est que même les appels récursifs sont pris en compte. Par exemple : Soit une classe A qui créer un objet de classe B qui elle même créer un tableau. Le tableau sera bel et bien supprimé.

- Pour tout ce qui est allocation dynamique (utilisation de l'opérateur new ou malloc) à l'intérieur d'une classe et qui sera donc stocké sur le tas, il est impératif d'écrire soit-même le code du destructeur. C'est pour ça qu'il est faux de dire qu'un destructeur ne sert à rien ou qu'il ne faut jamais le re-implémenter.

Pour résumer :

  • Langage objet avec ramasse-miettes : pas de destructeur à implémenter
  • Langage objet sans ramasse-miettes :
    • utilisation de l'allocation statique à l'intérieur d'une classe : pas besoin de redéfinir le destructeur par défaut.
    • utilisation de l'allocation dynamique à l'intérieur d'une classe : il faut redéfinir le destructeur par défaut (mais aussi le constructeur de recopie et l'opérateur d'affectation pour bien faire ;)).

ÉDIT du 28/10/2011 à 14h : Et si vous avez un doute sur la libération de la mémoire, vous pouvez utiliser Valgrind. Je l'ai utilisé uniquement sur du C et du C++ mais, d’après le grand Web, il fonctionne aussi avec du Python. Fin de l'édit.

Protéger le cache ARP de vos machines

Table des matières

Pour comprendre cet article, il est nécessaire de connaitre les bases du protocole réseau ARP.

Quel est l'intérêt de protéger la table ARP ?

La modification, par un acteur malveillant, de la table ARP peut conduire à des attaques réseau très efficaces telle que l'attaque de l'homme du milieu (in english : man of the middle attack 😀 ) qui permet de voir les flux échangés. Vu le nombre de flux qui circulent en clair sur un réseau informatique, on comprend mieux le problème. Si vous voulez tester, chez vous évidemment, la mise en place et les effets d'une attaque de l'homme du milieu, je vous recommande le logiciel ettercap.

Cette attaque est efficace car elle est difficile à contrecarrer. En effet, ils faut faire en sorte que chaque équipement relié au réseau connaisse, de manière statique l'adresse MAC de tous les autres équipements du réseau. Pour un petit réseau, c'est encore gérable. Mais pour un grand réseau, cela devient vite la galère a gérer (nombre d'associations, hétérogénéité des systèmes d'exploitations, etc.). C'est encore plus ingérable avec des périphériques mobiles car la même IP sur deux réseaux distincts n'aura pas la même MAC. Exemple pour comprendre : sur le réseau A, l'IP 192.168.1.1 est associée à la MAC aa:bb:cc:dd:ee:ff. Sur le réseau B, la même IP est aussi utilisée et a pour adresse MAC gg:hh:ii:jj:kk:ll. Il faudra changer l'association IP <=>MAC selon le réseau sur lequel vous êtes. Cela peut se révéler pénible selon la fréquence à laquelle vous changez de réseau.

Il existe des solutions que nous n'aborderons pas telle que le logiciel arpwatch, qui permet d'être prévenu dans le cas où une nouvelle machine se connecterait au réseau ou changerait d'adresse. Dans la même veine, les système de détection d'intrusion (qui a parlé d'élever un cochon ? 😉 ) permettent de s'apercevoir qu'une attaque de type corruption du cache ARP est en cours d'exécution.

L'intérêt de protéger le cache ARP est faible pour le réseau local d'un particulier. En effet, à moins que le wifi soit activé et insuffisamment protégé, le seul moyen de vous nuire est de rentrer chez vous et de placer un équipement minimaliste sur votre réseau. Mais si un acteur malveillant parvenait à s'introduire chez vous, il aurait surement plus intéressant à faire car le monde des attaques physiques s'ouvrirait alors à lui.

Nous allons quand même voir comment protéger le cache ARP dans un but de connaissance.

Quelle est la problématique ?

Il faut, pour chaque système d'exploitation, pour chaque interface réseau, pour chaque machine reliée au réseau, enregistrer, de manière statique, toutes les correspondances entre toutes les adresses IP et les adresses MAC qui circulent sur le réseau. Deux problèmes se posent alors :

  • le cache ARP est vidé à chaque arrêt d'une machine. Il nous faut donc trouver un procédé pour le remplir à chaque démarrage
  • les systèmes d'exploitation, que ce soit Windows ou GNU/Linux, refusent que l'on modifie l'adresse de la passerelle (sur le réseau local d'un particulier, il s'agit en général du routeur) en cours de route. C'est justement là que se trouve le plus gros vecteur d'attaque : pour avoir une vue intégrale des flux échangés entre une machine et les autres machines (y compris celles sur internet), l'attaquant se placera entre la machine et sa passerelle. Il va donc falloir ruser.

Comment faire sous Windows

D'abord, renommez votre interface (dans le panneau de configuration) afin d'enlever le "é" dans "Connexion au réseau local". Le nouveau nom n'a pas d'importance : il doit juste ne pas contenir d'accent. Nous aurons besoin de deux scripts batch.

Il n'y a pas de retour à la ligne. Le premier script configurera la connexion sur une plage d'adresse que nous n'avons pas. Ce qui donne :

netsh interface ip set address "Connexion au reseau local" static 10.0.0.20 255.0.0.0 10.0.0.50 1

Ici on configure la connexion pour être sur le réseau 10.0.0.0/8 avec la passerelle 10.0.0.50. Bien sûr, si vous utilisez cette plage au quotidien, prenez-en une autre car il ne faut pas que la plage que vous utilisez au quotidien soit la même que celle que vous déclarez dans ce script.

Le deuxième script devra vider puis remplir la table ARP et basculer la configuration de l'interface réseau sur la bonne plage d'adresse. Ce qui nous donne :

timeout 15
arp -d *
arp -s 192.168.1.1 95-49-e5-79-4e-09
netsh interface ip set address "Connexion au reseau local" dhcp

N'oubliez pas d'adapter la dernière ligne si vous n'utilisez pas DHCP. Le timeout 15 n'est pas nécessaire : un timeout 5 peut suffire. Mais je joue la prudence dans cet exemple. D'autant plus que cela ne nous gêne pas : le temps d'ouvrir votre session, le réseau sera quand même configuré.

Maintenant, il s'agit de lancer le premier script à l'arrêt de Windows et le deuxième au démarrage de Windows. Attention, je dis bien au démarrage de Windows, pas à l'ouverture d'une session. Tout cela se fait dans gpedit.msc. Ouvrez-le. Sous "configuration de l'ordinateur", allez dans "Paramètres Windows" puis dans "Scripts (démarrage/arrêt)". Il ne vous reste plus qu'à ajouter les scripts dans la bonne catégorie.

Comment faire sous GNU/Linux

J'utiliserai Ubuntu. Tout ce qui suit devra être réaliser avec le compte root. Il faut créer un script dans le dossier /etc/init.d dont voici le contenu :

#!/bin/sh
arp -s 192.168.1.1 95:49:e5:79:4e:09

Le squelette de ce script est inspiré de celui de ce site.

Notes :

  • Vous pouvez utiliser la commande ip à la place de la commande arp. Sa syntaxe : ip neigh add IP lladdr MAC nud permanent dev INTERFACE.
  • Vous pouvez aussi utiliser un fichier pour remplir le cache ARP. Cela allégera votre script. Généralement, on utilise le fichier /etc/ethers. Il faut remplir le fichier avec une association par ligne, en respectant cette mise en forme :
    95:49:e5:79:4e:09 192.168.1.1

    Ensuite, il faut remplir le cache ARP en se servant de ce fichier avec la commande :

    arp -f /etc/ethers

    C'est donc cette commande que vous mettrez dans le script que vous avez créé dans /etc/init.d si vous choisissez cette méthode.

Ensuite vous devez rendre le script créé exécutable avec un bon vieux :

chmod +x /chemin/vers/le/script

Il ne reste qu'à demander à exécuter le script au boot avec la commande :

update-rc.d SCRIPT defaults 20

SCRIPT est le nom que vous avez donné au script. 20 désigne l'ordre de démarrage.

Cas d'OpenWRT

Sous OpenWRT, la commande arp ne sert qu'à visionner la table ARP. Vous devez donc utiliser la commande ip.

La première étape consiste à installer cette commande :

opkg install ip

La deuxième étape consiste à créer un script dans /etc/init.d dont voici le contenu :

#!/bin/sh /etc/rc.common
START=40
boot() 
{
	ip neigh add 192.168.1.1 dev br-lan lladdr 95:49:e5:79:4e:09 nud permanent

}
 
start() 
{
	ip neigh add 192.168.1.1 dev br-lan lladdr 95:49:e5:79:4e:09 nud permanent
}

Il n'y a toujours pas de retour à la ligne. Ce code est inspiré du code des autres scripts de démarrage fournis par défaut avec OpenWRT.

La troisième étape, tout comme sous Ubuntu est de rendre le script exécutable :

chmod +x /chemin/vers/le/script

La dernière étape est de faire un lien symbolique de /etc/init.d/Script vers /etc/rc.d/SxxScript (où Script est le nom du script et xx l'ordre de démarrage du script dans le boot) :

ln -s /etc/init.d/eviterARPCachePoisoning /etc/rc.d/S40eviterARPCachePoisoning

Toujours pas de retour à la ligne 😉

Il ne vous reste plus qu'à redémarrer toutes vos machines et à contrôler le résultat avec la commande suivante :

arp -a

Toutes les adresses que vous avez configuré doivent apparaitre, complétées par le terme "PERMANENT" sous les systèmes *nix.

Si tout est en place, vous pouvez retenter une attaque de l'homme du milieu. Vous ne parviendrez pas à capturer le moindre flux, cette fois-ci.

Pour illustrer le fait que toutes les machines du réseau doivent connaitre, de manière statique, toutes les autres associations IP/MAC du réseau, faites l'expérience suivante : sur une machine, ne fixez pas l'association IP/MAC de la passerelle. Sur la passerelle, fixez l'association IP/MAC de la machine. Tentez maintenant une attaque de l'homme du milieu et surprise : vous aurez la moitié des flux : la machine vous enverra bien les paquets mais la passerelle ne se laissera pas berner puisqu'elle connais la véritable MAC de votre machine et répondra à cette adresse MAC. Même si les réponses de la passerelle lui parviennent, la machine ne sait pas les interpréter car ce n'est pas la passerelle qu'elle a interrogé mais ce qu'elle croit être la passerelle mais qui est en fait la machine de l'attaquant. Dans ce cas de figure, l'attaque n'est pas invisible pour la victime car le traffic réseau est paralysé.

Enjoy 😀

Laissez moi tranquille !

Ce soir, je redémarre mon ordinateur et je choisis Windows comme système à démarrer afin de tester quelques commandes pour le prochain article (qui du coup aura du retard !). Il démarre sans problème. Mais lors de l'ouverture de ma session, surprise ! Il paraît que ma version de Windows n'est pas authentique. Je sens monter en moi la colère ...

C'est une blague ? J'ai trois licences de Windows :

  • une de Windows XP. Mon CD de Windows XP livré lors de l'achat de mon ordinateur venait d'exploser dans le lecteur CD de mon ordinateur alors que je procédais à une réinstallation : j'étais en plein dans la phase de copie des fichiers depuis le CD sur le disque dur. Je me souviens encore de la note : 149€
  • une de Windows 7, obtenue via MSDN
  • une autre de Windows 7 Pro, achetée dans le commerce avant que j'obtienne la licence avec MSDN. Prix : 109.99€ (promo inside)

Mais alors, où est le problème ? Le problème est que je n'active jamais mes Windows. J'installe Windows et je crack le processus d'activation. Beaucoup trouvent ça complètement débile (big up à Loïc) : si tu as une licence légale forcement tu dois l'activer. Cela reviens à dire une phrase naïve : si tu as rien a te reprocher, tu dois activer ton Windows. Mais l'explication est simple : quand j'achète un produit, quel qu'il soit, je veux qu'on me laisse tranquille ! Non mais c'est une blague ? Activer le logiciel que je viens d'acheter ? De quels droits vous surveillez l'utilisation que je fais de ce que je vous ai acheté ?

Je vais vous raconter d'autres exemples :
D'une part, j'ai acheté le jeu The Chronicles of Riddick : Assault on Dark Athena et je n'ai jamais réussi à installer ce jeu sur mon ordinateur. La raison ? La protection du jeu, Tages ou plus particulièrement son pilote, n'a jamais voulu s'installer sur mon Windows. Oui, j'installe bien le jeu depuis le compte administrateur, je suis quand même pas idiot à ce point ! Je conserve le jeu en attendant une solution mais j'ai la rage.

D'autre part, j'ai acheté le jeu Grand Theft Auto 4. Et là aussi je peste contre le système d'activation. On remarquera que le jeu utilise une défense par trigger (= déclencheurs) : c'est ça qui produit le phénomène de caméra qui bouge toute seule ou le blocage des ordinateurs des cyber-cafés quand on utilise un mauvais crack. Comment je rejoue au jeu quand mon routeur (oui, oui le DG834Gv3) a grillé et que je souhaite attendre son remplaçant en jouant ? Comment je rejoue si le serveur d'activation est saturé ? Comment je fais, bon sang, pour rejouer dans 5 ans, comme j'aime bien le faire avec d'autres jeux, alors que les serveurs d'activation auront été démantelés par Rockstar depuis longtemps ?

ÉDIT 21/06/2011 18h15 : Illustration récente de ce que je disais il y a 10 mois : Fermeture de serveurs de jeux: On recommence.

C'est pareil pour les DRM que l'on trouve sur les films et la musique : il y a de l'abus ! De quels droits vous me donnez un délai pour regarder l'épisode d'une série que je viens d'acheter (cas de la VOD) ? De quels droits vous limitez le nombre de copies que je peux faire pour mon usage personnel alors que je paye une taxe pour la copie privée ? Je n'ai pas le droit d'avoir plusieurs appareils sur lesquels je souhaitent écouter/regarder ce que je vous ai acheté ?

En plus, les majors se permettent de faire du lobbyisme à l'Assemblée et de l'œil au gouvernement afin de réduire un peu plus nos libertés (qui à dit HADOPI ?) et notamment sur le net en se cachant derrière le bon prétexte de protéger les intérêts des artistes. Heureusement, certains artistes ont compris leur exploitation et se réveillent : je les félicite et j'espère qu'ils seront de plus en plus nombreux. Les majors sont l'une des représentations de l'ultra capitalisme : toujours plus de pognon, au delà du raisonnable, au delà de l'excès.

Mais plutôt que de cracker les protections, il faut changer ses habitudes de consommation et n'accepter aucun compromis. Ainsi ils seront bien obligés de se mettre au pas, à condition que le mouvement soit suivi par la masse, ce qui est loin d'être le cas.

Concernant la musique : j'écoute la radio et j'enregistre la musique qui me plaît.

Concernant les films sur DVD/Blu-ray : Je paye la redevance télé et j'attends que les films passent et j'enregistre. Et les blu-ray sont trop contraignants pour moi : ils sont illisibles par les logiciels libres ... à moins de cracker la protection (et encore : adieu les menus et l'interactivité)... Je préfère donc le boycott en espérant (douce utopie) que cette protection soit supprimée.

Concernant le cinéma : la dernière fois que j'y suis allé, j'ai payé une somme vraiment pas chère du tout : 8€ ! Cela fait donc plus qu'un SMIC horaire net pour 1H30 de vidéo même pas en 3D ! Ils sont fous. Comme je ne suis pas associable, j'accepte encore quelques invitations de mes amis mais moins qu'avant, ça c'est sûr.

Concernant les jeux vidéos : avec la leçon que viennent de me donner Rockstar et Tages, sans compter Ubisoft qui se permet de réclamer une connexion continue au net pour pouvoir jouer à leur derniers bébés, je ne suis pas prêt d'acheter un jeu vidéo.

Concernant les autres logiciels : Cela fait des années maintenant que je n'utilise presque plus que des logiciels gratuits. Et au fil du temps, je me suis tourné progressivement vers des logiciels libres. Ils me respectent, eux ! Malheureusement, je dois encore utiliser, pour diverses raisons (le boulot ?), des logiciels propriétaires comme Windows.

Que je sois clair : je ne suis pas contre rémunérer la création ou contre le fait que les groupes de prodution/distribution fassent une marge sur les produits vendus. Je veux juste un mode de consommation plus juste pour le consommateur. C'est tout. La liberté est précieuse, je ne compte pas l'échanger contre le dernier blu-ray sorti hier.

Je supporte les initiatives intelligentes comme par exemple celle des cinémas Utopia : un film pour 5€, au format Matroska et sans DRM. On n'est pas loin du top. Malheureusement, les grands groupes ne signeront jamais : 5€ c'est pas assez cher, mon fils. Il n'y a qu'à voir le traitement de Jiwa par Warner ... Aujourd'hui, les grands groupes sont plus occupés à développer un nouveau DRM interopérable (sic !), UltraViolet, qu'à trouver un business-model adapté aux années 2000 et à la vente dématérialisée.

C'est pas grave : je continuerai à refuser qu'ils se payent ma tête avec des tarifs prohibitifs ou une offre légale qui n'est pas adaptée à notre temps (format bidon, codec bidon, sans sous-titrage, etc). Je continuerai également de refuser qu'on me trace/contrôle avec des systèmes d'activation.

Ceci me ramène au cas Windows : j'ai malheureusement besoin de lui donc je ne peux pas le boycotter. J'attends ce jour là avec impatience ! En attendant, pour remédier à la mise à jour qui m'a "bloqué" (KB971033) : Windows 7 Loader 1.9.1, redémarrer l'ordinateur, suivre l'assistant d'activation, Windows 7 Loader 1.9.1 encore, redémarrer et basta.