OpenVPN est un logiciel libre de création de réseau privé virtuel (VPN). Il permet à 2 hôtes (ou réseaux) distants de communiquer entre eux de manière sécurisée grâce à la cryptographie asymétrique, d’un certificat électronique ou d’un couple de noms d’utilisateur/mot de passe.

Ce tutoriel explique comment installer & configurer un serveur OpenVPN 2.3.4 sous Debian 8.6.0.
Si vous utilisez une autre distribution (ou version), il pourrait y avoir quelques divergences de paramétrage.

Toutes les manipulations à venir seront à effectuer en tant que super-utilisateur de la machine.


Avant de commencer, quelques expliquons s’imposent pour comprendre l’avantage de l’utilisation de certificats électroniques.

Cryptographie asymétrique

L’utilisation de certificat électronique fonctionne avec la cryptographie asymétrique. Elle-même fonctionne avec une clé publique (connue de tous) et une clé privée (connue seulement de son propriétaire). La clé publique permet de chiffrer les messages tandis que la clé privée permet de les déchiffrer (là où la cryptographie symétrique utilise une unique clé pour chiffrer et déchiffrer).

Fonctionnement

Avec cette méthode, le destinataire des messages doit fournir sa clé publique à l’expéditeur qui l’utilisera pour crypter ses messages. Etant donné que le destinataire possède la clé privé, seul lui pourra décrypter le message. Les 2 acteurs peuvent être un expéditeur et un destinataire, chacun doit juste avoir sa propre pair de clés. Pour exemple :

Fonctionnement cryptographie asymétrique

Point faible

Le point faible de ce système se situe au niveau de la clé publique que reçoit l’expéditeur. Comment être sûr que la clé publique récupérée soit bien celle du destinataire du message et non celle d’un pirate  qui aurait intercepté les communications ? Après tout, supposons qu’Alice ait publiée sur son site internet sa clé publique (ou dans un annuaire) et que le pirate accède à celui-ci, puis qu’il remplace la clé d’Alice par la sienne. Les personnes qui iront chercher la clé pour envoyer des messages en Alice et le pirate n’aura plus qu’à écouter les communications qu’il pourra décrypter. Pour exemple :

Point faible cryptographie asymétrique

La solution à ce problème n’est d’autre que l’utilisation du certificat électronique.

Le certificat électronique

Le certificat électronique est en quelque sorte la carte d’identité de la clé publique. C’est grâce à lui que nous seront en mesure de savoir si la clé et celle du bon destinataire. Le certificat est composé d’une multitude d’informations dont la clé publique de son propriétaire et d’une signature électronique. C’est la signature qui permet de garantir l’authenticité du destinataire et elle est créée par une autorité de certification (CA) qui est la garante de l’authenticité de la signature.

La CA possède son propre certificat d’autorité de certification et sa clé privée qu’elle utilise pour signer les certificat de ses clients.

Dans le cadre de OpenVPN, nous utiliserons des certificats au format X.509 avec les informations suivante :

Version du certificat

Numéro de série

Algorithme de signature utilisé

Nom de domaine de l’autorité de certification

Période de validité du certificat

Nom de domaine du propriétaire du certificat

Clé publique du propriétaire

ID de l’autorité de certification (optionnel pour X.509v2)

ID du propriétaire du certificat (optionnel pour X.509v2)

Extensions (optionnel, à partir de X.509v3)

Signature électronique

Types de certificats

Il existe 2 types de certificats, selon l’origine de la signature :

  • Certificat auto-signé : certificat signé sois-même à l’aide de sa propre CA. C’est le cas d’OpenVPN qui permet donc de créer une CA et de générer des certificats auto-signés. Cette solution est adaptée aux réseaux d’entreprises.

  • Certificat signé par une entité de certification : certificat signé par une entité tiers. Cette solution est obligatoire pour les échanges sur l’internet.

Signature électronique

La signature électronique est créée à partir des informations contenue dans le certificat et la clé privée du CA. Elle s’effectue en 2 étapes :

  1. Application d’une fonction de hachage : condenser les informations du certificat (le résultat est appelé condensat).
  2. Cryptage du condensat : crypter le condensat  à l’aide de la clé privée du CA.

Une fois le condensat crypté, on appel le résultat « signature électronique ».

Voyons maintenant l’utilité de ces 2 étapes…

Débutons avec la première, le hachage, qui permet de contrôler l’intégrité des données. En appliquant une fonction de hachage sur les données on obtient un condensat unique. Quand le client voudra envoyer des données, il devra envoyer le condensat et les données écrites en clair. Ensuite, le serveur va à son tour appliquer la même fonction de hachage (indiqué parmi les informations) sur les données écrites en clair reçu du client et il va comparer le condensat obtenu avec le condensat envoyé par le client. Si le condensat du message crypté par le serveur est différent de celui envoyé par le client, alors le message a été falsifié.

Puis, la seconde, le cryptage du condensat, qui permet d’assurer la provenance des données. Une clé privée (celle du CA) est utilisée pour crypter le condensat tandis que la clé publique associée (celle du CA : que tout le monde possède) permet d’obtenir le condensat original à partir de celui crypté. De ce fait, si le condensat obtenu à l’aide de la clé publique est identique à celui reçu par le client, alors les données sont authentiques.

Une autre méthode pour contrôler la validité d’un certificat est de stocker tous les certificats des clients autorisés sur le serveur afin d’effectuer une comparaison (plus rapide mais plus coûteuse en espace de stockage).

En résumé, si le pirate falsifie la clé publique du certificat, les informations seront différentes de celles d’origine et quand le serveur va les hacher pour les comparer au condensat directement créé par la CA, il remarquera qu’il y a eu falsification. Le seul moyen pour le pirate de passer inaperçu et d’obtenir la clé privée du CA (bon courage ^^). Pour exemple :

Fonctionnement certificat électronique

Dans le cas d’OpenVPN, l’authentification est bidirectionnelle : le client et le serveur doivent s’authentifier entres (donc chacun envoyer son certificat à l’autre). Le serveur OpenVPN et tous les clients possèdent le certificat d’autorité de certificat du CA.

Petite remarque, vous avez du vous poser des questions quand j’ai dit que la clé privée servirait à crypter (le condensat) et la clé publique à décrypter (la signature) alors que dans la cryptographie asymétrique « classique » c’est l’inverse. Néanmoins, afin de d’être certain de la provenance des données on inverse les rôles car tout le monde peut avoir la clé publique mais, une seule personne possède la clé privée (et c’est la CA).

Pour terminer les explications, il n’est pas obligatoire que la CA génère elle-même les pairs de clés. Il est possible de générer sois-même sa pair de clés et d’envoyer la clé publique à une autorité de certification pour qu’elle puisse créer le certificat, signé.


Installation et préparation d’OpenVPN

Mettre à jour la distribution

Exécutez la commande suivante :

apt update -y && apt upgrade -y

Cette commande permet de mettre à jour la liste des paquets et de mettre à jour les paquets installés sur votre système.

Installer OpenVPN

Exécutez la commande suivante :

apt install openvpn

Pour sécuriser d’avantage votre serveur OpenVPN, vous pouvez installer fail2ban pour limiter le nombre d’essais possibles d’authentification (recommandé pour éviter les attaques brutes et DDOS) :

apt install fail2ban

fail2ban est pré-configuré à l’installation, il n’est pas obligatoire de le configurer : la limite d’essais possibles est de 3. Au bout les 3 essais, l’adresse de l’hôte tentant de se connecté est bannie pendant 10 minutes.

Configuration de l’architecture

Générer le certificat d’autorité de certification maître (CA)

Récupérer le dossier easy-rsa

Le dossier /usr/share/easy-rsa/ contient les scripts nécessaires pour générer les certificats dont nous allons avoir besoin.

Par précaution, faite une copie de ce dossier dans le dossier personnel (sécurisé) de l’utilisateur que vous voulez utiliser pour la génération des certificats :

mkdir -p ~/openvpn/easy-rsa/ && cp /usr/share/easy-rsa/* ~/openvpn/easy-rsa/

De préférence la génération des certificats est a faire sur une machine différente du serveur OpenVPN et des clients mais ici nous ferons cela sur le serveur même.

Initialiser les variables globales

Placez-vous dans le dossier easy-rsa et éditez le fichier vars qui doit si trouver :

cd ~/openvpn/easy-rsa/ && nano vars

6 variables sont présentes dans ce fichier (vers la fin) : KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, KEY_EMAIL et KEY_OU. C’est en ce basant sur les valeurs de chacune de ces variables que sera généré le CA.

Complétez-les de la manière suivante (exemple) :

export KEY_COUNTRY="FR"                     # Pays (en 2 lettres)
export KEY_PROVINCE="Nord-Pas-Calais"       # Région
export KEY_CITY="Dunkerque"                 # Ville
export KEY_ORG="JeanBart"                   # Organisation
export KEY_EMAIL=steven.douilliet@lycee.jb  # Adresse mail
export KEY_OU="BTSSIO"                      # Section

Ne laissez aucune de ces variables vide !

Enregistrez les modifications ;

Initialisez les variables :

. ./vars

Le script vars (à lancé avec un . devant) est sourcé et les variables sont initialisées. A chaque démarrage du serveur, il faut de nouveau initialiser les variables.

Générer le certificat

Nettoyez le dossier keys :

./clean-all

Le script clean-all supprime toutes les clés et certificats existants dans le dossier ~/openvpn/easy-rsa/keys/. C’est dans ce dossier que sera généré nos futurs fichiers. Si vous devez générer un nouveau CA il est préférable de vider keys au préalable.

Maintenant nous allons créer un certificat d’autorité de certification et avec sa clé privée à l’aide du script build-ca. Le certificat sera enregistré dans un fichier nommé ca.crt et la clé dans un fichier nommé ca.key, tous deux dans le dossier ~/openvpn/easy-rsa/keys.

Exécutez le script build-ca :

./build-ca

Laissez les valeurs par défauts (que vous avez renseigné dans les variables précédemment) aux paramètres qui vous seront demandés, sauf à celui-ci :

 Common Name (eg, your name or your server's hostname)

Renseignez le nom de l’autorité de certification (ou laissez la valeur par défaut) ;

Vous devriez obtenir un résultat similaire à celui-ci (exemple) :

Country Name (2 letter code) [FR]:
State or Province Name (full name) [Nord-Pas-Calais]:
Locality Name (eg, city) [Dunkerque]:
Organization Name (eg, company) [JeanBart]:
Organizational Unit Name (eg, section) [BTSSIO]:
Common Name (eg, your name or your server's hostname) [JeanBart CA]:
Name [EasyRSA]:
Email Address [steven.douilliet@lycee.jb]:

Attention : le paramètre Common Name doit être unique, ne générez pas plusieurs certificats avec le même nom !

Générer des certificats

Pour un serveur OpenVPN

Comme vous avez dû le comprendre durant la phase d’explication au début du tutoriel, le serveur aura de son propre certificat, signé par la CA que nous venons de créer. Pour cela nous allons utiliser le script build-key-server. Le certificat sera enregistré dans un fichier nommé server.crt et la clé dans un fichier nommé server.key, tous deux dans le dossier ~/openvpn/easy-rsa/keys.

Exécuter le script build-key-server :

./build-key-server server

Laissez les valeurs par défauts aux paramètres qui vous sont demandés. Le paramètre Common Name prendra le nom du certificat (ici server) mais, vous pouvez le modifier si vous le voulez.

Vous pouvez ensuite renseigner un mot de passe et un nom d’entreprise si vous le souhaitez ;

Répondez positivement aux autres questions, pour auto-signer le certificat.

Pour un client

Pour générer le ceryficiat du client, nous utiliserons le script build-key ou build-key-pass (si vous voulez votre clé privée avec un mot de passe). Le certificat sera enregistré dans un fichier, du nom de votre choix, en .crt et la clé dans un fichier, du nom de votre choix, en .key, tous deux dans le dossier ~/openvpn/easy-rsa/keys.  Le certificat et la clé doivent être uniques pour chaque client.

Exécutez le script build-key[-pass] :

./build-key NomClient

Laissez les valeurs par défauts aux paramètres qui vous seront demandés ;

Vous pouvez ensuite renseigner un mot de passe et un nom d’entreprise si vous le souhaitez ;

Répondez positivement aux autres questions, pour auto-signer le certificat.

Générer les paramètres Diffie-Hellman

Diffie-Hellman est un protocole de cryptographie utilisé dans les échanges de clés. Cette clé sera utilisé par le serveur et le client pour communiquer en utilisant la cryptographie symétrique. Nous allons utiliser le script build-db prévu à cet effet, qui va générer une clé de chiffrement de 2048 bits dans le fichier dh2048.pem de dans le dossier ~/openvpn/easy-rsa/keys

Exécutez le script build-db :

./build-dh

L’opération peut être longue en fonction des ressources de votre machine.

Configuration des éléments

Envoyer les certificats au serveur et aux clients

Il est coutume de faire un récapitulatif des fichiers créé à laide d’un tableau, alors voici :

Fichier Utile à Utilité Privée ?
ca.crt Serveur et clients Certificat du CA Non
ca.key CA Clé privée du CA Oui
dh{2048}.pem Serveur Clé de chiffrement sysmétrique Non
server.crt Serveur Certificat du serveur Non
server.key Serveur Clé privée du serveur Oui
client.crt Client Certificat du client Non
client.key Cient Clé privée du client Oui

Si nous nous fions à ce tableau, nous voyons que le serveur OpenVPN va avoir besoin des fichiers ca.crt, server.crt, server.keyet dh{n}.pem.

Copiez ces fichiers dans le répertoire/etc/openvpn/ : 

cp keys/dh*.pem keys/ca.crt keys/server.crt keys/server.key /etc/openvpn/

Quant au client, il aura besoin des fichiers ca.crt, client.crt, client.key.  Nous allons lui envoyer à l’aide de la scp, dont le format sera le suivant :

scp CheminFichieràEnvoyer utilisateur@IPClient:~/

L’utilisateur est celui que vous souhaitez autoriser à créer VPN avec votre serveur OpenVPN ou un administrateur que vous utiliserez ensuite pour placer les fichiers dans le dossier personnel de l’utilisateur devant utilisant un VPN. Je vous conseille de créer un dossier openvpn dans le dossier personnel de l’utilisateur concerné, avec les fichiers que vous enverrez.

Configurer le serveur OpenVPN

Créer le fichier de configuration

Dans le répertoire /usr/share/doc/openvpn/examples/sample-config-files/, vous trouverez le fichier compressé server.conf.gz qui contient un exemple de fichier de configuration d’un serveur OpenVPN. Nous allons le récupérer et l’adapter.

Décompressé le fichier server.conf.gz dans le dossier /etc/openvpn/ :

zcat /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

Éditez le fichier server.conf :

nano /etc/openvpn/server.conf

Repérez la ligne suivante :

dh dh1024.pem

Si vous avez généré une clé Diffie Hellman de 2048 bits (normalement oui), remplacez la valeur 1024 par 2048 ;

Repérez la ligne suivante :

server 10.8.0.0 255.255.255.0

Si l’adresse du réseau auquel donne accès le VPN est identique à l’adresse spécifiée ici (adresse du réseau qui sera utilisée dans le VPN), modifiez-la.

Pour que le client puisse avoir accès au réseau à l’autre bout du tunnel, le serveur doit posséder la route lui indiquant de rediriger les requêtes vers le réseau concerné. Ajoutez une route (à la fin du fichier) vers votre réseau de destination de la manière suivante :

push route @RéseauDestination Masque

Enregistrez les modifications ;

Redémarrez le serveur :

reboot

Le service openvpn n’est pas exécuté automatiquement (sous Debian 8) en tâche de fond après son redémarrage, il faut redémarrer la machine pour cela.

Affichez les informations des interfaces réseau IP :

ifconfig

Vous devriez maintenant voir l’interface virtuelle d’OpenVPN (exemple) :

tun0      Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet adr:172.17.17.1 P-t-P:172.17.17.2 Masque:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:100
          RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

Cette interface est utilisé par le VPN (pour le routage) et permet d’écouter les connexions clientes sur le port UDP 1194, et de distribuer des adresses virtuelles aux clients se connectant depuis le réseau par défaut 10.8.0.0/24 (dans mon cas 172.17.17.0/24).

Activer le FORWARDING

Si le forwarding n’est pas activé, le serveur OpenVPN ne redirigera pas (NAT) les requêtes vers le réseau auquel vous voulez accéder et vous ne pourrez communiquer qu’avec le serveur lui-même.

Éditez le fichier /etc/sysctl.conf :

nano /etc/sysctl.conf

Repérez et dé-commentez la ligne suivante pour activer le routage :

#net.ipv4.ip_forward=1

Enregistrez les modifications ;

Redémarrez le service procps :

service procps restart

Configurez la règle d’iptables qui activera le NAT sur l’interface réseau connecté au réseau au donne accès le VPN :

iptables -t nat -A POSTROUTING -o NomInterface -j MASQUERADE

Sauvegardez les règles iptables dans le fichier /etc/iptables_rules.save :

iptables-save > /etc/iptables_rules.save

Éditez le fichier /etc/network/interfaces :

nano /etc/network/interfaces

Ajoutez la ligne suivante à la fin du fichier :

 post-up iptables-restore < /etc/iptables_rules.save

Cette ligne permet de restaurer les règles iptables au démarrage du service networking (donc du serveur).

Enregistrez les modifications ;

Redémarrez le service networking :

service networking restart

Configurer le client OpenVPN

Installer OpenVPN

Exécutez la commande suivante :

apt install openvpn

Créer le fichier de configuration

Dans le répertoire /usr/share/doc/openvpn/examples/sample-config-files/ (du client), vous trouverez le fichier client.conf qui contient un exemple de fichier de configuration d’un client. Nous allons le récupérer et l’adapter.

Copiez le fichier client.conf là où se trouve le certificat et les autres fichiers du client (dans mon cas, ~/openvpn) :

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/openvpn/client.conf

Éditez le fichier client.conf :

nano ~/openvpn/client.conf

Repérez la ligne suivante :

remote my-server-1 1194

Renseignez l’adresse IP du serveur OpenVPN à la place de la valeur my-server-1 (1194 correspond au port utilisé pour la connexion) ;

Repérez les lignes suivantes :

cert client.crt
key client.key

Remplacez les noms des fichiers .crt et .key par les noms de ceux que vous avez créé pour le client (si ce sont les mêmes, ne changez rien) ;

Enregistrez les modifications.

Créer un VPN

Le client et le serveur sont près, il ne vous reste plus qu’à tester la création d’un VPN entre le client et le serveur OpenVPN.

Exécutez le fichier de configuration de votre client (pour moi, client.conf:

 cd ~/openvpn/ && sudo openvpn client.conf &

L’option & permet de lancer le service en tâche de fond, pour pouvoir continuer à utiliser la console.

Vous devez obtenir un résultat final similaire à celui-ci :

[1] 815
root@Debian-8:/home/debian/openvpn# Tue Jul 18 18:26:46 2017 OpenVPN 2.3.4 i586-pc-linux-gnu [SSL (OpenSSL)] [LZO] [E POLL] [PKCS11] [MH] [IPv6] built on Jun 26 2017
Tue Jul 18 18:26:46 2017 library versions: OpenSSL 1.0.1t 3 May 2016, LZO 2.08
Tue Jul 18 18:26:46 2017 Socket Buffers: R=[163840->131072] S=[163840->131072]
Tue Jul 18 18:26:46 2017 UDPv4 link local: [undef]
Tue Jul 18 18:26:46 2017 UDPv4 link remote: [AF_INET]192.168.1.254:1194
Tue Jul 18 18:26:46 2017 TLS: Initial packet from [AF_INET]192.168.1.254:1194, sid=fb00021f 2f78fddd
Tue Jul 18 18:26:46 2017 VERIFY OK: depth=1, C=FR, ST=Nord-Pas-Calais, L=Dunkerque, O=JeanBart, OU=BTSSIO, CN=JeanBar t CA, name=EasyRSA, emailAddress=steven.douilliet@lycee.jb
Tue Jul 18 18:26:46 2017 VERIFY OK: nsCertType=SERVER
Tue Jul 18 18:26:46 2017 VERIFY OK: depth=0, C=FR, ST=Nord-Pas-Calais, L=Dunkerque, O=JeanBart, OU=BTSSIO, CN=server, name=EasyRSA, emailAddress=steven.douilliet@lycee.jb
Tue Jul 18 18:26:46 2017 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Tue Jul 18 18:26:46 2017 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Jul 18 18:26:46 2017 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Tue Jul 18 18:26:46 2017 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Tue Jul 18 18:26:46 2017 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 2048 bit RSA
Tue Jul 18 18:26:46 2017 [server] Peer Connection Initiated with [AF_INET]192.168.1.254:1194
Tue Jul 18 18:26:48 2017 SENT CONTROL [server]: 'PUSH_REQUEST' (status=1)
Tue Jul 18 18:26:48 2017 PUSH: Received control message: 'PUSH_REPLY,route 10.15.17.0 255.255.255.0,route 172.17.17.1 ,topology net30,ping 10,ping-restart 120,ifconfig 172.17.17.6 172.17.17.5'
Tue Jul 18 18:26:48 2017 OPTIONS IMPORT: timers and/or timeouts modified
Tue Jul 18 18:26:48 2017 OPTIONS IMPORT: --ifconfig/up options modified
Tue Jul 18 18:26:48 2017 OPTIONS IMPORT: route options modified
Tue Jul 18 18:26:48 2017 ROUTE_GATEWAY 192.168.1.1/255.255.255.0 IFACE=eth0 HWADDR=08:00:27:9c:12:89
Tue Jul 18 18:26:48 2017 TUN/TAP device tun0 opened
Tue Jul 18 18:26:48 2017 TUN/TAP TX queue length set to 100
Tue Jul 18 18:26:48 2017 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Tue Jul 18 18:26:48 2017 /sbin/ip link set dev tun0 up mtu 1500
Tue Jul 18 18:26:48 2017 /sbin/ip addr add dev tun0 local 172.17.17.6 peer 172.17.17.5
Tue Jul 18 18:26:48 2017 /sbin/ip route add 10.15.17.0/24 via 172.17.17.5
Tue Jul 18 18:26:48 2017 /sbin/ip route add 172.17.17.1/32 via 172.17.17.5
Tue Jul 18 18:26:48 2017 Initialization Sequence Completed

Vous devriez ensuite pouvoir communiquer avec les machines à l’autre bout du tunnel (dans mon cas je communique avec mon serveur interne) :

PING 10.15.17.1 (10.15.17.1) 56(84) bytes of data.
64 bytes from 10.15.17.1: icmp_seq=1 ttl=63 time=0.612 ms
64 bytes from 10.15.17.1: icmp_seq=2 ttl=63 time=2.02 ms
64 bytes from 10.15.17.1: icmp_seq=3 ttl=63 time=2.05 ms

Ce tutoriel est terminé. Pour la configuration d’un client OpenVPN sous Windows, c’est par ici.

Si vous avez des problèmes, où que vous trouvez que certains points sont mal expliqués (ou faux), n’hésitez pas à m’avertir.