====== 4. PKI pour OpenVPN ====== {{tag>ssl openssl crypto openvpn}} //par julien - dec. 2005// ===== 1 - Introduction ===== Quand on parle de certificats X.509, de SSL et des PKI en général, on pense surtout aux applications WEB. Mais il est un domaine dans lequel l'installation d'une PKI prend tout son sens: Les VPN/SSL ! L'idée est q'une autoritée centrale donne ou reprend l'accès a un membre d'un réseau de serveurs VPN répartis sur de nombreux points géographique et reliés entre eux par l'Internet (réseau non sûr). N'abordez cet article que si vous avez bien compris le principe des PKI et du protocole TLS, sinon vous allez pédaler dans la choucroute ! Pour ce qui est du VPN, je vais passer succintement dessus mais les docs sont nombreuses sur le net. So, here we go !!!! ===== 2 - PKI pour la Gestion des Accès ===== L'interet d'utiliser une PKI dans un réseau de serveurs VPN est que c'est elle qui vas émettre les certificats pour tous les serveurs et clients du réseau. Ainsi, la condition pour qu'un client OpenVPN puisse se connecter a un serveur, ou que deux serveurs se connecte entre eux, est que leurs certs respectifs aient tout les deux été émis par l'autorité. Deux entités qui possédent des certificats émis par des autorités différentes ne pourront pas communiquer. Et comme c'est nous qui gérons l'autorité, que sa clé est privée est bien protégée, nous avons la main mise sur tous les accès au réseau VPN. Donc, chaque fois qu'un nouveau client ou un nouveau serveur veut avoir accès à un serveur VPN, il faut aller sur l'autorité de certificat et générer un nouveau certificat client ou serveur, comme vu dans le chapitre précédent. Nous verrons dans le dernier chapitre de ce dossier comment gérer les révocations de certificats, et donc d'accès au réseau. **/!\ ATTENTION /!\** Si cette technique permet limiter de l'accès aux membres de la PKI, elle ne permet pas de limiter l'accès d'un client à un serveur spécifique. TOUT LES CLIENTS PEUVENT SE CONNECTER A TOUS LES SERVEURS !!! Heureusement, OpenVPN résoud ce problème: chaque serveur posséde sa propre clé, le client souhaitant se connecter à un serveur doit donc être en possession de cette clé (en plus des indispensables certificats). ===== 3 - Base du VPN/SSL ===== L'idée générale est de permettre à deux réseaux de communiquer de façon sécurisée au travers d'un troisiéme réseau (typiquement, l'Internet) qui lui n'est pas sécu. Quand on dit communiquer, c'est principalement pour les couches basses du modéle OSI. Dans une interconnection classique de réseaux, vous ne pouvez pas, par exemple, pinguer les machines du LAN distant. Et bien le VPN permet celà. Par exemple, vous avez cette topologie: +----------+ {~~~~~~~~~~~~~~} +----------+ | réseau A |===========>{ INTERNET }===============>| réseau B | +----------+ ~~~~~~~~~~~~~~ +----------+ Vos clients sont sous Windows, vos deux réseaux utilisent le même workgroup. Vous êtes d'accord que vous ne pouvez pas voir les machines du réseau B dans l'application "voisinnage réseau" des machines du réseau A ? Le VPN nous permet de le faire, comme celà: +----------+ +---+ {~~~~~~~~~~~~~~} +---+ +----------+ | réseau A |=|SRV|=====>{ INTERNET }=========|SRV|=>| réseau B | +----------+ |VPN| ~~~~~~~~~~~~~~ |VPN| +----------+ +---+ +---+ Les serveurs VPN sont connectés ensemble et encapsule les paquets IP dans des trames spécifiques pour se les envoyer et les retransmettre sur le LAN de destination. Ainsi, vous avez l'impression que A et B sont un seul et même LAN. Voici comment se passe l'encapsulation: +-------+---------------+ |header | DATA | { L } | TCP | | { A } +-------+---------------+ { N } || \/ +-------+-----------------------+ |header | DATA | | IP | | +-------+-----------------------+ || \/ { S } +-------+-------------------------------+ { E } |header | DATA | { R V } | TLS | | { V P } +-------+-------------------------------+ { E N } || { U } \/ { R } +-------+---------------------------------------+ |header | DATA | | UDP | | +-------+---------------------------------------+ || \/ #################### ##COMPRESSION GZIP## #################### || \/ +-------+-----------------------+ |header | DATA | | PPP | | +-------+-----------------------+ || // ~~~~~~~~~~~~~~~~ <<==== {{ INTERNET }} ~~~~~~~~~~~~~~~~ Les paquets IP forgés par les machines du réseau sont reprise par le serveur VPN et ré-encapsulées dans TLS puis dans des paquets UDP. On compresse le tout avec gzip et le colle le résultat dans une trame PPP pour l'envoyer sur le net au serveur VPN de destination. Ici j'ai pris l'exemple de deux serveurs qui relient entre eux deux réseaux mais ca marche de la même facon entre un pc client qui se connecte à un serveur. **Le périphérique TAP** Pour pouvoir ré-encapsuler les paquets qu'il transmet, le serveur VPN a besoin d'une interface réseau virtuelle appelée TAP. Il s'agit d'un pilote du kernel qui récupére les paquets reçut sur eth0, les modifie et les renvoie à eth0 pour transmission physique. Le périphérique doit donc exister dans la configuration du noyau. De plus, TAP et ETH doivent être bridgé pour pouvoir s'échanger des trames directement au niveau 2 du modéle OSI (802.3). Les clients windows (oui ils sont généralement sous windows, hélas) doivent également posséder ce pilote. Ce dernier étant inclus dans le logiciel client OpenVPN pour windows, donc pas de soucis ;) Voyons tout celà plus en détail. ===== 4 - Déploiement ===== //important: je suppose dans cette partie que vous êtes capable de changer des adresses IP, des noms et des chemins dans les fichiers de configuration que je présente plus bas alors ne copiez pas bêtement ce qu'il y a ci-dessous :) // Pour mettre en place un serveur VPN, nous avons besoin de: - un certificat serveur (et sa clé privée) signé par l'autorité - le certificat signé de l'autorité (chap. 3 => ca.pem) - les packages openvpn, openssl et bridge-utils - un noyau compilé avec le support TUN (dans Device Drivers) # Network device support # (...) CONFIG_TUN=y Avec tout celà de prêt sur votre serveur, vous pouvez attaquer la configuration du VPN. **OpenVPN** OpenVPN crée un répertoire dans /etc/openvpn. Nous allons placer les fichiers de configuration dans /etc/openvpn/etc et les fichiers de log dans /etc/openvpn/log. Puis, à l'exécution du daemon, nous allons chrooter OpenVPN dans /etc/openvpn. Si ils n'existent pas, créer un groupe "nogroup" et un utilisateur "nobody" membre de "nogroup". Modifiez le script de démarrage de nobody dans /etc/passwd pour qu'il pointe vers /dev/null. Placez les certificats du serveur et du CA dans /etc/openvpn/etc/certs/ et modifiez les droits sur la clé privée du serveur (400 pour nobody). Editez maintenant le fichier /etc/openvpn/etc/openvpn.conf: ################################################# #### fichier de configuration du serveur VPN #### ################################################# #port en écoute port 1194 #device à utiliser dev tap #clé diffie-hellman pour la négociation dh dh1024.pem #certificat de l'autorité racine ca ./certs/ca.pem #certificat signé du serveur cert ./certs/srv-vpn-signed-cert.pem #clé privée du serveur key ./certs/srv-vpn.key #clé de connection #c'est cette clé qui identifie le serveur #tout client qui veux se connecter doit la posséder #donc pensez à la récupérer dans un endroit sûr tls-auth ta-srv-vpn.key 0 #la liste de révocation de certificats sera étudié au #prochain chapitre #crl-verify /etc/crl_authority.pem #paramétres IP, netmask, début et fin de plage DHCP #à remettre sur une seule ligne server-bridge 192.168.1.55 255.255.255.0 192.168.1.100 192.168.1.150 #paramétres du serveur, RTFM ;) client-to-client duplicate-cn mtu-test mode server tun-mtu 1500 tun-mtu-extra 32 mssfix 1450 ping 10 ping-restart 120 persist-tun persist-key push "ping 10" push "ping-restart 60" push "dhcp-option DOMAIN linuxwall.info" comp-lzo status-version 2 ifconfig-pool-persist ipp.txt cipher BF-CBC max-clients 50 user nobody group nogroup chroot /etc/openvpn status /etc/openvpn/log/status.log log-append /etc/openvpn/log/openvpn.log verb 4 mute 10 Maintenant, on crée la clé diffie-hellman utilisée pour la négociation: #openssl dhparam -out /etc/openvpn/etc/dh1024.pem 1024 et la clé TA qui sera utilisée pour chiffrer les challenges (des hashs SHA-1) qui permettrons aux entités clients/serveur de s'authentifier entre eux: #openvpn --genkey --secret ta-srv-vpn.key #mv ta-srv-vpn.key /etc/openvpn/etc/ Cette clé, vous devez la récupérer car elle devra être présente sur chacun des clients VPN. MAIS ! Ne la diffusez pas n'importe comment ! Elle est presque aussi importante que la clé privée du serveur. Pensez à changer les droits sur ces deux fichiers, le plus simple est de lancer une commande pour tous les rep d'un seul coup: #chown -R nobody:nogroup /etc/openvpn //en faisant des changements de droits récursifs vous pouvez changer les droits sur la clé privée du serveur sans vous en rendre compte... pensez bien à vérifiez ces droits réguliérement// **Bridge des interfaces** Si vous voulez que vos clients VPN accède à tout votre réseau local, l'interface ethernet du serveur VPN doit être bridgée avec l'interface TAP. Pour celà, on utilise les outils du package bridge-utils pour créer deux scripts: l'un pour démarrer le bridge, l'autre pour le stopper: #Script bridge-start à placer dans /etc/init.d #et a linker dans les répertoires de runlevel #! /bin/sh brctl addbr br0 brctl addif br0 eth0 brctl addif br0 tap0 ifconfig tap0 0.0.0.0 promisc up ifconfig eth0 0.0.0.0 promisc up ifconfig br0 192.168.1.55 route add default gw 192.168.1.1 #Script bridge-stop pour casser le bridge et #relancer les interfaces correctement #! /bin/sh ifconfig br0 down brctl delbr br0 ifconfig eth0 192.168.1.55 Dans ma config, ces scripts sont présents dans /etc/init.d/bridge-start et /etc/init.d/bridge-stop Le fait de bridger une interface ne géne pas l'utilisation normale du réseau, celà rajoute seulement la communication tap0 <-> eth0. Un détail important: il faut lancer OpenVPN AVANT le bridge. C'est facile à gérer au lancement du système (il suffit de mettre bridge-start aprés openvpn dans le rc.d qui va bien), par contre quand on relance le daemon OpenVPN pendant le fonctionnement, c'est quelque chose que l'on oublie facilement. Pour palier à ce petit soucis, il faut éditer le script openvpn dans /etc/init.d. Voici le script que j'utilise sur mes Debian sarge: ########################################### ## script de lancement du daemon openvpn ## ########################################### #!/bin/bash ## ## Variables locales, vérifez les chemins ## DAEMON=/usr/sbin/openvpn CONF=/etc/openvpn/etc/openvpn.conf CONFIG_DIR=/etc/openvpn/etc DAEMONARG="--daemon openvpn" PIDFILE=/var/run/openvpn.pid BRIDGESTART=/etc/init.d/bridge-start BRIDGESTOP=/etc/init.d/bridge-stop test -x $DAEMON || exit 0 test -d $CONFIG_DIR || exit 0 case "$1" in start) echo -n "Starting openvpn : " $DAEMON --writepid $PIDFILE --config $CONF $DAEMONARG \ --cd $CONFIG_DIR --chroot /etc/openvpn echo "Done." ;; stop) echo -n "Stopping openvpn : " PID=`cat $PIDFILE` kill $PID rm $PIDFILE echo "Done." ;; ## ##Si on veux relancer le daemon openvpn, on commence par ##stopper le bridge, puis on relance openvpn et enfin ##on relance le bridge ## restart) echo "Restarting openvpn : " echo "" sh /etc/init.d/bridge-stop sh $0 stop sh $0 start sh /etc/init.d/bridge-start echo "" echo "Openvpn has restarted." echo "verifiez la configuration de br0" echo "" /sbin/ifconfig |head -n 7 ;; *) echo "Usage: $0 {start|stop|restart}" >&2 exit 1 ;; esac Voilà, avec tout ça normalement ça doit fonctionner... Lancez le daemon puis lancez le bridge. Si ca plante, vérifiez les logs dans /etc/openvpn/log/openvpn.log (en général, les problèmes viennent des droits sur les fichiers, de fichiers absents et de mauvaise config). Si le daemon est lancé correctement, vous avez un port 1194 qui écoute les connections UDP. Attention, c'est important ! Je me suis fait avoir en forwardant sur ma passerelle le port 1194 vers le serveur VPN et pourtant j'arrivais pas a le joindre... tout simplement parce que je forwarder en TCP et non en UDP ! Mefiez vous ;) **Configuration du Client** les clients avec lesquels j'ai travaillé sont sous windows mais ca ne change rien au niveau de la configuration. Un client à besoin des fichiers suivants: - certificat signé et clé privée du client - certificat signé de l'autorité - clé ta-srv-vpn.key générée par le serveur - fichier de configuration La génération des certificats clients est abordée au chapitre précédent. Je n'ai pas encore testé sous Linux, mais un fichier de conf windows ressemble à ça: dev tap proto udp remote [ADRESSE_IP_DU_SERVEUR_VPN] 1194 tls-client ca ca.pem cert client-signed-cert.pem key client.key tls-auth ta-srv-vpn.key 1 resolv-retry infinite nobind persist-key persist-tun ns-cert-type server cipher BF-CBC comp-lzo pull ping 20 verb 2 mute 5 Bon... je m'étend pas dessus c'est sensiblement similaire à la config du serveur. Juste un détail sur la ligne "tls-auth" qui donne le nom de la clé TA: sur le serveur, on a un "0" à la fin de cette ligne pour préciser que c'est la clé d'un serveur. sur le client, on a cette même ligne mais avec un "1" à la fin pour préciser que c'est un client qui l'utilise. Voilà, pour le reste => RTFM Il faut également installer le logiciel qui va bien. La version windows est accessible à l'adresse : http://openvpn.se Lors de la connection, le client demande le mot de passe pour accèder à la clé privée puis il établit la connection TLS, établit la négociation avec le serveur VPN,configure l'interface locale avec l'adresse IP reçu du serveur et ferme la fenêtre. Si tout se passe bien, vous devez pouvoir pinger depuis le client les machines du réseau de destination. ===== 5 - Conclusion ===== Nous avons mis en place une architecture VPN complétement basée sur la PKI étudiée au chapitre précédent. J'ai volontairement zappé de nombreux points de détails sur la config du VPN car le point important de ce chapitre est l'utilisation de ces certificats pour gérer des accès à un système. Dans une configuration comme celle là, vous pouvez créer de nouveau utilisateurs trés facilement via l'autorité de certificats. Mais ce qui est vraiment puissant et interessant, c'est la révocation de ces utilisateurs qui est complétement centralisée sur l'autorité de certificats. C'est ce que nous allons étudier au chapitre suivant: comment révoquer un certificat ? Quelles les techniques qui le permettent ? Comment propager une révocation ? Pour le savoir, lisez le prochain (et dernier) chapitre ;) ~~DISCUSSION~~