Tinc - VPN de Mesh
Introduction
Je dispose de 3 serveurs différents:
- Un serveur dédié en cloud (avec une dizaine de VMs)
- Un cluster de raspberry à la maison (4 machines)
- Et un serveur de redondance dans un autre DC
Et juste avec ces machines, ça fait un bon nombre d’accès à gérer sur ma workstation. De plus, les machines peuvent difficilement communiquer entre elles (en local je passe par des redirections ssh), et il m’est impossible de faire communiquer mes machines sans ouvrir un accès.
C’est pourquoi j’étais en pleine recherche d’une solution comme Wireguard en tant que VPN Mesh (exemple ici), et je suis tombé sur un article de ZWindler expliquant sa solution autour de Tinc.
Cette page n’est qu’une reprise de son tutoriel en réadaptant certains points.
Installation du serveur
La machine hote de l’hébergeur est une VM sur mon dédié ayant Debian 11 comme distribution. Tinc est directement disponible sur les dépots officiels sans aucune action (pas besoin d’ajouter les paquets unstables)
apt install tinc
Dans mon cas, je créé “vpnforky” (forky étant le nom de mon dédié), celui-ci doit être déclaré dans le fichier nets.boot si vous utilisez sysvinit (sinon on pourra passer par systemd)
mkdir -p /etc/tinc/vpnforky/hosts
echo "vpnforky" >> /etc/tinc/nets.boot # inutile si vous utilisez systemd
Nous allons créer le fichier /etc/tinc/vpnforky/tinc.conf
pour définir le nom de notre machine. (servertinc dans mon cas)
Name = servertinc
AddressFamily = ipv4
Interface = tun0
Puis on va créer le fichier réprésentant notre machine dans le réseau du VPN ainsi que l’endpoint (ip) accessible par toutes les machines
Address = 100.100.100.100
Subnet = 10.0.0.1/32
Ce fichier sera complété par génération des clés RSA permettant l’authentification des machines du réseau.
sudo tincd -n vpnforky -K4096
Nous allons également créer 2 scripts Bash pour configurer notre IP Privée dans le réseau mesh. /etc/tinc/vpnforky/tinc-up
#!/bin/sh
ip link set $INTERFACE up
ip addr add 10.0.0.1/32 dev $INTERFACE
ip route add 10.0.0.0/24 dev $INTERFACE
/etc/tinc/vpnforky/tinc-down
#!/bin/sh
ip route del 10.0.0.0/24 dev $INTERFACE
ip addr del 10.0.0.1/32 dev $INTERFACE
ip link set $INTERFACE down
et rendre ces scripts executales
chmod 755 /etc/tinc/vpnforky/tinc-*
Nous n’avons plus besoin de faire quoique ce soit pour configurer le serveur. (Nous reviendrons un peu plus tard pour autoriser des machines à se connecter)
On démarre le VPN
sudo systemctl status tinc@vpnforky
Installation d’un client
Maintenant, on va créer notre premier hote externe au réseau. Mon client se nomme “offsite”
apt install tinc
mkdir -p /etc/tinc/vpnforky/hosts
On va créer notre fichier /etc/tinc/vpnforky/tinc.conf
Name = offsite
AddressFamily = ipv4
Interface = tun0
ConnectTo = servertinc
Notez que maintenant, nous avons un ConnectTo qui permettra de dire quelle machine est notre serveur.
On créé le fichier hote (qui sera complété automatiquement) /etc/tinc/vpnforky/hosts/offsite
Subnet = 10.0.0.2/32
Génération des clés
tincd -n vpnforky -K4096
Et comme pour le serveur, on créé les scripts de configuration réseau /etc/tinc/vpnforky/tinc-up
#!/bin/sh
ip link set $INTERFACE up
ip addr add 10.0.0.2/32 dev $INTERFACE
ip route add 10.0.0.0/24 dev $INTERFACE
/etc/tinc/vpnforky/tinc-down
#!/bin/sh
ip route del 10.0.0.0/24 dev $INTERFACE
ip addr del 10.0.0.2/32 dev $INTERFACE
ip link set $INTERFACE down
et rendre ces scripts executales
chmod 755 /etc/tinc/vpnforky/tinc-*
Maintenant que notre client est bien configuré, nous allons copier le fichier /etc/tinc/vpnforky/hosts/offsite
(contenant notre IP-VPN et notre certificat) vers le dossier /etc/tinc/vpnforky/hosts du serveur Tinc. Cela permettra d’authentifier notre machine pour se connecter au réseau.
Notre machine possède bien la bonne IP et on peut maintenant ping dans notre réseau.
root@offsite:~# systemctl start tinc@vpnforky
root@offsite:~# ping -c 3 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=157 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=156 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=156 ms
Les délais sont assez élevés, je pense que c’est dû à ma VM Tinc qui n’est pas puissante, et ne possède pas un grand débit.
S’il faut ajouter d’autres machines, il faudra suivre la même procédure (Installer tinc, générer certificat et fichier hôte, ajouter le fichier sur le serveur).
Configuration Nix pour rejoindre le réseau Tinc
Voici le fichier Nix me permettant de rejoindre le VPN avec l’ip 10.0.0.101.
{ config, pkgs, ... }:
let
myMeshIp = "10.0.0.101";
myMeshMask = "255.255.255.255";
myMeshName = "vpnforky";
in {
networking.firewall.enable = false; # todo : ajouter seulement bon port
environment.etc = {
"tinc/vpnforky/tinc-up".source = pkgs.writeScript "tinc-up-vpnforky" ''
#!/bin/sh
${pkgs.iproute2}/bin/ip link set $INTERFACE up
${pkgs.iproute2}/bin/ip addr add 10.0.0.101/32 dev $INTERFACE
${pkgs.iproute2}/bin/ip route add 10.0.0.0/24 dev $INTERFACE
'';
"tinc/vpnforky/tinc-down".source = pkgs.writeScript "tinc-down-vpnforky" ''
#!/bin/sh
${pkgs.iproute2}/bin/ip addr del 10.0.0.101/32 dev $INTERFACE
${pkgs.iproute2}/bin/ip route del 10.0.0.0/24 dev $INTERFACE
${pkgs.iproute2}/bin/ip link set $INTERFACE down
'';
};
networking.interfaces."tinc.${myMeshName}".ipv4.addresses = [{ address = myMeshIp; prefixLength = 32; }];
services.tinc.networks."${myMeshName}"= {
name = "nixwork"; # le nom de notre machine
debugLevel = 4;
chroot = false;
interfaceType = "tap";
extraConfig = ''
ConnectTo = servertinc
ExperimentalProtocol = yes
PrivateKeyFile = "/etc/tinc/vpnforky/rsa_key.priv" # ce fichier doit avoir +r en permission
'';
hosts = {
servertinc = ''
Address = 100.100.100.100
Subnet = 10.0.0.1/32
-----BEGIN RSA PUBLIC KEY-----
censored
-----END RSA PUBLIC KEY-----
'';
nixwork = ''
Subnet = 10.0.0.101/32
-----BEGIN RSA PUBLIC KEY-----
censored
-----END RSA PUBLIC KEY-----
'';
};
};
security.sudo.extraRules = [
{
users = [ "tinc.vpnforky" ];
commands = [
{
command = "${pkgs.nettools}/bin/ip";
options = [ "NOPASSWD" ];
}
];
}
];
networking.extraHosts = ''
10.0.0.1 servertinc
10.0.0.2 offsite
'';
}