Cette page a été initialiement écrite par David Baelde qui m'a ensuite chargé de l'héberger et de la maintenir.

OpenVPN à fond la caisse

Argh et Igloo veulent se parler à travers le/les firewalls qui les séparent. Un ou deux tunnels ssh ne leur suffisent pas, il leur faut une floppée de ports UDP pour faire du gnomemeeting.

Autre problème, Youpi a toujours besoin d'accès à différents services dans le LAN bien protégé de l'ENS Lyon. Il ne veut pas se farcir de trente tunnels ssh ... Pour Sparshong c'est pire, il lui faut faire passer de l'UDP!

Une solution chouette, c'est openvpn. Ce logiciel crée une interface réseau à part entière entre les deux zigotos -- ou entre Youpi et un zigoto de l'ENS. Une fois le tunnel lancé, Igloo pourra parler à Argh (et réciproquement) comme si elle était à côté de lui, sans firewall, à une adresse locale quelconque. Dans la suite je suppose qu'on va donner 192.168.0.1 à Igloo et 192.168.0.2 à Argh. En plus, on verra dans un second temps comment crypter ce canal de communication pour que les amoureux puissent se dire des cochonneries en privé.

Avant de vous lancer dans la bidouille, sachez quand même qu'il faut être root pour lancer les deux côtés du tunnel. Vous devez aussi avoir le support de /dev/tun* dans votre noyau, le flag c'est CONFIG_TUN.

Installation

Sous Gentoo : emerge openvpn, classique. Ensuite, créez le répertoire /etc/openvpn/test, ou un autre nom plus fun. C'est là qu'on mettra la conf pour un test de tunnel. Le script d'init d'openvpn lance un tunnel pour chaque /etc/openvpn/*/local.conf.

Montage simple

Voici le local.conf de chez Igloo qui va ouvrir un simple tunnel non crypté entre les deux machines. En commentaire, la modification à faire pour obtenir la conf à mettre chez Argh.

remote argh.is-a-geek.org # igloo.is-a-geek.org dev tun ping 30 ifconfig 192.168.0.1 192.168.0.2 # échanger ces IPs port 4000

En gros ça dit : ouvre une interface tun vers Argh, elle sera 0.2 et moi 0.1. Le point obscur c'est port 4000, ça c'est pour éviter un conflit avec une autre appli éventuellement (5000 par défaut) ...

Une fois les confs recopiées, lancer les tunnels, à la main pour l'instant, et en root : openvpn --config local.conf. Cela doit être fait des deux côtés. Si tout va bien yaura un tun0 dans votre ifconfig et Igloo (resp. Argh) pourra pinger 192.168.0.2 (resp. 192.168.0.1).

Si les firewalls ne sont pas trop bêtes, il parait que le tunnel passe à travers. Sinon ya moyen de faire passer le vpn à travers un tunnel ssh, en tcp.

Un tunnel par un port TCP, un tunnel dans un tunnel SSH

Ce bricolage formidable m'a permis de venir à bout du réseau super restrictif que j'ai dans mon labo au Japon. Les machines sont sur un réseau local mais il n'y a pas de passerelle. Seulement un serveur mail, un proxy http. Et enfin, ssh possible sur la machine connectée à Internet, nommée moon.

D'abord on donne à Argh le droit de se loguer sur moon. Pour cela, copier le ~/.ssh/id_dsa.pub de Argh à la fin du ~/.ssh/authorized_keys sur moon.

D'abord on établit un tunnel entre Argh et Igloo. Pour cela, Igloo fait ssh moon -R 5000:localhost:5000 et Argh ssh dbaelde@moon -L 5000:localhost:5000.

Une fois ceci fait on lance très simplement le VPN, des deux côtés, localhost:5000 pointe vers l'autre. Comme les adresses en 192.168.* sont utilisées pour le réseau local du côté de l'Igloo, on choisit celles en 10.0.0.* pour le VPN.

# Chez Igloo remote localhost dev tun ping 30 ifconfig 10.0.0.2 10.0.0.3 proto tcp-server port 5000

Vous auriez pu deviner l'autre conf.

# Chez Argh remote localhost dev tun ping 30 ifconfig 10.0.0.3 10.0.0.2 proto tcp-client port 5000

Au passage, comme la communication est cryptée par le tunnel ssh, pas la peine de se compliquer la vie avec SSL dans ce cas là.

Si pour une certaine raison vous avez besoin de faire passer le tunnel VPN par TCP, sans pour autant utiliser un tunnel ssh, il suffit bien sûr de remplacer localhost dans chaque fichier par le nom de l'autre bout du tunnel.

On crypte avec SSL

C'est là que ça devient dur. D'ailleurs je vais vous dire ce que j'ai fait, pas ce que j'ai compris car ce n'est pas très clair!

Je me suis aidé de man openvpn qui dit bien ce qu'il faut faire dans la doc des options --ca, --dh, --cert. Ce qui est chiant c'est que SSL n'était pas configuré chez moi, j'ai du le faire pour l'occasion.

Passons donc dans /etc/ssl...

L'autorité

Je vais supposer que vous partez de zéro comme moi, qu'avait pas d'autorité sous la main ... On la génère sur une des deux machines. Igloo par exemple ici. openssl req -nodes -new -x509 -days 3650 -keyout igloo-ca.key -out igloo-ca.crt Ca pose des questions chiantes, répondez attentivement, et pas n'importe quoi, il faudra remettre les mêmes réponses ailleurs plus tard. L'option days permet de préciser la durée de validité du certificat. On en met une longue ici parce qu'on n'est pas les services secrets, et la valeur par défaut de 30 jours c'est emmerdant.

Mettons cela en lieu sûr. mkdir private ; mv igloo-ca.key private ; mv igloo-ca.crt certs. Sur certaines distributions, private existe déjà, ou pas certs, ajustez en fonction. En tout cas, la clef étant très importante, elle ne doit être accessible qu'à root. Changez donc les droits d'accès en fonction, par exemple avec chmod 600 private/igloo-ca.key. Si tout le répertoire private était déjà en mode 700, ça suffit.

Les certificats

On a une autorité qui en gros va valider des certificats. On va générer deux certifs, un pour Argh et un pour Igloo. On pourra utiliser l'autorité d'Igloo pour signer ces deux papiers.

D'abord on le fait sur Igloo. Toujours d'après la page du manuel : openssl req -nodes -new -keyout igloovpn.key -out igloovpn.csr . On répond soigneusement les mêmes choses que tout à l'heure. On bloque la lecture sur le .key et on le met au chaud dans private. Ensuite on fait valider sa demande de certif par l'autorité : openssl ca -policy policy_anything -out igloovpn.crt -in igloovpn.csr.

Il faut préciser un "common name" différent de celui utilisé dans l'autorité. Par contre, théoriquement, à part ce "common name" différent, il faudrait utiliser la même organisation que dans l'autorité. L'option -policy policy_anything est passée ci-dessus à openssl pour désactiver cette contrainte. Si toute fois vous souhaitez utiliser la solution propre (sans -policy policy_anything) et donc voulez entrer la même organisation (sauf le "common name") mais avez oublié ce que vous avez mis dans l'autorité, faites openssl x509 -text -in /etc/ssl/certs/igloo-ca.crt et regardez par exemple le champ O= pour savoir l'organisation à mettre dans les certificats.

C'est là que ça ne marche pas ... Il faut éditer /etc/ssl/openssl.cnf. Voici la partie que j'ai changée chez moi. En gros je me suis laissé guider par les erreurs de la commande précédente.

[ CA_default ] dir = /etc/ssl certs = $dir/certs crl_dir = $dir/crl # Ne m'a pas servi, n'existe pas d'ailleurs ... database = $dir/index.txt # Il faut le créer avec un touch par exemple. new_certs_dir = $dir/newcerts # A créer avec mkdir certificate = $dir/certs/igloo-ca.crt # Le CA qu'on a créé plus haut serial = $dir/serial # Initialiser: echo 01 > /etc/ssl/serial crl = $dir/crl.pem # Pas servi ... private_key = $dir/private/igloo-ca.key # The private key

Pour ceux qui ne lisent pas les commentaires, pensez bien à créer et initialiser ce qu'il faut : mkdir newcerts ; echo 01 > serial ; touch index.txt .

Voila, vous devriez avoir réussi à créer le certificat. On le range dans certs pour faire propre.

Chez Argh on génère la clé privée, et la demande de certif : openssl req -nodes -new -keyout arghvpn.key -out arghvpn.csr. On range et sécurise la clé, et on envoir le csr à Igloo par un scp par exemple, ou tout autre moyen même pas forcément sécurisé. Chez Igloo on valide cette demande : openssl ca -out arghvpn.crt -in arghvpn.csr. Enfin, on renvoie à Argh son certif arghvpn.crt ainsi que l'autorité igloo-ca.crt, qu'elle range tous deux dans certs. On peut virer tous les csr partout.

Enfin, Argh va jouer le rôle de serveur dans l'échange des clés lors de l'initialisation de la communication. Il lui faut pour cela un fichier supplémentaire décrivant le protocole d'échange. openssl dhparam -out dh1024.pem 1024 le crée sans encombre.

Le tunnel, enfin

Voici la conf tant attendue, ajoutant le cryptage par SSL. Remplacez la précédente, qui ne vaut pas grand chose ...

remote argh.is-a-geek.org # changer en igloo chez Argh dev tun ping 30 ifconfig 192.168.0.1 192.168.0.2 # permuter port 4000 tls-client # tls-server chez Argh # chez Argh il faut ajouter: dh /etc/ssl/dh1024.pem ca /etc/ssl/certs/igloo-ca.crt cert /etc/ssl/certs/igloovpn.crt # changer igloo en argh key /etc/ssl/private/igloovpn.key # idem

Relancer les tunnels ... si tout va bien (ping), les lancer en tâche de fond avec /etc/init.d/openvpn start. Un côté du tunnel ne meurt pas si l'autre n'est pas là, on peut donc même mettre ce service par défaut chez Igloo et Argh. Attention quand même, l'IP de Argh n'est lue qu'une fois à l'init du tunnel chez Igloo. Alors si Argh démarre avec une autre IP, ça ne va pas marcher.

Il est possible de rediriger plus de trafic à travers ce tunnel, avec l'option route. C'est utile pour percer les firewalls vers un LAN complet d'un coup, comme Youpi. Par exemple, route 140.77.0.0 255.255.0.0 dans la conf de Youpi déroute le trafic vers 140.77.*.* (l'ENS) à travers son tunnel. Mais attention, dans ce cas, si l'extrémité du VPN est située dans ce sous-réseau 140.77.*.*, les paquets formant le VPN vont eux-mêmes passer dans le VPN. Il faut donc exclure explicitement l'adresse de l'extrémité du VPN en forçant sa route à utiliser le réseau normale (en particulier la passerelle normale). Pour ce faire, on ajoute ensuite route argh.is-a-geek.org gw <ma_passerelle_normale>.

Et encore merci à Youpi et Grincheux!