Ca y est !!!
Le projet est enfin validé, vous avez le feu vert et un irrépressible envie d’ouvrir un vi et d’y coucher les premières balises HTML du document.
La partie Intranet peut enfin commencer ! Wiki par équipe, liberté sur le contenu des pages des utilisateurs,…
Oui, mais voilà, à force d’avoir cotoyé petits et grands désagréments, vous vous dîtes quand même que, niveau sécurité, ce serait bien d’encadrer la chose sans que ce ne soit contraignant pour vos utilisateurs. Et quand je dis « encadré », il faut comprendre tant au niveau serveur qu’au niveau client, et même entre les deux.
Pour tout ça, et pour tout le reste, il y a x509.
Petite parenthèse, ce sujet s’arque sur 2 articles. Dans un premier temps, nous allons d’abord créer et apprendre à gérer notre PKI, et ensuite nous verrons comment l’intégrer à l’architecture déjà en place.
Mais tout d’abord, commençons par le commencement.
Selon Wikipedia notre ami, X509 est avant tout une norme concernant les PKI, Public Key Infrastructures, qui amène une notion d’authentification et de cryptage. D’ailleurs, notre ami nous informe bien clairement des tenants et aboutissants concernant x509. Si vous préférez savoir ce qu’il vous attend, je vous conseille d’en lire quelques lignes à l’adresse http://fr.wikipedia.org/wiki/X.509. Le maître mot de l’histoire tient en 3 tokens : gestion de certificat.
C’est bien beau tout ça, me direz-vous, mais une norme ne fait que stipuler quelques règles, elle ne constitue pas en soi un moyen de les mettre en oeuvre.
Pour cela, nous nous confions à notre bon package OpenSSL, qui va se charger, à lui-seul -et avec vous aux commandes- de transformer toute cette poignée de concepts en opérationnel. Et oui, c’est aussi ça la magie des Unix-like…
Mais avant tout, quelques rappels sur le fonctionnement des certificats SSL.
Un certificat est un équivalent de pièce d’identité. Il a été validé par une Autorité de Certification (CA), est limité dans le temps et peut être renouvelé au terme de sa période de validité ou révoqué à n’importe quel moment. Il permet d’assurer l’identification et l’authentification de l’intervenant, ainsi que l’intégrité, la confidentialité, et la non répudiation des données échangées.
Il peut être applicable aux utilisateurs pour la gestion de leur profil, de leurs droits et de leur données, comme aux serveurs, afin de prouver leur légitimité.
Cet ensemble hiérarchique est appelé une PKI. Et, avec le concours d’un serveur Linux et de notre OpenSSL, nous allons mettre tout cela d’aplomb. C’est parti !
Tout d’abord, nous allons installer sur notre serveur le package à tout faire, openssl, et puis d’autres, plus auxiliaires, ca-certificates, et la librairie SSL, libssl. Vous connaissez vos lignes. Que ce soit apt-get, yum, dpkg, rpm, ou autre, tous les moyens sont bons.
Une fois les packages installés, nous allons créer notre CA (Certificate Autority). Pour cela, je vous conseille tout de même de créer un répertoire qui contiendra les fichiers, mais de manière organisée.
kbux@mucti:~$ mkdir -p ~/certs/signedcerts && mkdir ~/certs/private; kbux@mucti:~$ ll certs/total 8 drwxr-xr-x 2 kbux kbux 4096 2009-11-17 14:41 private drwxr-xr-x 2 kbux kbux 4096 2009-11-17 14:41 signedcerts kbux@mucti:~$ cd certs/ kbux@mucti:~$ echo '01' > serial && touch index.txt;
Il faut ensuite, bien que ce ne soit pas une obligation, créer et paramétrer un fichier qui se chargera de customiser nos configurations par rapport à celles mentionnées dans le fichier de configuration par défaut d’openssl -qui, sachons-le en cas de besoin, est /etc/ssl/openssl.cnf-.
Ne vous privez pas de vi, ici le chemin absolu du fichier de conf est /home/kbux/certs/openssl.cnf -paramétrez le vôtre selon vos besoins- :
# Fichier de configuration customisé # # [ ca ] default_ca = local_ca # # # Repertoires par defaut concernant la generation des certificats # [ local_ca ] dir = /home/kbux/certs certificate = $dir/cacert.pem database = $dir/index.txt new_certs_dir = $dir/signedcerts private_key = $dir/private/cacertkey.pem serial = $dir/serial crl = $dir/crl.pem # # # Politique par défaut d'expiration et d'encryption des certificats # default_crl_days = 365 default_days = 1825 default_md = md5 # policy = local_ca_policy x509_extensions = local_ca_extensions # # # Politique par defaut a appliquer lors de la generation des server certificates. # Les champs mentionnes doivent imperativement apparaitre dans le certificat server # [ local_ca_policy ] commonName = supplied stateOrProvinceName = supplied countryName = supplied emailAddress = supplied organizationName = supplied organizationalUnitName = supplied # # # x509 extensions pour la generation des server certificates. # [ local_ca_extensions ] subjectAltName = DNS:k-tux.com basicConstraints = CA:false nsCertType = server # # # Politique de generation par defaut du Root certificate # [ req ] default_bits = 2048 default_keyfile = /home/kbux/certs/private/cacertkey.pem default_md = md5 # prompt = no distinguished_name = root_ca_distinguished_name x509_extensions = root_ca_extensions # # # Root Certificate Authority distinguished name. # # [ root_ca_distinguished_name ] commonName = K-TUX CA stateOrProvinceName = FR countryName = FR emailAddress = CA@k-tux.com organizationName = K-TUX organizationalUnitName = K-TUX # [ root_ca_extensions ] basicConstraints = CA:true
On exporte la configuration -à savoir que, pour le shell courant, on lui stipule expressement de ne pas recourir au fichier de configuration openssl par défaut mais au nôtre, tout juste rempli tout comme il faut-.
kbux@mucti:~$ export OPENSSL_CONF=/home/kbux/certs/openssl.cnf
On crée notre CA, à proprement parler, qui se résume à une requête x509 autosignée.
kbux@mucti:~$ openssl req -x509 -newkey rsa:2048 -out cacert.pem -keyout private/cacertkey.pem -days 1825 Generating a 2048 bit RSA private key ..................................+++ ..................................+++ writing new private key to 'private/cacertkey.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- kbux@mucti:~$ ll -R .: total 16 -rw-r--r-- 1 kbux kbux 1493 2009-11-17 15:01 cacert.pem -rw-r--r-- 1 kbux kbux 0 2009-11-17 14:45 index.txt drwxr-xr-x 2 kbux kbux 4096 2009-11-17 14:59 private -rw-r--r-- 1 kbux kbux 3 2009-11-17 14:45 serial drwxr-xr-x 2 kbux kbux 4096 2009-11-17 14:41 signedcerts ./private: total 4 -rw-r--r-- 1 kbux kbux 1743 2009-11-17 15:01 cacertkey.pem ./signedcerts: total 0
Bref, on se retrouve avec un cacert.pem, et un cacertkey.pem. Soit dit en passant, cacert.pem est notre certificat et cacertkey.pem esr notre clé privée, clé qui a été encryptée par la passphrase que nous avons été amené à définir. D’autre part, nous pouvons constater que serial et index n’ont pas évolué.
Pour vérifier que tout est bon, on peut jouer avec :
kbux@mucti:~/certs# openssl verify cacert.pem cacert.pem: /C=FR/ST=SomeState/L=Somewhere/O=Internet Widgits Pty Ltd/CN=CA K-TUX error 18 at 0 depth lookup:self signed certificate OK
Ici, tout est OK, sauf le fait justement que le certificat soit auto-signé (ce qui est normal pour un CA). Un autre moyen, plus bavard, est de lancer la commande :
kbux@mucti:~/certs# openssl x509 -in cacert.pem -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: c9:[...]:ea Signature Algorithm: sha1WithRSAEncryption Issuer: C=FR, ST=SomeState, L=Somewhere, O=Internet Widgits Pty Ltd, CN=K-TUX Validity Not Before: Nov 17 14:01:11 2009 GMT Not After : Nov 16 14:01:11 2014 GMT Subject: C=FR, ST=SomeState, L=Somewhere, O=Internet Widgits Pty Ltd, CN=CA K-TUX Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): 00:[...]:db Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: C0:A9:8B:C3:FD:50:3B:39:F9:A5:C8:CA:31:34:A0:48:70:23:E0:38 X509v3 Authority Key Identifier: keyid:C0:A9:8B:C3:FD:50:3B:39:F9:A5:C8:CA:31:34:A0:48:70:23:E0:38 DirName:/C=FR/ST=SomeState/L=Somewhere/O=Internet Widgits Pty Ltd/CN=K-TUX serial:C9:77:04:D2:CF:33:59:EA X509v3 Basic Constraints: CA:TRUE Signature Algorithm: sha1WithRSAEncryption 26:[...]:b3
ATTENTION !!! Force est de rappeler que dans ABSOLUMENT aucun cas de figure vous n’êtes amené(e) à communiquer les clés privées des entités sensibles, surtout celle du CA, qui doit être plus précieuse à vos yeux que vos yeux eux-mêmes !
Nous allons maintenant générer un certificat serveur et le signer avec notre Autorité de Certification.
L’opération se fait en 2 temps : d’abord, on génère la requête et ensuite on la valide avec le CA.
La génération se fait ainsi :
kbux@mucti:~/certs$ openssl req -newkey rsa:2048 -keyout private/server.key -out server-req.pem Generating a 2048 bit RSA private key ............+++ ............+++ writing new private key to 'private/server.key' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: phrase is too short, needs to be at least 4 chars Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- kbux@mucti:~/certs$ ll total 20 -rw-r--r-- 1 kbux kbux 1493 2009-11-17 15:01 cacert.pem -rw-r--r-- 1 kbux kbux 0 2009-11-17 14:45 index.txt drwxr-xr-x 2 kbux kbux 4096 2009-11-17 15:54 private -rw-r--r-- 1 kbux kbux 3 2009-11-17 14:45 serial drwxr-xr-x 2 kbux kbux 4096 2009-11-17 14:41 signedcerts -rw-r--r-- 1 kbux kbux 720 2009-11-17 15:55 tmpreq.pem
Le verify nous indique bien que nous avons fait les choses à moitié.
kbux@mucti:~/certs$ openssl verify -CAfile cacert.pem server-req.pem unable to load certificate 5083:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:647:Expecting: TRUSTED CERTIFICATE
A présent, validons-le.
kbux@mucti:~/certs$ openssl ca -in serveur-req.pem -days 365 -out signedcerts/serveur-cert.pem -cert cacert.pem -keyfile private/cacertkey.pem Using configuration from /home/kbux/certs/openssl.cnf Enter pass phrase for private/cacertkey.pem: Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows commonName :PRINTABLE:'K-TUX CA' stateOrProvinceName :PRINTABLE:'FR' countryName :PRINTABLE:'FR' emailAddress :IA5STRING:'CA@k-tux.com' organizationName :PRINTABLE:'K-TUX' organizationalUnitName:PRINTABLE:'K-TUX' Certificate is to be certified until Nov 17 21:40:22 2010 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
Et vérifions un peu ce que nous raconte OpenSSL :
kbux@mucti:~/certs$ openssl verify -CAfile cacert.pem signedcerts/serveur-cert.pem signedcerts/serveur-cert.pem: OK kbux@mucti:~/certs$ openssl x509 -in signedcerts/serveur-cert.pem -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: 2 (0x2) Signature Algorithm: md5WithRSAEncryption Issuer: C=FR, ST=SomeState, L=Somewhere, O=Internet Widgits Pty Ltd, CN=K-TUX Validity Not Before: Nov 17 21:40:22 2009 GMT Not After : Nov 17 21:40:22 2010 GMT Subject: CN=K-TUX CA, ST=FR, C=FR/emailAddress=CA@k-tux.com, O=K-TUX, OU=K-TUX Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (2048 bit) Modulus (2048 bit): 00:[...]:63 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Alternative Name: DNS:k-tux.com X509v3 Basic Constraints: CA:FALSE Netscape Cert Type: SSL Server Signature Algorithm: md5WithRSAEncryption 04:[...]:3d
Voila une affaire qui marche ! Grâce à notre fichier de conf, OpenSSL a rempli tout seul comme un grand les champs paramétrés. Dans le cas où nous n’avions pas de fichier de configuration customisé ou que nous n’avions pas prérempli ces champs, il nous aurait inondé de questions.
Il nous reste à générer l’équivalent pour chacun de nos utilisateurs, à la différence que si ceux-ci sont sous Mac OS X ou sous Windows, il vous faudra rajouter une conversion de type de fichier de pem à pkcs12. La méthode est la même que celle utilisée pour générer le certificat serveur-cert.pem, avec un petit plus.
kbux@mucti:~/certs$ openssl req -newkey rsa:2048 -keyout private/kbux.key -out kbux-req.pem kbux@mucti:~/certs$ openssl ca -in kbux-req.pem -days 365 -out signedcerts/kbux-cert.pem -cert cacert.pem -keyfile private/cacertkey.pem kbux@mucti:~/certs$ openssl pkcs12 -export -inkey private/kbux.key -in signedcerts/kbux-cert.pem -name K-TUXUser -certfile cacert.pem -out signedcerts/kbux-cert.p12
Il est maintenant possible d’intégrer -ou de faire intégrer, il n’y a pas de raison !- le certificat utilisateur dans son propre navigateur. C’est d’ailleurs un important prérequis pour pouvoir faire fonctionner l’authentification x509.
Bon à savoir, avant que l’on ne s’éloigne trop de l’aspect administration de PKI, la partie révocation d’un certificat passe par la création d’une Certificate Revokation List (une liste de révocation de certificat), dont le chemin par défaut est stipulé dans le fichier de configuration d’OpenSSL -chemin que nous avons pris soin de redéfinir dans notre fichier de configuration customisé.
Cette liste contient les numéros de série des certificats révoqués pour une Autorité de Certification. Comme cette liste n’existe pas par défaut, il nous faut dans un premier temps la créer avec la commande :
kbux@mucti:~/certs$ openssl ca -gencrl -keyfile private/cacertkey.pem -cert cacert.pem -out crl.pem Enter pass phrase for private/cacertkey.pem:
Si vous avez la curiosité de catter la liste en question, vous aurez un truc du genre :
kbux@mucti:~/certs$ cat crl.pem -----BEGIN X509 CRL----- MIIBrjCBlzANBgkqhkiG9w0BAQQFADBoMQswCQYDVQQGEwJGUjESMBAGA1UECBMJ U29tZVN0YXRlMRIwEAYDVQQHEwlTb21ld2hlcmUxITAfBgNVBAoTGEludGVybmV0 IFdpZGdpdHMgUHR5IEx0ZDEOMAwGA1UEAxMFSy1UVVgXDTA5MTEyMDA3MzgyOVoX muTn6MxcVhmw14o+bAfLPP9exIOTi7X+AISakYKCe/up2nuP5rY8PVS3sgcoYJpm kwTE0NQQs3QQoGQzeTVnCR8R6wlz0HlYx45eEPaV5gj8RLLrPnUV3lJlhhbK10J4 TnNslWQctp+9DuRaC/8bm1gnv/T0i5vGbYRVX82wQMGLcyGVx+yJ7RrnAx5VxBtM odI= -----END X509 CRL-----
Ensuite, pour révoquer -par exemple notre certificat utilisateur, kbux-cert.pem-, il vous suffit de faire :
kbux@mucti:~/certs$ openssl ca -revoke signedcerts/kbux-cert.pem -keyfile private/cacertkey.pem -cert cacert.pem Using configuration from /home/kbux/certs/openssl.cnf Enter pass phrase for private/cacertkey.pem: Revoking Certificate 03. Data Base Updated
Et enfin, regénérer et consulter le contenu de cette CRL. Et là vous pouvez saisir la véritable nature de la CRL : une version lisible et exploitable des certificats révoqués, uniquement vouée à un objectif d’information et de publication.
kbux@mucti:~/certs$ openssl ca -gencrl -keyfile cacert.pem -cert cacert.pem -out crl.pem kbux@mucti:~/certs$ openssl crl -in crl.pem -noout -text Certificate Revocation List (CRL): Version 1 (0x0) Signature Algorithm: md5WithRSAEncryption Issuer: /C=FR/ST=SomeState/L=Somewhere/O=Internet Widgits Pty Ltd/CN=K-TUX Last Update: Nov 20 08:01:45 2009 GMT Next Update: Nov 20 08:01:45 2010 GMT Revoked Certificates: Serial Number: 03 Revocation Date: Nov 20 07:41:11 2009 GMT Signature Algorithm: md5WithRSAEncryption 52:[...]:37
Voila pour ce qui est de la PKI.
Pour ceux que ça connait, ce n’est quand même pas de la tarte à maintenir, entre les renouvellements, les « perdu passphrase », les révocations, on a de quoi se tenir chaud l’hiver, près des serveurs.
A savoir tout de même qu’OpenSSL vous permet de tester -et on en fera un usage bien massif- les discussions entre serveurs et clients via les certificats.
Ce point-là sera d’ailleur expliqué, mis en place et exploité dans un prochain post. Et oui, l’informatique c’est comme tout. Faut d’abord laisser infuser !
Sur ce, je vous laisse méditer et vous souhaite un bon wiikend !
Bienvenue sur ces pages qui constituent une petite parenthèse de sujets informatiques pour ceux qui n'ont pas la science infuse et qui ont, eux-aussi, besoin parfois de reminders. Avec l'avantage de ne pas être constitué d'un tas de post-it !
2 réponses à OpenSSL : création et mise en place d’une PKI
Visiteur-JP
5 décembre 2009 à 8 h 02
article tres interresant et complet,
un autre guide sur le net, un pe mois detaille.
http://www.codealias.info/technotes/manipulating_pki_certificates
K-TUX
7 décembre 2009 à 17 h 43
Merci !
Je vais bouquiner ton lien, histoire de voir ce que je n’ai pas mis dans ce post, en tout cas j’apprécie ton commentaire !
A + !