Aujourd’hui, j’aimerais parler à propos d’OpenVPN. Pour ceux qui ne connaissent pas, OpenVPN est un logiciel libre et avec le code est ouvert et qui implémente des différentes façons de créer des réseaux virtuels (VPN) sécurisés * Wikipedia. L’application est développée par OpenVPN Incorporation et il propose également différents services payants privatetunnel.
De nos jours, de nombreux tutoriaux ont été publiés qui décrivent comment l’installer et configurer. Contrairement à eux, je vais essayer de vous proposer un tutoriel complet d’une installation avec les paramètres de sécurités les plus élevés. Le tutoriel se basera sur OpenVPN 2.4.0 et Debian 9.5. Dans celui-ci, je décrirai autant que possible les différentes étapes afin qu’il soit le plus compréhensible et lisible possible, bonne lecture.
Introduction
Pour commencer, nous devons installer le paquet OpenVPN et quelques autres avec l’utilisateur root.
1 2 3 |
apt update apt upgrade apt install -y iptables-persistent openvpn vim sudo |
La génération des certificats
Téléchargements et configuration de EasyRSA
Pour générer les certificats, nous allons utiliser EasyRSA. EasyRSA est une application en ligne de commande qui permet de générer et de gérer les clés et certificats nécessaires à l’authentification des clients et serveurs. Vous pouvez télécharger la dernière version disponible ici EasyRSA est un des outils les plus simples à utiliser pour générer les certificats. Cet article se concentre principalement sur la configuration de OpenVPN.
Malheureusement, bien que EasyRSA propose de générer des certificats et clés très sécurisés, ceux-ci ne sont pas les plus sécurisés possible. Pour les générer de façon la plus sécurisée possible, vous devrez utiliser directement OpenSSL. Un tutoriel est disponible ici.
1 2 3 4 5 6 7 |
mkdir /tmp/openvpn cd /tmp/openvpn/ wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz tar xf EasyRSA-nix-3.0.5.tgz cd EasyRSA-3.0.5 cp vars.example vars vim vars |
Vous devez maintenant modifier le fichier var dans le but d’activer les courbes elliptiques et d’améliorer l’algorithme de hachage utilisé. En étudiant plus en détail les courbes elliptiques, il semblerait que celles proposaient par l’institut national des standards et de la technologie (NIST) soient délibérément affaiblies. C’est pourquoi je recommande d’utiliser la courbe Curve25519 parce qu’elle est aussi solide que son équivalente proposé par le NIST, plus rapide, plus sûr et elle n’a pas été crée par le NIST. Il y a d’autres courbes plus sécurisées disponibles, mais elles ralentissent beaucoup le trafic réseau.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Activer les courbes elliptiques set_var EASYRSA_ALGO ec # Choix d'une courbe en particulier, les courbes supportées par OpenVPN peuvent être affichées avec - openvpn --show-curves # Impossible de choisir la couber elliptic Curve25519 avec EasyRSA et openvpn ne la supporte pas. set_var EASYRSA_CURVE secp521r1 # Durée de validité du certificat racine avant expiration (en jours) set_var EASYRSA_CA_EXPIRE 3650 # Durée de validité des certificats avant expiration (en jours) set_var EASYRSA_CERT_EXPIRE 3650 # Nombre de jours avant vérification de la validité du certificat set_var EASYRSA_CRL_DAYS 3650 # Choix de l'algorithme de hachage, malheureusement, seul MD5 et la famille SHA sont disponibles set_var EASYRSA_DIGEST "sha512" |
Génération des certificats
Merci de choisir le “Common name” soigneusement pour chaque certificat, en particulier pour le certificat du serveur. Celui-ci sera utilisé par la configuration cliente de OpenVPN pour vérifier le serveur et éviter les attaques de type Homme du milieu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# Génération d'un répertoire pour conserver les fichiers ./easyrsa init-pki # Génération du certificat racine de l'autorité ./easyrsa build-ca nopass # Génération de la clé pour le serveur (server.key) et de la demande de signature du certificat (server.req) ./easyrsa gen-req server nopass # Signature du certificat serveur par l'autorité de certification créée préalablement (server.ca) ./easyrsa sign-req server server nopass # Génération de la clé pour le client (client.key) et de la demande de signature du certificat (client.req) ./easyrsa gen-req client nopass # Signature du certificat client par l'autorité de certification créée préalablement (client.ca) ./easyrsa sign-req client client nopass |
Structure des dossiers
Nous allons maintenant créer une structure de fichiers facile à lire
1 2 3 4 5 6 7 8 9 10 11 |
mkdir /tmp/openvpn/server/ mkdir /tmp/openvpn/server/certificates cp /tmp/openvpn/EasyRSA-3.0.5/pki/ca.crt /tmp/openvpn/server/certificates/ca.crt cp /tmp/openvpn/EasyRSA-3.0.5/pki/issued/server.crt /tmp/openvpn/server/certificates/server.crt cp /tmp/openvpn/EasyRSA-3.0.5/pki/private/server.key /tmp/openvpn/server/certificates/server.key mkdir /tmp/openvpn/client/ mkdir /tmp/openvpn/client/certificates cp /tmp/openvpn/EasyRSA-3.0.5/pki/ca.crt /tmp/openvpn/client/certificates/ca.crt cp /tmp/openvpn/EasyRSA-3.0.5/pki/issued/client.crt /tmp/openvpn/client/certificates/client.crt cp /tmp/openvpn/EasyRSA-3.0.5/pki/private/client.key /tmp/openvpn/client/certificates/client.key |
Configuration réseau
Considérons que nous avons un serveur OpenSSH qui écoute le port 22 et que le port 443 est dédié au serveur OpenVPN.
Règles du pare-feu
Nous devons définir les règles du pare-feu (iptables) dans le fichier /etc/iptables/rules.v4:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
*nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] # Forward the VPN traffic to eth0 -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE COMMIT *filter # Autorise le trafic de l'interface loopback en provenance de l'interface loopback et rejette le reste -A INPUT -i lo -j ACCEPT -A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT -A OUTPUT -o lo -j ACCEPT # Autorise le ping et les retours du protocole icmp -A INPUT -p icmp -m state --state NEW --icmp-type 8 -j ACCEPT -A INPUT -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT -A OUTPUT -p icmp -j ACCEPT # Authorise SSH. -A INPUT -i eth0 -p tcp -m state --state NEW,ESTABLISHED --dport 22 -j ACCEPT -A OUTPUT -o eth0 -p tcp -m state --state ESTABLISHED --sport 22 -j ACCEPT # Authorise le traffic TCP. -A INPUT -i eth0 -p tcp -m state --state NEW,ESTABLISHED --dport 443 -j ACCEPT -A OUTPUT -o eth0 -p tcp -m state --state ESTABLISHED --sport 443 -j ACCEPT # Autorise la résolution DNS et limite l'écoute du serveur OpenVPN à l'interface eth0 -A INPUT -i eth0 -p udp -m state --state ESTABLISHED --sport 53 -j ACCEPT -A OUTPUT -o eth0 -p udp -m state --state NEW,ESTABLISHED --dport 53 -j ACCEPT # Autorise le trafic pour l'interface tunnel créée par OpenVPN -A INPUT -i tun0 -j ACCEPT -A OUTPUT -o tun0 -j ACCEPT # rejet du reste -A INPUT -j REJECT -A OUTPUT -j REJECT COMMIT |
Attention à bien adapter ces règles à vos besoins avant de les déployer.
sudo iptables-restore < /etc/iptables/rules.v4
Nous pouvons vérifier les règles appliquées avec:
sudo iptables -L
Autoriser le suivi IPV4 et désactivation de ipv6
Dans le fichier /etc/sysctl.d/99-sysctl.conf, ajouter les lignes suivantes pour activer le suivi IPV4 et désactiver le fonctionnement ipv6:
1 2 3 4 5 6 7 8 9 |
net.ipv4.ip_forward = 1 net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 net.ipv6.conf.eth0.disable_ipv6 = 1 # activation de la nouvelle configuration sudo sysctl -p |
Suppression de la ligne ipv6 dans /etc/hosts:
#::1 localhost ip6-localhost ip6-loopback Rejeter le trafic ipv6 en éditant le fichier /etc/iptables/rules.v6, il doit contenir:
1 2 3 4 5 6 7 8 9 10 11 12 |
vim /etc/iptables/rules.v6 *filter -A INPUT -j REJECT -A FORWARD -j REJECT -A OUTPUT -j REJECT COMMIT # puis appliquer sudo ip6tables-restore < /etc/iptables/rules.v6 |
Exemple de configuration très sécurisée
Afin de poursuivre, nous allons utiliser une configuration très sécurisée de OpenVPn que nous détaillerons ci-dessous.Attention, suivez bien le tutoriel jusqu’au bout pour vous assurez du bon fonctionnement de la configuration. .
Exemple de la configuration serveur
Veuillez copier les lignes suivantes dans /tmp/openvpn/server/server.conf. Il s’agit de la configuration OpenVPN du serveur. N’oubliez pas de remplacer IP_OF_YOUR_OPENVPN_SERVER par l’adresse IP de votre serveur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#/tmp/openvpn/server/server.conf local IP_OF_YOUR_OPENVPN_SERVER dev tun topology subnet proto tcp port 443 server 10.8.0.0 255.255.255.0 tls-server ca /etc/openvpn/server/certificates/ca.crt # crl-verify /etc/openvpn/server/certificates/crl.pem cert /etc/openvpn/server/certificates/server.crt key /etc/openvpn/server/certificates/server.key tls-crypt /etc/openvpn/server/certificates/tls_crypt.key dh none ecdh-curve ED25519 tls-cipher TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 cipher AES-256-GCM ncp-ciphers AES-256-GCM tls-version-min 1.2 persist-tun compress persist-key keepalive 10 120 user ovpn group ovpn status /var/log/openvpn-status.log log /var/log/openvpn.log push "redirect-gateway" push "dhcp-option DNS 10.8.0.1" push "dhcp-option WINS 10.8.0.1" push "route-ipv6 2000::/3" |
Exemple de la configuration client
Veuillez copier les lignes suivantes dans /tmp/openvpn/client/client.conf. Il s’agit de la configuration OpenVPN du serveur. N’oubliez pas de remplacer IP_OF_YOUR_OPENVPN_SERVER par l’adresse IP de votre serveur ainsi que COMMON_NAME_OF_THE_SERVER_CERTIFICATE par le Common name que vous avez choisi lors de la génération du certificat pour le serveur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# /tmp/openvpn/client client dev tun remote IP_OF_YOUR_OPENVPN_SERVER 443 proto tcp resolv-retry infinite compress nobind verify-x509-name "COMMON_NAME_OF_THE_SERVER_CERTIFICATE" name remote-cert-tls server tls-cipher TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 cipher AES-256-GCM tls-version-min 1.2 auth-nocache persist-key persist-tun status /var/log/openvpn-status.log log /var/log/openvpn.log verb 3 ca /etc/openvpn/client/certificates/ca.crt cert /etc/openvpn/client/certificates/client.crt key /etc/openvpn/client/certificates/client.key tls-crypt /etc/openvpn/client/certificates/tls_crypt.key |
Durcissement de la configuration OpenVPN
Cette partie décrit la plupart des paramètres de configuration présents dans la configuration exemple.
TCP/IP protocole et port d’écoute
Dans le but d’éviter que le trafic du VPN ne soit bloqué par les pare-feu rencontrés, il est fortement recommandé de remplacer le protocole udp par le protocole tcp. OpenVPN configurait avec le protocole TCP est un petit plus lent, mais a plus de chance de passer outre les configurations réseaux restrictives.
Vous devez également configurer le serveur OpenVPN pour écouter sur le port 443. Le port 443 est le port standard pour un serveur web. Ce port est en général ouvert en sortie dans la plupart des configurations réseau. Pour information, le port standard d’OpenVPN est le 1194.
proto tcp4
port 443
Diffie-Hellman
L’échange de clé Diffie–Hellman key est une méthode sécurisée d’échange cryptographique de clé sur un canal publique. Dans Openvpn, ce protocole est utilisé dans les premières étapes de l’établissement d’une connexion TLS. Avec une clé de 1024 bits ou moins, le protocole est vulnérable à la vulnérabilité Logjam. Les auteurs de la vulnérabilité recommandent d’utiliser un nombre de bits égales ou supérieurs à 2048 bits pour Diffie-Hellman ou de basculer sur une courbe elliptique Diffie–Hellman. Dans ce tutoriel, nous allons utiliser la courbe Diffie–Hellman
HMAC signature pendant la poignée de main TLS
Depuis openVPN 2.4, il est recommandé de remplacer le paramètre tls-auth par tls-crypt. Principalement parce que tls-crypt va en plus de faire exactement la même chose que tls-auth, va chiffrer le canal de contrôle lors de l’établissement d’une connexion chiffrée avec TLS. Pour se faire, il faut ajouter les lignes suivantes:
tls-crypt /etc/openvpn/certificates/ta.key 0
et générer le fichier contenant la clé HMAC key dans le répertoire OpenVPN
openvpn –genkey –secret /tmp/openvpn/server/certificates/tls_crypt.key
cp /tmp/openvpn/server/certificates/tls_crypt.key /tmp/openvpn/client/certificates/tls_crypt.key
Persistent tun/tap device et clé
A chaque fois que votre connexion réseau est interrompue et qu’OpenVPN essaye de se reconnecter, il est possible que vous utilisiez votre réseau non sécurisé. Cela peut exposer des informations sensibles.
persist-key n’est pas un paramètre de sécurité, mais une option pour éviter un problème au redémarrage d’OpenVPN et à l’impossibilité que l’application peut avoir à relire les clés.
persist-tun
persist-key
Utilisateur limité
Probablement un des paramétrages les plus importants. Dans le but de réduire l’impact d’une vulnérabilité d’OpenVPN, il est hautement recommandé de l’exécuter avec un utilisateur possédant des droits limités. Pour ce faire, nous allons créer un utilisateur dédié à OpenVPN avec des droits limités.
adduser –system –shell /usr/sbin/nologin –no-create-home ovpn
groupadd ovpn
usermod -a -G ovpn ovpn
et spécifié à OpenVPN d’utiliser cet utilisateur:
user ovpn
group ovpn
Algorithme de chiffrement et fonction de hachage
Dans le fichier/etc/openvpn/server.conf, nous avons à spécifier l’algorithme de chiffrement à utiliser ainsi que la fonction de hachage. Il semble recommander d’utiliser l’algorithme de chiffrement GCM à la place de CBC. Plus d’informations sur les raisons de choix sont disponibles ici et ici
tls-version-min 1.2
ncp-ciphers AES-256-GCM:AES-256-CBC
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384
cipher AES-256-GCM
ecdh-curve ED25519
dh none
Nous allons désactiver la conservation en cache du mot de passe afin de réduire la surface d’attaque.
auth-nocache
Algorithmes de compression
Dans OpenVPN version 2.3, l’algorithme de compression LZ0 est celui par défaut. Depuis OpenVPN version 2.4, l’algorithme de compression LZ4 est disponible. Contrairement à ce que dit la documentation, la version 2 de LZ4 est est disponible et pas encore documenté.
Si la sécurité est votre seul critère, vous devez désactiver cette fonctionnalité. En effet, les vulnérabilités de type Beast, Crime et Voracle exploitent l’information relative à la taille différente de paquets suite à la compression. Plus précisément, si un attaquant connaît exactement les données qu’il est censé recevoir et qu’il réussit à capturer suffisamment de paquet, ces deux éléments combinés peuvent l’aider à réduire le temps nécessaire au cassage du chiffrement.
Pour moi, dans notre monde réel, cette attaque est très compliquée à mettre en oeuvre. La société OpenVPN recommande de désactiver les algorithmes de compression et à déjà procéder à cela sur leurs produits. Dans les fichiers de configuration fourni ici, axé sur la sécurité, la compression est désactivée. Si vous hésitez, vous pouvez faire des tests de performance pour mieux choisir.
Pousser les configurations réseau aux clients
OpenVPN est autorisé à pousser des règles réseau aux clients. La règle la plus importante concerne la directive push “redirect-gateway” qui modifie la route par défaut par celle spécifiée. Dans la plupart des cas, il s’agit de faire passer toutes les données par le tunnel ouvert par OpenVPN.
Une deuxième option intéressante est de pousser une configuration IPv6 erronée afin de s’assurer qu’aucun paquet ipv6 n’outrepasse le tunnel OpenVPN.
push “route-ipv6 2000::/3”
Revoquer et annuler la révocation du certificat d’un client
Revoquer le certificat d’un client
Il peut arriver que vous souhaitiez révoquer l’accès au VPN à un client. OpenVPN se base sur les Certification Revocation List (CRL) afin de déterminer si un certificat est valide. Pour révoquer le certificat du client que nous avons généré, vous devez exécuter les commandes suivantes:
./easyrsa revoke client
./easyrsa gen-crl
Ces commandes modifient également le fichier index.txt dans le répertoire /tmp/openvpn/EasyRSA-3.0.5/pki. Pour notre cas d’usage, le fichier devrait être ainsi:
V 893632988188Z CWGT67WFA9QLQ9YZ65VGB8FLJKUKV3JL unknown /CN=server R 943755258824Z Y9BFEB757EFV47Y9ENNBUGJLKGP9KQCD unknown /CN=client
Comme vous pouvez le voir, la première colonne est composée de la lettre V ou R. V signifie Validate (validé) et R signifie Revoke (révoqué). Un fichier crl.pem a été créé dans /tmp/openvpn/EasyRSA-3.0.5/pki. Ce fichier contient la liste des certificats révoqués. Nous devons le copier afin de le mettre dans un endroit accessible à OpenVPN et modifier server.conf pour lui indiquer.
1 2 3 4 5 |
cp /tmp/openvpn/EasyRSA-3.0.5/pki/crl.pem /etc/openvpn/server/certificates/crl.pem chown ovpn:ovpn /etc/openvpn/server/certificates/crl.pem # in server.conf crl-verify /etc/openvpn/server/certificates/crl.pem systemctl restart openvpn |
Annuler la révocation d’un certificat client
La liste contenant les certificats révoqués est unique et contient les indications concernant tous les certificats révoqués. Si vous souhaitez annuler la révocation d’un certificat, il est nécessaire de générer une nouvelle liste. Pour se faire, vous devez modifier le fichier /tmp/OpenVPN/EasyRSA-3.0.5/index.txt et remplacer la lettre R pour le certificat en question par la lettre V puis générer une nouvelle liste de certificats révoqués et finalement remplacement le fichier crl.pem chargé par OpenVPN.
Configuration et amélioration de performance
OpenVPN peut être configuré de nombreuses façon afin d’améliorer les performances. Je n’aborderai pas ici cette question, car ce n’est pas l’objet de l’article. Pour information, vous pouvez par exemple modifier l’algorithme de chiffrement utilisé, le protocole de communication utilisé ou également modifier les paramètres ci-dessous:
- mssfix
- fragment
- tun-mtu
- compression algorithme
Si vous voulez allez plus loin, n’hésitez pas cette page .
Déploiment et nettoyage
Félicitations ! La partie la plus compliquée est terminée. Il ne reste plus qu’à déplacer les fichiers et répertoires de façon correcte et à nettoyer l’installation.
Structure des fichiers
A ce stade, vous devriez avoir cette structure dans le répertoire /tmp/openvpn/server/. Le server OpenVPN aura besoin des fichiers suivants pour fonctionner correctement:
- server.conf
- certificates/ca.crt
- certificates/crl.pem
- certificates/server.key
- certificates/server.crt
- certificates/tls_crypt.key
A ce stade, vous devriez avoir cette structure dans le répertoire /tmp/openvpn/client/. Le client OpenVPN aura besoin des fichiers suivants pour fonctionner correctement
- client.conf
- certificates/client.crt
- certificates/client.key
- tls_crypt.key
Un lecteur a fait un très judicieux commentaire à propos de la configuration du client. Pour plus de praticité, vous pouvez agréger en un seul fichier; client.conf, toutes les données cryptographiques nécessaires à l’établissement de la connexion avec le serveur OpenVPN. Cette méthode est plus simple à utiliser et à maintenir. Pour l’utiliser, vous devez modifier le fichier client.conf en supprimant les lignes ca, cert, key et tls-crypt et les remplacer avec les lignes suivantes:
<ca>
–STRIPPED INLINE CA CERT–
</ca>
<cert>
–STRIPPED INLINE CERT–
</cert>
<key>
–STRIPPED INLINE KEY–
</key>
<tls-crypt>
–STRIPPED INLINE KEY–
</tls-crypt>
Dernière configuration et déploiement
Avant de déplacer les répertoires, nous allons les rendre accessibles au seul utilisateur root en mode lecture uniquement.
chmod 400 -R /tmp/openvpn/
Nous allons également déplacer toutes les clés dans un endroit sur et déplacer le répertoire lié à la configuration du serveur à l’endroit prévu à cet effet:
cp -r /tmp/openvpn/server /etc/openvpn/
cp -r /tmp/openvpn/ /etc/ssl/openvpn-pki
ln -s /etc/openvpn/server/server.conf /etc/openvpn/server.conf
Concernant le client, le répertoire dédié à celui-ci doit être déplacé à un autre endroit, que ce soit sur un autre ordinateur ou autre. Vous devez copier le répertoire /tmp/openvpn/client vers /etc/openvpn/ et créer un lien symbolique depuis /etc/openvpn/client/client.conf vers /etc/openvpn/client.conf
Execution
Pour exécuter le programme OpenVPN avec Systemd, vous devez modifier le fichier /etc/default/openvpn et décommenter la ligne AUTOSTART=”all” puis replacer “all” par le nom du fichier relatif à la configuration OpenVPN. Dans notre exemple, il faut remplacer “all” par “server”.
systemctl daemon-reload
Vous pouvez maintenant démarrer le serveur OpenVPN avec la commande suivante:
systemctl start openvpn
Vous pouvez procéder de la même façon pour le client.
Cleaning
Attention, n’oubliez pas de conserver le répertoire /tmp/openvpn. Il contient tous les certificats, dont les certificats racines nécessaires à la génération de nouveaux clients.
Conclusion
Réseaux sociaux
Merci pour votre lecture, j’espère que cet article vous a été utile. N’hésitez pas à commenter et à le partager.
Sources
Cet article n’aura pu être possible sans les contributions d’autres personnes. Leur travail m’a beaucoup aidé, merci à vous !
- Durcissement de OpenVPN
- Durcissement de OpenVPN de linode
- Durcissement de OpenVPN par Ester
- Lien vers un tutoriel openVPN
- Lien vers un tutoriel avec la meilleure configuration pour les courbes Elliptic
- La différence entre l’algorithme de chiffrement GCM et CBC
- Pourquoi tun/tap est utile
- Page man officielle de OpenVPN 2.4
- Retours des lecteurs de lobste.rs
Mises-à-jour :
- 30/07/2019 : Ajoût de la mention concernant le non support de la courbe elliptic Curve25519 par EasyRSA et openvpn.
- 31/07/2019 : Remplacement de TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384 par TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384. Le certificat racine étant de type elliptic curve, il n’est pas possible d’utiliser l’algorithme de chiffrement RSA pour signer avec.