le vendredi 22 août

Secure Socket Layer

Après avoir joué avec Apache, je me suis intéressé à un autre sujet : SSL. C'est d'ailleurs ce qui m'a prit le plus clair de mon temps. Pour faire fonctionner SSL avec Apache, en faisant tout bien dans les règles de l'art, il faut bien comprendre le fonctionnement de SSL et de ses certificats.

SSL fonctionne avec la notions de tiers de confiance. Un tiers de confiance est une entité reconnue plus ou moins universellement qui certifie l'identité, et donc les certificats qu'on lui présente. On peut citer plusieurs entités comme Thawte ou Verisign pour les connus et les plus chers (et espérons le, les plus sérieuses dans leurs opérations de vérification). Ensuite, pleins d'autres entreprises se sont vue accréditées par les deux premiers cités pour également délivrer des certificats.

Les certificats de ces autorités de certifications sont publics. Par courtoisie, les éditeurs de navigateurs livrent ceux-ci préchargés avec les certificats des autorités de confiances les plus connues. Vous pouvez bien sur rajouter tous les certificats d'autorités de confiance que vous le souhaitez. Par exemple, j'ai pour ma part importé les certificats de CACert.org, qui propose des certificats gratuits basés sur un système de vérification automatisé.

Attention, ajouter un certificat, c'est accorder sa confiance complète à l'organisme sur tous les certificats qu'il pourrait accorder par la suite, et sur tout ceux qu'il a déjà accordé. Ce n'est donc pas une décision à prendre à la légère. C'est une opération qui n'est pas naturelle, aussi, il ne faut le faire qu'une fois que l'on a compris toutes les implications que cela entraîne.

En effet, l'autorité de certification va le plus souvent vérifier que les informations contenues dans un certificat sont bien celles qui sont alléguées. Un certificat peut contenir les informations suivantes :

  • le CN, common name, est l'information technique qui permettra au navigateur de s'assurer que le certificat proposé correspond bien à l'url entrée. Il s'agit du nom de domaine.
  • le pays
  • l'État
  • le nom de l'organisation
  • l'email

Dans le cas de CACert, le système ne vérifie que le nom de domaine (pour le cas le plus simple), et toutes les autres informations sont effacées du certificat.

La question qui vient à l'esprit, c'est : pourquoi vérifier qu'on parle bien au bon serveur puisqu'on a rentré son adresse dans sa barre d'adresse ? En effet, à moins que les serveurs DNS soient corrompus (risque qu'on ne peut pas exclure), la connexion se fera toujours avec le bon serveur.

Et bien, ce n'est pas aussi simple : d'une part, un serveur DNS est un serveur sur lequel vous n'avez pas forcement la main. Et il s'agit d'un tiers qui n'est pas forcement fiable. Celui de votre entreprise peut vous retourner sur l'adresse d'un proxy transparent, ou tout autre serveur. D'autre part, HTTP a été conçu pour fonctionner via des proxy qui peuvent très bien modifier ou générer les informations sans passer par le serveur auquel vous pensez vous connecter. La vérification du certificat prouve que vous vous adressez bien au serveur que souhaitez joindre, et non pas à un quelconque intermédiaire.

Mais dans ce cas, pourquoi une autorité de confiance ? Cette autorité va vérifier (par courrier, téléphone, huissier ou tout autre méthode qui lui semble pertinente) que les données contenues dans le certificat sont bien celles correspondant au propriétaire. Ainsi, Verisign vérifiera que FNAC SA, propriétaire du certificat (vous pouvez aller vérifier) est bien un nom que peut utiliser la Fnac pour son site web. Il est d'ailleurs amusant de constater que ce certificat n'utilise pas le wildcard * dans son certificat et que donc https://fnac.com ne fonctionne pas, alors que https://www.fnac.com, lui fonctionne.

Le wildcard, qu'est ce que c'est ?

Comme on a pu le constater, le certificat embarque le nom de domaine auquel il est associé. Ainsi, un certificat plo.org ne peut pas fonctionner chez bla.com. Mais c'est plus sévère que ça : un certificat www.fnac.com ne peut pas fonctionner pour fnac.com ! Cela introduit une certaine rigidité dans le système puisqu'il faut un certificat pour chaque domaine et sous domaine que l'on doit administrer. La réponse est venu de certificats wildcards, qui permettent de mettre une étoile * à la place d'un des éléments de l'url, pour que par exemple ftp.fnac.com et www.fnac.com puissent fonctionner avec le même certificat SSL qui contient *.fnac.com. Les wildcard sont très cher et difficile à obtenir auprès de Verisign ou Thawte. Vous pouvez par contre en obtenir un auprès de CACert. Malheureusement, le certificat racine de CACert n'est pas tout le temps inclus dans les navigateurs.

Est ce qu'on peut créer un certificat * ?

Oui, on peut, mais aucune autorité de confiance ne vous le signera. Tout simplement parce que vous ne pourrez jamais justifier de la propriété de tous les domaines. De plus, il vous drait des certificats comme *.*.* si vous voulez un certificat pour www.plop.org.

Et techniquement, comment ça marche ?

Du coté de l'autorité de certification (c'est à dire probablement jamais vous), c'est simple, elle se créé un certificat qu'elle signe elle même. C'est un certificat auto-signé. Sa valeur ne provient que parce qu'il est inclus dans tous les navigateurs. Ainsi, même si vous créez votre propre certificat, il a très peu de chance d'être inclus d'office dans un quelconque navigateur. Vous devrez donc demander à vos utilisateur de l'ajouter eux même, et peu seront enclin à le faire, d'autant plus qu'ils ne connaissent pas votre sérieux. La création d'un certificat passe par la création d'une paire de clé privée / publique.

   # génération d'une paire de clés
   openssl genrsa -aes256 -out privkey.pem
   
   # génération d'un certificat auto-signé 
   openssl req -new -x509 -key privkey.pem -out cert.pem

Attention, le fichier privkey.pem ne doit jamais être rendu publique. Sa seule utilisation sera pour la signature future de certificat. Donc, en gros, ce fichier ne bougera pas de machine.

Par contre, le fichier cert.pem est un fichier publique. Vous pouvez (ou pas) le diffuser librement. C'est ce fichier que vos utilisateurs doivent importer dans leurs navigateurs. Suivant leur modèle, cela fonctionnera tout de suite ou cela nécessitera une conversion du format PEM au format DER pour les saveurs Redmond. En tout cas, ce fichier ne contient rien de privé. Par contre, il est inutile de chercher à le modifier, il serait rendu inutilisable.

Attention encore, vous ne pourrez plus rien signer si vous perdez le certificat ou la clé.

Du coté de l'éditeur du serveur SSL (donc peut-être vous un jour), c'est légèrement plus compliqué, vous devez créer une paire de clés comme décrit précédemment (avec les mêmes réserves), ainsi qu'une demande de certificat (en effet un certificat est toujours signé, c'est la définition d'un certificat). Une fois votre demande créé, vous devez l'envoyer à une autorité quelconque pour signature. La procédure est en général un copier coller vers le site de l'autorité de certification (dont vous aurez constaté que le site est sécurisé, mais ce n'est pas indispensable). Une fois signé, vous pourrez constater que la signature de cette demande correspond à l'un des certificat préchargé dans votre navigateur.

   # génération d'une paire de clés
   openssl genrsa -aes256 -out privkey.pem
   
   # demande de certificat
   openssl req -new -out demande -key privkey.pem

Là encore, la clé est privée et secrète. La demande est quant à elle publique même s'il n'y a aucun intérêt à la publier.

Pour signer votre certificat, l'autorité va faire plein de paperasse et de vérification et, entre autre, va signer votre demande, qui se muera en certificat :

   # signature d'un certificat avec le certificat de l'autorité
   openssl x509 -CA ./cert.pem -CAkey ./privkey.pem -req -in ../servercert/demande -out ../servercert/servercert.pem -CAcreateserial

C'est à ce moment qu'elle vérifie que les informations contenues dans le certificat sont exactes. Chez CACert, ils ne certifient que le nom de domaine (pour les certificats de serveur http) et l'adresse email (pour les certificats d'adresse email). Pour vérifier un nom de domaine, ils envoient un marqueur aléatoire à l'une des adresses email trouvées dans le whois. Charge à vous d'aller lire les mails de cette adresse et d'y répondre favorablement.

L'autorité de certification doit faire d'autres démarches, comme par exemple tenir à jour une liste de révocation, etc. Le fonctionnement d'une autorité de certification est un sujet complet et je n'en parlerai pas plus maintenant.

Une fois le certificat récupérer, l'exploitation peut commencer. Dans Apache 2, il suffit de rajouter les directives suivantes dans le contexte approprié :

   LoadModule ssl_module         modules/mod_ssl.so
   <IfModule ssl_module>
   SSLRandomSeed startup builtin
   SSLRandomSeed connect builtin
   SSLEngine on
   
   SSLCertificateFile /home/manu/perso/web/runtime/ssl/servercert/servercert.pem
   SSLCertificateKeyFile /home/manu/perso/web/runtime/ssl/servercert/privkey.pem
   </IfModule>

Le serveur pourra ainsi s'authentifier et déchiffrer tout ce qui lui sera renvoyé.

Une dernière chose, tous les certificat possèdent une date limite d'utilisation : un certificat doit donc être renouvellé régulièrement au risque d'avoir une alerte du navigateur. Ainsi les certificats de Verisign expirent entre 2028 et 2036. Par contre, il y a fort à parier que les certificats que vous achèterez chez eux ne seront pas valable plus d'un an...

LAMP

LAMP, c'est quoi ? C'est un acronyme qui veux dire Linux Apache MySQL et PHP. C'est en gros la plateforme la plus courante pour faire tourner des applications en PHP. L'exemple le plus proche est le blog que vous êtes en train de lire. Suite à mon entrée précédente, je suis en train de regarder les différents CMS qui existent afin de choisir quelques chose qui pourrait me seoir [1].

La première étape a été de télécharger les sources d'apache et de les compiler. Réalisé avec les autotools, il ne s'agit que de faire ./configure && make -j 2 && make install

Voici le config.nice qui contient tous les éléments de configuration particulier

   #! /bin/sh
   #
   # Created by configure
   
   "./configure" \
   "--prefix=/home/manu/perso/web/runtime/httpd" \
   "--enable-rewrite=shared" \
   "--enable-ssl=shared" \
   "$@"

Ensuite, il a fallu faire quelques adaptations au fichier de configuration d'Apache : déclarer des alias et inclure certains modules. Rien de bien complexe.

Pour MySQL, j'ai juste fais un apt-get install mysql-qqch. Connaissant déjà un peu Mysql, je n'ai jugé utile de tout faire à la main (en plus, le serveur sert pour d'autres projets).

Vint ensuite le tour de PHP, hop, là aussi téléchargement des sources, ./configure && make -j 2 && make install

le config.nice qui va bien

   #! /bin/sh
   #
   # Created by configure
   
   './configure' \
   '--with-apxs2=/home/manu/perso/web/runtime/httpd/bin/apxs' \
   '--with-mysql' \
   '--prefix=/home/manu/perso/web/runtime/php' \
   '--with-config-file-path=/home/manu/perso/web/runtime' \
   '--with-gd' \
   '--enable-mbstring' \
   "$@"

Il m'a fallu recompiler plusieurs fois PHP et Apache pour y ajouter tous les modules complémentaires dont j'avais besoin. À chaque fois le système génère un fichier config.nice qui contient toutes les options déjà présentes. Cela dit, tant que la compilation ne plante pas, on n'est pas obligé de tout reconstruire. Si cela se passe mal, il suffit de faire un make clean, puis de relancer la compilation (depuis le début, mais ce n'est pas non plus dramatique)

J'ai ensuite essayé (concretement) dotclear 2 et drupal. Dotclear me semble pas mal, rien de transcendant si ce n'est qu'une interface d'extension complète a été prévue. Pour Drupal, c'est un peu plus compliqué, je n'ai pas saisi tous les concepts pour faire fonctionner le site...

Je n'ai pas encore choisi la solution que je vais utiliser, c'est toujours en cours...

Notes

[1] et non pas scier.

le samedi 9 août

Cyberrail, le retour

Je vais faire ici un petit point sur l'état du projet en ce qui concerne le passé et le futur.

Read next