Il est des fois où il est commode d’avoir une solution de Virtual Private Network (VPN) rapide et facile à mettre en place dans un contexte de Serveur à Serveur. Il y a des solutions comme IPSec, OpenVPN , ou autres qui sont bien connues et assez répandues mais dans notre cas, nous avons fait le choix d’une autre solution :

tinc

Tinc est une solution open-source de VPN, créée en 1998 par Guus Sliepen, Ivo Timmermans, et Wessel Dankers sous licence GPL. Elle devient particulièrement pratique dans le contexte actuel avec la multitude des solutions d’hébergement hybride qui nous impose d’avoir une solution qui puisse être utilisable facilement dans un grand nombre de situation.

Nos trois cas d’usage les plus répandus :

  • Sur une instance dans le cloud
  • Sur un serveur dédié hébergeant des machines virtuelles KVM
  • Dans le cas de serveurs physiques derrière un routeur

Nous allons dans les différents scénarios avoir une installation sur CentOS 7, et nous insisterons sur les points de configuration qui les différencient.

1. Installation sur CentOS 7

Pour installer tinc,, il faut tout d’abord installer le dépôt EPEL via le paquet epel-release :

~# yum install -y epel-release
~# yum install -y tinc net-tools

Ensuite pour simplifier l’organisation des fichiers de configuration, nous allons créer un répertoire. Par exemple pour l’organisation acme :

~# mkdir -p /etc/tinc/acme

Puis on va créer le fichier correspondant à notre routeur VPN :

~# vim /etc/tinc/acme/tinc.conf
Name = <ID>
BindToAddress = <IP Local> 65535
AddressFamily = ipv4
Interface = tinc
ConnectTo = <ID d'un autre noeud>
PMTU = 1518
KeyExpire = 3600
Compression = 10
TCPOnly = yes

On crée ensuite un répertoire hosts pour stocker les configurations de connexion aux différents nœuds :

~# mkdir -p /etc/tinc/acme/hosts

La manière d’authentifier les nœuds et de gérer le chiffrement est fait par clé, il y a un outil pour les générer :

~# tincd -n acme -K4096

Cette commande génère deux fichiers, un correspondant à la clé privée dans le répertoire acme, un autre correspondant à la clé publique dans le répertoire hosts. Ce sera le cas de tous les fichiers dans le répertoire hosts qui ne contiendra que les clés publiques. Une fois les configurations réalisées, il va falloir créer les scripts pour réaliser le routage et démarrer les services :

  • Montée de l’interface tinc
    ~# vim /etc/tinc/acme/tinc-up
    ip address add <IP de l'interface tinc>/24 dev $INTERFACE
    ip route add <Réseau local distant> via <IP de l'interface tinc>
    ~# chmod +x /etc/tinc/acme/tinc-up
    
  • Arrêt de l’interface tinc
    ~# vim /etc/tinc/acme/tinc-down
    ip link set $INTERFACE down
    ip route del <Réseau local distant>
    ~# chmod +x /etc/tinc/acme/tinc-down
    
  • Script systemd
    ~# vim /etc/systemd/system/tinc.service
    [Unit]
     Description=Tinc VPN
     After=network.target
    [Service]
     Type=oneshot
     RemainAfterExit=yes
     ExecStart=/bin/true
     ExecReload=/bin/true
     WorkingDirectory=/etc/tinc
    [Install]
     WantedBy=multi-user.target
    ~# vim /etc/systemd/system/tinc@.service
    [Unit]
     Description=Tinc net %i
     PartOf=tinc.service
     ReloadPropagatedFrom=tinc.service
    [Service]
     Type=simple
     WorkingDirectory=/etc/tinc/%i
     ExecStart=/usr/sbin/tincd -n %i -D --logfile=/var/log/tinc.log --chroot
     ExecReload=/usr/sbin/tincd -n %i -kHUP
     ExecStop=/usr/sbin/tincd -n %i -k
     TimeoutStopSec=5
     Restart=always
     RestartSec=60
    [Install]
     WantedBy=tinc.service
    ~# systemctl daemon-reload
    ~# systemctl status tinc@acme
    
  • Il faut ouvrir le port 65535 sur le pare-feu du système d’exploitation
    ~# firewall-cmd --add-port=65535/tcp --add-port=65535/udp
    ~# firewall-cmd --permanent --add-port=65535/tcp --add-port=65535/udp
    

Si on prend comme exemple un routeur avec le nom Alice et l’autre Bob avec respectivement des réseaux partagés en 192.168.1.0/24 et 192.168.2.0/24, et on définit un réseau d’interconnexion en 10.255.255.0/24, on aura dans les répertoires hosts d’Alice et de Bob en prenant en compte les fichiers tinc-up et tinc-down décrits plus haut :

Sur le routeur Alice :

  • /etc/tinc/acme/tinc.conf
    Name = alice
    BindToAddress = xx.xx.xx.xx 65535
    AddressFamily = ipv4
    Interface = tinc
    ConnectTo = bob
    PMTU = 1518
    KeyExpire = 3600
    Compression = 10
    TCPOnly = yes
    
  • /etc/tinc/acme/hosts/bob
    Address = yy.yy.yy.yy 65535
    Subnet = 10.255.255.2/32
    Subnet = 192.168.2.0/24
    -----BEGIN RSA PUBLIC KEY-----
     [...]
    -----END RSA PUBLIC KEY-----
    

Sur le routeur Bob :

  • /etc/tinc/acme/tinc.conf
    Name = bob
    BindToAddress = yy.yy.yy.yy 65535
    AddressFamily = ipv4
    Interface = tinc
    ConnectTo = alice
    PMTU = 1518
    KeyExpire = 3600
    Compression = 10
    TCPOnly = yes
    
  • /etc/tinc/acme/hosts/alice
    Address = xx.xx.xx.xx 65535
    Subnet = 10.255.255.1/32
    Subnet = 192.168.1.0/24
    -----BEGIN RSA PUBLIC KEY-----
    [...]
    -----END RSA PUBLIC KEY-----
    

À partir de cet instant vous avez une configuration opérationnelle en lançant le service via systemd.

2. Différences entre les trois cas

2.a. Sur une instance cloud

Par rapport à l’installation décrite au dessus, il n’y aura qu’un seul réseau correspondant au réseau d’interconnexion de déclarer, et l’ip en xx.xx.xx.xx correspondra à l’ip publique de l’instance.

2.b. Sur un hyperviseur kvm

Dans le cas d’un hyperviseur kvm, il ne faut pas héberger le daemon tinc sur l’hyperviseur, il est plus facile de dédier une machine virtuelle à cet usage. Pour cela, on défini deux réseaux sur l’hôte :

  • Un réseau NAT en /29 partagé entre l’hyperviseur et la machine virtuelle qui sert de routeur
  • Un réseau Privé pour l’hôte où la machine virtuelle servira de passerelle par défaut aux autres VMs

Dans ce cas, l’IP dans la configuration du tinc correspond à l’IP locale sur le réseau en NAT, et un simple daemon haproxy ou iptable pourra faire le travail, par exemple avec :

~# yum install haproxy
~# vim /etc/haproxy/haproxy.cfg
 [...]
frontend tinc
 bind <IP Public>:65535
 mode tcp
 option tcplog
 default_backend tinc_internal
backend tinc_internal
 mode tcp
 option tcplog
 server tinc <IP dans la VM dans le réseau Nat>:65535
~# firewall-cmd --add-port=65535/tcp --add-port=65535/udp
~# firewall-cmd --permanent --add-port=65535/tcp --add-port=65535/udp
~# systemctl enable haproxy
~# systemctl start haproxy

Dans la configuration, on ajoutera aussi le réseau Privé dans les réseaux partagés, et il faut configurer sur la VM routeur le NAT masquerade pour l’accès à internet.

2.c. Sur un routeur

Dans le cas d’un routeur, c’est le mélange des deux précédents exemples, avec une IP d’écoute correspondant à l’IP publique et l’ajout du réseau des machines physiques dans la configuration.

Conclusion

Pour des réseaux assez simples, avec une modification faible, cette configuration peut être facilement maintenable, en revanche dans le cas d’une infrastructure mouvante, il serait préférable de rajouter des outils de gestion et déploiement de configuration pour gérer les fichiers. Idem pour la partie routage, il serait bon d’ajouter un élément tel que de l’OSPF ou autre pour faciliter l’apprentissage. Il est aussi préférable de gérer un connectTo sur trois noeuds pour permettre une redondance de l’accès en cas de perte de l’un d’eux. En espérant que cela vous donne envie d’essayer et d’adopter Tinc.

Sources