SSH : du port forwarding au VPN bon marché

Table des matières

Quand je suis sur un réseau insecure (wifi, dont la charte précise que des contrôle techniques de bon usage du réseau peuvent être effectués sans préavis, etc. ), je sécurise mes connexions grâce à SSH et à ses fonctionnalités de port forwarding / tunnels. Dans cet article, je souhaite vous faire un retour sur mes découvertes plus ou moins récentes.

Voici une page web qui explique clairement le principe du port forwarding avec SSH et la différence entre une redirection locale (ssh -L) et une redirection distante (ssh -R) : Tynsoe projects.

La redirection locale

Au commencement, j'utilisais une redirection locale afin de rediriger ma navigation internet sur un proxy Squid se trouvant sur un serveur "at home". Donc une bête ligne de commande comme celle-ci suffisait :

ssh -NL8080:localhost:3128 login@host

Ensuite, je configurais mon navigateur pour utiliser le proxy HTTP/HTTPS suivant :

  • Hôte : 127.0.0.1
  • Port : 6666

Et dans les rares cas ou j'avais besoin d'un autre service, je transférais un autre port en même temps :

ssh -NL8080:localhost:3128 -L2200:serveurSSH:22 login@host

Je pouvais alors surfer tranquillement et me connecter à la machine serveurSSH via l'adresse 127.0.0.1:2200

La redirection dynamique

Ensuite, j'ai voulu utiliser plus de services (mail, messagerie instantané, etc.) et j'ai donc trouvé les limites de la redirection locale de ports (transférer tous ces ports à la mano c'est pas top). De plus, mon serveur proxy était en panne. Mais j'ai découvert la redirection dynamique (ssh -D). Du coup, c'est mon fidèle WRT54GL qui me sert de proxy.

Maintenant, une simple ligne de commande suffit pour avoir accès à tous mes services :

ssh -ND 6666 login@host

Ensuite, il faut définir un proxy SOCKS dans les paramètres de chaque application dont vous avez besoin :

  • Hôte : 127.0.0.1
  • Port : 6666

Remplacez 6666 par le port que vous avez choisi lors de l'initialisation de la connexion SSH.

Se pose une première problématique : que faire si l'application ne possède pas une telle option ?
Se pose ensuite une seconde problématique : certains applications n'utilise pas le proxy pour faire transiter certaines informations. C'est typiquement le cas de la résolution d'un nom de domaine via le protocole DNS. A quoi peut bien servir un tunnel si le réseau insecure arrive encore à voir une partie de notre trafic réseau ?

Ces deux questions trouvent la même réponse : il faut utiliser un programme qui capture les "appels réseau" d'un programme et force la redirection de ceux-ci dans le tunnel SSH. Il en existe plusieurs : tsocks, torsocks, proxychains, etc. . Il fait néanmoins faire attention : certains laisse encore passer les fameuses requêtes DNS entre les mailles de leur filet. Personnellement, j'utilise proxychains et je n'ai jamais rencontré de problèmes.

EDIT 09/01/2011 19h35 : Il faut dire aussi que mon choix pour proxychains a été influencé par les différents inconvénients qui apparaissent sur les alternatives :

  • La version de tsocks disponible sur sourceforge laisse fuiter les résolutions DNS, à moins d'appliquer un patch. De plus, je rencontre beaucoup d'erreur de segmentation avec des applications courantes
  • Torsocks me sort une erreur de segmentation pour quelques uns de mes programmes. Néanmoins, il y a quand même des progrès, par rapport à tsocks, sur ce point là.
  • Dsocks me paraissait un peu "brouillon" avec son script python servant de forwardeur DNS. De plus, le script ne fonctionne pas et me lève des exceptions.
  • Socat est une alternative que je n'ai pas essayé mais qui me parait plus que correcte mais lourde à utiliser.

Le fichier de configuration (/etc/proxychains.conf) est d'une simplicité enfantine. Voici le mien (j'ai supprimé quelques commentaires mais je vous invite à les lire dans votre fichier) :

# Strict - Each connection will be done via chained proxies
# all proxies chained in the order as they appear in the list
# all proxies must be online to play in chain
# otherwise EINTR is returned to the app
strict_chain

# Quiet mode (no output from library)
quiet_mode

# Proxy DNS requests - no leak for DNS data
proxy_dns

[ProxyList]
socks5 127.0.0.1 6666

Il ne vous reste plus qu'à utiliser proxychains :

proxychains firefox
proxychains thunderbird
proxychains filezilla
proxychains pidgin
...
sudo proxychains apt-get update/install

Il ne vous reste plus qu'à modifier les raccourcis de votre menu (Gnome, KDE, etc.) afin d'inclure proxychains dans la commande à lancer pour les programmes dont vous souhaitez qu'il passent via le tunnel SSH.

A noter quand même que certains logiciels jouent le jeu et ne laisse pas filer les requêtes DNS, même sans utiliser proxychains. C'est le cas par exemple de Firefox, une fois la valeur "true" passée à l'option booléenne "network.proxy.socks_remote_dns" dans le about:config. Par contre, je n'ai pas constaté d'améliorations en faisant la même manipulation sous Thunderbird.

EDIT 09/01/2011 22h00 : Pour plus d'information sur le transfert des requêtes DNS via un proxy SOCKS, voir cet article : SSH, redirection dynamique, proxychains et DNS.

Vous comprenez que votre meilleur ami ici sera Tsark/Wireshark (ou n'importe quel autre programme d'analyse du trafic réseau), afin de tester qu'aucun flux transite en clair. Il apparait évident de procéder à ces tests avant d'aller dans le réseau insecure. Un iptables correctement paramétré permet également d'éviter les fuites causées par les démons ou par les programmes que l'utilisateur aurait oublié de proxyfier. Voir ce billet à ce sujet : Configuration rapide d’iptables pour les réseaux insecures.

ÉDIT 23/02/2011 22h45 :

Lorsque vous n'utilisez pas votre tunnel SSH, la connexion est fermée automatiquement. Pour maintenir la connexion, il suffit de se rappeler de la notion de keepalive.

Encore une fois, je ne réinventerai pas la roue puisqu'une recherche sur Google vous conduira sur ce blog : Aaron Toponce : Keeping Your SSH Connection Alive.

J'ajouterai cependant que vous pouvez définir le paramètre "ServerAliveInterval" dans le fichier /etc/ssh/ssh_config, ce qui évite de le répéter lors de chaque connexion. Personnellement, je définis un intervalle de 5 minutes soit 300 secondes : c'est amplement suffisant pour maintenir la connexion.

Si toute cette méthode vous semble encore trop contraignante, il vous reste encore la possibilité de vous monter un VPN avec OpenVPN. Je me suis penché sur cette alternative mais, malheureusement, mon WRT54GL n'a pas assez d'espace libre pour accueillir la libssl nécessaire au fonctionnement d'OpenVPN. Donc je n'ai pas creusé le sujet plus loin. Néanmoins, excellents tutoriel existent sur le net.

Un VPN bon marché avec SSH

Il y a quelques jours, je me disais qu'il devait y avoir un moyen de s'amuser avec SSH et les interfaces tun/tap. Je me tourne vers mon ami Google afin d'avoir une idée sur la marche à suivre. Je découvre alors que d'autres personnes ont eu mon idée depuis bien longtemps et notamment les développeurs d'openSSH qui permet, depuis sa version 4.3, de créer un tunnel de niveau 3 grâce aux interfaces virtuelles tun. Si j'étais un "artiste" ou un patent troll, je porterai plainte ... oser me voler mon idée que je n'avais pas à l'époque, c'est quand même scandaleux ! ;) .

Voici les tutoriels qui m'ont éclairés sur le sujet :

J'ai évidemment voulu tester tout ça, en utilisant la méthode manuelle (sans ifup), avec une machine virtuelle, avant une mise en production sur mon WRT54GL. Il n'y a aucune difficulté et ça fonctionne très bien (avec la machine virtuelle).

Malheureusement, dropbear, le serveur ssh allégé fourni par défaut avec OpenWRT, ne supporte pas ce type de tunnel. Installer OpenSSH sur mon routeur pose le même problème que celui de l'installation d'OpenVPN : la nécessaire libssl est trop lourde.

Donc je suis contraint d'utiliser un tunnel dynamique pour sécuriser mes connexions depuis un réseau insecure. Pour l'instant, cela me convient. Mais il faudra quand même que je songe à greffer une carte mémoire à mon WRT54GL.

Une dernière chose : comme signalé dans les commentaires de Debian Administration ou sur la page de la Community Ubuntu Documentation, la méthode de VPN over SSH n'est pas la meilleure solution du fait que le protocole SSH repose sur TCP et que l'on va faire circuler des trames TCP dans ce tunnel. Cette solution est impeccable quand il n'y a pas de problèmes sur le(s) réseau(x) traversé(s), mais dans le cas d'une perte de paquet, on assiste à un effondrement interne de la connexion. C'est pour cela qu'il veut mieux utiliser un VPN basé sur OpenVPN, configuré en UDP, bien entendu.

Je vous invite à lire ces deux documents, le deuxième étant la traduction, en français, du premier, afin d'avoir plus d'informations sur le sujet :

Note : dans cet article, je me préoccupe des systèmes UNIX/UNIX-like. Mais sous Windows, PuTTY permet la redirection locale, distante et dynamique. Ensuite, il doit exister des équivalents de proxychains, torsocks. Enfin, cygwin doit permettre de monter un VPN over SSH mais je ne me suis pas renseigné sur ce point.

Aucun commentaire.

Ajoutez votre commentaire