Protéger ses canaux de communication

Nous l'avons vu dans un précédent numéro de Linux Magazine, écouter un réseau afin de récupérer des informations comme le contenu d'emails n'est pas une chose difficile. En effet, beaucoup de services communiquent en clair sur le réseau (pop, ftp, telnet, etc.). Afin de protéger ce genre de communication, il faut détourner les canaux de communication classiques et les rediriger dans un tunnel.

Ce genre de manipulation est exactement ce que permet de faire un petit utilitaire/démon connu sous le nom de stunnel. Celui-ci utilise SSL afin de protéger les informations circulant dans le tunnel. Point important, si vous travaillez avec un environnement hétérogène, stunnel est disponible aussi bien pour les plates-formes Unix (dont GNU/Linux), mais également pour Win32.

Théorie

Le principe de fonctionnement d'un tunnel est relativement simple. Les données ne circulent plus en clair à l'extérieur de la machine, comme c'est le cas habituellement (en rouge sur le schéma). Plutôt que d'établir une connexion depuis le client vers le serveur, le système se connectera au même port, mais cette fois en local (en bleu). stunnel protégera alors les données et les renverra sur un port différent pour les faire transiter à l'extérieur de la machine (en vert). Les données protégées seront reçues sur le serveur où stunnel les transformera en données claires pour ensuite les rediriger vers le bon port. Enfin, l'application serveur pourra les interpréter. Comme vous pouvez le voir, aucune information n'est "écoutable" sur le réseau. Ce type de manipulation sécurisera d'une manière sûre des communications comme celles entre un client et un serveur POP3 (réputée très fragile). L'utilisateur mal intentionné ne percevra que du bruit en écoutant (sniffant) la communication. Pire, s'il écoute spécifiquement le port utilisé habituellement (110 dans le cas de POP3), il n'entendra rien du tout.

Schema


<--> Données en clair
<--> Données protégées
<--> Communication interne en clair

Utilisation

Après avoir récupéré la dernière version en date de stunnel (ici la 3.14), vous devrez vous assurer d'avoir une bibliothèque SSL (comme OpenSSL par exemple) afin de pouvoir compiler tout cela tranquillement. Ensuite, le triplet classique fera l'affaire :

./configure
make
make install

Au terme de la commande make, quelques informations complémentaires vous seront demandées afin de générer votre fichier certificat. Notez également que, parmi les sources de stunnel, vous pourrez trouver un binaire au format Win32. Afin de pouvoir vous en servir, vous devrez néanmoins récupérer une bibliothèque SSL au format DLL (libssl32.dll et/ou libeay32.dll). Votre certificat se trouvera quant à lui dans le répertoire courant sous le nom stunnel.pem.

Nous pouvons maintenant tenter notre première expérience. Sur la machine serveur où, par exemple, un serveur POP3 attend paisiblement des requêtes, lancez le démon stunnel comme suit :

stunnel -D 6 -f -p /chemin/stunnel.pem -d 14000 -r localhost:110

Par cette commande, nous demandons à stunnel d'écouter le port 14000 (-d), de décoder les informations qui en parviennent pour envoyer les informations en clair sur le port 110 de l'hôte local (-r). Les options -D 6 et -f nous permettent ici de demander respectivement un niveau de débogage 6 et un fonctionnement du démon en avant-plan (foreground). L'option -p permet de spécifier le nom et l'emplacement du fichier certificat. Toutes les données arrivant sur le port 14000 sont donc censées être des communications SSL. Notre serveur POP3 quant à lui aura l'impression que les requêtes proviennent de l'hôte local (127.0.0.1:110).

Sur la machine cliente, il ne nous reste plus qu'à opérer la manipulation inverse :

stunnel -D 6 -f -d 110 -r serveur:14000

Ici, toutes les communications sur le port 110 seront protégées et envoyées sur le port 14000 du serveur. Notez que les options de débogage et de fonctionnement en avant-plan ne sont là que pour des raisons de démonstration. Dans le cadre d'une utilisation courante, vous pouvez vous en passer.

Dernière étape, demandez à votre client mail d'utiliser non plus le serveur distant, mais l'hôte local comme serveur POP3. Attention, c'est une erreur courante de penser que stunnel intercepte les sorties sur le port 110. Ce n'est bien sûr pas le cas et il faut bien comprendre que le démon stunnel fonctionne sur le port 110 du client; pour le MUA, le serveur POP3 est donc bel et bien 127.0.0.1.

Un peu plus loin

Avant de poursuivre, précisons qu'il est possible de "tunneler" n'importe quel port, les plus courants étant http, smtp, nntp, imap, pop3, telnet et ftp. Ce fait est tellement courant qu'une convention a été mise en place pour chiffrer et nommer ces ports :

serviceport	serviceport

http	80	https	443
smtp	25	smtps	465
nntp	119	nntps	563
telnet	23	telnets	23
imap	143	imaps	993
pop3	110	pop3s	995
ftp	21	ftps	990

Voici pour ce qui est de l'utilisation courante du tunneling. Ajoutez donc ces différentes valeurs (de droite) à votre /etc/services. Cela vous facilitera grandement les manipulations de ports. Notez cependant que vous n'êtes absolument pas tenu d'utiliser ces noms et valeurs de port. Il ne s'agit que d'une convention.

En poussant le vice un peu plus loin avec stunnel, il est possible de créér un VPN, c'est-à-dire un réseau dont les données seront protégées par SSL "par-dessus" un réseau existant. C'est vicieux, mais cela fonctionne parfaitement. En effet, rien ne vous empêche d'utiliser PPP dans un tunnel pour établir une connexion permanente entre deux hôtes.

Configurez serveur et client comme pour une connexion PPP classique par modem. N'oubliez pas de préciser l'option noauth afin d'éviter d'avoir un message du type "Peer is not authorized to use remote adress xxx.xxx.xxx.xxx" sur le serveur. Vous voici fin prêt à créer votre VPN. Sur la machine serveur, lancez ceci :

stunnel -D 6 -f -d 5555 -L /usr/sbin/pppd -- pppd local

Tout ce qui arrive sur le port 5555 est traité par les routines SSL et envoyé à pppd. Sur la partie cliente :

stunnel -f -D 6 -c -r serveur:5555 -L /usr/sbin/pppd -- pppd local

Pas de mystère, nous connaissons déjà ces commandes. Nous nous retrouvons, sur le client, avec une nouvelle interface réseau qui est le point d'entrée du tunnel SSL :

ppp0      Link encap:Point-to-Point Protocol  
          inet adr:192.168.10.2  P-t-P:192.168.10.1  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:11 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3 

En jetant un coup d'oeil au log système, on se rend vite compte que la connexion ne provient pas d'une ligne série classique (/dev/ttyp9) :

pppd[14569]: Using interface ppp0
pppd[14569]: Connect: ppp0 <--> /dev/ttyp9
pppd[14569]: Deflate (15) compression enabled
pppd[14569]: local  IP address 192.168.10.2
pppd[14569]: remote IP address 192.168.10.1

Idem côté serveur où nous utilisons les PTY Unix 98 :

pppd[9421]: Using interface ppp0
pppd[9421]: Connect: ppp0 <--> /dev/pts/1
pppd[9421]: Deflate (15) compression enabled
pppd[9421]: local  IP address 192.168.10.1
pppd[9421]: remote IP address 192.168.10.2

Le VPN fonctionne parfaitement, nous pouvons même devenir parano au point de créer un autre tunnel à l'intérieur du réseau 192.168.10.0 pour relever nos comptes POP3, au cas où des oreilles traîneraient à l'intérieur du VPN ;)

Finissons cet article en signalant que stunnel n'est pas la seule implémentation de tunneling utilisant SSL. Un projet du nom de SSLwrap propose plus ou moins les mêmes fonctionnalités.

Liens

Stunnel Homepage
http://www.stunnel.org

OpenSSL
http://www.openssl.org

IANA (Internet Assigned Numbers Authority)
http://www.iana.org

SSLwrap
http://www.rickk.com/sslwrap/

Linux Magazine France n°28 - Mai 2001