Tutoriel d'installation et de configuration d'OpenVPN
OpenVPN est un logiciel qui permet de créer des réseaux privés virtuels qui permettent de joindre des machines du monde entier comme si elles étaient dans notre réseau local. Ceci ne se fait que si les machines sont clientes dans le VPN.
Openvpn a l'immense avantage de s'installer aussi bien sous Linux que sous Windows. L'installation ne sera détaillée ici que sous Linux. Sachez que sous Windows les fichiers de configuration sont identiques ce qui permet d'ajouter des clients aisément.
Tout au long de ce tutoriel nous utiliseront la distribution Debian. Cette configuration a été testée sur une Debian Etch et Lenny en client et en serveur. Les clients Windows ont également étés testés sous Windows XP.
Nous verrons donc d'abord comment installer le serveur OpenSSL qui gère l'encodage des données, la génération des clefs, ensuite l'installation du serveur OpenVPN proprement dit puis nous finiront par l'installation d'un client.
Un petit détail qui est essentiel : Le serveur VPN doit posséder une IP publique que vous pourrez agrémenter d'un nom de domaine. Dans le cas contraire, aucun accès au serveur n'est possible. Les clients, eux, peuvent se trouver n'importe où pourvu que le port/protocole utilisé soit ouvert. Dans cette optique nous avons utilisé le port 443 en TCP qui est ouvert quasiment partout (c'est le port utilisé également pour les connexion SSL). Celà n'altère pas le fonctionnement des connexion SSL sur le client mais cela empêche le serveur d'héberger un serveur Web permettant les connexions sécurisées.
OpenSSL
Pourquoi installer OpenSSL ? En effet, ca ne parait pas avoir un rapport avec les réseaux. En réalité, SSL est une algorithme de chiffrement très utilisé sous Linux par beaucoup d'applications parmi lesquelles Apache, SSH, SFTP et bien d'autres encore. Il gère également l'authentification par clefs. C'est surtout pour cette fonctionnalité que nous allons l'utiliser.
L'authentification par clefs est la plus sécurisée. Pour se connecter dans le VPN il est nécessaire d'avoir la bonne clef certifiée par le serveur qui peut à tout moment révoquer une clef si celle-ci est compromise.
Pour installer OpenSSL tappez la commande suivante :
apt-get install openssl
Pour configurer SSL il faut éditer le fichier /etc/ssl/openssl.cnf qui est très bien documenté. Une version est disponible ci-dessous. Remplacez user par votre nom d'utilisateur.
Configuration de : /etc/ssl/openssl.cnf (Cliquez pour faire apparaitre le fichier)
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = /home/user/.ssl/
RANDFILE = ::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = ::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = /usr/local/etc/ssl # Where everything is kept
certs = /certs # Where the issued certs are kept
crl_dir = /crl # Where the issued crl are kept
database = /index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = /certif # default place for new certs.
certificate = /certif/ca.crt # The CA certificate
serial = /serial # The current serial number
crlnumber = /crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = /crl.pem # The current CRL
private_key = /private/ca.key # The private key
RANDFILE = /private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 3650 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha1 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = FR
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = region
stateOrProvinceName_default = region
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Internet Widgits Pty Ltd
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (eg, YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
Une fois OpenSSL configuré, il est temps d'installer OpenVPN, donc :
apt-get install openvpn
OpenVPN comporte par défaut sur les distributions de type Debian une aide pour la génération de clefs et de gestion du serveur SSL.
Génération des clefs
L'utilitaire de génération de clef se situe dans le répertoire /usr/share/doc/openvpn/examples/easy-rsa/2.0/ et constitue essentiellement une batterie de scripts. Nous nous placeront dans ce répertoire pour toute cette partie. N'hésitez pas :
cd /usr/share/doc/openvpn/examples/easy-rsa/2.0/
La plus grande difficulté se trouve ici : ne pas se perdre dans toutes les clefs et les certificats générés. Pour ce faire, il est vivement recommandé de les nommer correctement. Pour notre cas, nous voulons un VPN avec un serveur et un client. Il faut trois clefs et certificats : une paire pour le SERVEUR OPENSSL, une paire pour le serveur VPN et une paire pour le client. D'une manière générale comptez une paire clef/certificat par client plus deux.
Chaque certificat doit être validé par le serveur pour pouvoir se connecter dans le VPN. Cette opération est faite automatiquement dans les scripts. Cependant, il est possible de générer un certificat avec les mêmes caractéristiques sur une autre machine et de le signer sur le serveur (c'est nettement moins pratique).
Nous appellerons le certificat du serveur SSL ca.crt, la clef du serveur SSL ca.key. Pour éditer les caractéristiques de vos clefs/certificats, éditer le fichier vars et remplacez les valeurs. Pour la taille de la clef, sachez que plus la clef est grosse plus elle demande de la puissance aux machines pour encoder/décoder le flux et que, si on veut vraiment voir ce que vous faites dans votre VPN ça reste possible. Soit vous êtes parano à ce moment 2048 me parait une valeur déraisonnable (même si c'est ce que j'ai mis) et qui est interdite en France, soit vous êtes normal, et 512 convient tout à fait. Toutes les clefs et tous les certificats générés seront placés dans le sous-répertoire keys. A la suite de ça, sourcez le fichier vars :
./clean-all
source vars ou
. ./vars
Il faudra sourcer votre fichier à chaque fois que vous voulez générer une clef (si vous avez redémarré depuis la fois précédente).
Vient le moment de générer les clefs/certificats. Nous allons générer le certificat pour OpenSSL d'abord (ca.crt et ca.key)
./build-ca
Par défaut, le certificat est valable 10 ans (3650 jours) mais cette valeur est modifiable directement dans le script (option -days). Si vous modifiez cette valeur pour le ca.crt, modifiez la également pour toutes les clefs/certificats. Vous pouvez voir que les droits 600 sont automatiquement mis sur le fichier ca.key : ceci est primordial. Si quelqu'un arrive à se procurer cette clef, toute la séciruté de votre VPN est compromise parce qu'un(e) autre que vous pourra générer des clefs clients.
Après cela il faut générer ce qu'on appelle le paramètre de Diffie-Hellman. Je ne sais pas exactement à quoi ca correpond mais il faut le faire. Pour cela, tappez la commande suivante. Ca peut prendre du temps, beaucoup de temps (surtout pour les grosses clefs) alors soyez patients !
./build-dh
Le fichier de sortie est en théorie dh512.pem pour une clef de 512 bits.
Vient ensuite le moment de générer une paire clef/certificat pour le serveur OpenVPN. Tappez donc la commande suivante :
./build-key-server openvpn
Vous obtiendez ici 3 fichiers de sortie : openvpn.crt, openvpn.csr et openvpn.key. Vous pouvez supprimer le fichier .csr. En effet, c'est en réalité le fichier du certificat pas encore signé. Comme les petits scripts signent automatiquement les certificats, ce fichier n'est plus nécessaire. Ceci sera valable pour toutes les clefs.
Générez ensuite une clef pour le client à l'aide de la commande suivante :
./build-key client
Vous obtiendrez de nouveau les fichiers suivants : client.crt, client.csr (à supprimer) et client.key. Tous les fichiers .key sont en droits 600 et il faut les laisser ainsi.
Pour résummer nous avons les fichiers suivants :
Fichiers Openvpn
| Nom du fichier |
Utilité (public/privé) |
| ca.crt |
Certificat serveur SSL (public) |
| ca.key |
Clef de signature serveur SSL (hautement super méga top secret) |
| openvpn.crt |
Certificat du serveur OpenVPN (peu importe, de préférence privé) |
| openvpn.key |
Clef d'authentification du serveur OpenVPN (privé) |
| client.crt |
Certificat du client (public) |
| client.key |
Clef d'authentification du client (très privé) |
Si un seul de vos fichiers privé est compromis, refaites tout le jeu de clefs (Serveur SSL compris !)
Après la génération de tous ces fichiers, vous pouvez passer à la configuration d'OpenVPN proprement dite.
Serveur OpenVPN
A ce moment, vous devriez avoir dans le répertoire /usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ un certain nombre de fichiers de chiffrement. Créer dans le répertoire /etc/openvpn/ un répertoire server.
mkdir /etc/openvpn/server/
Copiez dans le répertoire /etc/openvpn/server/ les fichiers suivants : dh512.pem, openvpn.key, openvpn.crt et ca.crt (laissez ca.key en place). Copiez également le fichier de configuration d'exemple qui se trouve dans le répertoire /usr/share/doc/openvpn/examples/sample-config-files/ il se nomme server.conf.gz et placez le dans /etc/openvpn/server/ et déGzippez-le.
gunzip server.conf.gz
Ce fichier est très bien documenté. Ci-dessous vous avez la version que j'ai modifié. Pour l'utiliser vous devez ajouter l'utilisateur openvpn au système pour augmenter légèrement la sécurité de l'exécution du programme à l'aide de la commande suivante :
useradd openvpn
Configuration de : /etc/openvpn/server/server.conf (Cliquez pour faire apparaitre le fichier)
port 443
proto tcp
dev tun0
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/openvpn.crt
key /etc/openvpn/server/openvpn.key
#Notre DHparam de 512 bits. Si votre cryptage est sur 1024 bits, son nom sera dh1024.pem
dh /etc/openvpn/server/dh512.pem
#On définit la classe d'adresse utilisées par le serveur VPN (ip privées)
server 10.1.0.0 255.255.255.0
#les clients ont des IP fixes dans le VPN (liste dans ipp.txt)
ifconfig-pool-persist ipp.txt
#Ajout de route dans les tables des clients
push "route 10.2.0.0 255.255.255.0"
#Celle-ci sert à joindre le serveur VPN, ne pas la retirer ...
#Les clients passent toute leur connexion par le VPN.
;push "redirect-gateway"
#Le signe ; permet également de commenter des lignes.
#les clients peuvent se joindrent entre eux
client-to-client
#Ping toutes les 10 secondes. Au bout de 120 secondes de non réponse, le tunnel est considéré comme mort
keepalive 10 120
#On compresse les données pour gagner un peu en débit
comp-lzo
#Nécessite la librairie LZO
#On limite le nombre de clients
max-clients 10
#Openvpn est lancé avec l'utilisateur openvpn créé juste avant
user openvpn
group openvpn
#Normalement le groupe a été créé en même temps que l'utilisateur
#Des options que j'ai pas comprises
persist-key
persist-tun
#On ajoute au fichier de log la sortie
log-append openvpn-server.log
#Avec l'option log, le fichier est purgé à chaque redémarrage d'openvpn.
#Degré de verbosité du programme (compris entre 0 et 9)
verb 4
#Si un message apparait plusieurs fois, on ne l'affiche qu'une fois et le nombre de fois qu'il est apparu à côté. S'il apparit plus de 20 fois, on l'affiche 2 fois (évite d'avoir des logs énormes).
mute 20
Une fois ce fichier en place, vérifiez que le serveur fonctionne à l'aide de la commande suivante :
openvpn --config /etc/openvpn/server/server.conf
En théorie, au bout d'un moment doit s'afficher le texte suivant qui signifie que le serveur est lancé.
Initialization Sequence Completed
Après cela, faites un lien du fichier serveur dans /etc/openvpn/
ln /etc/openvpn/server/server.conf /etc/openvpn/server.conf
pour que le script d'init le voit et quand vous tapperez
/etc/init.d/openvpn restart
tout sera bien démarré. Le serveur est fonctionnel !
Installation d'un client
La configuration du client se passe dans le même répertoire que la configuration serveur mais sur la machine client qui doit également avoir openvpn d'installé. Déplacez vous donc dans /etc/openvpn/ et créez un répertoire client (il peut prendre le nom que vous voulez).
cd /etc/openvpn/
mkdir client
Cette organisation en sous dossier, à première vue inutile, le devient si une machine est cliente dans plusieurs VPN, si une machine est à la fois client et serveur. Le fait de faire un lien permet également de se retirer facilement d'un VPN (supression du fichier et redémarrage du serveur) sans pour autant perdre la configuration.
La configuration du client resemble de très près à celle du serveur. Le principe est le même, le client doit avoir à disposition le certificat serveur (ca.crt) ainsi que les clefs qui lui sont destinées (client.crt et client.key). Pour la configuration il est impératif d'utiliser le même port, le même protocole, la même compression, etc. Ca peut paraître évident, mais on est jamais à l'abri. Le fichier de configuartion est très semblable. Un fichier de démonstration est également disponible dans /usr/share/doc/openvpn/examples/sample-config-files/client.conf. Vous pouvez soit partir de cette configuration soit de celle ci-dessous qui est en théorie compatible avec la configuration serveur ci-dessus (si tout se passe bien ...). Remplacer adresse_serveur par l'adresse publique de votre serveur (IP ou nom de domaine).
Configuration de : /etc/openvpn/client/client.conf (Cliquez pour faire apparaitre le fichier)
#C'est une conf client
client
#Interface créée lors de la création du tunnel
dev tun0
#Protocole
proto tcp
#Adresse du serveur et port (défaut 1194)
remote adresse_serveur 443
#Tenter la connexion indéfiniment
resolv-retry infinite
#Lancer openvpn avec l'utilisateur openvpn
user openvpn
group openvpn
#Les mêmes lignes que je comprend pas :D
persist-key
persist-tun
#Emplacement des certificats
ca /etc/openvpn/client/ca.crt
cert /etc/openvpn/client/client.crt
key /etc/openvpn/client/client.key
#Activation de la compression
comp-lzo
#Mode "verbeux"
verb 3
Normalement, après ca, vous devriez pouvoir vous connecter au serveur. Tentez une connexion à l'aide de la commande suivante :
openvpn --config /etc/openvpn/client/client.conf
Si la sortie affiche au bout d'un moment :
Initialization Sequence Completed
C'est que vous êtes connectés. Faites un petit lien vers le répertoire /etc/openvpn/ et redémarrez OpenVPN :
ln /etc/openvpn/client/client.conf /etc/openvpn/
/etc/init.d/openvpn restart
Normalement, votre VPN est opérationnel !
Vous devriez voir apparaître l'interface tun0 dans votre ifconfig et vous devriez pouvoir pinguer le serveur :
ping -c 1 10.1.0.1
Quelques petites précisions. Tous les clients peuvent joindre le serveur à l'adresse 10.1.0.1 mais chaque client peut joindre également le serveur à l'aide de l'IP du tunnel. Si vous souhaitez ajouter une route par défaut (pour faire sortir l'intégralité de votre connexion par le VPN) utilisez :
route add -net default gw 10.1.0.x
Où x est le dernier chiffre de l'IP du serveur dans le tunnel ! Ca n'est pas 10.1.0.1.
En espérant que cette petite aide vous aura été utile !
Smurf