[Linux-bruxelles] Apache2 SSL : Virtual Hosts, Certificats, etc

Frederic Peters fpeters at entrouvert.com
Lun 7 Jan 11:08:48 CET 2008


Didier Misson écrivait :

> J'ai 2 sites (pour le moment, pour debugguer, j'ai désactivé les autres)
> 
> - misson.net (ou www.misson.net) : qui doit être accessible aussi bien
>   en HTTP qu'en HTTPS certificat signé par CAcert.org
> 
> - phpmyadmin.misson.net qui doit être accessible en HTTPS : le HTTP doit
>   être redirigé vers https://phpmyadmin.misson.net certificat auto-signé

La cause du problème a déjà été citée par ailleurs, je vais expliquer
le pourquoi du comment, et pointer deux pistes supplémentaires.

Dans des temps immémoriaux (quoique), le monde fonctionnait avec un
site web par serveur, un serveur par adresse IP, et je demandais le
site www.debian.org, l'adresse IP était résolue, le navigateur
connectait cette adresse, sur le port 80, et recevait une page.

Petite simulation :

   $ host www.debian.org
  www.debian.org          A       194.109.137.218
   $ telnet 194.109.137.218 80
  GET / HTTP/1.0
     <-- là j'appuie une seconde fois sur enter
  HTTP/1.1 200 OK
  Date: Mon, 07 Jan 2008 09:37:23 GMT
  Server: Apache/2.0.54 (Debian GNU/Linux)
  Content-Type: text/html

  <html>
    <head>
      <title>Debian GNU/Linux</title>
      ...

Le protocole HTTP 1.0 est défini dans la RFC 1945
  http://www.ietf.org/rfc/rfc1945.txt
Il fait suite à un HTTP 0.9 baptisé de ce numéro de version à titre
posthume, mais c'est du détail insignifiant.

Mais voilà qu'arrive une multiplication de sites, et la réalisation
que la nécessité d'une adresse IP par site, ça va pas tenir, alors
vient le tour d'HTTP 1.1 (maintenant RFC 2616).

   $ host www.debian.org
  www.debian.org          A       194.109.137.218
   $ host www.plop.org
  www.plop.org            A       194.109.137.218

Ah ah, il y a deux sites qui peuvent répondre à cette adresse.

   $ telnet 194.109.137.218 80
  GET / HTTP/1.1
  Host: www.debian.org   <-- j'ajoute un entête, Host
     <-- là j'appuie une seconde fois sur enter
  HTTP/1.1 200 OK
  Date: Mon, 07 Jan 2008 09:37:23 GMT
  Server: Apache/2.0.54 (Debian GNU/Linux)
  Content-Type: text/html

  <html>
    <head>
      <title>Debian GNU/Linux</title>
      ...

C'est dans cet entête Host: que se trouve la possibilité d'avoir un
serveur web servant plusieurs sites depuis une seule adresse.  Cela
correspond à la directive NameVirtualHost d'Apache, qui indique qu'un
site sera servi en faisant gaffe à l'entête Host, il regardera alors
les ServerName et ServerAlias pour trouver le site à envoyer.

Et tout ça, c'est super, mais l'HTTPS...

   $ telnet 194.109.137.218 443
  jazojda,x<w,xpozajuedoa"à&"!ésqmljdqmziueéoqsmkqùkfs

Je fais assez mal l'HTTPS, mais ce qui se passe là c'est qu'il va y
avoir un petit échange, certificats tout ça, puis la demande sera
déchiffrée et le serveur web recevra son GET / et cie.

Il recevra aussi son Host: mais c'est là qu'est le problème, le petit
échange de négociation, il se fait avant de déchiffrer la demande, il
est même nécessaire à déchiffrer la demande, il n'est donc pas
possible au site de connaitre l'Host: avant d'envoyer le certificat,
et donc pas moyen d'envoyer un certificat différent suivant l'Host:.

Cela explique tout, mais j'annonçais deux pistes.

La première n'est pas d'une grande finesse, elle consiste à utiliser
un certificat qui sera bon pour plusieurs domaines, genre *.misson.net

La seconde est cent fois plus classe, elle vient en deux temps,
d'abord TLS, le "successeur" de SSL, Pour info, la RFC 2818 décrit
comment faire de l'HTTP sur du TLS.

TLS, il y a de grandes chances que vous l'utilisez déjà pour les
services SMTP, TLS permet à une connexion de passer d'un état clair à
un état chiffré, exemple SMTP:

   $ telnet smtp.example.com 25
  Trying 127.0.0.1...
  Connected to smtp.example.com.
  Escape character is '^]'.
  220 smtp.example.com ESMTP Exim 4.63 Mon, 07 Jan 2008 10:57:50 +0100
  EHLO plop
  250-smtp.example.com Hello plop [212.71.10.27]
  250-SIZE 52428800
  250-PIPELINING
  250-STARTTLS
  250 HELP
  STARTTLS
  220 TLS go ahead

Et à partir de là, communication chiffrée.

Le second temps vient de la RFC 3546, c'est SNI, Server Name
Indication, qui s'ajoute à TLS, et dont la description est
cristalline :

   [TLS] does not provide a mechanism for a client to tell a server the
   name of the server it is contacting.  It may be desirable for clients
   to provide this information to facilitate secure connections to
   servers that host multiple 'virtual' servers at a single underlying
   network address.

Avec SNI, il est donc possible lors de la négociation de signifier le
nom du site qu'on voudrait contacter, le certificat sera reçu après,
et donc il y aura moyen d'avoir des certificats différents.


C'est bon, vous rêvez de nouveaux horizons ?

Retour sur terre.

Il n'y a pas moyen de faire d'SNI avec mod_ssl, mais il existe
mod_gnutls, c'est expérimental, pas packagé.  Mais si jamais, voici un
HOWTO pour sa mise en place :

  http://www.g-loaded.eu/2007/08/10/ssl-enabled-name-based-apache-virtual-hosts-with-mod_gnutls/

L'autre point noir, c'est au niveau des navigateurs, particulièrement
Microsoft Internet Explorer, dont la version 7 serait ok, mais
uniquement quand exécutée sous Vista.


C'était le long message de début de semaine, j'espère que je n'ai
injurié personne, même par quelques raccourcis que j'ai pu prendre,
à la prochaine !


        Frédéric




Plus d'informations sur la liste de diffusion Linux-bruxelles