Utiliser les certificats SSL avec Ubuntu 10

Pour éviter que le dialogue entre les serveurs LDAP puisse être capté, et notamment lors des phases de changement de mot de passe, il est conseillé de crypter les échanges entre le serveur maître et les serveurs esclaves.

Pour cela, nous allons mettre en place la couche TLS en utilisant OpenSSL.

Documentation

Quelques liens qui m’ont permis de mettre au point la configuration :

http://www-lor.int-evry.fr/ michel/LDAP/SASL/TLS-SSL.html

mais également sur la documentation officielle openldap :

http://www.openldap.org/doc/admin24/

Et sur le cryptage SSL :

http://www.commentcamarche.net/contents/crypto/certificat.php3

http://fr.wikipedia.org/wiki/X.509

http://fr.wikipedia.org/wiki/Certificat_électronique

http://fr.wikipedia.org/wiki/Cryptographie_asymétrique

http://www.frpki.org/index.php?/openssl_base.html

Rappel sur le cryptage SSL

Le cryptage SSL (remplacé depuis par TLS) est basé sur l’utilisation du cryptage asymétrique. Son principe est le suivant.

Deux clés sont générées. Un message crypté avec une des deux clés peut être déchiffré avec l’autre. Il suffit de transmettre une des deux clés à son correspondant pour que celui-ci puisse, non seulement décrypter le message que nous venons de lui envoyer, mais également crypter un message que nous pourrons décrypter. Dans la pratique, une seule des deux clés est transmise à l’ensemble des correspondants, la clé publique. L’autre clé est conservée précieusement et ne doit jamais être transmise, la clé privée.

Dans un échange, il est important de pouvoir s’assurer que le correspondant est bien celui qu’il dit être. Pour cela, la clé publique est signée par une autorité reconnue, en qui on peut faire confiance : le tiers de confiance. La clé publique est ainsi transmise à l’intérieur d’un certificat, qui contient non seulement la clé publique, mais également le nom du serveur à laquelle elle se réfère (pour une clé correspondant à un serveur), le nom de l’autorité qui a signé le certificat et la signature du certificat.

La signature du certificat fonctionne ainsi : l’ensemble des informations du certificat est haché (compressé en une empreinte unique). Cette empreinte est cryptée avec la clé privée du certificateur, et est ensuite rajoutée dans le certificat.

Pour s’assurer de la validité de la clé publique, il faut donc extraire l’empreinte cryptée, la déchiffrer avec la clé publique du certificateur, puis la comparer avec l’empreinte que nous pouvons calculer.

L’ensemble de ces mécanismes sont décrits dans une norme, la norme X.509.

Pour résumer :

  • une clé privée, associée à une clé publique, est créée sur chaque machine. Elle ne doit jamais être transmis à quiconque ;
  • la clé publique est intégrée dans une demande de signature, envoyée à l’autorité de certification ;
  • L’autorité de certification crée le certificat à partir de la clé publique et des informations transmises lors de la demande, puis calcule l’empreinte du certificat, et crypte cette empreinte avec sa clé privée. Cette empreinte cryptée est rajoutée au certificat, qui est transmis à l’ensemble des personnes ou machines qui en ont besoin ;
  • l’autorité de certification transmet sa clé publique (en général appelée CAkey), qui va servir à décrypter la signature du certificat.

Nous avons donc besoin de quatre objets :

  • la clé privée de l’autorité racine, qui va être utilisée pour signer les clés publiques des serveurs ;
  • le certificat de l’autorité de certification, qui contient la clé publique de l’autorité racine, et qui va être utilisée pour décrypter les signatures des certificats ;
  • la clé privée du serveur, qui est unique et conservée uniquement sur le serveur ;
  • le certificat du serveur, qui comprend la clé publique, et qui est signé par l’autorité racine.

Générer les certificats

Deux possibilités s’offrent à nous : soit nous signons nous-mêmes nos clés publiques, soit nous faisons appel à une autorité de certification pour réaliser cette signature.

Pour commencer, nous allons signer nous-mêmes nos clés publiques. C’est la seule solution si vous ne disposez pas d’une autorité de certification.

Créer le certificat racine

Créons la clé privée de l’autorité de certification racine :

openssl req -new -x509 -keyout cacert.pem -out  cacert.pem -days 3650

Lors de la procédure, le programme demande un mot de passe : c’est celui qui devra être fourni à chaque demande de signature d’un certificat.

Nous allons maintenant générer le certificat de l’autorité de certification, qui va être utilisé pour valider les certificats des serveurs ; ce certificat contient donc la clé publique de l’autorité de certification :

openssl x509 -in cacert.pem -out cacert.crt

Créer la clé privée

Nous allons générer la clé privée du serveur :

openssl genrsa  -out server.key 1024

Puis nous la protégeons pour éviter que quiconque, à part root ou les process autorisés, puissent y accéder :

chmod 600 server.key

Créer la requête de certificat qui sera validée par l’autorité racine

A partir de la clé privée, nous allons préparer une requête qui sera transmise à l’autorité de certification. Cette requête contient non seulement la clé publique, mais également un certain nombre d’informations, dont le nom du serveur.

openssl req -new -key server.key -out server.csr

Une fois la commande lancée, un certain nombre de champs vont devoir être renseignés. Les champs laissés à vide doivent comporter un point (.).

Country Name (2 letter code) [AU]:FR 
State or Province Name (full name) [Some-State]:. 
Locality Name (eg, city) []:. 
Organization Name (eg, company) [Internet Widgits Pty Ltd]: MA SOCIETE
Organizational Unit Name (eg, section) []: . 
Common Name (eg, YOUR name) []:girondetest2
Email Address []: .
Please enter the following 'extra' attributes 
to be sent with your certificate request 
A challenge password []: 
An optional company name []:

Les deux derniers champs sont laissés à vide.

Attention : le Common Name doit impérativement correspondre au nom du serveur qui va être utilisé dans les requêtes. Si vous utilisez un serveur DNS, vous devrez donner le nom complet. Sinon, indiquez uniquement le nom de la machine (et renseignez, sur les clients, le fichier hosts pour faire la correspondance). De nombreux soucis de fonctionnement de la couche TLS sont liés à une gestion des noms erronée...

Signer le certificat localement

Si vous n’utilisez pas les services d’une autorité d’enregistrement, vous devez générer vous même le certificat :

openssl x509 -req -days 3650 -in server.csr -CA cacert.pem -out server.crt

Si vous avez un message d’erreur du type :

cacert.srl: No such file or directory

il faut rajouter l’option suivante : -CAcreateserial, qui va créer le fichier contenant le numéro de série. La commande devient donc :

openssl x509 -req -in server.csr -CA cacert.pem -CAkey cacert.pem -out server.crt -Cacreateserial

Ne lancez cette commande qu’une seule fois...

Créer un certificat autosigné

Certaines applications ont besoin d'un certificat autosigné, quand il n'est pas possible d'en obtenir un (domaine privé, par exemple).

Une fois la requête de création du certificat exécutée, lancez la commande suivante :

openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt

qui permet de créer un certificat (server.crt) autosigné.

Faire signer le certificat par une autorité d’enregistrement

Si vous disposez d’une autorité de certification, envoyez le fichier qui vient d’être généré (server.csr) pour recevoir, en retour, la clé publique. En général, les champs Organization Name et Organizational unit name vous sont imposés : consultez votre autorité de certification pour connaître les bonnes informations à fournir.

Il vous faut également récupérer le certificat racine (équivalent du cacert.crt, la clé publique de l’autorité de certification) qui permettra de vérifier la validité du certificat qui vous sera fourni par l’autorité de certification.

Quelques commandes pour consulter les clés et les certificats

Pour visualiser le contenu d’une clé privée :

openssl rsa -in server.key -text

Pour visualiser la clé publique associée :

openssl rsa -in server.key -pubout

Pour visualiser un certificat :

openssl x509 -in server.crt -text -noout

Pour vérifier la validité du certificat :

openssl verify -CAfile cacert.crt server.crt

Intégrer les certificats dans ldap

Recopiez la clé publique (server.crt), la clé privée (server.key) et le certificat racine (cacert.crt) dans le dossier /etc/ldap/. Modifiez les droits pour que :

  • openldap puisse accéder aux certificats ;
  • la clé privée soit en mode 600.

Editez le fichier /etc/ldap/ldap.conf, et rajoutez la ligne (ou modifiez-là) :

TLS_CACERT /etc/ldap/cacert.crt

qui va permettre à tous les processus LDAP de vérifier les clés à partir du certificat racine.

Intégrer les certificats dans webmin

Par défaut, webmin génère ses propres certificats. Il est possible de lui faire utiliser les certificats que nous venons de générer.

Pour cela :

  • connectez-vous à webmin (https://serveur:10000)
  • Choisissez webmin > webmin Configuration
  • choisissez SSL Encryption, puis positionnez-vous dans l’onglet SSL Settings(l’onglet par défaut)
  • Sélectionnez sur le serveur l’emplacement de votre clé privée, puis cochez Certificate file : separate file, et indiquez l’emplacement de votre clé publique
  • Validez : le nouveau certificat va être utilisé à la place de l’ancien.

Intégrer les certificats dans Apache

Pour que les accès à l’annuaire LDAP à partir de Ldap Account Manager soient protégés, nous aurons besoin de basculer la liaison en mode SSL. Là aussi, nous pouvons intégrer les certificats que nous venons de générer dans Apache.

Recopiez les certificats dans le dossier /etc/apache2, puis éditez le fichier /etc/apache2/sites-available/default-ssl :

SSLCertificateFile    /etc/apache2/server.crt
SSLCertificateKeyFile /etc/apache2/server.key

Activez le support ssl dans Apache :

a2enmod ssl
a2ensite default-ssl

Redémarrez ensuite le service apache :

service apache2 restart

Une alternative : stocker les clés privées et publiques à un seul endroit

Les certificats sont utilisés par de nombreux processus, et leur emplacement décrit dans de nombreux fichiers.

Plutôt que de recopier les certificats dans chaque dossier spécifique d’un service, il peut être judicieux de les stocker à un seul endroit.

Pour cela, recopiez la clé primaire dans le dossier /etc/ssl/private, et donnez lui les droits suivants :

chmod 640 /etc/ssl/private/server.key
chown root:ssl-cert /etc/ssl/private/server.key

Recopiez la clé publique et le certificat racine dans /etc/ssl/certs, et vérifiez que les fichiers sont bien en mode 644.

Nous allons créer un lien vers la valeur de hachage du fichier cacert.crt (la clé racine) :

cd /etc/ssl/certs
ln -s cacert.crt `openssl x509 -hash -in cacert.crt -noout`.0

Ce lien va permettre de retrouver très rapidement la clé de l’autorité de certification pour pouvoir vérifier la clé publique. L’empreinte est calculée à partir de la valeur Subject du certificat, qui figure dans notre certificat public et dans le certificat de l’autorité de certification.

Notre clé privée n’est accessible qu’au compte root et au groupe ssl-cert. Pour que le service Ldap puisse accéder à cette clé, nous allons intégrer le compte openldap dans le groupe ssl-cert :

usermod -a -G ssl-cert openldap

Il ne reste plus qu’à modifier les chemins vers les certificats, par exemple, dans le fichier /etc/ldap/slapd.conf :

TLSCertificateFile       /etc/ssl/certs/server.crt 
TLSCertificateKeyFile    /etc/ssl/private/server.key 
TLSCACertificateFile /etc/ssl/certs/cacert.crt

Si vous avez besoin de générer plusieurs certificats

Il est fortement conseillé de n’avoir qu’un seul certificat racine : cela simplifie grandement la configuration des clients.

De fait, l’étape de génération du certificat racine (paragraphe 1 Créer le certificat racine, page 12) n’est à réaliser qu’une seule fois.

Sur les autres serveurs, après avoir généré la clé privée et la demande de clé publique, il faut :

  • recopier le fichier .csr (la demande de clé publique) sur le premier serveur
  • générer le certificat à partir de ce fichier .csr sur ce serveur
  • recopier le certificat généré (fichier .crt) sur le serveur pour lequel nous générons une nouvelle clé.

Ainsi, le même certificat racine sera utilisé pour valider l’ensemble des certificats de votre infrastructure.