Installer un VPN en IPv6 avec un serveur OVH
Langues : anglais
dimanche 30 mars 2014
Introduction
Ce tutoriel combine une solution à deux problèmes différents mais assez liés :
- Le fait de vouloir que des machines pas forcément voisines appartiennent au
même réseau
local
. C'est typiquement le rôle d'un VPN - Le fait que la majorité du réseau Internet (IPv4) de nos jours est
constitué de sous-réseaux cachés derrière des routeurs et qu'il est donc
impossible de contacter
publiquement
les machines de ces sous-réseaux à moins d'avoir recours à des redirections de ports (ce qui empêche du coup que deux machines du même réseau proposent le même service sur le même port).
Dans le cas précis que je vais traiter, j'ai un serveur personnel (chez
OVH), possédant une unique adresse IPv4 (198.51.100.24
), et un /64
en IPv6 (2001:db8:200:13::/64
), toutes les deux fixes.
À côté de ça, j'ai plusieurs PCs avec des configurations diverses et des accès à Internet plus ou moins restreints, dans des réseaux différents et non nécessairement connectés entre eux (voire pas dans le même pays) et que j'aimerais relier par un réseau virtuel.
Pour créer le réseau virtuel, deux possibilités s'offrent à nous :
- Soit on crée un sous réseau IPv4 privé (mais alors attention aux maux de têtes si par malheur on branche le pc sur un réseau physique identique)
- Sinon...On a accès à pas moins de 264 adresses IPv6 via notre serveur OVH, qu'on peut mettre à profit !
Création d'un sous-réseau virtuel
Pour créer ce réseau, j'utilise tinc. C'est un programme assez simple, et assez intuitif une fois qu'on a compris en quoi consiste un VPN.
Dans ce cas particulier, la façon d'interconnecter nos machines est assez simple : toutes sont capables de se connecter au serveur (qui a une IPv4 publique). Il suffit donc de demander à chacune de s'y connecter. tinc s'occupe alors de l'interconnexion entre elles !
Partie commune
Cette partie est à faire pour chacun des hôtes du VPN, que ce soit le client ou le serveur :
-
On commence par installer tinc (via les paquets de votre distribution préférée)
-
tinc est capable de gérer plusieurs réseaux VPN, auquel cas on sépare les dossier en créant un sous-dossier dans
/etc/tinc/NAME
pour chaque configuration (NAME
n'a pas besoin d'être le même entre les différents hôtes)- Sur une distribution de type Debian ou dérivé, il faut un fichier
/etc/tinc/nets.boot
qui contienne la liste des dossiers qui sont démarrés automatiquement au démarrage (à condition que le service soit activé) - Sur une distribution qui utilise systemd, il faut activer le(s)
service(s)
tincd@NAME.service
séparément.
- Sur une distribution de type Debian ou dérivé, il faut un fichier
-
On crée le fichier de configuration
tinc.conf
, avec au minimum :Name = NomDeLHote Interface = vpn6 Mode = switch
Ici,
Name
désigne le nom de l'hôte dans le réseau VPN, etInterface
est le nom de l'interface associée au VPN qui sera créée. -
Il faut éventuellement ajouter une ligne
Device
si la valeur par défaut n'est pas correcte.# The tap device tinc will use. # Default is /dev/tap0 for ethertap or FreeBSD, # /dev/tun0 for Solaris and OpenBSD, # and /dev/net/tun for Linux tun/tap device. Device = /dev/net/tun
Si nécessaire, charger le module tun
modprobe tun
-
On crée ensuite le couple clé publique/clé privée qu'on va utiliser pour l'hôte :
tincd -n NAME -K
Mettre la partie publique (en .pub) dans
/etc/tinc/NAME/hosts/NomDeLHote
(en lecture publique, créer le dossier hosts), et garder la partie privée dans/etc/tinc/NAME/
uniquement lisible par root. -
Voilà pour la partie commune.
Partie serveur
La partie serveur est la partie la plus complexe. Plus en détails :
-
tinc peut lancer deux scripts
tinc-up
ettinc-down
s'ils sont présents (et exécutables) dans/etc/tinc/NAME/tinc-{up,down}
au moment du démarrage/de l'arrêt du serveur. Ici, on va avoir besoin d'ajouter quelques commandes :# tinc-up #!/bin/bash echo 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp echo 1 > /proc/sys/net/ipv6/conf/all/forwarding ip -6 link set $INTERFACE up mtu 1280 txqueuelen 1000 ip -6 addr add 2001:db8:200:13:1::1/96 dev $INTERFACE ip -6 route add 2001:db8:200:13:1::/80 dev $INTERFACE ip neigh add proxy 2001:db8:200:13:1::1 dev eth0
et
# tinc-down #!/bin/bash echo 0 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp echo 0 > /proc/sys/net/ipv6/conf/all/forwarding ip neigh del proxy 2001:db8:200:13:1::1 dev eth0 ip -6 addr del 2001:db8:200:13:1::1/96 dev $INTERFACE ip -6 link set $INTERFACE down
Penser à remplacer
eth0
par l'interface sur laquelle arrive l'IPv4, et les IPv6 par les vôtres.
Ici, j'ai fait le choix de n'utiliser que la partie2001:db8:200:13:1::/80
pour le VPN, et d'assigner au VPN la première de ces adresses.
La ligneecho 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp
est importante dans ce cas précis car on ne va donner des adresses que dans la partie en/64
de l'adresse et sans ça les paquets ne seront pas retransmis de l'extérieur du VPN vers l'intérieur (à l'inverse, si on veut rester fermé dans le VPN, on peut enlever cette ligne).
L'explication est un peu floue pour moi, mais si j'ai bien compris les 64 derniers bits de l'adresse sont censés être locaux et donc non routés. Plus précisément, quand le serveur recevra sureth0
une demande de la formeoù puis-je contacter
(par le routeur d'OVH auquel il est attaché), il répondra2001:db8:200:13:1::42
?c'est moi
(sous certaines conditions, on verra ensuite), puis il fera suivre à qui de droit dans le VPN. -
Voilà, la partie
configuration
pour le serveur est essentiellement finie. Il va falloir lui faire connaître ensuite chacun des clients du VPN. On peut mettre de côté le fichier/etc/tinc/Immae/hosts/NomDeLHote
car on va devoir le transmettre à chacun des clients
Partie client
J'utilise ici le terme NomDuServeur
pour désigner le nom du
serveur tel qu'on l'a défini à la ligne Name
dans le fichier
tinc.conf
pour le serveur.
-
Récupérer
/etc/tinc/Immae/hosts/NomDuServeur
sur le serveur et le mettre dans/etc/tinc/Immae/hosts/
(à côté du sien), l'éditer et ajouter une ligne au début :Address = 198.51.100.24
(Remplacer l'ip par l'adresse IPv4 du serveur, ou éventuellement son nom de domaine)
-
Éditer le fichier
tinc.conf
et ajouter les informations pour qu'il se connecte au serveur :# The internet host to connect with. # Comment these out to make yourself a listen-only connection # You must use the name of another tinc host. # May be used multiple times for redundance. ConnectTo = NomDuServeur
-
On va également créer des fichiers
tinc-up
ettinc-down
comme sur le serveur, mais cette fois on n'a pas besoin d'activer de proxy ni de forward :# tinc-up #!/bin/bash ip -6 link set $INTERFACE up mtu 1280 ip -6 addr add 2001:db8:200:13:1::42/96 dev $INTERFACE ip -6 route add default via 2001:db8:200:13:1::1
et
# tinc-down #!/bin/bash ip -6 addr del 2001:db8:200:13:1::42/96 dev $INTERFACE ip -6 link set $INTERFACE down
Il faut bien sûr faire attention à ne pas prendre deux fois la même ip pour deux clients différents du VPN.
Connexion Client-Serveur
J'utilise ici NomDuClient
pour désigner le nom choisi par un
client.
-
Maintenant il faut faire savoir au serveur que le client est autorisé, pour cela il faut envoyer le fichier
/etc/tinc/NAME/hosts/NomDuClient
du client vers le serveur dans le dossier correspondant (en conservant le nom du fichier). -
Finalement, il faut créer deux fichiers (exécutables)
NomDuClient-up
etNomDuClient-down
dans le dossierhosts/
sur le serveur pour mettre en place et détruire le proxy lorsque le client apparaît et disparaît :# hosts/NomDuClient-up #!/bin/bash ip neigh add proxy 2001:db8:200:13:1::42 dev eth0
et
# hosts/NomDuClient-down #!/bin/bash ip neigh del proxy 2001:db8:200:13:1::42 dev eth0
Fin, détails de configuration
Plus qu'à démarrer les différents services tinc sur les machines, et tout le
monde sera interconnecté et pourra accéder au net en IPv6 ! Pour résumer, les
répertoires /etc/tinc/NAME/
devraient ressembler à ça :
# Serveur$ ls -1R /etc/tinc/NAME
/etc/tinc/NAME:
hosts
rsa_key.priv
tinc-down
tinc-up
tinc.conf
/etc/tinc/NAME/hosts:
Serveur
Client1
Client1-up
Client1-down
Client2
Client2-up
Client2-down
et
# Client1$ ls -1R /etc/tinc/NAME
/etc/tinc/NAME:
hosts
rsa_key.priv
tinc-down
tinc-up
tinc.conf
/etc/tinc/NAME/hosts:
Serveur
Client1
Remarque importante
Par défaut, les distributions
récentes de Linux donnent priorité à l'IPv6 pour les connexions Internet. Cela
signifie concrètement que toutes les connexions vont passer en priorité par
votre serveur dès lors que l'IPv6 est disponible pour le service demandé. Pour
éviter cela, on peut éditer le fichier /etc/gai.conf
, dans lequel
une section explique justement comment faire (i.e. donner priorité à l'IPv4).
Notez que cette configuration se fait au choix sur chaque client indépendamment
(voir ci-dessous).
-
Par défaut :
# /etc/gai.conf # Add another rule to the RFC 3484 precedence table. See section 2.1 # and 10.3 in RFC 3484. The default is: # #precedence ::1/128 50 #precedence ::/0 40 #precedence 2002::/16 30 #precedence ::/96 20 #precedence ::ffff:0:0/96 10 # # For sites which prefer IPv4 connections change the last line to # #precedence ::ffff:0:0/96 100
-
Pour donner priorité à l'IPv4 :
# /etc/gai.conf # Add another rule to the RFC 3484 precedence table. See section 2.1 # and 10.3 in RFC 3484. The default is: # precedence ::1/128 50 precedence ::/0 40 precedence 2002::/16 30 precedence ::/96 20 #precedence ::ffff:0:0/96 10 # # For sites which prefer IPv4 connections change the last line to # precedence ::ffff:0:0/96 100