User Tools

Site Tools


start:openvpn_how-to

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

start:openvpn_how-to [2006/05/12 17:40] (current)
Line 1: Line 1:
 +====== OpenVPN How-To ====== ​
  
 +  * Auteur : G. Arcas <​guillaume.arcas>​ at <​free.fr>​ || <​guillaume.arcas>​ at <​retiaire.org>​
 +  * Date : 26 février 2006
 +  * Version : 1.1
 +
 +----
 +
 +**ToDo Liste**
 +
 +  * Diagramme des paquets UDP et TCP OpenVPN
 +  * Règles de filtrage
 +
 +----
 +
 +====== Introduction ======
 +
 +  * OpenVPN est une solution Libre de mise en oeuvre de VPN (Virtual Private Network, Réseau Privé Virtuel en bon français).
 +  * Construite au-dessus de la bibliothèque de fonctions cryptographiques OpenSSL, OpenVPN est une application client/​serveur qui s'​installe et s'​exécute en environnement Utilisateur (Userland) sur les systèmes d'​exploitation les plus courants des mondes Unix/Linux, Microsoft et Apple.
 +  * Comme toute bonne solution VPN, OpenVPN apporte les fonctionnalités de confidentialité (chiffrement des données), d'​intégrité du trafic réseau et d'​authentification forte mutuelle des participants (clients et serveurs) au VPN.
 +  * Nous allons voir dans la suite de ce document comment utiliser OpenVPN à partir d'une situation "​réelle"​ ou tout du moins réaliste.
 +  * [[http://​www.openvpn.net|Site Officiel du projet OpenVPN]]
 +
 +===== Cahier des charges =====
 +  * La société ACME SARL souhaite mettre en oeuvre une solution VPN pour ses commerciaux et techniciens itinérants. Ceux-ci pourront ainsi bénéficier de l'​infrastructure du SI de l'​entreprise durant leurs déplacements.
 +  * Compte tenu du caractère sensible des données que ces personnels sont amenés à traiter ou manipuler, la solution doit fournir un haut niveau de sécurité et garantir la confidentialité et l'​intégrité des données échangées,​ ainsi que l'​authentification de chaque composante du VPN.
 +  * Les machines seront ainsi identifiées et authentifiées à l'aide de certificats et les utilisateurs à l'aide de mots de passe. Ces éléments seront propres à chaque partie et donc uniques.
 +  * Une fois connectés au VPN de la société, les postes nomades utiliseront exclusivement les infrastructures du SI ACME. Le VPN est un moyen d'​étendre de manière sûre le SI de l'​entreprise.
 +  * La solution doit être adaptée à l'​infrastructure réseau et au parc informatique de l'​entreprise : serveurs Unix et postes clients sous MS Windows et Apple Mac OS X.
 +
 +===== Architecture =====
 +  * Le SI de la société ACME est représenté ci-dessous :
 +{{ start:​archi-vpn-ssl-ovpn2.png }}
 +
 +  * Le serveur VPN est placé dans une DMZ publique afin de cloisonner les flux selon leur provenance. Il est ainsi facilement possible de limiter les accès aux services internes depuis le VPN.
 +
 +===== Choix de la technologie du VPN =====
 +  * La sensibilité des données qui vont transiter par le VPN ACME impose leur chiffrement. Cet impératif exclut les solutions de tunnels non chiffrés qui n'​apportent pas un niveau suffisant de protection.
 +  * Deux technologies offrent le niveau de sécurité souhaité : les VPN dits SSL/TLS et les VPN IPSEC.
 +  * Dans les deux cas, la confidentialité et l'​intégrité des données et l'​authentification forte des membres du VPN sont assurées par l'​utilisation de tunnels chiffrés et de méthodes éprouvées d'​authentification cryptographiques. Le choix de la technologie va donc se faire sur d'​autres cirtères dont certains plus arbitraires que techniques.
 +
 +==== VPN SSL/TLS ====
 +  * Le protocole SSL, actuellement dans sa version 3, a été initialement développé par la société Netscape pour sécuriser les transactions électroniques. L'IETF a repris son développement et a normalisé le protocole sous le vocable Transport Layer Security (TLS) dans la RFC 2246 ([[http://​www.ietf.org/​rfc/​rfc2246.txt|RFC 2246]]). Dans le langage courant, SSLv3 et TLS sont souvent synonymes.
 +  * Sans entrer dans le détail, le protocole SSL/TLS s'​insert entre la couche Application et la couche Transport du modèle OSI/TCPIP et concerne donc les protocoles TCP et UDP. Il est lui-même composé de deux sous-protocoles : TLS Handshake et TLS Record. ​
 +  * TLS Record prend en charge le chiffrement - symétrique - des données et le contrôle de leur intégrité. ​
 +  * TLS Handshake prend en charge l'​authentification de chaque partie, la négociation des algorithmes de chiffrement er de signature ainsi que les échanges des clefs de session qui sont utilisés par le protocole TLS Record, ainsi que la remontée d'​alertes.
 +  * Pour plus d'​informations sur le protocole SSL/TLS : [[http://​fr.wikipedia.org/​wiki/​SSL|Wikipédia]]
 +
 +=== Avantages ===
 +  * D'une manière générale, les VPN SSL/TLS sont mis en oeuvre par des programmes qui s'​éxécutent en mode Utilisateur (user). Ils ne nécessitent donc pas de modification ni de recompilation du noyau du système d'​exploitation hôte. De ce fait, ils sont également plus facilement portés d'un OS à l'​autre.
 +  * Ce mode d'​exécution permet également de cloisonner (chroot) ces programmes et de les faire tourner avec des privilèges système réduits.
 +  * Un VPN SSL/TLS s'​appuie sur une connexion réseau TCP/IP "​normale"​ en ce sens qu'il encapsule le trafic chiffré dans un paquet IP "​classique"​. La nature et la topologie des réseaux sous-jacents est donc sans impact sur le VPN y compris en cas de translation d'​adresse (NAT).
 +
 +=== Inconvénients ===
 +  * Les VPN SSL/TLS supposent l'​installation de logiciels clients sur les machines membres du VPN. Comme ce type de VPN n'est pas normalisé (Note : le protocole SSL/TLS l'est quant à lui), il n'y a aucune garantie d'​interopérabilité entre différentes solutions logicielles.
 +  * Dans la plupart des cas, les solutions VPN SSL/TLS utilisent des interfaces réseau virtuelles de type tun/tap. Ces interfaces redirigent le trafic émis par les applications vers les programmes VPN. Chaque paquet émis et reçu passe ainsi plusieurs fois dans le noyau avant d'​être effectivement trasnmis sur le réseau, ce qui peut impacter plus ou moins sensiblement les performances générales de la solution.
 +
 +==== VPN IPSEC ====
 +
 +  * IPSEC est une suite de protocoles destinés à sécuriser la couche Réseau (Network layer) de la suite TCP/IP.
 +  * IPSEC comprend trois sous-protocoles : AH, ESP et IKE.
 +  * Le protocole AH (Authentication Header) définit les fonctionnalités d'​authentification,​ de contrôle d'​intégrité et de protection contre le rejeu de trafic.
 +  * Le protocole ESP (Encapsulating Security Payload) définit les mêmes fonctionnalités et y ajoute la garantie de confidentialité par le chiffrement.
 +  * Le protocole IKE (Internet Key Exchange) enfin définit les méthodes d'​échange de clefs entre hôtes.
 +
 +=== Avantages ===
 +  * IPSEC est une modification de la suite TCP/IP. Les fonctionnalités qu'il offre sont donc mises en oeuvre directement au sein du noyau des machines hôtes. Cela signifie que les performances ne sont pas dégradées autant qu'​elles peuvent l'​être dans le cadre d'un VPN SSL/TLS. Cela signifie surtout qu'il n'est pas nécessaire d'​installer des programmes clients ou serveurs sur chaque membre du VPN.
 +  * Tout système d'​exploitation - et plus précisément toute suite TCP/IP - qui intègre les fonctionnalités IPSEC est nativement interopérable. Il n'est pas nécessaire de choisir une solution IPSEC unique pour tous les membres du VPN.
 +
 +=== Inconvénients ===
 +  * Les solutions IPSEC ont encore la réputation d'​être moins faciles à paramètrer que leurs "​homologues"​ SSL/TLS. L'​infrastructure réseau sous-jacente peut constituer un point bloquant notamment en cas de translation d'​adresse.
 +  * IPSEC étant une modification de la suite TCP/IP, il est nécessaire de modifier le noyau du système d'​exploitation de l'​hôte. Ce point cependant est tempéré par le fait que les dernières versions des OS les plus couramment utilisés intègrent par défaut IPSEC dans le noyau.
 +
 +==== Choix ====
 +  * Dans le cas de la société ACME, le choix s'est porté sur une solution de VPN SSL/TLS : compte tenu du fait que le personnel itinérant utilise des infrastructures réseau très diverses - connexions RTC ou Wifi, réseaux des entreprises Clients ou partenaires,​ connexions ADSL domestiques - l'​inconvénient que constitue l'​installation sur chaque poste nomade du client VPN est compensé par la garantie de fonctionnement du VPN dans ces environnements réseau hétérogènes.
 +  * En terme de produit, la solution Libre OpenVPN a été retenue. Nous allons par la suite décrire comment elle va être intégrée au réseau Acme et comment seront configurés les postes clients et le serveur pour remplir notre cahier des charges.
 +  * Le serveur OpenVPN tournera sous OpenBSD 3.8, GNU/Debian, etc., au choix. Les postes nomades quant à eux tournent majoritairement sous MS Windows XP/2000 et Mac OS X. Quelques postes sous GNU/Debian et Red Hat Linux seront également pris en compte.
 +
 +====== OpenVPN ======
 +
 +===== Présentation =====
 +  * OpenVPN est une projet initié par James Yonan en 2001 qui permet de créer des VPN SSLT/TLS entre machines qui utilisent ce logiciel distribué sous licence GPL.
 +  * A l'​origine "​simple"​ tunnel IP sur UDP, OpenVPN est devenu au fil des années une solution client/​serveur complète qui offre toutes les fonctionnalités et les garanties que l'on est en droit d'​attendre d'un tel produit.
 +  * Le principe de fonctionnement d'​OpenVPN est le suivant : une interface réseau virtuelle de type TUN (pour les tunnels IP) ou TAP (pour les tunnels Ethernet) est utilisée pour rediriger le trafic émis ou reçu par les applications d'une machine hôte vers un démon OpenVPN. Ce démon assure le chiffrement des données ainsi transmises gràce à une liaison (le tunnel) établi entre un client et un serveur. Sur ce dernier, un démon OpenVPN effectue les mêmes opérations.
 +  * Le schéma ci-dessous illustre ce mode de fonctionnement :
 +{{ start:​flux-ovpn-1.png }}
 +
 +  * En plus du chiffrement,​ le démon OpenVPN apporte les fonctions d'​authentification forte mutuelle de chaque partie : le client s'​authentifie auprès du serveur et vice versa.
 +  * OpenVPN utilise les fonctions cryptographiques fournies par la bibliothèque OpenSSL.
 +  * OpenVPN s'​appuie indifféremment sur UDP ou TCP comme protocole de transport. L'​utilisation du protocole UDP repose sur l'​extension DTLS (Datagram Transport Layer Security) fournie par la bibliothèque OpenSSL depuis la version 0.9.8.
 +  * OpenVPN est supporté par les systèmes d'​exploitation les plus couramment utilisés : Linux, Solaris, *BSD, MS Windows et Mac OS X.
 +
 +===== Installation =====
 +
 +  * L'​installation d'​OpenVPN,​ tant sur le serveur que sur les postes nomades, est réalisée à l'aide des paquetages binaires. Ce mode de déploiement facilite les mises à jour et permet d'​industrialiser le processus.
 +  * Les paquetages fournissent les interfaces virtuelles TUN et TAP et les binaires OpenVPN.
 +  * A noter qu'il n'y a pas de distinction entre client et serveur au niveau binaire : dans tous les cas, c'est le même démon openvpn qui est lancé. C'est dans le fichier de configuration (ou les paramètres de ligne de commande) que se fait cette différence entre le démon client et le démon serveur. Cela signifie qu'un démon peut être client ET serveur selon les cas. Nous verrons plus loin comment s'​assurer que le démon installé et lancé sur les postes nomades ne se transforme pas en serveur et comment protéger les postes clients des serveurs "​pirates"​.
 +  * Pour les postes sous MS Windows l'​installation se base sur [[http://​openvpn.se/​|GUI OpenVPN pour Windows]]. Pour les postes sous Mac OS X 10.3 et 10.4, on utilisera [[http://​www.tunnelblick.net/​|TunnelBlick]]. Ces interfaces permettent à des utilisateurs "​lambda"​ de lancer facilement l'​application VPN depuis leur environnement de travail habituel.
 +
 +===== Authentification =====
 +  * OpenVPN offre deux méthodes d'​authentification des membres (clients et serveurs) d'un VPN : par clef secrète partagée et par certificat X.509.
 +
 +==== Clef secrète partagée ====
 +  * Cette méthode permet à deux hôtes de s'​authentifier à l'aide d'une clef secrète identique installée sur chacun d'eux.
 +  * Cette clef est créée à l'aide de la commande openvpn lancée avec l'​option --genkey suivie du nom du fichier dans lequel sera stocké la clef (ici : secret.key) :
 +<code html>
 +$ openvpn --genkey /​etc/​openvpn/​secret.key
 +</​code>​
 +  * Dans le fichier de configuration du client et du serveur, on indiquera au démon openvpn l'​emplacement de ce fichier à l'aide du paramètre secret :
 +<code html>
 +secret /​etc/​openvpn/​secret.key
 +</​code>​
 +
 +  * Le fichier ainsi créé doit alors être copié de manière sûre (SSH est un bon moyen) sur chaque machine.
 +  * Note : ce fichier contient en réalité quatre clefs : une pour l'​envoi des empreintes HMAC, une pour la réception des empreintes HMAC, une pour le chiffrement et une autre enfin pour le déchiffrement. Par défaut, chaque membre du VPN utilise les mêmes clefs pour ces opérations mais il est possible de créer des jeux de clefs propres à chaque membre en précisant, lors de la création du fichier secret.key la direction. Celle-ci est désignée à l'aide des options 0 et 1.
 +  * Cela se traduira dans le fichier de configuration par la ligne suivante sur le serveur :
 +<code html>
 +secret /​etc/​openvpn/​secret.key 0
 +</​code>​
 +Et dans celui du client par :
 +<code html>
 +secret /​etc/​openvpn/​secret.key 1
 +</​code>​
 +  * Cette méthode d'​authentification peut être utile lors d'une phase de prise en main initiale car elle est relativement simple à mettre en oeuvre. Cependant, elle est trop limitée pour une utilisation dans un contexte de clients nombreux.
 +
 +==== Certificats X.509 ====
 +  * La seconde méthode d'​authentification proposée par OpenVPN utilise des certificats au format X.509.
 +  * Pour plus d'​informations sur les certificats X.509 : [[http://​fr.wikipedia.org/​wiki/​X.509|Wikipédia]].
 +  * Ces certificats sont utilisés pour authentifier chaque membre du VPN : cela signifie que le client peut vérifier l'​identité du serveur mais que le serveur aussi peut vérifier celle de chaque client. Dans notre cas, cette authentification mutuelle sera requise.
 +  * Pour mettre en oeuvre cette méthode d'​authentification,​ il faut constituer une Autorité de Certification : cette AC signera les certificats des membres du VPN (clients et serveur). Chaque membre du VPN devra disposer du certificat (autosigné dans notre cas) de l'AC afin de valider les certificats des autres membres. L'AC fait office de référence absolue et d'​autorité de confiance.
 +  * Il convient de noter que les certificats permettent d'​authentifier une machine mais pas forcément un utilisateur. Par défaut en effet, les scripts easy-rsa fournis avec OpenVPN créent des certificats sans mot de passe. Dans le cas du serveur, cela peut être accepté : si un mot de passe est associé au certificat du serveur, il faut qu'un opérateur soit présent lors du lancement de démon OpenVPN. Par contre, il peut tout à fait être souhaitable que les utilisateurs des postes nomades utilisent des certificats à mot de passe. Ainsi, il faudra pour rejoindre le VPN, que le poste nomade soit authentifié (certificat) ET que l'​utilisateur le soit aussi (mot de passe du certificat). Dans ce cas de figure cependant, le serveur n'a aucun moyen de vérifier l'​identité de l'​utilisateur : celle-ci est supposée valide car on part du principe que le certificat est associé à un mot de passe connu du seul utilisateur légitime du poste nomade. Or, les outils comme la GUI Windows pour OpenVPN permettent à l'​utilisateur de modifier unilatéralement et facilement ce mot de passe. Il est ainsi possible à un utilisateur de diminuer la force de son mot de passe... ou tout simplement de le supprimer. Il convient donc d'​utiliser d'​autres moyens côté serveur pour valider l'​identité des utilisateurs.
 +  * Nous allons voir maintenant comment créer les certificats et clefs qui permettront de mettre en oeuvre l'​authentification X.509.
 +
 +=== Scripts easy-rsa ===
 +  * OpenVPN fournit un ensemble de scripts dits "​easy-rsa"​ pour faciliter la création des certificats et clefs pour l'AC, les clients et les serveurs du VPN.
 +  * Ces scripts appellent le programme openssl : il est donc tout à fait possible de créer les éléments que nous allons décrire ci-dessous à l'aide de ce programme sans passer par ces scripts. Cependant, si vous n'​êtes pas suffisamment à l'aise avec openssl et ses options à rallonge, ces scripts seront d'une grande utilité ! :-)
 +
 +=== Création de l'AC ===
 +  * La création d'un AC - ou plus exactement la génération des clefs privées et publiques puis du certificat autosigné associé - constitue la première étape.
 +  * Note : on peut utiliser n'​importe quelle machine susceptible d'​exécuter openssl et les scripts easy-rsa comme AC. Il est même fortement conseillé de ne pas mutualiser AC et serveur OpenVPN. Si l'on dispose d'une solution PKI compatible, celle-ci peut parfaitement être mise à contribution.
 +  * Pour créer les éléments propres à l'AC, il faut utiliser le script build-ca après avoir chargé les paramètres contenus dans le fichier vars :
 +<code html>
 +# cd /​path/​to/​easy-rsa
 +# . vars
 +# ./build-ca
 +</​code>​
 +  * Le fichier vars contient les paramètres OpenSSL qui seront utilisés lors de chaque création de certificat ou chaque révocation. Parmi eux, la taille par défaut des clefs et les valeurs par défaut des principaux champs des certiticats : ville, pays, nom de la société, etc.
 +  * Le script build-ca se compose de la ligne de commande suivante :
 +<code html>
 +openssl req -days 3650 -nodes -new -x509 -keyout ca.key -out ca.crt ​
 +</​code>​
 +A l'​issue,​ la clef privée de l'AC - ca.key - et son certificat - ca.crt - sont créés. Seul le certificat doit être exporté vers chaque membre du VPN.
 +
 +=== Création des éléments Serveur ===
 +== Clef privée et certificat ==
 +  * Une fois l'AC constituée,​ on crée la clef privée et le certificat pour le serveur.
 +  * Le script builid-key-server est utilisé pour cela sur la machine AC :
 +<code html>
 +# ./​build-key-server nom_du_serveur
 +</​code>​
 +  * Ce script se compose des lignes suivantes :
 +<code html>
 +openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -extensions server
 +openssl ca -days 3650 -out $1.crt -in $1.csr -extensions server
 +</​code>​
 +  * On a donc en premier lieu création de la clef privée et d'une demande de certificat puis signature par l'AC et création du certificat final.
 +  * L'​option -extensions permet de "​typer"​ le certificat comme étant de type Server. Ce typage nous sera bien utile pour interdire (ou tout du moins rendre moins facile) toute communication VPN entre postes nomades.
 +
 +  * Un certificat Serveur type ressemble à cela :
 +<code html>
 +Certificate:​
 +    Data:
 +        Version: 3 (0x2)
 +        Serial Number: 1 (0x1)
 +        Signature Algorithm: md5WithRSAEncryption
 +        Issuer: C=FR, ST=ESSONNE, L=ORSAY, O=OpenVPN-TEST,​ OU=Crypto-Labs,​\
 +          CN=vpn-ac/​emailAddress=admin@vpn-ac
 +        Validity
 +            Not Before: Feb 20 16:47:51 2006 GMT
 +            Not After : Feb 18 16:47:51 2016 GMT
 +        Subject: C=FR, ST=ESSONNE, O=OpenVPN-TEST,​ OU=Crypto-Labs,​\
 +          CN=vpn-server/​emailAddress=admin@vpn-server
 +        Subject Public Key Info:
 +            Public Key Algorithm: rsaEncryption
 +            RSA Public Key: (1024 bit)
 +                Modulus (1024 bit):
 +                    00:​b5:​06:​53:​2f:​23:​d0:​3e:​cb:​6b:​e7:​07:​30:​04:​d8:​
 +                    ef:​4f:​5a:​a0:​26:​76:​e0:​be:​25:​7f:​ca:​7f:​2f:​4f:​41:​
 +                    31:​7e:​36:​ac:​b8:​d7:​c1:​29:​4f:​4c:​e9:​03:​ee:​1f:​1f:​
 +                    8c:​91:​5a:​61:​1e:​be:​8d:​b0:​6a:​c1:​83:​77:​77:​25:​b5:​
 +                    62:​43:​c1:​94:​52:​4f:​a3:​5a:​7a:​75:​14:​96:​53:​f9:​10:​
 +                    f6:​51:​f1:​db:​b4:​17:​43:​a4:​8e:​c9:​af:​da:​b6:​32:​18:​
 +                    ac:​ef:​c6:​0a:​af:​1c:​0b:​52:​fe:​ac:​5e:​65:​4a:​2a:​2c:​
 +                    3c:​de:​8e:​a0:​d3:​0c:​ae:​33:​28:​4e:​cd:​0a:​b4:​d3:​a5:​
 +                    6c:​04:​93:​11:​d2:​77:​17:​6b:​f5
 +                Exponent: 65537 (0x10001)
 +        X509v3 extensions:
 +            X509v3 Basic Constraints: ​
 +                CA:FALSE
 +            Netscape Cert Type: 
 +                SSL Server
 +            Netscape Comment: ​
 +                OpenSSL Generated Server Certificate
 +            X509v3 Subject Key Identifier: ​
 +                47:​D9:​AA:​45:​52:​DC:​A3:​56:​BF:​0A:​57:​8E:​9A:​28:​C5:​57:​0B:​2B:​A0:​E9
 +            X509v3 Authority Key Identifier: ​
 +                keyid:​0D:​C2:​85:​03:​AB:​96:​3E:​BC:​88:​31:​B3:​B6:​3F:​90:​3A:​B0:​49:​56:​5B:​CE
 +                DirName:/​C=FR/​ST=ESSONNE/​L=ORSAY/​O=OpenVPN-TEST/​OU=Crypto-Labs/​CN=vpn-ac/​\
 +                  emailAddress=admin@vpn-ac
 +                serial:​8A:​4D:​56:​E5:​75:​4E:​A1:​BD
 +
 +    Signature Algorithm: md5WithRSAEncryption
 +        e2:​87:​9f:​ac:​78:​c3:​c8:​1b:​36:​3d:​2b:​ef:​b1:​8a:​96:​76:​78:​45:​
 +        15:​f2:​bb:​d0:​53:​a3:​be:​3b:​1d:​63:​26:​90:​72:​7e:​b5:​fe:​5a:​17:​
 +        6f:​51:​77:​cb:​1b:​5a:​e8:​03:​5c:​f4:​db:​a3:​07:​fe:​29:​73:​61:​44:​
 +        69:​bb:​01:​88:​12:​1e:​a3:​f0:​27:​7b:​46:​7b:​64:​b9:​9b:​c8:​c5:​2e:​
 +        22:​38:​d1:​43:​26:​fc:​e9:​4b:​25:​ad:​13:​0b:​39:​2f:​0a:​2d:​39:​26:​
 +        0f:​eb:​ea:​f5:​e4:​8f:​d0:​48:​a9:​4d:​38:​03:​a5:​16:​8e:​cb:​2a:​c3:​
 +        58:​b8:​fc:​33:​3f:​8b:​cb:​2f:​d5:​34:​53:​62:​18:​83:​ef:​4f:​7c:​5d:​
 +        e1:63
 +-----BEGIN CERTIFICATE-----
 +MIIDvjCCAyegAwIBAgIBATANBgkqhkiG9w0BAQQFADCBijELMAkGA1UEBhMCRlIx
 +EDAOBgNVBAgTB0VTU09OTkUxDjAMBgNVBAcTBU9SU0FZMRUwEwYDVQQKEwxPcGVu
 +VlBOLVRFU1QxFDASBgNVBAsTC0NyeXB0by1MYWJzMQ8wDQYDVQQDEwZ2cG4tYWMx
 +GzAZBgkqhkiG9w0BCQEWDGFkbWluQHZwbi1hYzAeFw0wNjAyMjAxNjQ3NTFaFw0x
 +NjAyMTgxNjQ3NTFaMIGCMQswCQYDVQQGEwJGUjEQMA4GA1UECBMHRVNTT05ORTEV
 +MBMGA1UEChMMT3BlblZQTi1URVNUMRQwEgYDVQQLEwtDcnlwdG8tTGFiczETMBEG
 +A1UEAxMKdnBuLXNlcnZlcjEfMB0GCSqGSIb3DQEJARYQYWRtaW5AdnBuLXNlcnZl
 +cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtQZTLyPQPstr5wcwBNjvT1qg
 +JnbgviV/​yn8vT0ExfjasuNfBKU9M6QPuHx+MkVphHr6NsGrBg3d3JbViQ8GUUk+j
 +Wnp1FJZT+RD2UfHbtBdDpI7Jr9q2Mhis78YKrxwLUv6sXmVKKiw83o6g0wyuMyhO
 +zQq006VsBJMR0ncXa/​UCAwEAAaOCATgwggE0MAkGA1UdEwQCMAAwEQYJYIZIAYb4
 +QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBTZXJ2
 +ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFEfZqkVS3KNWvwpXjpooxVcLK6DpMIG/​
 +BgNVHSMEgbcwgbSAFA3ChQOrlj68iDGztj+QOrBJVlvOoYGQpIGNMIGKMQswCQYD
 +VQQGEwJGUjEQMA4GA1UECBMHRVNTT05ORTEOMAwGA1UEBxMFT1JTQVkxFTATBgNV
 +BAoTDE9wZW5WUE4tVEVTVDEUMBIGA1UECxMLQ3J5cHRvLUxhYnMxDzANBgNVBAMT
 +BnZwbi1hYzEbMBkGCSqGSIb3DQEJARYMYWRtaW5AdnBuLWFjggkAik1W5XVOob0w
 +DQYJKoZIhvcNAQEEBQADgYEA4oefrHjDyBs2PSvvsYqWdnhFFfK70FOjvjsdYyaQ
 +cn61/​loXb1F3yxta6ANc9NujB/​4pc2FEabsBiBIeo/​Ane0Z7ZLmbyMUuIjjRQyb8
 +6UslrRMLOS8KLTkmD+vq9eSP0EipTTgDpRaOyyrDWLj8Mz+Lyy/​VNFNiGIPvT3xd
 +4WM=
 +-----END CERTIFICATE-----
 +</​code>​
 +
 +  * Nous y retrouvons la mention "​Netscape Cert Type: SSL Server"​ ajoutée par l'​option -extensions server.
 +
 +== Paramètres Diffie-Hellman ==
 +  * Il faut ensuite générer les paramètres Diffie-Hellman qui seront utilisés par le serveur pour l'​échange des clefs de session avec les clients (Voir [[http://​www.rsasecurity.com/​rsalabs/​node.asp?​id=2248|F.A.Q RSA Labs]]).
 +  * Le script build-dh est fait pour ça :
 +<code html>
 +openssl dhparam -out ${KEY_DIR}/​dh${KEY_SIZE}.pem ${KEY_SIZE}
 +</​code>​
 +  * Note : par défaut, le paramètre KEY_SIZE est positionné à 1024. Il est cependant possible d'​augmenter cette valeur à 2048.
 +  * A l'​issue de cette étape, les fichiers nom_du_serveur.key,​ nom_du_serveur.crt et dh[1024|2048].pem doivent être installés sur le serveur. Dans notre cas, nous les déposerons dans le répertoire /​etc/​openvpn sur le serveur.
 +
 +=== Création des éléments Client ===
 +  * Pour chaque futur client du VPN, il faut également créer une clef privée et le certificat associé. Comme dans le cas du serveur, ces opérations seront effectuées sur la machine AC et les fichiers exportés de manière sûre (SSH ou via support amovible) sur les postes nomades.
 +  * Le script build-key est fait pour ça :
 +<code html>
 +# ./build-key nom_du_client
 +</​code>​
 +Ce script comporte les lignes suivantes :
 +<code html>
 +openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr
 +openssl ca -days 3650 -out $1.crt -in $1.csr
 +</​code>​
 +
 +  * Note : ce script peut aussi être utilisé pour créer un certificat serveur. Nous avons en effet dit plus haut qu'il n'y a aucune distinction dans le binaire openvpn entre une client et un serveur. Dans l'​absolu,​ chaque machine peut être client ou serveur voire client ET serveur (il faut alors exécuter plusieurs instances de démon OpenVPN sur la machine). Le script build-key-server diffère du script build-key en ceci qu'il utilise le paramètre -extensions positionné à server pour "​marquer"​ le certificat comme étant de type... serveur. Se faisant, l'​extension NsCertType est déclaré à "​server"​. Nous verrons plus loin comment nous utiliserons ce marquage pour renforcer la sécurité du VPN.
 +  * Il est important de créer à chaque fois que cela est possible un certificat unique par poste nomade : nous verrons en effet que nous pouvons côté serveur contrôler d'​autant plus finement les accès que les certificats seront uniques et précis.
 +  * A l'​issue de cette étape, nous déposerons les fichiers nom_du_client.crt et nom_du_client.key sur chaque poste nomade.
 +  * Un certificat Client type ressemble à cela :
 +<code html>
 +Certificate:​
 +    Data:
 +        Version: 3 (0x2)
 +        Serial Number: 2 (0x2)
 +        Signature Algorithm: md5WithRSAEncryption
 +        Issuer: C=FR, ST=ESSONNE, L=ORSAY, O=OpenVPN-TEST,​ OU=Crypto-Labs,​\
 +          CN=vpn-ac/​emailAddress=admin@vpn-ac
 +        Validity
 +            Not Before: Feb 20 16:51:19 2006 GMT
 +            Not After : Feb 18 16:51:19 2016 GMT
 +        Subject: C=FR, ST=ESSONNE, O=OpenVPN-TEST,​ OU=DAF,\
 +          CN=vpn-client1/​emailAddress=admin@vpn-client1
 +        Subject Public Key Info:
 +            Public Key Algorithm: rsaEncryption
 +            RSA Public Key: (1024 bit)
 +                Modulus (1024 bit):
 +                    00:​a9:​e1:​7b:​2f:​a0:​7d:​5f:​bf:​49:​4e:​0a:​30:​1e:​94:​
 +                    28:​9c:​c1:​ee:​39:​11:​4c:​1e:​d3:​9e:​e6:​57:​33:​0c:​ab:​
 +                    15:​0f:​79:​69:​59:​18:​d7:​e6:​5e:​fd:​49:​f6:​27:​78:​2a:​
 +                    ba:​c4:​ea:​e3:​d0:​81:​0c:​84:​29:​d1:​c1:​80:​c9:​42:​d9:​
 +                    ca:​64:​1e:​b1:​db:​47:​b6:​c7:​6c:​d2:​90:​60:​30:​b8:​ef:​
 +                    01:​ea:​82:​15:​5a:​d0:​95:​26:​43:​c5:​ae:​30:​3d:​ba:​ca:​
 +                    b8:​dd:​d6:​f2:​f0:​ac:​97:​08:​f8:​13:​bc:​e5:​7b:​07:​8c:​
 +                    5d:​33:​0f:​e6:​5c:​e5:​9a:​b5:​34:​91:​3b:​c9:​b2:​ce:​c1:​
 +                    0c:​fb:​dd:​ee:​f3:​ba:​61:​84:​c1
 +                Exponent: 65537 (0x10001)
 +        X509v3 extensions:
 +            X509v3 Basic Constraints: ​
 +                CA:FALSE
 +            Netscape Comment: ​
 +                OpenSSL Generated Certificate
 +            X509v3 Subject Key Identifier: ​
 +                F8:​98:​F8:​75:​9D:​D9:​D4:​1B:​03:​F3:​36:​C0:​E2:​67:​19:​BD:​EC:​48:​36:​0D
 +            X509v3 Authority Key Identifier: ​
 +                keyid:​0D:​C2:​85:​03:​AB:​96:​3E:​BC:​88:​31:​B3:​B6:​3F:​90:​3A:​B0:​49:​56:​5B:​CE
 +                DirName:/​C=FR/​ST=ESSONNE/​L=ORSAY/​O=OpenVPN-TEST/​OU=Crypto-Labs/​CN=vpn-ac/​\
 +                  emailAddress=admin@vpn-ac
 +                serial:​8A:​4D:​56:​E5:​75:​4E:​A1:​BD
 +
 +    Signature Algorithm: md5WithRSAEncryption
 +        8c:​72:​10:​97:​7d:​ba:​45:​72:​fe:​ff:​e6:​37:​0a:​cb:​fe:​a0:​19:​02:​
 +        4a:​03:​86:​a5:​9c:​72:​1c:​59:​e0:​c3:​58:​2f:​52:​4f:​9d:​f7:​cd:​54:​
 +        0b:​97:​b9:​da:​40:​6d:​6c:​c0:​07:​51:​c6:​08:​71:​73:​b5:​08:​8e:​b1:​
 +        8f:​c9:​3f:​e2:​8e:​b2:​d7:​f4:​41:​63:​e7:​c8:​6b:​dc:​49:​bc:​ca:​0e:​
 +        58:​cb:​8a:​3f:​ed:​9e:​f3:​bc:​79:​4e:​6c:​0c:​5b:​d8:​fc:​07:​4d:​21:​
 +        72:​96:​b4:​56:​60:​f6:​ff:​73:​e8:​a6:​f8:​ef:​cd:​39:​9e:​63:​bc:​99:​
 +        b7:​95:​5e:​d1:​15:​ab:​f9:​26:​8c:​f8:​6d:​45:​e3:​05:​89:​65:​39:​d1:​
 +        02:b6
 +-----BEGIN CERTIFICATE-----
 +MIIDnTCCAwagAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBijELMAkGA1UEBhMCRlIx
 +EDAOBgNVBAgTB0VTU09OTkUxDjAMBgNVBAcTBU9SU0FZMRUwEwYDVQQKEwxPcGVu
 +VlBOLVRFU1QxFDASBgNVBAsTC0NyeXB0by1MYWJzMQ8wDQYDVQQDEwZ2cG4tYWMx
 +GzAZBgkqhkiG9w0BCQEWDGFkbWluQHZwbi1hYzAeFw0wNjAyMjAxNjUxMTlaFw0x
 +NjAyMTgxNjUxMTlaMHwxCzAJBgNVBAYTAkZSMRAwDgYDVQQIEwdFU1NPTk5FMRUw
 +EwYDVQQKEwxPcGVuVlBOLVRFU1QxDDAKBgNVBAsTA0RBRjEUMBIGA1UEAxMLdnBu
 +LWNsaWVudDExIDAeBgkqhkiG9w0BCQEWEWFkbWluQHZwbi1jbGllbnQxMIGfMA0G
 +CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp4XsvoH1fv0lOCjAelCicwe45EUwe057m
 +VzMMqxUPeWlZGNfmXv1J9id4KrrE6uPQgQyEKdHBgMlC2cpkHrHbR7bHbNKQYDC4
 +7wHqghVa0JUmQ8WuMD26yrjd1vLwrJcI+BO85XsHjF0zD+Zc5Zq1NJE7ybLOwQz7
 +3e7zumGEwQIDAQABo4IBHjCCARowCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYd
 +T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFPiY+HWd2dQb
 +A/​M2wOJnGb3sSDYNMIG/​BgNVHSMEgbcwgbSAFA3ChQOrlj68iDGztj+QOrBJVlvO
 +oYGQpIGNMIGKMQswCQYDVQQGEwJGUjEQMA4GA1UECBMHRVNTT05ORTEOMAwGA1UE
 +BxMFT1JTQVkxFTATBgNVBAoTDE9wZW5WUE4tVEVTVDEUMBIGA1UECxMLQ3J5cHRv
 +LUxhYnMxDzANBgNVBAMTBnZwbi1hYzEbMBkGCSqGSIb3DQEJARYMYWRtaW5AdnBu
 +LWFjggkAik1W5XVOob0wDQYJKoZIhvcNAQEEBQADgYEAjHIQl326RXL+/​+Y3Csv+
 +oBkCSgOGpZxyHFngw1gvUk+d981UC5e52kBtbMAHUcYIcXO1CI6xj8k/​4o6y1/​RB
 +Y+fIa9xJvMoOWMuKP+2e87x5TmwMW9j8B00hcpa0VmD2/​3PopvjvzTmeY7yZt5Ve
 +0RWr+SaM+G1F4wWJZTnRArY=
 +-----END CERTIFICATE-----
 +</​code>​
 +
 +=== Rappels sur les clefs ===
 +  * Par défaut, aucune clef privée n'est chiffrée, l'​option -nodes est en effet utilisée dans les scripts.
 +  * Pour la clef Serveur, il est préférable de ne pas chiffrer la clef : il faudrait dans le cas contraire qu'un opérateur soit présent au lancement du démon OpenVPN pour entrer la "pass phrase"​ de la clef.
 +  * Par contre il peut être souhaitable de chiffrer les clefs privées des postes nomades. Cela peut être considéré comme une méthode d'​authentification Utilisateur dans la mesure où il faudra que ce dernier entre sa "pass phrase"​ au lancement du démon OpenVPN sur le poste nomade Client. Pour générer une clef chiffrée lors de la création des éléments Client, il faut utiliser le script build-key-pass.
 +  * Rappelons que cette méthode d'​authentification Utilisateur ne permet pas au serveur de s'​assurer de l'​identité de celui-ci : la "pass phrase"​ peut être modifiée via les GUI installées sur les postes nomades. De plus, cela suppose que le créateur du certificat Client connait la "pass phrase"​ de chaque Utilisateur si la procédure de génération des certificats n'est pas automatisée. Si elle l'est, il faut s'​assurer que l'​interface de dialogue entre l'​utilisateur et l'AC est suffisamment sécurisée pour que cette pass phrase soit transmise du poste nomade à l'AC de manière sûre. On peut très vite tomber dans un dilemne de type "qui de l'oeuf ou de la poule ?"... :-)
 +
 +=== Révocation d'un certificat ===
 +  * Un des intérèts de l'​utilisation des certificats X.509 comme méthode d'​authentification est la - relative - souplesse qu'​elle offre en matière de révocation.
 +  * Chaque membre du VPN est identifié par un certificat.
 +  * Durant la phase d'​authentification,​ chaque partie - client et serveur - valide le certificat de l'​autre à partir d'​éléments "​internes"​ du certificat : date de validité, valeur du Common Name, etc. En parallèle, chaque partie va également consulter une liste de révocation (CRL) : cette liste, générée et gérée par l'AC, permet de valider chaque certificat est licite, c'​est-à-dire qu'il est autorisé par l'AC.
 +  * En bref et en clair : si un certificat, d'un client ou d'un serveur, figure dans la CRL, il sera rejeté lors de la phase d'​authentification.
 +  * Dans la pratique, la CRL sera mise à jour au fur et à mesure qu'un poste nomade ne sera plus autorisé à utiliser le VPN.
 +  * Le script revoke-full permet de générer et mettre à jour la CRL. Le fichier crl.pem doit alors être diffusé à tous les membres du VPN. Cette diffusion peut se faire par le moyen "le plus approprié"​. Dans le cas du serveur, cela peut être fait par SSH, pour les clients par téléchargement depuis un serveur Web par exemple.
 +  * Ce script est appelé de la manière suivante sur l'AC :
 +<code html>
 +# cd /​path/​to/​easy-rsa
 +# . vars
 +# ./​revoke-full common-name
 +</​code>​
 +Où common-name est la valeur du CommonName (étonnant, non ? :-)) du certificat que l'on souhaite révoquer.
 +  * A l'​issue,​ le fichier CRL est mis à jour et peut être diffusé.
 +
 +===== Type de tunnel =====
 +
 +  * OpenVPN propose deux types de tunnel : tunnel de niveau 2, c'​est-à-dire de type Ethernet et tunnel de niveau 3, donc IP.
 +
 +==== Pont Ethernet ====
 +
 +  * Pour monter un tunnel de niveau 2, OpenVPN va utiliser une interface virtuelle de type TAP.
 +  * Ce type de tunnel est particulièrement recommandé si des protocoles autres qu'IP (IPX, etc.) sont utilisés. Il est également adapté à certains protocoles du monde Windows qui ont une fâcheuse tendance à user et abuser du broadcast.
 +  * Dans cette configuration,​ OpenVPN crée un bridge Ethernet entre chaque partie du VPN.
 +  * Pour plus de détails sur ce mode de fonctionnement : [[http://​openvpn.net/​bridge.html|Doc. OpenVPN]]
 +
 +==== Tunnel IP ====
 +
 +  * Pour monter un tunnel de niveau 3, OpenVPN va utiliser une interface virtuelle de type TUN.
 +  * C'est le type de tunnel le plus couramment utilisé. Il permet de monter le tunnel sur n'​importe quelle liaison IP existante.
 +  * C'est le mode que nous avons choisi pour notre VPN.
 +
 +===== Récapitulatif =====
 +
 +  * Nous avons donc fait pour notre VPN les choix suivants :
 +  - Tunnel IP.
 +  - Authentification par certificats X.509.
 +  - Les postes nomades ne seront autorisés à se connecter qu'au serveur VPN.
 +  - Le VPN fonctionnera en "​étoile"​ : les clients ne pourront pas communiquer entre eux, les tunnels VPN seront cloisonnés par défaut.
 +  - Les postes nomades une fois connectés au VPN ne pourront plus dialoguer qu'​avec le serveur VPN ; leur routage sera modifié lors de la création du tunnel.
 +  - L'​identité des utilisateurs des postes nomades sera vérifiée côté serveur, indépendamment des éventuelles "pass phrase"​ des clefs privées installées sur ces postes.
 +
 +===== Configuration du serveur =====
 +
 +  * Le serveur VPN est construit sur une plate forme matérielle de type Serveur sur une architecture Intel/AMD.
 +  * Le système d'​exploitation retenu est OpenBSD dans sa version 3.8. Un serveur sous GNU/Debian peut également très bien faire l'​affaire ! :-)
 +  * OpenVPN y a été installé dans sa version 2.0.2 via les paquetages fournis sur le site FTP du projet OpenBSD. L'​installation du paquetage OpenVPN nécessite celle du paquetage LZO (compression). L'​utilisation de la compression restera cependant facultative.
 +  * Nous avons créé un répertoire /​etc/​openvpn qui contient les clefs, certificats serveur et AC ainsi que la CRL et le fichier de configuration du démon (openvpn.conf).
 +  * Les paramètres présentés ci-dessous sont stockés dans le fichier openvpn.conf.
 +
 +==== Paramètres généraux ====
 +  * Les paramètres décrits dans ce paragraphe définissent le comportement général du démon.
 +  * Mode : client ou serveur ? Il n'est pas idiot de commencer le fichier en précisant le mode de fonctionnement du démon : client ou serveur. Nous pousserons même le vice jusqu'​à spécifier que le démon fonctionne comme serveur SSL/TLS :
 +<code html>
 +mode server
 +tls-server
 +</​code>​
 +  * Paramètre local : spécifie l'​adresse IP sur laquelle le démon doit se mettre en écoute. Par défaut, OpenVPN, comme tout démon Unix, écoute sur toutes les interfaces réseaux de la machine, ce qui n'est peut-être ni souhaité... ni souhaitable !
 +<code html>
 +local 192.168.0.1
 +</​code> ​
 +  * Type d'​interface virtuelle utilisée : tun ou tap.
 +<code html>
 +dev tun
 +</​code>​
 +  * Protocole de transport utilisé : UDP ou TCP. Par défaut, OpenVPN utilise UDP.
 +<code html>
 +proto udp
 +</​code>​
 +  * Note : le protocole UDP est le meilleur choix tant au niveau des performances et de la fiabilité que de la sécurité (ce protocole est moins sensible aux attaques de type DoS).
 +  * port : numéro du port sur lequel le démon se met à l'​écoute. Par défaut OpenVPN utilise le port 1194.
 +<code html>
 +port 1194
 +</​code>​
 +  * Privilèges système : nom de l'​utilisateur et du groupe sous l'​identité desquels le démon OpenVPN s'​exécute après son lancement.
 +<code html>
 +user nobody
 +group nobody
 +</​code>​
 +
 +=== Journalisation ===
 +  * Par défaut les messages de journalisation sont envoyés au démon syslog. Il est cependant possible de les diriger dans des fichiers propres au démon OpenVPN. Si le démon OpenVPN s'​éxécute dans un environnement cloisonné (chroot) cette méthode de journalisation peut être la seule facilement exploitable.
 +  * verb : degré de détails des fichiers de journalisation,​ de 0 (très peu de détails) à 9 (beaucoup de détails, mode "​debug"​).
 +<code html>
 +verb 4
 +</​code>​
 +  * log| log-append : chemin d'​accès au fichier de journalisation du démon. Si le paramètre log-append est utilisé, le fichier est ouvert en mode Ajout. Si le paramètre log est utilisé, le contenu du fichier est tronqué à chaque redémarrage du démon.
 +<code html>
 +log /​var/​openvpn/​openvpn.log
 +</​code>​
 +  * status : chemin d'​accès au fichier qui contient les informations sur l'​état du serveur et des connexions actives.
 +<code html>
 +status /​var/​openvpn/​openvpn-status.log
 +</​code>​
 +
 +=== Paramètres d'​authentification ===
 +  * Il s'agit d'​indiquer où sont les certificats,​ clef privée et le fichier qui contient les paramètres Diffie-Hellman.
 +  * Ces éléments sont déclarés de la manière suivante :
 +<code html>
 +ca ca.crt
 +cert server.crt
 +key server.key ​
 +dh dh1024.pem
 +</​code>​
 +
 +==== Options Réseau ====
 +
 +=== Adressage IP ===
 +  * Le serveur peut faire office de serveur DHCP et distribuer les adresses IP aux clients sur une plage IP déterminée. Cette plage d'​adresses est spécifiée par le paramètre server.
 +<code html>
 +server 10.8.0.0 255.255.255.0
 +</​code>​
 +Le paramètre server est suivi par la première adresse de la plage et son masque. Le serveur s'​attribue l'​adresse IP juste au-dessus de la première (soit 10.8.0.1 dans notre exemple). Les clients se verront attribuer les adresses IP suivantes jusqu'​à épuisement de la plage.
 +
 +=== Routage ===
 +  * Le serveur VPN sera la route par défaut pour les clients du VPN. La directive push est utilisée pour modifier le routage côté client.
 +  * Cette directive permet de pousser des routes spécifiques comme dans l'​exemple ci-dessous :
 +<code html>
 +push "route 192.168.10.0 255.255.255.0"​
 +</​code>​
 +et peut aussi modifier la passerelle par défaut :
 +<code html>
 +push "​redirect-gateway def1"
 +</​code>​
 +  * Cette option redirect-gateway fonctionne de la manière suivante :
 +  - Une route statique est créée pour rediriger le trafic vers la route par défaut pré-existante,​ afin d'​éviter que ne se forme une loop après l'​étape 3.
 +  - La route par défaut est effacée.
 +  - L'​adresse du tunnel devient la route par défaut.
 +
 +  * Quand le tunnel VPN est démonté, ces opérations sont effectuées en sens inverse pour rétablir le routage d'​origine.
 +  * L'​option local peut être ajoutée après redirect-gateway si les clients sont reliés au serveur via un sous-réseau commun (cas d'une connexion sans fil WiFi). L'​étape 1 décrite ci-dessus sera alors omise.
 +  * L'​option def1 permet de supplanter la valeur de la passerelle par défaut en ajoutant un masque en /1 plutôt qu'en /0. Le principal avantage est de ne pas effacer la configuration originale. Cette option devrait devenir l'​option par défaut dans les prochaines versions d'​OpenVPN et son usage est fortement recommandé.
 +
 +=== Options DHCP ===
 +  * Les clients Windows tireront le plus grand bénéfice des options DHCP fournies par OpenVPN.
 +  * Ils pourront ainsi récupérer à la connexion les adresses des serveurs DNS et WINS entre autres.
 +  * Chaque option DHCP est introduite de la manière suivante :
 +<code html>
 +push dhcp-option "​type_of_option value"
 +</​code>​
 +Les types d'​options supportées sont les suivants :
 +  - DOMAIN nom_de_domaine : quite self-understanding,​ ins't it ? :-)
 +  - DNS a.b.c.d : adresse du serveur DNS primaire.
 +  - WINS a.b.c.d : adresse du serveur WINS primaire.
 +  - NBDD a.b.c.d : adresse du serveur NBDD (NetBIOS over TCP/IP Name Server) primaire.
 +  - NTP a.b.c.d : adresse du serveur NTP (horodatage réseau).
 +  - NBT type : type de dialogue NetBIOS/TCP avec type = 1 pour désigner le type b-node (broadcast),​ 2 pour p-node (liaison point-à-point pour les requêtes destinées à un serveur WINS), 4 pour m-node (broadcast puis requête au serveur de nom) et 8 pour h-node (requête au serveur puis broadcast).
 +  - NBS scope-id : définit le périmètre NetBIOS, ce qui permet de limiter au seul scope-id le trafic NetBIOS.
 +  * Note : pour chacun des paramètres qui désignent l'​adresse d'un serveur, il est possible de renseigner les adresses de serveurs secondaires ou tertiaires, etc. en répétant chaque ligne comme ceci :
 +<code html>
 +push dhcp-option "DNS 10.8.0.10"​ // serveur DNS primaire
 +push dhcp-option "DNS 10.8.0.20"​ // serveur DNS secondaire
 +</​code>​
 +Cela s'​applique aux options DHCP DNS, WINS, NTP et NBDD.
 +
 +==== Contrôle d'​accès ====
 +  * Le contrôle d'​accès concerne l'​identité des machines et celle des utilisateurs afin de confirmer que ceux-ci sont autorisés à utiliser la VPN.
 +  * La première opération - contrôle de l'​identité des machines - est implicite : il est cependant possible de renforcer la procédure comme nous allons le voir.
 +  * La seconde - contrôle de l'​identité des utilisateurs - n'est pas automatique et repose sur des scripts exécutés sur le serveur.
 +  * Rappelons en effet que même dans le cas où une clef privée est associée à une pass phrase sur une machine cliente, le serveur n'​interfère pas dans la phase d'​authentification locale de l'​utilisateur. Or nous souhaitons que le serveur vérifie par lui-même l'​identité des machines clients **et** des utilisateurs lors de chaque ouverture de session VPN.
 +
 +=== Vérification du certificat Client ===
 +  * Durant cette phase, le client valide l'​identité du serveur grâce à son certificat, et le serveur valide celle du client par le même moyen. Cette authentification mutuelle est implicite.
 +  * A chaque ouverture de session, les opérations suivantes sont réalisées :
 +  - Envoi du certificat du serveur au client conformément au protocole SSL/TLS ;
 +  - Demande du certificat client par le serveur ;
 +  - Lecture du fichier CRL si il existe par chaque partie ;
 +  - Vérification de la validité du certificat client et serveur.
 +  * Sur le serveur, nous nous contenterons de ces vérifications de base. Nous verrons que sur les postes nomades, nous affinerons un peu plus.
 +  * Note : le fichier CRL est lu à chaque ouverture de session. Il n'est pas nécessaire de relancer le démon openvpn lors de la mise à jour du fichier CRL.
 +
 +=== Vérification Utilisateur ===
 +  * Pour vérifier l'​identité de l'​utilisateur sur le poste nomade, il n'y a pas d'​autre choix que le mot de passe.
 +  * Nous appellerons pour cela un script sur le serveur; Ce script sera exécuté à chaque ouverture de session.
 +  * Ce script est défini par le paramètre auth-user-pass-verify :
 +<code html>
 +auth-user-pass-verify /​path/​to/​script via-env
 +</​code>​
 +  * Le paramètre auth-user-pass-verify est suivi du chemin absolu du script à lancer et de la méthode de transmission des login et mot de passe. via-env indique que ces deux items seront passés au script par l'​intermédiaire de variables d'​environnement. via-file indique qu'il faut stocker ces valeurs dans un fichier temporaire. Dans ce cas, il est plus que fortement conseillé de définir la variable tmp-dir et lui assigner un espace en mémoire afin d'​éviter que les mots de passe des utilisateurs soient stockés sur le disque dur.
 +  * Le script appelé doit renvoyer 0 en cas de succès et 1 en cas d'​échec.
 +  * Voici un exemple de script faisant appel à un serveur LDAP :
 +<code html>
 +#!/bin/sh
 +#
 +# a simple ldap auth script for openvpn
 +#
 +LDAP_HOST=a.b.c.d
 +
 +# check if username/​password is empty or anonymous
 +#
 +if [ "​$username"​ = "​anonymous"​ || -z "​$username"​ || -z "​$password"​ ] ; then
 +   exit 1;
 +fi
 +
 +#
 +ldapwhoami -x -h $LDAP_HOST -D uid=$username,​ou=users,​dc=example,​dc=com \
 +           -w $password
 +#
 +if [ "​$?"​ = "​0"​ ]; then
 +   exit 0;
 +else
 +   exit 1;
 +fi
 +exit 1;
 +</​code>​
 +
 +  * On peut également s'​appuyer sur des outils comme winbindd ou ntlm_auth pour faire le même contrôle depuis un serveur Active Directory.
 +  * Autre exemple de script fourni avec le code source :
 +<code perl>
 +#​!/​usr/​bin/​perl -t
 +
 +# OpenVPN PAM AUTHENTICATON
 +#   This script can be used to add PAM-based authentication
 +#   to OpenVPN 2.0.  The OpenVPN client must provide
 +#   a username/​password,​ using the --auth-user-pass directive.
 +#   The OpenVPN server should specify --auth-user-pass-verify
 +#   with this script as the argument and the '​via-file'​ method
 +#   ​specified. ​ The server can also optionally specify
 +#   ​--client-cert-not-required and/or --username-as-common-name.
 +
 +# SCRIPT OPERATION
 +#   ​Return success or failure status based on whether or not a
 +#   given username/​password authenticates using PAM.
 +#   ​Caller should write username/​password as two lines in a file
 +#   which is passed to this script as a command line argument.
 +
 +# CAVEATS
 +#   * Requires Authen::PAM module, which may also
 +#     ​require the pam-devel package.
 +#   * May need to be run as root in order to
 +#     ​access username/​password file.
 +
 +# NOTES
 +#   * This script is provided mostly as a demonstration of the
 +#     ​--auth-user-pass-verify script capability in OpenVPN.
 +#     For real world usage, see the auth-pam module in the plugin
 +#     ​folder.
 +
 +use Authen::​PAM;​
 +use POSIX;
 +
 +# This "​conversation function"​ will pass
 +# $password to PAM when it asks for it.
 +
 +sub my_conv_func {
 +    my @res;
 +    while ( @_ ) {
 +        my $code = shift;
 +        my $msg = shift;
 +        my $ans = "";​
 +
 +        $ans = $password if $msg =~ /​[Pp]assword/;​
 +
 +        push @res, (PAM_SUCCESS(),​$ans);​
 +    }
 +    push @res, PAM_SUCCESS();​
 +    return @res;
 +}
 +
 +# Identify service type to PAM
 +$service = "​login";​
 +
 +# Get username/​password from file
 +
 +if ($ARG = shift @ARGV) {
 +    if (!open (UPFILE, "<​$ARG"​)) {
 +        print "Could not open username/​password file: $ARG\n";​
 +        exit 1;
 +    }
 +} else {
 +    print "No username/​password file specified on command line\n";​
 +    exit 1;
 +}
 +
 +$username = <​UPFILE>;​
 +$password = <​UPFILE>;​
 +
 +if (!$username || !$password) {
 +    print "​Username/​password not found in file: $ARG\n";​
 +    exit 1;
 +}
 +
 +chomp $username;
 +chomp $password;
 +
 +close (UPFILE);
 +
 +# Initialize PAM object
 +
 +if (!ref($pamh = new Authen::​PAM($service,​ $username, \&​my_conv_func))) {
 +    print "​Authen::​PAM init failed\n";​
 +    exit 1;
 +}
 +
 +# Authenticate with PAM
 +
 +$res = $pamh->​pam_authenticate;​
 +
 +# Return success or failure
 +
 +if ($res == PAM_SUCCESS()) {
 +    exit 0;
 +} else {
 +    print "Auth '​$username'​ failed, PAM said: ", $pamh->​pam_strerror($res),​ "​\n";​
 +    exit 1;
 +}
 +</​code>​
 +
 +==== Sécurité du service ====
 +
 +=== Disponibilité ===
 +
 +  * Il est toujours utile, lorsqu'​un service est critique, de mettre en oeuvre des moyens pour en renforcer la disponibilité.
 +  * Parmi ces moyens, nous retiendrons :
 +  - la redondance de machines ;
 +  - la redondance du service.
 +
 +== Redondance de machines == 
 +  * Cette méthode consiste à doubler (au moins) le nombre de machines qui rendront le service VPN.
 +  * Pour assurer la disponibilité du service via ces machines, on pourra opter pour la redondance et la répartition de charge par DNS : on associera le service VPN à un enregistrement DNS qui comprendra plusieurs enregistrements IN A :
 +<code html>
 +vpn.acme.fr ​ IN A a.b.c.d
 +             IN A a.b.c.e
 +</​code>​
 +Dans le cas où le service DNS s'​appuie sur le serveur BIND9, celui-ci répondra aux requêtes en résolution du nom vpn.acme.fr en renvoyant tantôt l'​adresse IP a.b.c.d, tantôt l'​adresse IP a.b.c.e.
 +  * On peut aussi opter pour une redondance OpenVPN : on indiquera dans les fichiers de configuration des clients plusieurs adresses de serveurs :
 +<code html>
 +remote a.b.c.d
 +remote a.b.c.e
 +</​code>​
 +Par défaut, le client tentera de se connecter au serveur d'​adresse IP a.b.c.d ou, en cas d'​échec,​ à celui d'​adresse IP a.b.c.e. Ce mode de redondance n'​assure cependant aucune répartition de charge : tant que le premier serveur répond aux requêtes, c'est lui qui est utilisé exclusivement.
 +  * Pour introduire une notion de répartition de charge, il faudra utiliser le paramètre remote-random :
 +<code html>
 +remote-random
 +</​code>​
 +
 +== Redondance de service == 
 +  * Si il n'est pas possible d'​utiliser plusieurs machines, on pourra toutefois renforcer le service VPN en exécutant sur une seule machine plusieurs démons OpenVPN sur des ports différents.
 +  * Cette méthode est applicable également si l'on souhaite mettre à disposition des postes nomades plusieurs types d'​accès au-dessus de ports et de protocoles différents. En effet, il n'y a aucune garantie que, depuis les points de connexion externes, tous les flux soient autorisés. Cette méthode permet alors de proposer plusieurs choix en fonction de l'​infrastructure réseau utilisée par les postes nomades.
 +  * Cela se traduira dans la configuration des postes nomades par les lignes suivantes :
 +<code html>
 +remote a.b.c.d
 +remote a.b.c.d:​8181
 +remote a.b.c.d:443
 +</​code>​
 +Dans cet exemple, trois démons OpenVPN s'​exécutent sur le serveur d'​adresse IP a.b.c.d : un démon sur le port standard, un sur le port 8181 et un troisième sur le port 443.
 +  * Là encore, la connexion sera tentée sur le premier (standard) puis en cas d'​échec sur le second et enfin sur le troisième.
 +  * Note : si on ne souhaite pas lancer plusieurs démons, il reste possible d'​utilser le démon xinetd comme aiguilleur. Alternative : utiliser les pare-feux Netfilter/​IPTables ou PF pour faire de la redirection de port.
 +
 +== Redondance mixte == 
 +  * Il n'est pas interdit de mixer les deux méthodes :
 +<code html>
 +remote a.b.c.d
 +remote a.b.c.e
 +remote a.b.c.d:​8181
 +remote a.b.c.e:​8181
 +etc.
 +</​code>​
 +
 +=== Sécurisation du HandShake SSL/TLS ===
 +  * Par nature, notre serveur VPN est à l'​écoute de toute demande de connexion en provenance d'​Internet. Il est par conséquent susceptible de répondre à n'​importe quelle machine et potentiellement vulnérable aux attaques de type DoS.
 +  * Ces attaques peuvent intervenir durant la phase d'​initialisation de la connexion SSL/TLS, quand le client n'est pas encore authentifié et échange avec le serveur les options SSL/TLS initiales. Ces opérations sont "​coûteuses"​ en temps machine et en ressources (allocation de mémoire et d'une socket réseau pour chaque client). Cette phase est donc sensible et par défaut relativement exposée.
 +  * Il est possible de sécuriser cette phase en "​signant"​ les paquets échangés à l'aide d'une clef secrète partagée entre le client et le serveur.
 +  * L'​idée est de signer chaque paquet à l'aide d'une empreinte HMAC et leur attribuer un identifiant unique afin de détecter et interdire toute tentative de rejeu d'une session.
 +  * Chaque paquet qui transite sur le canal de contrôle TLS est signé : les paquets dont la signature n'est pas correcte ou inexsitante sont alors tout simplement ignorés, avant même l'​ouverture de la connexion TLS.
 +  * Il est enfin possible de stocker dans un fichier l'​état des sessions passées de manière à permettre au démon de retrouver la trace des précédents échanges à son redémarrage.
 +  * La mise en oeuvre de cette protection se fait de la manière suivante :
 +<code html>
 +// Génération de la clef partagée
 +openvpn --genkey --secret nom_de_fichier.key
 +</​code>​
 +  * Cette clef doit ensuite être exportée sur chaque client.
 +  * Dans le fichier de configuration du serveur, on active cette protection :
 +<code html>
 +tls-auth nom_de_fichier.key 0
 +</​code>​
 +  * Dans le fichier de configuration des clients on ajoute :
 +<code html>
 +tls-auth nom_de_fichier.key 1
 +</​code>​
 +  * Le paramètre replay-persist permet de spécifier l'​emplacement du fichier dans lequel seront stockés les états des sessions :
 +<code html>
 +replay-persist /​path/​to/​fichier
 +</​code>​
 +  * OpenVPN utilise ce fichier pout conserver une trace du dernier paquet reçu (horodatage et numéro de séquence).
 +
 +==== Récapitulatif ====
 +  * Voici un exemple de fichier openvpn.conf pour notre serveur :
 +<code html>
 +#################################################​
 +# Sample OpenVPN 2.0 config file for            #
 +# multi-client server. ​                         #
 +#                                               #
 +# This file is for the server side              #
 +# of ACME VPN.                                  #
 +#                                               # ​                                              
 +# Comments are preceded with '#'​ or ';' ​        #
 +#################################################​
 +
 +# Server or Client ?
 +mode server
 +tls-server
 +
 +# Which local IP address should OpenVPN
 +# listen on? (optional)
 +local a.b.c.d
 +
 +# Which TCP/UDP port should OpenVPN listen on?
 +port 1194
 +
 +# TCP or UDP server?
 +proto udp
 +
 +# "dev tun" will create a routed IP tunnel,
 +# "dev tap" will create an ethernet tunnel.
 +dev tun
 +
 +# SSL/TLS root certificate (ca), certificate
 +# (cert), and private key (key). ​ Each client
 +# and the server must have their own cert and
 +# key file.  The server and all clients will
 +# use the same ca file.
 +ca ca.crt
 +cert server.crt
 +key server.key
 +
 +# Where is the CRL ?
 +# This file is read each time a new sessions begins.
 +crl-verify crl.pem
 +
 +# Diffie hellman parameters.
 +dh dh1024.pem
 +
 +# Configure server mode and supply a VPN subnet
 +# for OpenVPN to draw client addresses from.
 +# The server will take 10.8.0.1 for itself,
 +# the rest will be made available to clients.
 +# Each client will be able to reach the server
 +# on 10.8.0.1. Comment this line out if you are
 +# ethernet bridging. See the man page for more info.
 +server 10.8.0.0 255.255.255.0
 +
 +# If enabled, this directive will configure
 +# all clients to redirect their default
 +# network gateway through the VPN, causing
 +# all IP traffic such as web browsing and
 +# and DNS lookups to go through the VPN
 +# (The OpenVPN server machine may need to NAT
 +# the TUN/TAP interface to the internet in
 +# order for this to work properly).
 +push "​redirect-gateway def1"
 +
 +# Certain Windows-specific network settings
 +# can be pushed to clients, such as DNS
 +# or WINS server addresses. ​ CAVEAT:
 +push "​dhcp-option DNS 10.8.0.1"​
 +push "​dhcp-option WINS 10.8.0.1"​
 +
 +# Uncomment this directive to allow different
 +# clients to be able to "​see"​ each other.
 +;​client-to-client
 +
 +# The keepalive directive causes ping-like
 +# messages to be sent back and forth over
 +# the link so that each side knows when
 +# the other side has gone down.
 +# Ping every 10 seconds, assume that remote
 +# peer is down if no ping received during
 +# a 120 second time period.
 +keepalive 10 120
 +
 +# For extra security beyond that provided
 +# by SSL/TLS, create an "HMAC firewall"​
 +# to help block DoS attacks and UDP port flooding.
 +tls-auth tls-auth.key 0
 +replay-persist tls-auth.log
 +
 +# Select a cryptographic cipher.
 +# This config item must be copied to
 +# the client config file as well.
 +;cipher BF-CBC ​       # Blowfish (default)
 +;cipher AES-128-CBC ​  # AES
 +;cipher DES-EDE3-CBC ​ # Triple-DES
 +
 +# Enable compression on the VPN link.
 +# If you enable it here, you must also
 +# enable it in the client config file.
 +comp-lzo
 +
 +# The maximum number of concurrently connected
 +# clients we want to allow.
 +max-clients 100
 +
 +# It's a good idea to reduce the OpenVPN
 +# daemon'​s privileges after initialization.
 +user nobody
 +group nobody
 +
 +# The persist options will try to avoid
 +# accessing certain resources on restart
 +# that may no longer be accessible because
 +# of the privilege downgrade.
 +persist-key
 +persist-tun
 +
 +# Output a short status file showing
 +# current connections,​ truncated
 +# and rewritten every minute.
 +status openvpn-status.log
 +
 +# Set the appropriate level of log
 +# file verbosity.
 +#
 +# 0 is silent, except for fatal errors
 +# 4 is reasonable for general usage
 +# 5 and 6 can help to debug connection problems
 +# 9 is extremely verbose
 +verb 4
 +
 +# Silence repeating messages. ​ At most 20
 +# sequential messages of the same message
 +# category will be output to the log.
 +mute 20
 +
 +</​code>​
 +
 +==== Administration du démon OpenVPN ====
 +  * Il est possible d'agir sur le démon OpenVPN via une interface de management. Cette interface est matérialisée par un port TCP sur lequel il est possible de passer des commandes au démon en cours d'​exécution. Cette interface, encore expérimentale,​ doit, à terme, permettre de développer des outils de gestion graphique du démon OpenVPN. ​
 +  * On peut ainsi interroger le démon et obtenir le status des connexions actives et en couper certaines sans devoir arrêter le démon.
 +  * Pour activer le port de management, il faut entrer les lignes suivantes dans le fichier de configuration :
 +<code html>
 +management 127.0.0.1 7505
 +</​code>​
 +Dans cet exemple, le port de management TCP/7505 sera affecté à l'​interface de bouclage.
 +  * Un telnet sur le port désigné permet de dialoguer avec le démon :
 +<code html>
 +Trying 127.0.0.1...
 +Connected to 127.0.0.1.
 +Escape character is '​^]'​.
 +>​INFO:​OpenVPN Management Interface Version 1 -- type '​help'​ for more info
 +
 +</​code>​
 +  * Comme cela nous est suggéré par la bannière, tapons '​help'​ :
 +<code html>
 +help
 +Management Interface for OpenVPN 2.0 i386-pc-linux [SSL] [LZO] [EPOLL] built on Nov  3 2005
 +Commands:
 +echo [on|off] [N|all] ​ : Like log, but only show messages in echo buffer.
 +exit|quit ​             : Close management session.
 +help                   : Print this message.
 +hold [on|off|release] ​ : Set/show hold flag to on/off state, or
 +                         ​release current hold and start tunnel.
 +kill cn                : Kill the client instance(s) having common name cn.
 +kill IP:​port ​          : Kill the client instance connecting from IP:port.
 +log [on|off] [N|all] ​  : Turn on/off realtime log display
 +                         + show last N lines or '​all'​ for entire history.
 +mute [n]               : Set log mute level to n, or show level if n is absent.
 +net                    : (Windows only) Show network info and routing table.
 +password type p        : Enter password p for a queried OpenVPN password.
 +signal s               : Send signal s to daemon,
 +                         s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2.
 +state [on|off] [N|all] : Like log, but show state history.
 +status [n]             : Show current daemon status info using format #n.
 +test n                 : Produce n lines of output for testing/​debugging.
 +username type u        : Enter username u for a queried OpenVPN username.
 +verb [n]               : Set log verbosity level to n, or show if n is absent.
 +version ​               : Show current version number.
 +END
 +</​code>​
 +  * La commande kill permet de mettre fin à une connexion active. Elle prend comme argument le CommonName d'un certificat client ou bien l'​adresse IP et le port utilisés par le client.
 +  * La commande signal permet d'​envoyer... un signal au démon. Elle est équivalente à passer ces informations via la commande système ps.
 +
 +==== Lancement du démon OpenVPN ====
 +  * Le démon OpenVPN est démarré à l'aide du script suivant sur un serveur Linux Red Hat :
 +<​file>​
 +#!/bin/sh
 +#
 +# openvpn ​      This shell script takes care of starting and stopping
 +#               ​openvpn on RedHat or other chkconfig-based system.
 +#
 +# chkconfig: 345 24 76
 +#
 +# description:​ OpenVPN is a robust and highly flexible tunneling application that
 +#              uses all of the encryption, authentication,​ and certification features
 +#              of the OpenSSL library to securely tunnel IP networks over a single
 +#              UDP port.
 +#
 +
 +# Contributed to the OpenVPN project by
 +# Douglas Keller <​doug@voidstar.dyndns.org>​
 +# 2002.05.15
 +
 +# To install:
 +#   copy this file to /​etc/​rc.d/​init.d/​openvpn
 +#   ​shell>​ chkconfig --add openvpn
 +#   ​shell>​ mkdir /​etc/​openvpn
 +#   make .conf or .sh files in /​etc/​openvpn (see below)
 +
 +# To uninstall:
 +#   run: chkconfig --del openvpn
 +
 +# Author'​s Notes:
 +#
 +# I have created an /etc/init.d init script and enhanced openvpn.spec to
 +# automatically register the init script. ​ Once the RPM is installed you
 +# can start and stop OpenVPN with "​service openvpn start" and "​service
 +# openvpn stop".
 +#
 +# The init script does the following:
 +#
 +# - Starts an openvpn process for each .conf file it finds in
 +#   /​etc/​openvpn.
 +#
 +# - If /​etc/​openvpn/​xxx.sh exists for a xxx.conf file then it executes
 +#   it before starting openvpn (useful for doing openvpn --mktun...).
 +#
 +# - In addition to start/stop you can do:
 +#
 +#   ​service openvpn reload - SIGHUP
 +#   ​service openvpn reopen - SIGUSR1
 +#   ​service openvpn status - SIGUSR2
 +#
 +# Modifications:​
 +#
 +# 2003.05.02
 +#   * Changed == to = for sh compliance (Bishop Clark).
 +#   * If condrestart|reload|reopen|status,​ check that we were
 +#     ​actually started (James Yonan).
 +#   * Added lock, piddir, and work variables (James Yonan).
 +#   * If start is attempted twice, without an intervening stop, or
 +#     if start is attempted when previous start was not properly
 +#     shut down, then kill any previously started processes, before
 +#     ​commencing new start operation (James Yonan).
 +#   * Do a better job of flagging errors on start, and properly
 +#     ​returning success or failure status to caller (James Yonan).
 +#
 +# 2005.04.04
 +#   * Added openvpn-startup and openvpn-shutdown script calls
 +#     ​(James Yonan).
 +#
 +
 +# Location of openvpn binary
 +openvpn=""​
 +openvpn_locations="/​usr/​sbin/​openvpn /​usr/​local/​sbin/​openvpn"​
 +for location in $openvpn_locations
 +do
 +  if [ -f "​$location"​ ]
 +  then
 +    openvpn=$location
 +  fi
 +done
 +
 +# Lockfile
 +lock="/​var/​lock/​subsys/​openvpn"​
 +
 +# PID directory
 +piddir="/​var/​run/​openvpn"​
 +
 +# Our working directory
 +work=/​etc/​openvpn
 +
 +# Source function library.
 +. /​etc/​rc.d/​init.d/​functions
 +
 +# Source networking configuration.
 +. /​etc/​sysconfig/​network
 +
 +# Check that networking is up.
 +if [ ${NETWORKING} = "​no"​ ]
 +then
 +  echo "​Networking is down"
 +  exit 0
 +fi
 +
 +# Check that binary exists
 +if ! [ -f  $openvpn ] 
 +then
 +  echo "​openvpn binary not found"
 +  exit 0
 +fi
 +
 +# See how we were called.
 +case "​$1"​ in
 +  start)
 +        echo -n $"​Starting openvpn: "
 +
 +        /​sbin/​modprobe tun >/​dev/​null 2>&1
 +
 +        # From a security perspective,​ I think it makes
 +        # sense to remove this, and have users who need
 +        # it explictly enable in their --up scripts or
 +        # firewall setups.
 +
 +        #echo 1 > /​proc/​sys/​net/​ipv4/​ip_forward
 +
 +        # Run startup script, if defined
 +        if [ -f $work/​openvpn-startup ]; then
 +            $work/​openvpn-startup
 +        fi
 +
 +        if [ ! -d  $piddir ]; then
 +            mkdir $piddir
 +        fi
 +
 +        if [ -f $lock ]; then
 +            # we were not shut down correctly
 +            for pidf in `/bin/ls $piddir/​*.pid 2>/​dev/​null`;​ do
 +              if [ -s $pidf ]; then
 +                kill `cat $pidf` >/​dev/​null 2>&1
 +              fi
 +              rm -f $pidf
 +            done
 +            rm -f $lock
 +            sleep 2
 +        fi
 +
 +        rm -f $piddir/​*.pid
 +        cd $work
 +
 +        # Start every .conf in $work and run .sh if exists
 +        errors=0
 +        successes=0
 +        for c in `/bin/ls *.conf 2>/​dev/​null`;​ do
 +            bn=${c%%.conf}
 +            if [ -f "​$bn.sh"​ ]; then
 +                . $bn.sh
 +            fi
 +            rm -f $piddir/​$bn.pid
 +            $openvpn --daemon --writepid $piddir/​$bn.pid --config $c --cd $work
 +            if [ $? = 0 ]; then
 +                successes=1
 +            else
 +                errors=1
 +            fi
 +        done
 +
 +        if [ $errors = 1 ]; then
 +            failure; echo
 +        else
 +            success; echo
 +        fi
 +
 +        if [ $successes = 1 ]; then
 +            touch $lock
 +        fi
 +        ;;
 +  stop)
 +        echo -n $"​Shutting down openvpn: "
 +        for pidf in `/bin/ls $piddir/​*.pid 2>/​dev/​null`;​ do
 +          if [ -s $pidf ]; then
 +            kill `cat $pidf` >/​dev/​null 2>&1
 +          fi
 +          rm -f $pidf
 +        done
 +
 +        # Run shutdown script, if defined
 +        if [ -f $work/​openvpn-shutdown ]; then
 +            $work/​openvpn-shutdown
 +        fi
 +
 +        success; echo
 +        rm -f $lock
 +        ;;
 +  restart)
 +        $0 stop
 +        sleep 2
 +        $0 start
 +        ;;
 +  reload)
 +        if [ -f $lock ]; then
 +            for pidf in `/bin/ls $piddir/​*.pid 2>/​dev/​null`;​ do
 +                if [ -s $pidf ]; then
 +                    kill -HUP `cat $pidf` >/​dev/​null 2>&1
 +                fi
 +            done
 +        else
 +            echo "​openvpn:​ service not started"​
 +            exit 1
 +        fi
 +        ;;
 +  reopen)
 +        if [ -f $lock ]; then
 +            for pidf in `/bin/ls $piddir/​*.pid 2>/​dev/​null`;​ do
 +                if [ -s $pidf ]; then
 +                    kill -USR1 `cat $pidf` >/​dev/​null 2>&1
 +                fi
 +            done
 +        else
 +            echo "​openvpn:​ service not started"​
 +            exit 1
 +        fi
 +        ;;
 +  condrestart)
 +        if [ -f $lock ]; then
 +            $0 stop
 +            # avoid race
 +            sleep 2
 +            $0 start
 +        fi
 +        ;;
 +  status)
 +        if [ -f $lock ]; then
 +            for pidf in `/bin/ls $piddir/​*.pid 2>/​dev/​null`;​ do
 +                if [ -s $pidf ]; then
 +                    kill -USR2 `cat $pidf` >/​dev/​null 2>&1
 +                fi
 +            done
 +            echo "​Status written to /​var/​log/​messages"​
 +        else
 +            echo "​openvpn:​ service not started"​
 +            exit 1
 +        fi
 +        ;;
 +  *)
 +        echo "​Usage:​ openvpn {start|stop|restart|condrestart|reload|reopen|status}"​
 +        exit 1
 +        ;;
 +esac
 +exit 0
 +</​file>​
 +
 +  * Même exemple de script pour une distribution GNU/Debian :
 +<​file>​
 +#!/bin/sh -e
 +#
 +# Original version by Robert Leslie
 +# <​rob@mars.org>,​ edited by iwj and cs
 +# Modified for openvpn by Alberto Gonzalez Iniesta <​agi@inittab.org>​
 +# Modified for restarting / starting / stopping single tunnels by Richard Mueller <​mueller@teamix.net>​
 +
 +test $DEBIAN_SCRIPT_DEBUG && set -v -x
 +
 +DAEMON=/​usr/​sbin/​openvpn
 +DESC="​virtual private network daemon"​
 +CONFIG_DIR=/​etc/​openvpn
 +test -x $DAEMON || exit 0
 +test -d $CONFIG_DIR || exit 0
 +
 +# Source defaults file; edit that file to configure this script.
 +AUTOSTART="​all"​
 +STATUSREFRESH=10
 +if test -e /​etc/​default/​openvpn ; then
 +  . /​etc/​default/​openvpn
 +fi
 +
 +start_vpn () {
 +    if grep -q '​^[ ​      ​]*daemon'​ $CONFIG_DIR/​$NAME.conf ; then
 +      # daemon already given in config file
 +      DAEMONARG=
 +    else
 +      # need to daemonize
 +      DAEMONARG="​--daemon ovpn-$NAME"​
 +    fi
 +
 +    if grep -q '​^[ ​      ​]*status ' $CONFIG_DIR/​$NAME.conf ; then
 +      # status file already given in config file
 +      STATUSARG=""​
 +    elif test $STATUSREFRESH -eq 0 ; then
 +      # default status file disabled in /​etc/​default/​openvpn
 +      STATUSARG=""​
 +    else
 +      # prepare default status file
 +      STATUSARG="​--status /​var/​run/​openvpn.$NAME.status $STATUSREFRESH"​
 +    fi
 +
 +    $DAEMON --writepid /​var/​run/​openvpn.$NAME.pid \
 +            $DAEMONARG $STATUSARG --cd $CONFIG_DIR \
 +            --config $CONFIG_DIR/​$NAME.conf || echo -n " FAILED->"​
 +    echo -n " $NAME"
 +}
 +stop_vpn () {
 +   kill `cat $PIDFILE` || true
 +  rm $PIDFILE
 +  [ -e /​var/​run/​openvpn.$NAME.status ] \
 +    && rm /​var/​run/​openvpn.$NAME.status
 +}
 +
 +case "​$1"​ in
 +start)
 +  echo -n "​Starting $DESC:"​
 +
 +  # autostart VPNs
 +  if test -z "​$2"​ ; then
 +    # check if automatic startup is disabled by AUTOSTART=none
 +    if test "​x$AUTOSTART"​ = "​xnone"​ -o -z "​$AUTOSTART"​ ; then
 +      echo " Autostart disabled."​
 +      exit 0
 +    fi
 +    if test -z "​$AUTOSTART"​ -o "​x$AUTOSTART"​ = "​xall"​ ; then
 +      # all VPNs shall be started automatically
 +      for CONFIG in `cd $CONFIG_DIR;​ ls *.conf 2> /dev/null`; do
 +        NAME=${CONFIG%%.conf}
 +        start_vpn
 +      done
 +    else
 +      # start only specified VPNs
 +      for NAME in $AUTOSTART ; do
 +        if test -e $CONFIG_DIR/​$NAME.conf ; then
 +          start_vpn
 +        else
 +          echo -n " (failure: No such VPN: $NAME)"​
 +        fi
 +      done
 +    fi
 +  #start VPNs from command line
 +  else
 +    while shift ; do
 +      [ -z "​$1"​ ] && break
 +      if test -e $CONFIG_DIR/​$1.conf ; then
 +        NAME=$1
 +        start_vpn
 +      else
 +        echo -n " (failure: No such VPN: $1)"
 +      fi
 +    done
 +  fi
 +  echo "​."​
 +
 +  ;;
 +stop)
 +  echo -n "​Stopping $DESC:"​
 +
 +  if test -z "​$2"​ ; then
 +    for PIDFILE in `ls /​var/​run/​openvpn.*.pid 2> /dev/null`; do
 +      NAME=`echo $PIDFILE | cut -c18-`
 +      NAME=${NAME%%.pid}
 +      stop_vpn
 +      echo -n " $NAME"
 +    done
 +  else
 +    while shift ; do
 +      [ -z "​$1"​ ] && break
 +      if test -e /​var/​run/​openvpn.$1.pid ; then
 +        PIDFILE=`ls /​var/​run/​openvpn.$1.pid 2> /dev/null`
 +        NAME=`echo $PIDFILE | cut -c18-`
 +        NAME=${NAME%%.pid}
 +        stop_vpn
 +        echo -n " $NAME"
 +      else
 +        echo -n " (failure: No such VPN is running: $1)"
 +      fi
 +    done
 +  fi
 +  echo "​."​
 +  ;;
 +# We only '​reload'​ for running VPNs. New ones will only start with '​start'​ or '​restart'​.
 +reload|force-reload)
 +  echo -n "​Reloading $DESC:"​
 +  for PIDFILE in `ls /​var/​run/​openvpn.*.pid 2> /dev/null`; do
 +    NAME=`echo $PIDFILE | cut -c18-`
 +    NAME=${NAME%%.pid}
 +# If openvpn if running under a different user than root we'll need to restart
 +    if egrep '^( |\t)*user'​ $CONFIG_DIR/​$NAME.conf > /dev/null 2>&1 ; then
 +      stop_vpn
 +      sleep 1
 +      start_vpn
 +      echo -n "​(restarted)"​
 +    else
 +      kill -HUP `cat $PIDFILE` || true
 +    echo -n " $NAME"
 +    fi
 +  done
 +  echo "​."​
 +  ;;
 +
 +restart)
 +  shift
 +  $0 stop ${@}
 +  sleep 1
 +  $0 start ${@}
 +  ;;
 +cond-restart)
 +  echo -n "​Restarting $DESC:"​
 +  for PIDFILE in `ls /​var/​run/​openvpn.*.pid 2> /dev/null`; do
 +    NAME=`echo $PIDFILE | cut -c18-`
 +    NAME=${NAME%%.pid}
 +    stop_vpn
 +    sleep 1
 +    start_vpn
 +  done
 +  echo "​."​
 +  ;;
 +*)
 +  echo "​Usage:​ $0 {start|stop|reload|restart|force-reload|cond-restart}"​ >&2
 +  exit 1
 +  ;;
 +esac
 +
 +exit 0
 +</​file>​
 +
 +===== Configuration des postes nomades =====
 +
 +==== Généralités ====
 +
 +  * Il faut installer OpenVPN sur chaque poste nomade qui doit se connecter au VPN.
 +  * Il faut ensuite adapter le fichier de configuration et déposer les certificats,​ clefs (privée et partagée) et les éventuels scripts.
 +  * Dans un monde idéal, chaque poste utilise un même fichier de configuration dont la maintenance sera ainsi aisée.
 +  * Pour les postes sous Windows, on utilisera la version d'​OpenVPN fournie avec une interface graphique.
 +  * De même, pour les postes sous Mac OS X 10.3 et 10.4 on utilisera Tunnelblick.
 +  * Pour les autres systèmes d'​exploitation supportés, il faudra se "​contenter"​ des paquetages : le démon sera lancé "à la main" ou depuis un script. On supposera cependant, pour les utilisateurs de postes nomades sous Linux/*BSD, que ces derniers sont suffisamment expérimentés pour lancer le démon openvpn depuis la ligne de commande...
 +
 +==== Les différents clients OpenVPN ====
 +
 +=== Postes sous MS Windows ===
 +
 +  * Pour les postes sous Windows, il existe une distribution qui fournit le démon openvpn ainsi qu'une interface graphique pour monter les tunels.
 +  * [[http://​openvpn.se/​|OpenVPN GUI for Windows]]
 +  * La GUI est accessible via une icône insérée dans la barre de status :
 +{{ start:​win-ovpn-1.png }}
 +  * Lorsque l'on clique sur cette icône on accède aux menus suivants :
 +{{ start:​win-ovpn-6.png }}
 +Puis :
 +{{ start:​win-ovpn-7.png }}
 +  * Le tunnel est monté en cliquant sur Connecter :
 +{{ start:​win-ovpn-5.png }}
 +  * Lorsque le tunnel est activé, l'​iône passe au vert après avoir affiché le status de la nouvelle connexion Réseau :
 +{{ start:​win-ovpn-3.png }}
 +Puis :
 +{{ start:​win-ovpn-4.png }}
 +
 +  * Cet utilitaire présente la particularité de supporter plusieurs configurations : par défaut, le répertoire qui contient les fichiers de configuration et les clefs Client est parcouru. Tout fichier d'​extension .ovpn est considéré comme un fichier de configuration OpenVPN. Une entrée est créée dans l'​onglet de la GUI pour chacun de ces fichiers, ce qui permet de proposer plusieurs choix à l'​utilisateur si nécessaire. Le nom qui apparait dans cet onglet est construit à partir du radical de son nom. Dans l'​exemple ci-dessus, le répertoire de c:\Program Files\OpenVPN\config contient deux fichiers : Agence de Lyon.ovpn et Agence de Paris.ovpn.
 +
 +=== Postes sous Mac OS X ===
 +
 +== Tunnelblick pour Mac OS X 10.3 et 10.4 ==
 +  * Pour les postes sous Mac OS X 10.3 et 10.4, il existe Tunnelblick,​ qui, comme OpenVPN GUI for Windows, fournit le démon openvpn et une interface graphique de lancement.
 +  * [[http://​www.tunnelblick.net/​|Tunnelblick]]
 +
 +== OpenVPN pour Mac OS X 10.2 ==
 +  * Pour les postes sous Mac OS 10.2, il n'​existe pas d'​interface graphique mais il est possible de compiler OpenVPN pour cette plate forme. Le lancement doit se faire à la main depuis un Terminal.
 +
 +=== Postes sous Unix ===
 +  * Pour les postes sous Unix, le démon peut être lancé à la main ou de manière automatique. Dans ce cas, le tunnel VPN sera la seule connexion réseau du poste.
 +  * Il existe une interface graphique pour KDE qui permet de monter des tunnels OpenVPN. ​ [[http://​home.gna.org/​kvpnc/​en/​screenshot.html|Kvpnc]]
 +  * Rappelons cependant que l'​unixien,​ le vrai, ne connait que la ligne de commande... :-)
 +
 +==== Paramètres de configuration Client ====
 +
 +  * Nous présentons dans ce paragraphe les paramètres de configuration qui s'​appliquront aux clients OpenVPN installés sur les postes nomades.
 +  * Notez que ces paramètres sont génériques et ne dépendent pas du client choisi ni de l'OS du poste nomade. Il est également intéressant,​ pour des questions de maintenance,​ que le fichier de configuration des postes nomades ne comportent pas de paramètères particuliers sans quoi la diffusion ou la mise à jour de ce fichier peut rapidement tourner au cauchemar.
 +  * Idéalement,​ toute l'//​intelligence//​ et tout le travail sera confié au serveur. Nous mettrons donc l'​accent,​ dans le fichier de configuration du poste nomade, sur les paramètres qui permettent de contrôler l'​identité du serveur et donc de garantir la confiance mutuelle serveur/​client.
 +  * Voici donc ce à quoi ressemblera notre fichier de configuration (il s'agit d'une version à peine modifiée du fichier client.conf livré avec OpenVPN) :
 +<​file>​
 +# Specify that we are a client and that we
 +# will be pulling certain config file directives
 +# from the server.
 +client
 +
 +# Use the same setting as you are using on
 +# the server.
 +dev tun
 +
 +# Are we connecting to a TCP or
 +# UDP server? ​ Use the same setting as
 +# on the server.
 +proto udp
 +
 +# The hostname/IP and port of the server.
 +# You can have multiple remote entries
 +# to load balance between the servers.
 +remote my-server-1 1194
 +remote my-server-2 1194
 +
 +# Choose a random host from the remote
 +# list for load-balancing. ​ Otherwise
 +# try hosts in the order specified.
 +remote-random
 +
 +# Keep trying indefinitely to resolve the
 +# host name of the OpenVPN server. ​ Very useful
 +# on machines which are not permanently connected
 +# to the internet such as laptops.
 +resolv-retry infinite
 +
 +# Most clients don't need to bind to
 +# a specific local port number.
 +nobind
 +
 +# Downgrade privileges after initialization (non-Windows only)
 +user nobody
 +group nobody
 +
 +# Try to preserve some state across restarts.
 +persist-key
 +persist-tun
 +
 +# If you are connecting through an
 +# HTTP proxy to reach the actual OpenVPN
 +# server, put the proxy server/IP and
 +# port number here.  See the man page
 +# if your proxy server requires
 +# authentication.
 +;​http-proxy-retry # retry on connection failures
 +;http-proxy [proxy server] [proxy port #]
 +
 +# Wireless networks often produce a lot
 +# of duplicate packets. ​ Set this flag
 +# to silence duplicate packet warnings.
 +;​mute-replay-warnings
 +
 +# SSL/TLS parms.
 +# See the server config file for more
 +# description. ​ It's best to use
 +# a separate .crt/.key file pair
 +# for each client. ​ A single ca
 +# file can be used for all clients.
 +ca ca.crt
 +cert client.crt
 +key client.key
 +
 +# Verify server certificate by checking
 +# that the certicate has the nsCertType
 +# field set to "​server"​.
 +ns-cert-type server
 +
 +# If a tls-auth key is used on the server
 +# then every client must also have the key.
 +tls-auth ta.key 1
 +
 +# Enable compression on the VPN link.
 +# Don't enable this unless it is also
 +# enabled in the server config file.
 +comp-lzo
 +
 +# Set log file verbosity.
 +verb 3
 +
 +# Silence repeating messages
 +mute 20
 +</​file>​
 +
 +
 +
 +====== Références documentaires & Liens ======
 +
 +  * [[http://​www.openvpn.net|Site du projet OpenVPN]]
 +  * [[http://​lehmann.free.fr/​openvpn/​|Documentation en français]]
 +  * [[http://​openvpn.se/​|OpenVPN GUI for Windows]]
 +  * [[http://​www.tunnelblick.net/​|Tunnelblick - OpenVPN GUI for Mac OS X]]
start/openvpn_how-to.txt · Last modified: 2006/05/12 17:40 (external edit)