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.
-
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, et
Interface
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
-
On crée ensuite le couple clé publique/clé privée qu'on va utiliser pour
l'hôte :
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
et
tinc-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 partie
2001:db8:200:13:1::/80
pour le VPN, et d'assigner au VPN la
première de ces adresses.
La ligne echo 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 sur eth0
une demande de la
forme où puis-je contacter 2001:db8:200:13:1::42
?
(par le routeur d'OVH auquel il est attaché), il répondra 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 :
(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
et
tinc-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
et
NomDuClient-down
dans le dossier hosts/
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).