Configuration d'une connexion VPN respectueuse de la neutralité du net pour l'ensemble de mes terminaux
I. Expression des besoins
Je dispose d’un abonnement VPN auprès d’un FAI associatif. Grâce à cet accès qui respecte la neutralité du net, je possède une adresse IPv4 publique, un bloc d’adresses IPv6 globales en /48.
Le problème s’avère être la diffusion d’une seule configuration à disposition de l’adhérent. Ainsi, si l’on fait le choix de la mettre en place sur son ordinateur, on monopolise cet accès pour un seul et unique équipement. Impossible de l’utiliser simultanément sur un smartphone et un autre PC en même temps.
J’ai donc décidé de remédier à ce problème en louant un VPS pour quelques euros par mois. Ce VPS servira de relais entre mes différents clients VPN et la connexion VPN offerte par mon FAI associatif. Cela me permettra relativement facilement d’exploiter ce service pour l’ensemble des périphériques à ma disposition.
II. Prérequis
- Un VPS avec Debian 12 disposant d’une adresse IPv4 publique, d’une adresse IPv6 globale.
- Le paquet openvpn installé sur le VPS.
- Les fichiers de configuration clients pour la connexion VPN vers le serveur du FAI associatif.
- Activation du routage, utilisation d’iproute2, de netfilter, et du routage PBR sur le VPS.
- Un client OpenVPN sur les terminaux.
III. Schéma réseau logique de l’architecture proposée
IV. Mise en oeuvre technique
Sur le papier l’idée semble plutôt simple :
- Utilisation d’un VPS avec OpenVPN et enjoy.
En réalité, quelques éléments importants doivent être pris en compte :
- Tout le trafic émis et reçu par le serveur VPS doit passer par la carte réseau (ens3) classique de la machine et non pas par le tunnel VPN (tun0).
- À contrario, le trafic correspondant aux clients devra être routé dans le tunnel VPN à destination du FAI associatif afin d’utiliser l’adresse IPv4 publique qui m’a été assignée.
C’est là que la notion de routage basé sur les stratégies (PBR) intervient. Contrairement au routage statique traditionnel qui se base sur l’adresse IP de destination du paquet, le routage PBR est une technique de routage basée sur des filtres particuliers supplémentaires. Ainsi, il est possible de définir une stratégie de routage en fonction de paramètres spécifiques tels que les adresses IP sources, les ports, la taille du paquet, etc.
A. Configuration de la connexion VPN cliente sur le VPS vers le FAI associatif
Tout d’abord, il est nécessaire d’installer les paquets indispensables sur le VPS Debian 12.
Puis, il faut se déplacer dans le répertoire /etc/openvpn/client/ et passer à la configuration de la connexion vers le serveur VPN du FAI associatif.
Nous récupérons le certificat X509 de l’autorité de certification du FAI associatif.
Nous définissons ensuite un nouveau fichier contenant le login et le mot de passe nous permettant de nous authentifier sur le serveur OpenVPN du FAI associatif.
bram.moolenaar@fdn.fr
FREEasinfreedom
Enfin, nous définissons un fichier de configuration client.
# C'est nous qui prenons l'initiative de nous connecter au serveur.
client
# On route de l'IP, on ne fait pas de l'ethernet.
dev tun
# Certains réseaux ont en fait une MTU bien inférieure à 1450. Dire aux connexions
# TCP d'être très conservatives, pour que ça marche plus ou moins partout.
#mssfix 1300
# En UDP, on peut s'assurer que ça passe de toutes façons en fragmentant au besoin
# quand ça dépasse.
# fragment 1300
# Idéalement, ça devrait être détecté tout seul, mais c'est loin de toujours fonctionner...
# mtu-disc yes
# Ne pas utiliser un port local statique, on est client de toutes façons.
nobind
# Il est préférable d'utiliser udp, le résultat fonctionne mieux. Il est
# cependant notable que les restrictions d'accès Internet laissent souvent
# plus facilement passer tcp. Essayer donc udp, et seulement s'il ne fonctionne
# pas, essayer tcp.
server-poll-timeout 3
# Les adresses des serveurs.
<connection>
remote vpn.fdn.fr 1194
explicit-exit-notify
</connection>
<connection>
remote vpn-rw.fdn.fr 53
explicit-exit-notify
</connection>
<connection>
remote vpn.fdn.fr 1194 tcp
</connection>
<connection>
remote vpn-rw.fdn.fr 80 tcp
</connection>
<connection>
remote vpn-rw.fdn.fr 443 tcp
</connection>
<connection>
remote vpn-rw.fdn.fr 993 tcp
</connection>
<connection>
remote vpn-rw.fdn.fr 22 tcp
</connection>
# Éventuellement, on peut avoir besoin de passer par un proxy http, décommenter cette ligne en mettant l'adresse et le port du proxy.
#http-proxy 192.0.2.1 8080
# Pour windows: utiliser route.exe.
#route-method exe
# Attendre un peu avant d'ajouter les routes.
route-delay 2
# Garder la clé en mémoire, pour ne pas avoir besoin de la relire lors d'un
# redémarrage.
persist-key
# On peut éventuellement ne pas tuer l'interface du tunnel lors d'un redémarrage, mais cela pose problème pour
# résoudre le nom de domaine du serveur si les résolutions DNS passent par le VPN, et aussi si au redémarrage
# on change de serveur (changement de passerelle).
#persist-tun
# Faire passer tout le trafic via le VPN:
#redirect-gateway def1
# Mais pas le trafic local:
#route 10.0.0.0 255.0.0.0 net_gateway
#route 172.16.0.0 255.240.0.0 net_gateway
#route 192.168.0.0 255.255.0.0 net_gateway
# Ajouter éventuellement d'autres routes locales, par exemple vers votre cache DNS
# Activer IPv6
tun-ipv6
# et faire passer tout le trafic IPv6 via le VPN:
#route-ipv6 ::/1
#route-ipv6 8000::/1
# On peut aussi vouloir plutôt router seulement quelques destinations, par
# exemple ici tout Gitoyen:
#route 80.67.160.0 255.255.224.0
# Envoyer un login et un mot de passe. Pour éviter de taper à la main login
# et mot de passe, vous pouvez ajouter à droite de "auth-user-pass" le nom d'un
# fichier contenant ces deux informations, une par ligne.
#auth-user-pass
auth-user-pass /etc/openvpn/client/auth-vpn.conf
# Un minimum de debug, c'est toujours bien.
verb 3
# Certificat permettant de vérifier que c'est bien à FDN que
# l'on se connecte et donc à qui on donne notre mot de passe.
verify-x509-name *.fdn.fr name
<ca>
-----BEGIN CERTIFICATE-----
MIIFGTCCAwGgAwIBAgIEWgh7mjANBgkqhkiG9w0BAQsFADAsMQswCQYDVQQGEwJG
UjEMMAoGA1UEChMDRkROMQ8wDQYDVQQDEwZDQSBGRE4wHhcNMTcxMTEyMTY0OTMx
WhcNMzcwMTExMTY0OTQzWjAsMQswCQYDVQQGEwJGUjEMMAoGA1UEChMDRkROMQ8w
DQYDVQQDEwZDQSBGRE4wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/
kZzJVsN4vpK7phHW7sX4UpJ1bEd1BveKBATiMTDIOY8ioVv7tAmNOSTABBi8KYzS
LmflAVgsMGh1JI4+b5O4ZN1DKjKp9WAkJZvotsmHnCYsKBhoYc4JqkZQgG2s7zOm
b7eigEWZQf0F5PIaNUzT2nZZlIjxnv7DiAI+lu46qWQfu09IAca4DyN3ViFmlv03
PD4QpTqdungSWCr2gv3VOVF3yX1+b/P4kX7oWae+U2XFL9hYDUuWaFFdWCTzSRvv
JV7QMSflicb7fCRKC6E2r8x7igxyzr5NT6NAkYWvazgyNc7NOsy2hJ9EkN4IWs/0
GORkzYKBcA0MMFdt5CgbAPBFXleLwoaFpZ4BVkFIhREJHNgK6ZFfK60U4O+F552R
QZPbgD+5geJOi6XbrBD3lQ/yb3qaNoejo1g39D7h571rPRYorDlTj6BZ925D+A+7
Mb6DOZMxYUfQ6SYqZSnWf7aivdLpNNsN8K0un8Z2BB98eK6cIhUv298FxF0+tSZI
ok9T5SxF8URU2VfI6wVcSVRh8Q5aeKf2NINIxN6wrBYSwAls3gkwDEsAny+tCwwL
3hy3Y7SEvg+ItFS+d2RYdqav72Av5H2o6Uxr9025ZPKo89/Czd6XPID96znK2x/N
l851UCjHfvNG2xzRqJa0HhUl2pLyEMpC62g31wKv+wIDAQABo0MwQTAPBgNVHRMB
Af8EBTADAQH/MA8GA1UdDwEB/wQFAwMHBAAwHQYDVR0OBBYEFCtQ0M1liMFOkprT
3G5JCpfc/pNAMA0GCSqGSIb3DQEBCwUAA4ICAQAscgi/f2oJIRwHHR+Yt/nW2Z43
hBVLTf0/u/Doa2m7Ae7Bv138ofaFwwF2q7iwnrb2F6L5deD0ZZoLtL0cNtNz7ajw
46SurhoftZh98ZaEmga6UtdNBDz8EO6aJtcwH4nXmzsfQFJ6WHdoKsWTC2L8u3Q8
nbxVF8x/J5QZKOiNp7hlxGEaFABmfaPvRXa4Fm/KLuITL74pEZ3K0+ufnrsT2S4+
8RcgFYkRsKBkXPbhaGp10XDKHC4PPq26fZYVKMb4WzoeDMVMcfotGmdOrehah0mu
0fC9qElVoKtuEEvKtzAsnAX/jRPRMYqqtD90fqL6txoVKzVQcP8cyY0L6eZhIdYe
nt0NfGhmxo6sRAnVmjA5yIriHOE70Zcd2ebeBcUITe7MReIynuygd85BhYyIegBB
WGsj3iSp2Gg5CBNOe8JBLV6UU7iexThlEfWwbSpgigpdICaAaqjTATsO9PWeIM+v
TsH51AC2wh63U5o6OCp3H18/bVJ3oX2F9fba8pPY5r7T7ou0Sq5Jy6i2US03vtDA
NT2/q5MXAHy7kdMCHzT4KQp81pUTY3bNtujUyGC9Nhgf0CMQMLOmwL7lF9aKWk8J
tG1ixRwplTEHEuJARpKp+MebiyfI87OoCSRJP+LygnkKeYNGxV0fhQnIW3+44bnw
NH0QlNNxLH0iV4UJQA==
-----END CERTIFICATE-----
</ca>
On lance ensuite la connexion cliente VPN afin de s’assurer que tout fonctionne correctement. L’usage de tmux permettra de simplifier l’administration de la solution.
Pour créer plusieurs sessions simultanées sur tmux, il suffit de taper la raccourci clavier Ctrl+b-c.
Nous pouvons ensuite quitter le multiplexeur de terminaux à l’aide du raccourci clavier Ctrl+b-d
B. Configuration d’un service OpenVPN serveur sur le VPS
Tout d’abord nous allons mettre en place l’autorité de certification qui sera en charge de générer un couple clé privée - certificat X509 pour l’ensemble des hôtes utilisant OpenVPN (clients et serveur). Pour gagner du temps, j’ai fait le choix d’utiliser le logiciel easy-rsa.
Dans un premier temps, nous allons créer l’autorité de certification puis générer les clés et les certificats X509 nécessaires au serveur ainsi qu’aux clients. La commande ./easyrsa gen-dh permet ensuite d’implémenter le principe d’échange de clés Diffie-Hellman lors des connexions VPN. DH est utilisé lors de l’échange de clés. Il permet au serveur d’envoyer aux clients VPN des paramètres leur permettant d’établir une “pre-master key” partagée.
Enfin, la dernière commande permet de générer une clé statique qui devra être présente sur le serveur et les clients. Elle permettra lors de l’établissement de la connexion TLS par les clients VPN de vérifier l’intégrité de la communication à l’aide d’un code d’authentification du message (HMAC) généré à l’aide de cette clé. C’est un paramètre recommandé pour renforcer la sécurité du service VPN.
Nous déplaçons ensuite les fichiers nécessaires dans le répertoire de configuration du service OpenVPN.
Il est alors nécessaire de produire un fichier de configuration adéquat pour le serveur VPN.
# On utilise le port 443 afin de contourner certains pare-feux
port 443
# TCP or UDP server?
proto tcp
# On monte une interface tun de niveau 3 pour faire du routage par le tunnel VPN
dev tun
# On déclare le certificat X509 de l'autorité, le certificat X509 et la clé privée du serveur VPN
ca ca.crt
cert issued/servervpn.crt
key private/servervpn.key # This file should be kept secret
# On déclare le fichier permettant de créer l'échange de clé Diffie Hellman
# Generate your own with:
# openssl dhparam -out dh2048.pem 2048
dh dh.pem
# On active le protocole IPv6 pour l'utiliser dans le tunnel VPN
server-ipv6 2001:910:1339:1::/64
tun-ipv6
push tun-ipv6
# On déclare le réseau IPv4 à utiliser entre les clients VPN et le serveur
server 172.16.169.0 255.255.255.0
# Permet d'enregistrer et de maintenir la configuration des clients VPN
ifconfig-pool-persist /var/log/openvpn/ipp.txt
# On force la redirection de tout le trafic du client VPN à passer par le tunnel en IPv4
push "redirect-gateway def1 bypass-dhcp"
# La même chose en IPv6, on définit une métrique plus petite pour prendre le pas sur la route
# par défaut classique définie dans les paramètres réseaux du client
push "route-ipv6 ::/0"
push "route-metric 200"
# Permet de maintenir le tunnel envoyant des ping tous les 10 secondes
# On considère que l'hôte distant est éteint si aucun ping n'est reçu pendant 120 secondes
keepalive 10 120
# Définition de la clé statique permettant de mettre en oeuvre le code d'authentification HMAC
tls-auth ta.key
# Algorithme cryptographique à utiliser
cipher AES-256-CBC
# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun
# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status /var/log/openvpn/openvpn-status.log
verb 3
# Notify the client that when the server restarts so it
# can automatically reconnect.
explicit-exit-notify 1
On peut démarrer ensuite le service OpenVPN.
Nous pouvons vérifier que la nouvelle interface tun1 a correctement été montée à l’aide de la commande ip addr show.
C. Mise en place du routage et du NAT
Il nous reste ensuite à prendre en charge toute la partie routage avec les problématiques évoquées en introduction. On active le routage de paquets IPv4 et IPv6.
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
# Uncomment the next line to enable packet forwarding for IPv6
# Enabling this option disables Stateless Address Autoconfiguration
# based on Router Advertisements for this host
net.ipv6.conf.all.forwarding=1
Nous mettons enfin en place la politique de routage PBR qui permettra le routage du trafic provenant des clients VPN dans le tunnel VPN à destination du FAI associatif. La translation d’adresses NAPT sera aussi implémentée.
Il est bien évidemment possible de scripter l’ensemble des commandes présenté ci-dessus et de les activer automatiquement après le lancement du VPN.
D. Configuration du client VPN
Sur le client, il est nécessaire d’avoir à disposition le certificat X509 de l’autorité de certification générée avec easy-rsa, la clé privée du client et le certificat X509 du client ainsi que le fichier commun ta.key. Enfin, il faudra disposer également d’un fichier de configuration OpenVPN client valide.
Pour récupérer les fichiers créés sur le serveur VPN avec easy-rsa la solution la plus simple s’avère être SFTP ou SCP.
Voici le contenu du fichier de configuration client.
client
dev tun
proto tcp
remote 192.0.2.10 443
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert laptop1.crt
key laptop1.key
tls-auth ta.key 1
verb 3
On lance ensuite la connexion du client OpenVPN vers le serveur.
On verifie que l’interface tun OpenVPN est présente dans les paramètres réseaux de la machine cliente.
Plusieurs tests sont possibles pour vérifier la bonne connectivité de notre vpn depuis le client.
Conclusion
Grâce à ces éléments de configuration, il est dorénavant possible de fournir un accès VPN commun à l’ensemble des machines clientes à notre disposition. Elles vont pouvoir ainsi bénéficier d’un accès Internet respectueux de la neutralité du net. Enjoy !