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
.
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
.
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.
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
ping
er 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.
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.
Vous auriez pu deviner l'autre conf.
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.
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
...
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.
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.
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.
Voici la conf tant attendue, ajoutant le cryptage par SSL. Remplacez la précédente, qui ne vaut pas grand chose ...
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!