6.  Mettre en œuvre et utiliser SSL pour protéger le trafic HTTP

De nos jours, la sécurité des données stockées sur un serveur de fichiers est très importante. Des données compromises peuvent coûter des milliers de dollars à une entreprise. Dans la dernière section, nous avons compilé le module d'authentification LDAP dans Apache pour fournir un mécanisme d'authentification. Cependant, le trafic http est très peu sur, et toutes les données sont transférées en clair — ce qui signifie que l'authentification LDAP (utilisateur/mot_de_passe) sera transmise elle aussi en clair. Ceci pose un problème. N'importe qui peut intercepter cet utilisateur/mot_de_passe et accéder aux dossiers de DAV. Pour éviter ceci nous devrons chiffrer le trafic http, essentiellement par HTTP + SSL ou HTTPS. Tout ce qui est transféré en HTTPS est chiffré, ce qui fait que le couple utilisateur/mot_de_passe LDAP ne peut pas être aisément déchiffré. HTTPS tourne sur le port 443. Les binaires résultants étant compilés selon la dernière section, Apache pourra écouter à la fois sur les ports 80 (HTTP normal) et 443 (HTTPS). Si vous désirez utiliser ce serveur uniquement pour DAV, alors je vous suggère fortement de fermer le port 80. Dans cette section du guide pratique, je fournirai des informations sur SSL et comment l'administrer dans un serveur http Apache.

6.1. Introduction à SSL

SSL (Secure Socket Layer) est une couche protocolaire qui se situe entre la couche Réseau et la couche Application. Comme son nom le suggère, SSL fournit un mécanisme de déchiffrement pour toutes sortes de trafic : LDAP, POP, IMAP et plus important, HTTP.

Ce qui suit est une structure ultra simplifiée des couches impliquées par SSL.

+-------------------------------------------+
|   LDAP   |   HTTP   |    POP   |   IMAP   |
+-------------------------------------------+
|                    SSL                    | 
+-------------------------------------------+
|               Couche réseau               |
+-------------------------------------------+

6.1.1. Algorithmes de cryptographie utilisés par SSL

SSL utilise trois sortes de techniques de cryptographie : les systèmes de clés publiques-privées, de clés symétriques et de signatures numériques.

Chiffrement par clés publiques-privées — Initialisation d'une connexion SSL : dans cet algorithme, le chiffrement et le déchiffrement sont effectués en utilisant une paire de clés publiques et privées. Le serveur Web détient la clé privée, et envoie la clé publique au client dans le certificat.

  1. Le client demande un contenu au serveur Web en utilisant HTTPS.

  2. Le serveur Web répond en envoyant un certificat numérique qui comprend la clé publique du serveur.

  3. Le client vérifie si le certificat est expiré.

  4. Puis le client vérifie si l'autorité de certification qui a signé le certificat est une autorité de confiance figurant dans la liste du navigateur. Ceci explique pourquoi il est nécessaire d'obtenir un certificat d'une autorité de certification de confiance.

  5. Puis, le client vérifie si le nom de domaine pleinement qualifié (FQDN) du serveur Web coïncide avec le Nom Commun (Common Name CN) du certificat.

  6. Si tout est correct, la connexion SSL est initialisée.

[Note]N.B. :

On ne peut déchiffrer ce qui a été chiffré avec une clé privée qu'avec sa clé publique. De la même façon, on ne peut déchiffrer ce qui a été chiffré avec une clé publique qu'avec sa clé privée. C'est une erreur répandue de penser qu'une clé publique est utilisée pour le chiffrement et que la clé privée est utilisée pour le déchiffrement. Ce n'est pas le cas. On peut utiliser les deux clés pour chiffrer ou déchiffrer. Cependant, si on utilise une clé pour chiffrer, alors l'autre clé devra servir à déchiffrer. Par exemple On ne peut chiffrer un message puis le déchiffrer en utilisant uniquement une clé publique.

L'utilisation d'une clé privée pour chiffrer et d'une clé publique pour déchiffrer garantit l'identité de l'émetteur (qui est le propriétaire de la clé publique) à ses destinataires. L'utilisation d'une clé publique pour chiffrer et d'une clé privée pour déchiffrer garantit que seul le destinataire (qui est le propriétaire de la clé publique) accédera aux données. (c'est-à-dire que seul le détenteur de la clé privée pourra déchiffrer le message).

Chiffrement symétrique — Transmission effective des données : une fois la connexion SSL établie, on utilise le chiffrement symétrique, qui est moins consommateur en cycles de processeur. Avec le chiffrement symétrique, on peut chiffrer et déchiffrer les données en utilisant la même clé. La clé de chiffrement symétrique est échangée durant le processus d'initialisation, en utilisant la clé de chiffrement publique.

Sommation de messages Le serveur utilise des algorithmes de sommation de messages comme HMAC, SHA-1, MD5 pour vérifier l'intégrité des données transférées.

6.1.2. Garantie d'authenticité et d'intégrité

Processus de chiffrement


           Clef privée              Clef publique
          de l'émetteur            du destinataire
          ,-.                     ,-.
         (   )..........         (   )..........
          `-' ''''|'|'||          `-' ''''''''||
                  | |                    |
                  | |                    |
   .----------.   | |    .----------.    |     .----------.
   |  Texte   |   V |    |   Texte  |    V     |   Texte  |
   |   en     |--------->|  chiffré |--------->|  chiffré |
   |  clair   | Étape1   |     1    | Étape2   |     2    |\
   `----------'     |    `----------'          `----------' \    __
         |          |                                        \   [_'
         |          |                                  Étape5 \   |
         |Étape3    |                                       __  --|--
         |          |                                  _.--'      |
         V          |                            _..-''          / \
    .---------.     |    .---------.       _..-''            Destinataire
    |  SHA 1  |     V    |Signature| _..-''
    |SomMessag|--------->|numérique|'
    `---------' Étape4   `---------' 
              _  ___ ___
        _    (_)/  _)  _)                                      _
   ____| |__  _ | |_| |_ ____ _____ _____  _____  _____ ____ _| |_
  / ___)  _ \| ||  _)  _) ___) ___ |  _  \|  _  \| ___ |  _ (_   _)
 ( (___  | | | || | | || |   | ____| || | | || | | ____| | | || |_
  \____)_| |_|_||_| |_||_|   |_____)_||_|_|_||_|_|_____)_| |_| \__)
  • Étape 1 : le message original en clair est chiffré avec la clé privée de l'émetteur, ce qui produit le texte chiffré 1. L'authenticité de l'émetteur est garantie.

  • Étape 2 : le « texte chiffré 1 » est chiffré à l'aide de la clé publique du destinataire, aboutissant au « texte crypté 2 ». Celui-ci garantira l'authenticité du destinataire, c'est-à-dire que seul le destinataire peut déchiffrer le message à l'aide de sa clé privée.

  • Étape 3 : la somme SHA1 du « texte en clair » est créée.

  • Étape 4 : la somme SHA1 du message est ensuite chiffrée avec la clé privée de l'émetteur, ce qui produit la signature numérique du « texte en clair ». Le destinataire peut utiliser la signature numérique pour s'assurer de l'intégrité du message et de l'authenticité de l'émetteur.

  • Étape 5 : la « signature numérique » et le « texte chiffré 2 » sont ensuite envoyés au destinataire.

Processus de déchiffrement

           Clef privée          Clef publique
         du destinataire        de l'émetteur
         ,-.                     ,-.
        (   )..........         (   )..........
         `-' ''''''''||          `-' '''''''|||
                |                      |    |
                |                      |    |
  .----------.  |       .----------.   |    | .----------.
  |  Texte   |  V       |  Texte   |   V    | |  Texte   |       .---No1---.
  | chiffré  |--------->| chiffré  |--------->|   en     |------>|  SHA 1  |
  |    2     | Étape1   |    1     | Étape2 | |  clair   |Étape3 |SomMessag|
  `----------'          `----------'        | `----------'       `---------'
                                            |                        ||
                                            |                        ||Étape5
                                            |                        ||
                                            |                        ||
                               .---------.  |                    .---------.
                               | Digital |  V                    |  SHA 1  |
                               |Signature|---------------------->|SomMessag|
                               `---------' Étape4                `---No2---'
     _    _              _  ___ ___
    | |  //        _    (_)/  _)  _)                                      _
  __| |_____  ____| |__  _ | |_| |_ ____ _____ _____  _____  _____ ____ _| |_
 / _  | ___ |/ ___)  _ \| ||  _)  _) ___) ___ |  _  \|  _  \| ___ |  _ (_   _)
( (_| | ____( (___  | | | || | | || |   | ____| || | | || | | ____| | | || |_
 \____|_____)\____)_| |_|_||_| |_||_|   |_____)_||_|_|_||_|_|_____)_| |_| \__)
  • Étape 1 : le « Texte chiffré 2 » est déchiffré avec la clé privée du destinataire, ce qui produit le texte chiffré 1.

  • Étape 2 : le « texte chiffré 1 » est déchiffré à l'aide de la clé publique de l'émetteur, ce qui produit le « texte en clair ».

  • Étape 3 : la somme SHA1 du « texte en clair » est créée.

  • Étape 4 : la « signature numérique » est ensuite déchiffrée à l'aide de la clé publique de l'émetteur, ce qui produit la « somme SHA 1 du message ».

  • Étape 5 : la « somme SHA 1 du message numéro 1 » est ensuite comparée à la « somme SHA 1 du message numéro 2 ». Si elles sont égales, cela signifie que les données n'ont pas été modifiées durant la transmission, et que l'intégrité de l'original « texte en clair » a été préservée.

6.2. Certificats de test

Lorsque nous compilons Apache, nous créons un certificat de test. Nous avons utilisé le makefile fourni par mod_ssl pour créer ce certificat sur mesure. Nous avons utilisé la commande :

# make certificate TYPE=custom

Nous pourrons utiliser ce certificat à des fins de test.

6.3. Certificats destinés à la production

Il est nécessaire d'obtenir un certificat d'une Autorité de Certification de confiance (nommée ci-après AC) pour une utilisation en production. Les autorités de certification sont des vendeurs de certificats, qui figurent dans la liste des AC de confiance de chaque navigateur. Comme on l'a précisé dans la section des algorithmes de cryptographie, si l'AC ne figure pas dans la liste des autorités de confiance, un message d'alerte s'affichera quand l'utilisateur essayera de se connecter à un site sécurisé.

Les certificats de test provoqueront eux aussi l'apparition d'un message d'alerte dans le navigateur de l'utilisateur.

6.4. Génération d'un CSR

Pour être signée, une CSR (Certificate Signature Request: Demande de Signature de Certificat) doit être envoyée à une AC de confiance. Cette section montre comment on crée une CSR, et comment on l'envoie à l'AC de son choix.

# openssl req

Pour créer une CSR, on peut recourir à cette commande comme suit :

# cd /usr/local/apache/conf/
# /usr/local/ssl/bin/openssl req -new -nodes -keyout private.key -out public.csr
Generating a 1024 bit RSA private key
............++++++
....++++++
writing new private key to 'private.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
Locality Name (eg, city) []:San Jose
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Seagate 
Organizational Unit Name (eg, section) []:Global Client Server
Common Name (eg, YOUR name) []:xml.seagate.com
Email Address []:saqib@seagate.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:badpassword
An optional company name []:
[Note]« PRNG not seeded »

Si le fichier /dev/random n'existe pas sur votre système, le message d'erreur « PRNG not seeded » s'affichera. Dans ce cas, vous pouvez utiliser la commande suivante :

# /usr/local/ssl/bin/openssl req -rand mon_fichier.ext -new -nodes -keyout private.key -out public.csr

Remplacez le fichier mon_fichier.ext par le nom d'un fichier existant dans votre système. Vous pouvez spécifier n'importe quel fichier. Openssl utilisera ce fichier pour générer le noyau.

Sur Solaris 9 on trouve le fichier /dev/random . Cependant, il est possible que vous ayez à installer le correctif 112438 pour accéder à /dev/random

Arrivé là, vous devrez répondre à plusieurs questions concernant votre serveur pour générer la CSR.

N.B. : Votre Common Name (CN) est le nom DNS pleinement qualifié (FQDN) de votre serveur web, c'est-à-dire dav.server.com . Si vous saisissez quelque chose d'autre, ça ne marchera PAS. Mettez de côté le mot de passe pour un usage ultérieur.

Une fois le processus achevé, un fichier private.key et un fichier public.csr seront présents dans votre arborescence. Il vous faudra envoyer le fichier public.csr à l'autorité de certification. À ce stade, le fichier public.key n'est pas chiffré. pour le chiffrer, saisissez :

# mv private.key private.key.unecrpyted
# /usr/local/ssl/bin/openssl rsa -in private.key.unecrpyted -des3 -out private.key

6.5. Installation de la clé privée et du certificat du serveur

une fois que l'autorité de certification aura traitée votre demande, elle vous renverra un certificat codé (certificat numérique). Le certificat numérique est au format défini par la norme X.509 v3. Les lignes qui suivent montre la structure d'un certificat numérique conforme à X509 v3 (version française entre parenthèses)

  • Certificat

    • Version (Version)

    • Serial Number (Numéro de série)

    • Algorithm ID (Identification de l'algorithme)

    • Issuer (Émetteur)

    • Validity (Validité)

      • Not Before (pas avant)

      • Not After (pas après)

    • Subject (sujet)

    • Subject Public Key Info (Info de sujet de clé publique)

      • Public Key Algorithm (algorithme de clé publique)

      • RSA Public Key (clé publique RSA)

    • Extensions (Extensions)

  • Certificate Signature Algorithm (algorithme de signature du certificat)

  • Certificate Signature (signature du certificat)

6.5.1. Vérification d'un certificat numérique

Pour vérifier un certificat X.509, utilisez la commande suivante :

# openssl verify server.crt
server.crt: OK

server.crt est le nom du fichier qui contient le certificat numérique.

6.5.2. Vérification du contenu d'un certificat numérique

On peut voir le contenu d'un certificat numérique en utilisant la commande # openssl x509 comme suit :

# openssl x509 -text -in server.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 312312312 (0x0)
        Signature Algorithm: md5WithRSAEncryption
	Issuer: C=US, O=GTE Corporation, CN=GTE CyberTrust Root
        Validity
            Not Before: Feb  8 03:25:50 2000 GMT
            Not After : Feb  8 03:25:50 2001 GMT
	    Subject: C=US, ST=New York, L=Pelham, O=xml-dev, OU=web, CN=www.xml-dev.com/Email=saqib@xml-dev.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
		............
		............
                Exponent: 65537 (0x10001)
    Signature Algorithm: md5WithRSAEncryption
    	............
	............

6.5.3.  Installation des certificats : modification du fichier httpd.conf

Vous devrez placer ce certificat dans le serveur, et indiquer à Apache où le trouver.

Dans cet exemple, la clé privée est située dans le répertoire /usr/local/apache2/conf/ssl.key/ et le certificat du serveur est placé dans le répertoire /usr/local/apache2/conf/ssl.crt/.

Copiez en le renommant le fichier reçu de l'autorité de certification en server.crt dans le répertoire /usr/local/apache2/conf/ssl.crt/.

et placez le fichier private.key généré à l'étape précédente dans le répertoire /usr/local/apache2/conf/ssl.key/

Puis modifiez le fichier /usr/local/apache2/conf/ssl.key/ pour qu'il pointe correctement vers la clé privée et le certificat du serveur :

#   Server Certificate:
#   Point SSLCertificateFile at a PEM encoded certificate.  If
#   the certificate is encrypted, then you will be prompted for a
#   pass phrase.  Note that a kill -HUP will prompt again.  Keep
#   in mind that if you have both an RSA and a DSA certificate you
#   can configure both in parallel (to also allow the use of DSA
#   ciphers, etc.)
SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt
#SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server-dsa.crt

#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/private.key
#SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/server-dsa.key

6.6. Annulation de la phrase de passe pour la clef privée RSA

La clé privée RSA conservée sur le serveur Web est d'habitude chiffrée, et il vous faut une phrase de passe pour parcourir le fichier. Voilà pourquoi quand Apache est lancé avec modssl, une phrase de passe vous est demandée :

# apachectl startssl
Apache/1.3.23 mod_ssl/2.8.6 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide us with the pass phrases.
Server your.server.dom:443 (RSA)
Enter pass phrase:

Il est très important de chiffrer une clé privée RSA. Si un pirate s'empare de votre clé privée RSA non chiffrée, il pourra facilement emprunter l'identité de votre serveur Web. Si la clé est chiffrée, la seule chose que pourra faire le pirate est de tenter une attaque en force brute sur votre phrase de passe. L'utilisation d'une phrase de passe robuste (c'est-à-dire longue) est encouragée.

Cependant, le fait de chiffrer la clé peut parfois être gênant, dans la mesure où vous devrez saisir la phrase de passe à chaque démarrage du serveur Web. En particulier si vous utilisez les scripts rc pour lancer le serveur Web au démarrage, le processus de démarrage sera stoppé sur l'invite de saisie d'une phrase de passe.

Vous pouvez facilement vous débarrasser de l'invite de saisie de la phrase de passe en déchiffrant la clé. Cependant, assurez-vous que personne ne pourra s'emparer de cette clé. Je ne saurais trop vous recommander d'appliquer les lignes de conduite de durcissement et de sécurisation du serveur avant de déchiffrer la clé du serveur Web.

Pour déchiffrer la clé :

tout d'abord, faites une copie de la clé chiffrée

# cp server.key server.key.cryp

Puis recréez la clé avec chiffrement. L'invite vous demandera la phrase de passe de la clé chiffrée d'origine

# /usr/local/ssl/bin/openssl rsa -in server.key.cryp -out server.key
read RSA key Enter PEM pass phrase: writing RSA key

Une façon de sécuriser la clé privée non chiffrée est de limiter l'accès en lecture à l'utilisateur root :

# chmod 400 server.key

6.7. Réglage des performances SSL

6.7.1. Cache de session SSL inter-processus

Le modèle de fonctionnement d'Apache est multi-processus ; toutes les requêtes ne seront PAS prises en charge par le même processus. L'information sur la session SSL se perd donc quand un client effectue de multiples requêtes. De multiples échanges de données SSL provoquent une surcharge du système sur le serveur Web et le client. Pour éviter cela, les informations de session SSL doivent être stockées dans un cache de session inter-processus, pour permettre à tous les processus d'accéder aux informations protocolaires. On peut spécifier l'emplacement du cache de session SSL dans la directive SSLSessionCache dans le fichier/usr/local/apache2/conf/ssl.key/ :

SSLSessionCache         shmht:logs/ssl_scache(512000)
#SSLSessionCache        shmcb:logs/ssl_scache(512000)
#SSLSessionCache        dbm:logs/ssl_scache
SSLSessionCacheTimeout  300

L'utilisation de dbm:logs/ssl_scache crée un cache de type fichier de hachage DBM sur le disque local.

L'utilisation de shmht:logs/ssl_scache(512000) crée un cache dans un segment de mémoire partagée

[Note]shmht contre shmcb

shmht : recoure à une table de hachage pour cacher les informations du protocole SSL dans la mémoire partagée.

shmcb : recoure à un tampon cyclique pour cacher les informations du protocole SSL dans la mémoire partagée.

[Note]N.B. :

tous les OS/plates-formes ne supportent pas de créer des tables de hachage dans la mémoire partagée. Donc, il faut utiliser dbm:logs/ssl_scache à la place.

6.7.2. Vérification du cache de session SSL

Pour vérifier si le cache de session SSL fonctionne correctement, vous devez utiliser la commande openssl avec l'option -reconnect comme suit :

# openssl s_client -connect your.server.dom:443 -state -reconnect
CONNECTED(00000003)
.......
.......
Reused, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
SSL-Session:
.....
Reused, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
SSL-Session:
.....
Reused, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
SSL-Session:
.....
Reused, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
SSL-Session:
.....
Reused, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
SSL-Session:
.....

-reconnect oblige le s_client à se connecter au serveur 5 fois de suite en utilisant la même ID de session SSL. Comme vous le voyez plus haut, vous devriez voir cinq tentatives de réutilisation de la même ID de session.