Systèmes et réseaux

OpenVPN : Installation et configuration détaillée

OpenVPN : Installation et configuration détaillée

Au quotidien, OpenVPN est très utile pour accéder à distance à son réseau local en toute sécurité. Pour ceux qui comme moi possèdent des serveurs à domicile, cela permet de les administrer à distance sans exposer SSH ou VNC (pour ne citer qu’eux) au monde entier.

J’ai récemment fait l’acquisition d’un Odroid N2+ qui vient en remplacement de ma vieille Raspberry pi 3B, dans le but de reprendre ses fonctions de NAS et de VPN. Il y a plusieurs années, lorsque j’ai mis en place ce serveur, j’ai utilisé PiVPN afin de me simplifier l’installation et la gestion d’OpenVPN. Mais maintenant qu’il est temps de le remplacer, je suis curieux de comprendre comment fonctionne OpenVPN en détail, et la meilleure méthode pour y arriver est probablement de l’installer sans l’aide d’aucun outil. Si comme moi vous cherchez à comprendre les rouages d’un VPN, ce guide est parfait pour vous !

Je tiens à préciser que j’ai appris le fonctionnement d’OpenVPN durant l’écriture de cet article, et donc que je n’en connaissait pas plus qu’un utilisateur de PiVPN avant. Si vous êtes un expert (ou pas d’ailleurs) du sujet et que vous constatez une inexactitude, n’hésitez pas à m’en faire part en commentaire !

L’installation sera ici effectuée sur Ubuntu Server 22.04 LTS aarch64, mais le processus devrait être sensiblement identique pour n’importe quelle distribution basée sur Debian.

La configuration du serveur utilisée pour ce guide

Sans plus attendre, plongeons nous dans cette installation !

Étape 1 : Préparation du système

La quasi-totalité des commandes effectuées nécessiteront les droits de super-utilisateur. Pour ne plus se préoccuper de cela, nous allons nous connecter en tant que root pour toute l’installation.

$ sudo su

Installation des paquets

Effectuons la classique mise à jour du système qui est de coutume avant chaque nouvelle installation, et procurons nous les deux paquets qui nous seront nécessaires.

# apt update
# apt upgrade
# apt install openvpn easy-rsa

Étape 2 : Préparation des certificats

OpenVPN nécessite différents fichiers pour fonctionner :

  • Le certificat racine : Ce certificat permettra de prouver que chacun des autres certificats que nous génèrerons proviennent de notre serveur. Il est utilisé comme autorité de certification.
  • Le certificat du serveur : Il servira au chiffrement des messages en provenance des clients.
  • Un certificat par client : Il servira au chiffrement des message en provenance du serveur.

Pour cette étape, le paquet easy-rsa nous sera d’une grande aide dans la mise en place de l’ensemble des certificats nécessaires à OpenVPN.

2.1. Configuration d’easy-rsa

Pour éviter la modification de la configuration que nous ferons, nous allons déplacer easy-rsa dans le dossier de configuration d’OpenVPN.

# cp -r /usr/share/easy-rsa/ /etc/openvpn/easy-rsa/

Nous allons maintenant pouvoir procéder à la configuration d’easy-rsa.
Cette configuration s’effectue au moyen du fichier vars.example, qu’il faudra renommer en vars pour qu’il soit utilisé.

# cd /etc/openvpn/easy-rsa
# ls -l
total 100
-rwxr-xr-x 1 root root 76923 Aug  9 16:34 easyrsa
-rw-r--r-- 1 root root  4616 Aug  9 16:34 openssl-easyrsa.cnf
-rw-r--r-- 1 root root  8896 Aug  9 16:48 vars.example
drwxr-xr-x 2 root root  4096 Aug  9 16:34 x509-types
# mv vars.example vars
# nano vars

Les paramètres à modifier seront les suivants (n’hésitez pas à définir vos propres paramètres à l’aide des explications présentes dans le fichier de configuration). N’oubliez pas de décommenter les lignes modifiées :

# Utiliser uniquement un nom commun (CN) dans les détails du certificat
# racine
set_var EASYRSA_DN      "cn_only"

# Longueur de la clé de chiffrement RSA
# 2048 est largement suffisant, mais vous pouvez renseigner un valeur
# jusqu'à 4096 si vous êtes paranoïaque
set_var EASYRSA_KEY_SIZE        4096

# Algorithme de chiffrement utilisé
set_var EASYRSA_ALGO            rsa

# Nombre de jours avant l'expiration du certificat racine
set_var EASYRSA_CA_EXPIRE       3650

# Nombre de jours avant l'expiration des certificats client
set_var EASYRSA_CERT_EXPIRE     730

# Algorithme de hachage utilisé
set_var EASYRSA_DIGEST          "sha256"

Il ne nous reste plus qu’à générer notre PKI (Public Key Infrastructure, infrastructure de clés publiques). Cette infrastructure permettra la création de tous nos certificats.

# ./easyrsa init-pki

Si vous souhaitez en savoir plus sur les commande d’easyrsa, vous pouvez utiliser cette commande

# ./easyrsa help <command>

2.2. Génération du certificat racine

Pour générer le certificat racine, nous avons juste besoin de cette simple commande.
Le programme vous demandera un mot de passe pour chiffrer la clé privée du certificat. Vous pouvez désactiver le chiffrement de la clé en ajoutant nopass à la fin de la commande, mais cela donnera la possibilité à n’importe qui ayant accès à cette clé de se faire passer pour votre entité.
Il vous sera également demandé de rentrer un nom commun (CN), qui sera le nom de l’autorité de certification qui signera tous vos certificats. Sentez-vous libre de renseigner ce que vous voulez.

# ./easyrsa build-ca
Retour de la commande
Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

Enter New CA Key Passphrase: (password here)
Re-Enter New CA Key Passphrase: (password here)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:Theiremi Networks

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/etc/openvpn/easy-rsa/pki/ca.crt

2.3. Génération du certificat serveur

La génération d’un couple clé publique / clé privée s’effectue avec cette commande :

# ./easyrsa gen-req <filename_base> nopass

<filename_base> peut être n’importe quoi, dans mon cas je me contenterai d’un sobre « server ».
L’option nopass est ici importante pour permettre au serveur d’utiliser sa clé privée sans intervention humaine. Cependant, pour les plus paranoïaques, vous pouvez supprimer ce paramètre et ajouter l’option askpass dans la configuration du serveur. Le serveur vous demandera à chaque démarrage le mot de passe de votre clé privée.

Lors de l’exécution de la commande, il nous sera demandé de choisir un nom commun pour le serveur. Encore une fois, ce paramètre n’a que peu d’importance, et peut très bien être identique au nom commun de l’autorité de certification défini ci-dessus.

# ./easyrsa gen-req server nopass
Retour de la commande
Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
.........+..+...+.+..+.......+...+...+.........+..+..........+.....+...+...+.......+..+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+...+..........+..+...+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+.......+......+.........+..+..........+...+........+.............+.....+......+...+.......+.....+....+..+..........+..+......+...............+....+...+.................+...+...+.......+........+.......+..+......+.+.....+.+.....+..........+........+....+...+...+...........+.+.........+........+...+....+........+...+...+......+....+........................+..+.+........+.......+............+..+......+....+...........+....+......+.................+............+......+...............+.......+...........................+...+.....+...+...+....+...........+..........+............+..+.......+...+............+.....+....+..+............+.+...........+.........+..........+......+........+.+.....+.........+.+............+....................+..........+.....+....+.....+..............................+....+...........+.+.......................+.......+.................+...+....+.........+.........+...+...+......+......+........+.......+........+............+....+...+..+.+.....+...+.........+.+...........+...+.+...............+............+..+...............+......+.........+.....................+......+..................+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
..+............+....+.....+...+.+......+...+........+....+.....+...+.+.....+......+....+......+...+..+...+......+......+......+.......+..+....+..+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+...+...............+.+..............+.+...........+..........+...+............+...+..+.........+............+....+...+........+....+......+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [server]:Theiremi Networks Server

Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/pki/reqs/server.req
key: /etc/openvpn/easy-rsa/pki/private/server.key

2.4. Signature du certificat serveur

Afin d’intégrer notre certificat serveur à notre autorité de certification, nous devons maintenant le signer. Cela s’effectue avec la commande :

# ./easyrsa sign-req <type> <filename_base>
  • <type> : Type de certificat, dans notre cas « server »
  • <filename_base> : nom des fichiers du certificat

Il vous sera ensuite demandé d’entrer le mot de passe de la clé de l’autorité de certification, afin de permettre la signature du certificat serveur avec la clé privée ainsi déchiffrée.

La commande donne un résultat similaire à celui-ci :

# ./easyrsa sign-req server server
Retour de la commande
Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)


You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a server certificate for 730 days:

subject=
    commonName                = Theiremi Networks


Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
Using configuration from /etc/openvpn/easy-rsa/pki/easy-rsa-21591.Z4sGHO/tmp.LpI52J
Enter pass phrase for /etc/openvpn/easy-rsa/pki/private/ca.key: (CA password)
20100B917F000000:error:0700006C:configuration file routines:NCONF_get_string:no value:../crypto/conf/conf_lib.c:315:group=<NULL> name=unique_subject
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'Theiremi Networks'
Certificate is to be certified until Aug  8 21:00:30 2025 GMT (730 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /etc/openvpn/easy-rsa/pki/issued/server.crt

2.5. Génération des paramètres Diffie-Hellman

Les paramètres Diffie-Hellman sont utiles pour la sécurité de la connexion entre le client et le serveur lors de l’authentification. Ils permettent un chiffrement asymétrique entre les deux machines afin de transmettre de manière sécurisée les informations de connexion. Ce protocole étant extrèmement gourmand en ressources, il n’est utilisé que le temps de transmettre des clés de chiffrement symétriques pour la suite des échanges.

La génération de ces paramètre s’effectuera simplement avec :

# ./easyrsa gen-dh

Attention : Cette commande peut prendre plusieurs heures à se terminer, en fonction de la longueur de clé choisie lors de la configuration (étape 2.1) et de la puissance de votre processeur. Dans mon cas, il a fallu environ 1 heure pour en venir à bout.

2.6. Génération du fichier CRL (Certificate Revocation List)

La liste des certificats révoqués, ou CRL, contient la liste des certificats signés par notre autorité de certification qu’il est interdit d’utiliser. Si un certificat vient à fuiter, il pourra être ajouté à cette liste, afin qu’OpenVPN puisse refuser la connexion à quiconque tentant d’utiliser ce certificat.
Nous allons ici générer une liste vide, la procédure pour révoquer un utilisateur étant décrite plus loin.

# ./easyrsa gen-crl
Retour de la commande
Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
Using configuration from /etc/openvpn/easy-rsa/pki/easy-rsa-5131.mRDufX/tmp.9fzlOf
Enter pass phrase for /etc/openvpn/easy-rsa/pki/private/ca.key: (CA password)

An updated CRL has been created.
CRL file: /etc/openvpn/easy-rsa/pki/crl.pem

2.7. Génération d’un clé d’authentification (recommandé)

Afin d’améliorer la sécurité de notre serveur, il nous est possible de générer une clé d’authentification partagée entre les clients et le serveur. Concrètement, cette clé permettra au serveur de confirmer que les paquets reçus proviennent bien d’un client connu. Cela permet d’abandonner le traitement du paquet dès son arrivée, ce qui permet entre autres :

  • D’empêcher un attaquant de détecter le service OpenVPN en scannant les ports de notre machine
  • De se protéger contre les attaques DDoS
  • De ne pas gaspiller de ressources à traiter des paquets non envoyés par nos clients

Cette clé est générée à l’aide de cette commande :

# cd /etc/openvpn
# openvpn --genkey secret ta.key

La directive secret sert juste à indiquer que la clé doit être enregistrée dans le fichier ta.key plutôt qu’affichée.

2.8. Copie des fichiers générés

Maintenant que nos certificats sont prêts, il ne nous reste plus qu’à les copier dans le répertoire /etc/openvpn :

# cd /etc/openvpn/easy-rsa/pki
# cp ca.crt issued/server.crt private/server.key dh.pem crl.pem /etc/openvpn
# mkdir /etc/openvpn/ccd

Étape 3 : Configuration d’OpenVPN sur la machine serveur

OpenVPN nous fournit un fichier de configuration exemple que vous pouvez utiliser comme base.
La première étape sera donc de copier ce fichier dans le dossier de configuration d’OpenVPN.

# cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server.conf

Je vous invite à consulter l’aide qu’il contient pour fixer vos propres paramètres, ainsi que l’aide relative aux commandes d’OpenVPN. Si toutefois vous ne souhaitez pas vous prendre la tête avec ces réglages, vous pouvez utiliser ma configuration fournie ci-dessous, que j’ai voulue comme étant la plus sécurisée possible. Veillez à ce que les champs ca, cert, key, dh et tls-auth pointent bien vers vos fichiers.

Attention : La suite de ce guide assumera que les paramètres que vous avez utilisés sont similaires à ceux exposés ici.

cd /etc/openvpn
mode server
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt 1200
# Allow users to see each others in the VPN network (comment if not needed)
client-to-client
# NOT RECOMMENDED : Allow multiple devices to connect to the VPN with the same certificate (comment for extra security)
duplicate-cn
client-config-dir ccd
#Change this setting according to your needs
max-clients 50
max-routes-per-client 10
stale-routes-check 300
verify-client-cert require
auth SHA256
cipher AES-256-GCM
tls-server
ca ca.crt
dh dh.pem
cert server.crt
key server.key
tls-version-min 1.3
tls-crypt ta.key
remote-cert-tls client
crl-verify crl.pem
user openvpn
group openvpn
persist-key
persist-tun
keepalive 5 60
log /var/log/openvpn/openvpn.log
status /var/log/openvpn/status.log
verb 3
mute 10
explicit-exit-notify 1

push "redirect-gateway def1 bypass-dhcp"
push "block-outside-dns"

Etape 4 : Configuration annexe de la machine serveur

La configuration d’OpenVPN seule ne suffit pas pour permettre à notre VPN de fonctionner pleinement. Il est nécessaire d’ajuster certains paramètres du système afin d’améliorer la sécurité ou obtenir l’accès à internet.

3.1. Gestion des permissions

Pour améliorer la sécurité, OpenVPN est ici configuré pour fonctionner sous l’utilisateur openvpn. Le service est toujours démarré en tant que root, ce qui lui permet de lire les fichiers importants comme la clé privée du serveur, mais une fois l’information récupérée, OpenVPN descend ses privilèges à ceux de l’utilisateur openvpn.

Il va donc falloir créer l’utilisateur openvpn et donner les permissions adéquates aux fichiers.

# adduser --no-create-home --disabled-login --shell /sbin/nologin openvpn
# cd /etc/openvpn
# chmod 644 crl.pem
# chmod 600 ca.crt server.crt server.key dh.pem ta.key

3.2 Accéder à l’extérieur

Les clients sont en capacité d’accéder au réseau local virtuel configuré par OpenVPN, mais il reste quelques étapes pour leur permettre d’atteindre le reste du monde.

Il faut tout d’abord indiquer à notre système qu’il doit transférer les paquets reçus entre l’interface réseau du VPN et les autres interfaces.
Pour cela, modifiez le fichier /etc/sysctl.conf et insérez (ou modifiez) cette ligne :

# nano /etc/sysctl.conf
net.ipv4.ip_forward=1

Les paquets peuvent maintenant sortir de notre serveur, mais ils apparaitront comme venant de réseau du VPN. Il est nécessaire de configurer un NAT afin que ces paquets apparaissent comme venant directement de notre serveur.

# apt install iptables
# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE

Pour sauvegarder la configuration d’iptables, il suffit d’installer iptables-persistent.

# apt install iptables-persistent

Au cours de l’installation, il nous sera demandé si l’on veut sauvegarder la configuration.

Ce message s’affichera lors de l’installation d’iptables-persistent

3.3. Accès au serveur

OpenVPN écoutera les connexions UDP sur le port 1194.
Ainsi, les clients doivent être en mesure d’accéder à ce port depuis l’extérieur de votre réseau local. Cette manipulation étant différente pour chaque routeur, je vous invite à vous renseigner en ligne sur comment mettre en place le port forwarding sur le vôtre.

3.4. Démarrage du serveur

Il ne nous reste plus qu’à démarrer le serveur et à le configurer pour qu’il démarre automatiquement

# systemctl enable openvpn
# systemctl start openvpn

N’hésitez pas à jeter un oeil aux fichiers journaux d’OpenVPN pour vérifier que tout s’est bien passé.

# tail -f /var/log/openvpn/openvpn.log

Étape 4 : Création d’une configuration client par défaut

Nous allons maintenant préparer un modèle de fichier de configuration que nous distribuerons aux clients. Ce fichier doit posséder une configuration similaire à celle du serveur pour fonctionner.
Afin de vous aider à créer ce fichier, l’aide relative aux commandes d’OpenVPN inclut aussi les commandes déstinées au client. Ma configuration allant de pair avec celle exposée ci-dessus, également orientée sécurité, est disponible juste en dessous.

# cat /home/remi/client.ovpn
client
dev tun
remote vpn.theiremi.fr 1994 udp
connect-retry 5 600
resolv-retry infinite
nobind
verb 3
mute 10
explicit-exit-notify 1

auth SHA256
cipher AES-256-GCM
tls-client
tls-version-min 1.3
remote-cert-tls server


<ca>
</ca>

<cert>
</cert>

<key>
</key>

<tls-crypt>
</tls-crypt>

Les quatre balises laissés vide en bas du fichier contiendront les différents certificats nécessaires au client. Par souci de simplicité, ils seront intégrés directement dans la configuration, afin que seul le fichier de configuration soit nécessaire.

Étape 5 : Ajouter un client

L’ajout d’un client se fait principalement par la création de ses propres certificats. Pour cela, la procédure est très similaire à celle grace à laquelle nous avons généré le certificat serveur.

5.1. Génération du certificat client

Le certificat est généré avec :

# ./easyrsa gen-req <client_name>

Puis signé avec :

# ./easyrsa sign-req client <client_name>

5.2. Création du fichier de configuration client

Nous allons maintenant pouvoir réutiliser notre modèle de configuration client en y ajoutant les informations spécifiques à notre client.
N’oubliez pas de changer <client_name> par le nom que vous avez choisi lors de la création du certificat.

# export CLIENT_NAME=<client_name>
# cd /path/to/client.ovpn
# cp client.ovpn $CLIENT_NAME.ovpn

Il ne reste plus qu’à remplir les quatre champs ca, cert, key et tls-crypt avec le contenu respectif des fichiers ci-dessous :

# cat /etc/openvpn/ca.crt
# cat /etc/openvpn/easy-rsa/pki/issued/$CLIENT_NAME.crt
# cat /etc/openvpn/easy-rsa/pki/private/$CLIENT_NAME.key
# cat /etc/openvpn/ta.key

La fin du fichier doit ressembler à ceci :

<ca>
-----BEGIN CERTIFICATE-----
# CA certificate
-----END CERTIFICATE-----
</ca>

<cert>
-----BEGIN CERTIFICATE-----
# Client certificate
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN ENCRYPTED PRIVATE KEY-----
# Client private key
-----END ENCRYPTED PRIVATE KEY-----
</key>

<tls-crypt>
-----BEGIN OpenVPN Static key V1-----
# TLS static key
-----END OpenVPN Static key V1-----
</tls-crypt>

Et voilà, vous n’avez plus qu’à distribuer ce fichier au client !

Étape 6 : (Bonus) Révoquer un client

Si l’un de vos certificats clients est compromis, mais que vous ne souhaitez pas reconstruire tous votre PKI, il est nécessaire de l’ajouter dans la liste des certificats révoqués (Certificate Revocation List).
Pour cela, il suffit d’utiliser la commande fournie par easy-rsa :

# cd /etc/openvpn/easy-rsa
# ./easyrsa revoke <client_name>

Puis on copie le nouveau fichier CRL :

# cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
# chmod 644 /etc/openvpn/crl.pem

Conclusion

J’espère que ce guide vous aura fourni tous les élements de réponse pour votre installation d’OpenVPN !
Ceci est mon premier article, alors n’hésitez pas à pointer mes lacunes en commentaire !

Publié par theiremi dans Informatique, Systèmes et réseaux, 0 commentaire