Serveur OpenVPN
dim. 01 sept. 2013 by MarmotteUn serveur OpenVPN permet à des machines d'établir un lien chiffré avec le serveur. Il peut permettre d'accéder à un réseau privé situé derrière le serveur. Il peut aussi être utilisé pour faire passer tout le traffic du client par ce lien, dans le cas où le client utilise une connexion publique non sécurisée, par exemple.
Cas spécifique d'un container LXC¶
Si le serveur OpenVPN est dans un container LXC, il faut lui autoriser l'accès à l'interface tun
.
Dans le fichier de configuration de la machine LXC, /var/lib/lxc/<container-name>/config
, il faut ajouter cette ligne :
# tun
lxc.cgroup.devices.allow = c 10:200 rwm
Cette modification demande un redémarrage du container pour prendre effet.
Note : Si le paquet
openvpn
a été installé avant que l'interfacetun
ne soit autorisée dans le container, il faut reconfigurer le paquet.$ sudo dpkg-reconfigure openvpn
Installation¶
Sous Debian, il suffit d'installer les paquets openssl
et openvpn
.
$ sudo apt-get install --no-install-recommends openssl openvpn
Note : Depuis Debian jessie, les scripts de génération des certificats ont été déplacés dans le paquet
easy-rsa
, qu'il faut donc installer en supplément.
Génération des certificats¶
Les certificats et les fichiers de travail seront placés dans le répertoire /etc/openvpn/<NetworkName>/
.
Il faut donc créer ce répertoire.
$ sudo mkdir /etc/openvpn/<NetworkName>
J'utilise les outils easy-rsa/2.0
fournis dans la documentation du paquet Debian pour générer les certificats et clés utilisés par le VPN.
Afin de ne pas travailler sur les fichiers originaux, et permettre de mettre facilement en place plusieurs instances d'OpenVPN, je copie les scripts de gestion des clés dans un répertoire spécifique.
$ sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/<NetworkName>/easy-rsa
Note : Sous Debian jessie, les scripts de génération des certificats sont dans le répertoire
/usr/share/easy-rsa
au lieu de/usr/share/doc/openvpn/examples/easy-rsa/2.0
.
Pour la suite de la génération des certificats, on doit se placer dans le répertoire où se trouvent les scripts, puisqu'ils travaillent avec des chemins relatifs.
$ cd /etc/openvpn/<NetworkName>/easy-rsa
il faut d'abord modifier les valeurs du fichier /etc/openvpn/<NetworkName>/easy-rsa/vars
, pour les adapter au réseau créé.
export KEY_COUNTRY="FR"
export KEY_PROVINCE="FR"
export KEY_CITY="Paris"
export KEY_ORG="Marmotte"
export KEY_EMAIL="marmotte@server"
Il faut ensuite charger les valeurs de ce fichier dans l'environnement.
$ . vars
Le script clean-all
nettoie l'environnement, et ajoute les éventuels répertoires manquants.
Il est donc conseillé de commencer par l'exécuter afin d'être certain que le répertoire de travail est conforme.
$ sudo -E ./clean-all
Le premier certificat qu'il faut est générer est le certificat d'autorité. Il servira à signer tous les autres certificats créés par la suite.
$ sudo -E ./build-ca
Il faut ensuite générer le certificat qui sera utilisé par le serveur. Le paramètre donné est le nom du certificat du serveur.
$ sudo -E ./build-key-server <ServerCertName>
Nous générons ensuite une clé DH. Cette clé permet de chiffrer la phase d'échange de clés entre le client et le serveur, avant de passer la main au chiffrement du VPN lui même, une fois la connexion établie.
$ sudo -E ./build-dh
Il est aussi possible d'utiliser une clé TLS. Cette clé permet d'authentifier les paquets envoyés par les clients au serveur VPN. Les paquets n'ayant pas la bonne signature seront simplement ignorés, permettant de limiter la possibilité de flood ou détection du serveur VPN.
$ sudo -E openvpn --genkey --secret keys/ta.key
Génération des certificats des clients¶
Les certificats clients sont générés de la même manière que celui du serveur, mais avec le script build-key
.
Comme pour le certificat du serveur, le paramètre permet de définir le nom qui sera donné au certificat.
$ cd /etc/openvpn/<NetworkName>/easy-rsa
$ . vars
$ sudo -E ./build-key <ClientCertName>
Note : La dernière opération doit être exécutée autant de fois qu'il y a de clients.
Configuration générale¶
OpenVPN propose un fichier de configuration par défaut, qui contient déjà la plupart des directives utiles. Le plus simple est donc de se baser sur ce fichier de configuration pour créer celui de notre serveur.
$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/<NetworkName>.conf.gz
$ sudo gunzip /etc/openvpn/<NetworkName>.conf.gz
Dans la configuration, il faudra au moins modifier ces éléments :
-
Le chemin des certificats et clés aux lignes
ca
,cert
,key
etdh
ca <NetworkName>/easy-rsa/keys/ca.crt cert <NetworkName>/easy-rsa/keys/<ServerCertName>.crt key <NetworkName>/easy-rsa/keys/<ServerCertName>.key # This file should be kept secret dh <NetworkName>/easy-rsa/keys/dh1024.pem
-
Éventuellement modifier l'adresse IP et le masque du réseau VPN à la ligne
server
-
Décommenter la ligne
tls-auth
et modifier le chemin de la clétls-auth <NetworkName>/easy-rsa/keys/ta.key 0 # This file is secret
-
Décommenter les lignes
user
etgroup
, pour limiter les droits du processus OpenVPN -
Décommenter et adapter la ligne
log-append
pour avoir un log persistantlog-append /var/log/openvpn/<NetworkName>.log
Attention : Il faut bien penser à créer le répertoire
/var/log/openvpn/
et à configurer une rotation des fichiers de log. -
Dans le cas d'un accès via un NAT, bien vérifier le protocole utilisé (TCP ou UDP) dans les règles de NAT donnant accès au serveur VPN
Il ne reste plus qu'à tester la configuration.
$ sudo openvpn /etc/openvpn/<NetworkName>.conf
Si le serveur se lance bien, vous pouvez l'arrêter, et le lancer comme service.
$ sudo service openvpn start <NetworkName>
Configurations supplémentaires¶
Utiliser le serveur VPN comme passerelle par défaut¶
Lorsqu'on se connecte sur une connexon publique non sécurisée, toutes les données transmises par l'ordinateur passent en clair sur le réseau. Ces données peuvent donc être capturées par n'importe quelle autre machine connectée au réseau, et parfois même par des machines non connectées au réseau.
Dans ce cas, il est très intéressant d'utiliser le serveur VPN comme passerelle par défaut. Ainsi, toutes les communications de l'ordinateur passeront à travers le VPN, et seront donc chiffrées, au moins jusqu'au serveur VPN.
Pour que le serveur VPN s'annonce comme passerelle par défaut à ses clients, il suffit de décommenter la route redirect-gateway
.
push "redirect-gateway def1 bypass-dhcp"
Note : Cette modification ne sera prise en compte qu'après avoir relancé le serveur VPN, et les connexions des clients au serveur.
Permettre aux clients VPN de dialoguer avec un LAN présent derrière le serveur VPN¶
Activer l'ip forwarding sur le serveur.
Dans un nouveau fichier /etc/sysctl.d/vpn.conf
, ajouter cette ligne :
net.ipv4.ip_forward = 1
Note : Pour activer cette règle à chaud, sans redémarrer le serveur, il faut recharger la configuration du kernel.
$ sudo sysctl --system
Ajouter la route vers le LAN dans la configuration du serveur VPN pour qu'il se déclare comme passerelle auprès des clients VPN.
push "route 10.0.0.0 255.255.255.0"
Note : Dans cet exemple,
10.0.0.0
est l'adresse du LAN à atteindre et255.255.255.0
le masque de ce réseau
Ajouter la route retour aux machines qui doivent être accessibles via le VPN.
Il est préférable, si possible, de donner la route aux machines du réseau via un serveur DHCP (option classless-static-route
dans Dnsmasq).
$ sudo ip route add 10.8.0.0/24 via 10.0.0.1
Note : Dans cet exemple,
10.8.0.0/24
est l'adresse de réseau et masque du réseau VPN et10.0.0.1
l'adresse IP de la passerelle du LAN vers le VPN
Révocation d'un certificat¶
Lorsque l'un des clients ne doit plus pouvoir se connecter au VPN, ou qu'un certificat a été compromis, il faut le révoquer. Ainsi, ce certificat ne permettra plus d'accéder au réseau.
Comme pour la génération de certificats, il faut commencer par charger le fichiers vars
.
$ cd /etc/openvpn/<NetworkName>/easy-rsa
$ . vars
Il faut ensuite utiliser le script revoke-full
, en lui donnant le nom du certificat à révoquer.
$ sudo -E ./revoke-full <ClientCertName>
Ce script génère, ou met à jour, un fichier nommé crl.pem
(Certificate Revocation List).
La première fois qu'on révoque un certificat, il faut donc ajouter une directive dans le fichier de configuration du serveur pour lui indiquer de vérifier cette liste.
crl-verify <NetworkName>/easy-rsa/keys/crl.pem
Attention : Si vous avez décidé de déplacer le répertoire contenant les clés et certificats, pour simplifier les chemins dans le fichier de configuration, vérifiez bien le chemin du fichier
crl.pem
. Si le serveur OpenVPN ne trouve pas ce fichier, il ne l'utilisera pas, et les certificats révoqués pourront donc continuer de se connecter.
Il faut ensuite relancer le serveur VPN, et le certificat révoqué sera alors devenu inutile.
$ sudo service openvpn restart <NetworkName>
Note : Si vous utilisez les directives
user
etgroup
, vérifiez que le serveur a bien la posibilité de lire le fichiercrl.pem
.