Mise en production

Implémentation Debian

Il suffit donc d'installer le paquet openvpn et les dépendances manquantes viendront avec. L'installation, en plus du code et de la documentation dans /usr/share/doc/openvpn (Le README.Debian n'est pas une lecture inutile) produit un répertoire /etc/openvpn vide et un fichier /etc/default/openvpn auquel il faudra jeter un coup d'œil. De plus, un script d'init /etc/init.d/openvpn permettra le démarrage et l'arrêt automatique du tunnel. Enfin, des scripts de gestion du réseau permettront de démarrer ou d'arrêter les tunnels suivant l'état des interfaces physiques associées.

Voici la liste complète des fichiers installés par le paquet :

:~# dpkg -L openvpn
/.
/etc
/etc/openvpn
/etc/network
/etc/network/if-up.d
/etc/network/if-up.d/openvpn
/etc/network/if-down.d
/etc/network/if-down.d/openvpn
/etc/default
/etc/default/openvpn
/etc/init.d
/etc/init.d/openvpn
/usr
/usr/sbin
/usr/sbin/openvpn
/usr/share
/usr/share/man
/usr/share/man/man8
/usr/share/man/man8/openvpn.8.gz
/usr/share/doc
/usr/share/doc/openvpn
/usr/share/doc/openvpn/README.auth-pam
/usr/share/doc/openvpn/README.down-root
/usr/share/doc/openvpn/AUTHORS
/usr/share/doc/openvpn/PORTS
/usr/share/doc/openvpn/README
/usr/share/doc/openvpn/README.Debian
/usr/share/doc/openvpn/copyright
/usr/share/doc/openvpn/examples
/usr/share/doc/openvpn/examples/sample-config-files
/usr/share/doc/openvpn/examples/sample-config-files/openvpn-startup.sh
/usr/share/doc/openvpn/examples/sample-config-files/firewall.sh
/usr/share/doc/openvpn/examples/sample-config-files/loopback-client
/usr/share/doc/openvpn/examples/sample-config-files/README
/usr/share/doc/openvpn/examples/sample-config-files/xinetd-server-config
/usr/share/doc/openvpn/examples/sample-config-files/loopback-server
/usr/share/doc/openvpn/examples/sample-config-files/office.up
/usr/share/doc/openvpn/examples/sample-config-files/xinetd-client-config
/usr/share/doc/openvpn/examples/sample-config-files/home.up
/usr/share/doc/openvpn/examples/sample-config-files/openvpn-shutdown.sh
/usr/share/doc/openvpn/examples/sample-config-files/static-home.conf
/usr/share/doc/openvpn/examples/sample-config-files/tls-home.conf
/usr/share/doc/openvpn/examples/sample-config-files/tls-office.conf
/usr/share/doc/openvpn/examples/sample-config-files/client.conf
/usr/share/doc/openvpn/examples/sample-config-files/static-office.conf
/usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz
/usr/share/doc/openvpn/examples/sample-keys
/usr/share/doc/openvpn/examples/sample-keys/README
/usr/share/doc/openvpn/examples/sample-keys/dh1024.pem
/usr/share/doc/openvpn/examples/sample-keys/pass.crt
/usr/share/doc/openvpn/examples/sample-keys/pass.key
/usr/share/doc/openvpn/examples/sample-keys/tmp-ca.crt
/usr/share/doc/openvpn/examples/sample-keys/tmp-ca.key
/usr/share/doc/openvpn/examples/sample-keys/server.crt
/usr/share/doc/openvpn/examples/sample-keys/server.key
/usr/share/doc/openvpn/examples/sample-keys/client.crt
/usr/share/doc/openvpn/examples/sample-keys/client.key
/usr/share/doc/openvpn/examples/sample-keys/pkcs12.p12
/usr/share/doc/openvpn/examples/easy-rsa
/usr/share/doc/openvpn/examples/easy-rsa/2.0
/usr/share/doc/openvpn/examples/easy-rsa/2.0/vars
/usr/share/doc/openvpn/examples/easy-rsa/2.0/list-crl
/usr/share/doc/openvpn/examples/easy-rsa/2.0/clean-all
/usr/share/doc/openvpn/examples/easy-rsa/2.0/Makefile
/usr/share/doc/openvpn/examples/easy-rsa/2.0/openssl.cnf
/usr/share/doc/openvpn/examples/easy-rsa/2.0/sign-req
/usr/share/doc/openvpn/examples/easy-rsa/2.0/build-key-pkcs12
/usr/share/doc/openvpn/examples/easy-rsa/2.0/build-key-server
/usr/share/doc/openvpn/examples/easy-rsa/2.0/build-key-pass
/usr/share/doc/openvpn/examples/easy-rsa/2.0/revoke-full
/usr/share/doc/openvpn/examples/easy-rsa/2.0/build-req-pass
/usr/share/doc/openvpn/examples/easy-rsa/2.0/inherit-inter
/usr/share/doc/openvpn/examples/easy-rsa/2.0/whichopensslcnf
/usr/share/doc/openvpn/examples/easy-rsa/2.0/build-key
/usr/share/doc/openvpn/examples/easy-rsa/2.0/build-req
/usr/share/doc/openvpn/examples/easy-rsa/2.0/build-ca
/usr/share/doc/openvpn/examples/easy-rsa/2.0/build-dh
/usr/share/doc/openvpn/examples/easy-rsa/2.0/build-inter
/usr/share/doc/openvpn/examples/easy-rsa/2.0/pkitool
/usr/share/doc/openvpn/examples/easy-rsa/2.0/README.gz
/usr/share/doc/openvpn/examples/easy-rsa/2.0/openssl-0.9.6.cnf.gz
/usr/share/doc/openvpn/examples/easy-rsa/vars
/usr/share/doc/openvpn/examples/easy-rsa/list-crl
/usr/share/doc/openvpn/examples/easy-rsa/clean-all
/usr/share/doc/openvpn/examples/easy-rsa/openssl.cnf
/usr/share/doc/openvpn/examples/easy-rsa/sign-req
/usr/share/doc/openvpn/examples/easy-rsa/build-key-pkcs12
/usr/share/doc/openvpn/examples/easy-rsa/build-key-server
/usr/share/doc/openvpn/examples/easy-rsa/build-key-pass
/usr/share/doc/openvpn/examples/easy-rsa/revoke-full
/usr/share/doc/openvpn/examples/easy-rsa/.externals
/usr/share/doc/openvpn/examples/easy-rsa/make-crl
/usr/share/doc/openvpn/examples/easy-rsa/build-req-pass
/usr/share/doc/openvpn/examples/easy-rsa/build-key
/usr/share/doc/openvpn/examples/easy-rsa/build-req
/usr/share/doc/openvpn/examples/easy-rsa/build-ca
/usr/share/doc/openvpn/examples/easy-rsa/build-dh
/usr/share/doc/openvpn/examples/easy-rsa/build-inter
/usr/share/doc/openvpn/examples/easy-rsa/revoke-crt
/usr/share/doc/openvpn/examples/easy-rsa/README.gz
/usr/share/doc/openvpn/changelog.Debian.gz
/usr/share/doc/openvpn/changelog.gz
/usr/share/openvpn
/usr/share/openvpn/verify-cn
/usr/lib
/usr/lib/openvpn
/usr/lib/openvpn/openvpn-auth-pam.so
/usr/lib/openvpn/openvpn-down-root.so
/usr/include
/usr/include/openvpn
/usr/include/openvpn/openvpn-plugin.h

Il suffira de placer dans le répertoire /etc/openvpn/ autant de fichiers de configuration que l'on souhaitera démarrer de tunnels différents. Ces fichiers de configuration devront contenir les paramètres que nous avons jusqu'ici indiqué en ligne de commande.

Mise en service

Nous allons donc créer pour chaque extrémité de tunnel un fichier de configuration qui aboutira au même mode de fonctionnement que celui que nous avons vu en page précédente.

Pour aaron

(Le serveur)

Nous avions la ligne de commande :

openvpn --port 8147 --dev tun1 --ifconfig 192.168.25.1 192.168.25.2 --comp-lzo --verb 5 --tls-server --dh dh1024.pem --ca bts.eme-cacert.pem --cert aaron.bts.eme.pem --key aaron.bts.eme-key.pem --reneg-sec 21600

Ceci va nous donner, avec quelques modifications nécessaires :

port 8147
dev tun1
ifconfig 192.168.25.1 192.168.25.2
comp-lzo
verb 5
tls-server
dh /root/dh1024.pem
ca /root/bts.eme-cacert.pem
cert /root/aaron.bts.eme.pem
key /root/aaron.bts.eme-key.pem
reneg-sec 21600

Il sera sans doute intéressant de compléter quelque peu ce fichier, et probablement de déplacer les clés, certificats et autres ustenciles de sécurité ailleurs, avant de démarrer le tunnel.

Pour cyclope

(Le client)

Nous avions :

openvpn --remote 82.127.57.95  --port 8147 --dev tun1 --ifconfig 192.168.25.2 192.168.25.1 --comp-lzo --verb 5 --tls-client --ca bts.eme-cacert.pem --cert cyclope.maison.mrs.pem --key cyclope.maison.mrs-key.pem

Ce qui nous donne :

remote 82.127.57.95
port 8147
dev tun1
ifconfig 192.168.25.2 192.168.25.1
comp-lzo
verb 5 
tls-client
ca /root/bts.eme-cacert.pem
cert /root/cyclope.maison.mrs.pem
key /root/cyclope.maison.mrs-key.pem

Mêmes remarques.

Durcissement

Voyons un peu, avant de mettre en production, s'il est possible de prendre quelques mesures susceptibles de rendre notre tunnel plus solide, en termes de sécurité.

Interface d'écoute

Dans la configuration actuelle, openvpn va écouter sur toutes les interfaces de l'hôte. Ce n'est ni nécessaire ni même souhaitable, suivant la configuration de notre hôte. Le paramètre :

local <adresse_ip>

permettra de n'écouter que sur l'adresse spécifiée. Pratique uniquement en cas d'adresse IP fixe bien entendu.

Mode point à point

OpenVPN, dans ses versions 2.0 et supérieures, sait faire des tunnels multipoints. Si ce n'est pas ce que nous souhaitons, autant le spécifier, même si la documentation dit que le mode par défaut est le mode point à point :

mode p2p

Gérer les routes

Notre tunnel a pour vocation d'être placé entre deux routeurs, afin d'interconnecter deux réseaux privés distants. Nos routeurs (serveur comme client) ont besoin de connaitre la route vers le réseau distant à atteindre.

Supposons que aaron soit dans le réseau IP 192.168.1.0/24 et que cyclope soit dans 192.168.2.0/24, nous n'aurons pour aaron qu'à rajouter dans la configuration la ligne suivante :

route 192.168.2.0 255.255.255.0 192.168.25.2

Et pour cyclope :

route 192.168.1.0 255.255.255.0 192.168.25.1

root

Par défaut, OpenVPN va démarrer sous l'identité root, puis le service restera sous cette identité. Ce n'est sans doute pas une bonne idée et mieux vaudra choisir un utilisateur sans privilèges.

Les paramètres :

user nobody
group nogroup

Arrangeront ça. Mais attention ! Sitôt le tunnel négocié (par root), openvpn va passer en mode « daemon » sans aucun privilèges. En cas de rupture du tunnel, il y aura des problèmes, les clés n'étant lisibles que par root. De même pour la manipulation de tun. Il est donc conseillé d'ajouter les paramètres :

persistent-key
persistent-tun

de manière à ce que nobody ne soit pas amené à faire des choses qu'il n'a pas le droit de faire.

Authentification supplémentaire

La directive tls-auth ajoute une authentification de type HMAC 1) au dessus du canal TLS « to protect against DoS attacks », dit la documentation.

Nous utilisons une clé partagée, comme celle que nous avons réalisée plus tôt dans ce chapitre, et que nous avions appelée poétiquement shared.key.

Cette mesure présente quelques avantages, surtout s'il n'est pas possible de spécifier les adresses IP de chaque bout (les vraies, pas celles qui sont dans le tunnel). Nous avons vu que le client doit connaitre l'adresse IP du serveur, mais dans notre configuration le serveur ne connait pas celle du client et peut difficilement la connaitre si le client dispose d'une adresse IP dynamique, ce qui est souvent le cas.

La documentation dit :

The tls-auth directive adds an additional HMAC signature to all SSL/TLS handshake packets for integrity verification. Any UDP packet not bearing the correct HMAC signature can be dropped without further processing. The tls-auth HMAC signature provides an additional level of security above and beyond that provided by SSL/TLS. It can protect against:

  • DoS attacks or port flooding on the OpenVPN UDP port.
  • Port scanning to determine which server UDP ports are in a listening state.
  • Buffer overflow vulnerabilities in the SSL/TLS implementation.
  • SSL/TLS handshake initiations from unauthorized machines (while such handshakes would ultimately fail to authenticate, tls-auth can cut them off at a much earlier point).

Ca fait envie…

La méthode d'utilisation est assez simple :

Sur aaron (serveur)

tls-auth <chemin_vers_shared.key> 0

Sur betelgeuse (client)

tls-auth <chemin_vers_shared.key> 1

Configuration finale

Dans un cas simple d'un seul tunnel par hôte, nous n'avons rien à modifier dans /etc/default/openvpn. Nous avons juste à créer un fichier de configuration pour chacune des extrémités, que nous appellerons par exemple vpn.conf et à le mettre dans /etc/openvpn.

Nous allons créer un répertoire pour y ranger tous les ustensiles de sécurité (certificats, clés…), par exemple /etc/openvpncerts, y placer pour chaque extrémité :

  • le certificat de la CA ;
  • le certificat de l'hôte ;
  • la clé privée de l'hôte, dont nous prendrons soin de ne la rendre lisible que par root ;
  • le secret partagé (clé symétrique) lisible uniquement par root elle aussi.

Enfin, la version finale des fichiers de configuration :

Pour aaron

mode p2p
port 8147
dev tun1
user nobody
group nogroup
persist-key
persist-tun
ifconfig 192.168.25.1 192.168.25.2
tls-server
dh /etc/openvpncerts/dh1024.pem
ca /etc/openvpncerts/bts.eme-cacert.pem
cert /etc/openvpncerts/aaron.bts.eme.pem
key /etc/openvpncerts/aaron.bts.eme-key.pem
tls-auth /etc/openvpncerts/shared.key 0
reneg-sec 900
comp-lzo
verb 1
route 192.168.0.0 255.255.255.0 192.168.25.2

Pour cyclope

mode p2p
remote 82.127.57.95
port 8147
dev tun1
user nobody
group nogroup
persist-key
persist-tun
ifconfig 192.168.25.2 192.168.25.1
tls-client
ca /etc/openvpncerts/bts.eme-cacert.pem
cert /etc/openvpncerts/cyclope.maison.mrs.pem
key /etc/openvpncerts/cyclope.maison.mrs-key.pem
tls-auth /etc/openvpncerts/shared.key 1
reneg-sec 900
comp-lzo
verb 1
route 192.168.10.0 255.255.255.0 192.168.25.1

Cette configuration devrait donner satisfaction dans bien des cas.

Conclusion

Nous sommes très loin d'avoir vu tout ce qu'il est possible de faire avec OpenVPN. Sa documentation n'est pas toujours très claire, mais elle vous en apprendra sans doute encore beaucoup plus sur ses possibilités.

La solution vue ici permettra de relier simplement deux réseaux IP privés distants à travers l'internet, avec un niveau de sécurité convenable.

1)
keyed-hash message authentication code (code d'authentification d'une empreinte cryptographique de message avec clé).