Table des matières
Ce billet fait suite à celui-ci : SSH : du port forwarding au VPN bon marché. J'y évoquais les problématiques de fuite des requêtes de résolution de nom via le protocole DNS. Mais je n'ai pas abordé un point sur lequel je m'interroge depuis quelques temps : je me demandais si les requêtes de résolution étaient envoyées au résolveur DNS défini dans le fichier /etc/resolv.conf du client SSH ou à celui défini dans le fichier du serveur SSH. Il paraît presque évident que c'est le résolveur définit sur le serveur qui sera utilisé.
Ayant sévèrement planté mon WRT54GL, j'en ai profité pour le flasher avec la déclinaison brcm2.4 d'OpenWRT. Cette déclinaison étant plus compact, j'ai pu installer tcpdump sur mon routeur et vérifier tout ceci.
Pourquoi ce test ?
Si votre ordinateur reçoit automatiquement l'adresse IP du résolveur DNS par le serveur DHCP du réseau insecure, que ce résolveur fait partit du réseau insecure et en admettant que les requêtes DNS sont envoyées à ce résolveur via votre serveur SSH, alors l'administrateur réseau du réseau insecure pourra faire un croisement entre l'adresse IP qui effectue les résolutions DNS sur le résolveur DNS interne (qui sera celle de votre serveur SSH) et l'adresse IP de destination du trafic SSH (là aussi, ce sera celle de votre serveur). Il pourra donc savoir quels noms de domaine vous avez résolus et par voie de conséquence, ce que vous avez fait sur internet. La redirection dynamique via SSH serait donc moins efficace. Comme déjà dit, il est peu probable que les résolutions de noms se fasse via le résolveur défini dans le fichier /etc/resolv.conf du client, mais cela ne coute rien de s'en assurer.
Mise en place du test
Évidemment, ce test ne sera pas effectué depuis un réseau dont vous n'avez pas confiance ...
D'abord, on installe tcpdump sur le WRT54GL :
opkg update
opkg install tcpdump
|
Sur la machine de test, on prépare un tsark/wireshark/tcpdump et un Firefox avec un proxy défini dans les paramètres et l'option network.proxy.socks_remote_dns à true dans le about:config.
Note : il n'est pas nécessaire de faire une capture du trafic réseau sur la machine de test si on est déjà convaincu que le trafic passera bien par le tunnel SSH. Je propose ici de faire une capture afin que les septiques puissent vérifier par eux-mêmes ce que je disais dans le billet sus-cité.
Ensuite, on définie un résolveur DNS différent sur le routeur et sur la machine.
Disons que sur la machine, nous utiliserons le résolveur d'OpenDNS : "nameserver 208.67.222.222" à mettre dans le fichier /etc/resolv.conf.
Disons que sur le routeur nous utiliserons le résolveur de Google : "nameserver 8.8.8.8" à mettre dans le fichier /etc/resolv.conf.
On redémarre ensuite dropbear (ou autre serveur SSH) sur le routeur :
/etc/init.d/dropbear/restart |
On se déconnecte puis reconnecte au routeur via SSH, en activant la redirection dynamique.
On lance la capture, que nous appellerons capture R par la suite, sur le routeur (voici un tutoriel pour tcpdump):
tcpdump -i eth0.1 not port 22 -s0 -w capture.cap |
Explication : tcpdump écoute sur l'interface wan (eth0.1), ne garde pas les messages correspondant à la session SSH, ne tronque pas les paquets et enregistre le trafic dans le fichier capture.cap.
On lance la capture, que nous appellerons capture M par la suite, sur la machine.
Dans Firefox, tentez d'accéder à n'importe quel site, de préférence un site sur lequel vous n'avez pas l'habitude d'aller.
On récupère la capture :
scp root@routeur:/root/capture.cap . |
On analyse la capture avec Wireshark (vous pouvez bien sur le faire avec tsark/tcpdump. Dans ce cas là, inutile de rapatrier la capture sur votre machine) :
wireshark capture.cap |
Résultat attendu
Capture M ne doit contenir que du trafic SSH et TCP (ack). Capture R doit contenir du trafic HTTP, TCP (ack) et du trafic DNS vers 8.8.8.8 et surtout pas vers 208.67.222.222.
Résultat obtenu
Exactement le résultat attendu. Firefox dirige les requêtes DNS vers le résolveur défini dans le fichier /etc/resolv.conf du serveur SSH au moment où le serveur SSH a été lancé sur la machine (d'où l'intérêt d'avoir redémarré le serveur SSH lors de la mise en place du test).
Le cas proxychains
Pour les applications ne prenant nativement pas en charge les proxy SOCKS et/ou le transfert des requêtes DNS vers ce proxy, il est, comme nous l'avons dit dans l'article sus-cité, nécessaire de faire appel à un wrapper SOCKS (proxychains, tsocks, torsocks, etc.). Le comportement envers les requêtes DNS dépendra du wrapper choisit.
Dans le cas de proxychains, les requêtes sont toutes envoyées au même résolveur : 4.2.2.2.
Vous pensez bien que je trouve cela intolérable : si j'ai installé un résolveur DNS sur mon WRT54GL, c'est pour l'utiliser (pour les raisons évoquées dans l'article linké).
Je me suis donc dis que ce résolveur devait bien être défini dans les sources de proxychains. J'avais dans l'idée de recompiler les sources après avoir changé l'adresse du résolveur utilisé.
J'ai donc téléchargé et décompressé les sources :
wget http://downloads.sourceforge.net/project/proxychains/proxychains/version%203.1/proxychains-3.1.tar.gz?r=&ts=1294602235&use_mirror=mesh tar -xf proxychains-3.1.tar.gz |
On cherche ensuite l'occurrence "4.2.2.2" dans les sources :
cd proxychains-3.1 find ./ -type f -exec bash -c "grep "4.2.2.2" {} && echo {}" \; |
Find/grep trouvent un résultat dans le fichier ./proxychains/proxyresolv. On affiche son contenu :
cat ./proxychains/proxyresolv |
Je vous quote le passage intéressant en vous invitant quand même à lire la suite du fichier qui est intéressante puisqu'elle permet de comprendre que proxychains résout les noms de domaine avec une méthode toute simple qui fait plaisir à voir :
#!/bin/sh # This script is called by proxychains to resolve DNS names # DNS server used to resolve names DNS_SERVER=4.2.2.2 |
Tout devient clair : proxychains se sert de ce script shell pour résoudre les noms de domaine. Il doit suffire de changer le contenu de la variable DNS_SERVER pour changer de résolveur.
On se dit que ce script ne sera pas compilé et donc qu'il doit y en avoir un exemplaire sur notre machine qui sert au proxychains installé :
sudo find / -type f -name "proxyresolv" |
Find nous trouve un résultat : /usr/lib/proxychains3/proxyresolv.
On modifie donc ce fichier en remplaçant 4.2.2.2 par l'adresse du résolveur DNS voulu. Pour ma part, ça sera le résolveur installé sur mon routeur donc 192.168.1.1 (adresse lan par défaut).
On refait ensuite le test effectué précédemment sauf qu'au lieu d'utiliser Firefox, on utilise un programme proxychainé ("proxychains programme").
On voit, dans la capture réseau de R, que c'est bien le résolveur déclaré dans le script /usr/lib/proxychains3/proxyresolv qui est utilisé. Pour ceux qui veulent une preuve de plus : pour peu que vous ayez lancé la commande depuis une console, vous pouvez lire quelquechose comme ça :
|S-chain|-<>-127.0.0.1:6666-<><>-192.168.1.1:53-<><>-OK" |