HSC
Cabinet de consultants en sécurité informatique depuis 1989 - Spécialisé sur Unix, Windows, TCP/IP et Internet
Mode texte : accès au contenu de la page
Hervé Schauer Consultants
Vous êtes ici : Accueil > Ressources > Brèves > Apache : Hôtes virtuels et SSL (mod_ssl)
Accéder au : Site HSC des formations
Télécharger le catalogue des formations
Recherche :  
English version
   Services   
o Domaines de compétences
o Conseil & Expertise
o Prestations ISO 27001
o Audit & Évaluation
o Tests d'intrusion
o Tests de vulnérabilités (TSAR)
o Analyse Forensique
o Certification ARJEL
o Formations
o E-learning
   Conférences   
o Agenda
o Interventions passées
o Tutoriels
   Ressources   
o Index thématique
o Brèves
o Présentations
o Cours
o Articles
o Outils (téléchargement)
o Veille en vulnérabilité
   Société   
o Hervé Schauer
o Equipe
o Offres d'emploi
o Références
o Historique
o Partenariats
o Associations
   Presse et
 communication
 
 
o Newsletter HSC
o Bulletin juridique HSC
o Revue de presse
o Communiqués de presse
o Publications
   Contacts   
o Coordonnées
o Requêtes particulières
o Accès à nos locaux
o Hôtels proches de nos locaux
|>|Apache : Hôtes virtuels et SSL (mod_ssl)  

par Franck Davy (21/12/2001)



--[ Apache : Hôtes virtuels et SSL (mod_ssl) ]--


1. Contexte

Cette brève s'attarde sur les difficultés créées par le fait que les protocoles
SSL/TLS s'accomodent mal d'un mécanisme d'hôte virtuel (Virtual Host) par nom.

En effet, le protocole HTTP/1.1 introduit l'en-tête 'Host: ', s'utilisant de la
façon suivante typiquement :

GET /index.html HTTP/1.1
Host: www.hsc.fr

L'objectif étant de ne pas avoir à affecter une adresse IP différente à chaque
hôte virtuel.

Le problème apparaît clairement avec ce test :
$ openssl s_client -connect 192.168.0.1:443
[...]

Le serveur présente « un » certificat signé, puis le tunnel chiffré est monté.
Les requêtes HTTP peuvent alors être faites, classiquement, dans ce tunnel. Et
plus particulièrement l'en-tête « Host: », ce qui est problématique : le nom
présenté dans le certificat n'est pas forcément celui correspondant à la valeur
du champ Host, correspondant à l'url passée par l'utilisateur dans son
navigateur. La conséquence est généralement un avertissement, dans la mesure où
le nom présenté par le certificat peut ne pas correspondre à l'url.


2. Configuration du Serveur Apache + mod_ssl

    2.1 Hôte virtuel par adresse IP.

        * Fichier httpd.conf

C'est la solution la plus courante et la plus simple. Dans ce cas, la
configuration doit avoir l'allure suivante :

<VirtualHost 192.168.0.1>
ServerName foo.hsc.fr
ServerAdmin webmaster@foo.hsc.fr
DocumentRoot /www/foo
[...]
SSLEngine on
SSLCertificateFile /usr/local/apache/conf/ssl.crt/foo.crt
SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/foo.key
[...]
</VirtualHost>

<VirtualHost 192.168.0.2>
ServerName bar.hsc.fr
ServerAdmin webmaster@bar.hsc.fr
DocumentRoot /www/bar
[...]
SSLEngine on
SSLCertificateFile /usr/local/apache/conf/ssl.crt/bar.crt
SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/bar.key
[...]
</VirtualHost>

Pour plus de détails, voir la documentation en ligne :
http://httpd.apache.org/docs/vhosts/examples.html

Dans ce cas, la génération du certificat se fait sans problème, avec l'url dans
le CN ou encore dans le subjectAltName (de type dNSName dans ce cas, autrement
dit de la forme « DNS: »).

Une contrainte cependant : cette méthode nécessite d'utiliser plusieurs adresses
IP, via l'utilisation d'alias.

        * Génération du certificat.

La méthode est celle appliquée dans l'immense majorité des documentations sur
Openssl.

Les étapes sont les suivantes :
- ajout d'une section dans le fichier openssl.cnf ;
- génération du bi-clé ;
- création de la demande de certificat serveur ;
- signature du certificat par l'autorité de certification.

La section à ajouter (et à utiliser via '-extensions VIP') est la suivante :

[VIP]
basicConstraints               = critical,CA:FALSE

nsCertType                      = server
nsComment                       = "Serveur FOO"

subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
subjectAltName                  = DNS:foo.hsc.fr
issuerAltName                   = issuer:copy

keyUsage                        = keyEncipherment, digitalSignature
extendedKeyUsage                = serverAuth

Pour la suite, la méthode est identique, à ces différences près :

- présence d'un subjectAltName de type dNSName (cf. section VIP) ;
- il est possible de mettre un CN nul (Attention à la « policy » dans ce cas).
	Dans ce cas subjectAltName doit être mis « critical ».

Au final, le certificat (foo.crt par exemple) obtenu a notamment) les
caractéristiques suivantes :

Subject: C=FR, ST=Ile-de-France, O=Herve Schauer Consultants, CN=foo.hsc.fr/Email=webmaster@foo.hsc.fr

X509v3 Basic Constraints: critical
	CA:FALSE
Netscape Cert Type:
	SSL Server
X509v3 Subject Alternative Name:
	DNS:foo.hsc.fr
X509v3 Issuer Alternative Name:
	email:webmaster@foo.hsc.fr
X509v3 Key Usage:
	Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
	TLS Web Server Authentication

Les fichiers foo.crt et foo.key peuvent être copiés, et Apache relancé.


    2.2 Hôte virtuel par Nom.

Dans ce cas, le serveur possède une et une seule adresse IP et plusieurs hôtes
virtuels, attaqués suivant la valeur du champ Host.

        * Fichier httpd.conf

NameVirtualHost 192.168.0.1

<VirtualHost 192.168.0.1>
ServerName foo.hsc.fr
ServerPath foo/         # Compatibilité HTTP/1.0
DocumentRoot /www/foo
[...]
SSLEngine on
SSLCertificateFile /usr/local/apache/conf/ssl.crt/foobar.crt
SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/foobar.key
[...]
</VirtualHost>

<VirtualHost 192.168.0.1>
ServerName bar.hsc.fr
ServerPath bar/
DocumentRoot /www/bar
[...]
SSLEngine on
SSLCertificateFile /usr/local/apache/conf/ssl.crt/foobar.crt
SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/foobar.key
[...]
</VirtualHost>

        * Génération du certificat.

Internet Explorer et Firefox sont conformes à la RFC 2818 (« HTTP Over TLS »).
Ils gèrent donc l'extension subjectAltName. Celle-ci peut être multivaluée et
doit être du type dNSName. Si le subjectAltName n'est pas présent, le commonName
est, au final, considéré. Les valeurs configurées peuvent éventuellement
comporter un wildcard. Ce comportement est décrit dans la partie « 3.1. Server
Identity » de la RFC : « If a subjectAltName extension of type dNSName is
present, that MUST be used as the identity. Otherwise, the (most specific)
Common Name field in the Subject field of the certificate MUST be used. Although
the use of the Common Name is existing practice, it is deprecated and
Certification Authorities are encouraged to use the dNSName instead. »

On notera que l'extension subjectAltName peut prêter à confusion, dans la mesure
où l'on peut supposer que la valeur configurée constitue une alternative à la
valeur du commonName. En pratique, il n'en est rien : s'il est présent, seul le
champ subjectAltName est considéré, le champ commonName n'est même pas évalué.
Si un certificat X509 doit référencer deux alias, ces derniers devront donc
figurer dans l'extension subjectAltName. Le champ commonName du sujet sera
présent à titre purement indicatif.

Remarque : le fonctionnement décrit dans la RFC 2818 n'est pas spécifique au
protocole HTTPS, et certaines implémentations du protocole SMTP-TLS s'en sont
par exemple inspiré, typiquement les sources du MTA Postfix évoquent le manque
de précision du RFC 3207 (« SMTP over TLS ») et mettent donc en oeuvre le
fonctionnement précédemment décrit : (src/tls/tls_client.c) « Another area where
RFCs aren't always explicit is the handling of dNSNames in peer certificates.
RFC 3207 (SMTP over TLS) does not mention dNSNames. Postfix follows the strict
rules in RFC 2818 (HTTP over TLS), section 3.1: The Subject Alternative
Name/dNSName has precedence over CommonName.  If at least one dNSName is
provided, Postfix verifies those against the peer hostname and ignores the
CommonName, otherwise Postfix verifies the CommonName against the peer
hostname».


Soit, dans le fichier de configuration openssl.cnf, on place la ligne suivante
dans la section relative au certificat serveur multivalué que l'on souhaite
générer :

subjectAltName                  = @ALIASES

La section ALIASES doit de même être définie :

[ALIASES]
DNS.1 = foo.hsc.fr
DNS.2 = bar.hsc.fr

Le certificat foobar.crt a donc les caractéristiques suivantes :

	X509v3 extensions:
		X509v3 Basic Constraints: critical
			CA:FALSE
		Netscape Cert Type:
			SSL Server
		X509v3 Subject Alternative Name:
			DNS:foo.hsc.fr, DNS:bar.hsc.fr
		X509v3 Issuer Alternative Name:
			email:webmaster@foobar.hsc.fr
		X509v3 Key Usage:
			Digital Signature, Key Encipherment
		X509v3 Extended Key Usage:
			TLS Web Server Authentication

Au final le test est réalisé avec IE et Firefox, et la connexion aux sites
foo.hsc et bar.hsc.fr est réalisée sans message d'erreur concernant l'url
présentée. Ce qui était le résultat désiré.


3. Récapitulatif

La méthode de génération d'un certificat possédant une extension subjectAltName
multivaluée est récapitulée dans cette partie.

Le fichier de configuration openssl.cnf est le suivant :
8< ---------------------------------------------------------------------------
[ ca ]
default_ca      = CA_default

[ CA_default ]
dir             = .
certs           = $dir/ca/certs
new_certs_dir   = $dir/ca/newcerts
database        = $dir/ca/index.txt
certificate     = $dir/ca/ca.pem
serial          = $dir/ca/serial
private_key     = $dir/ca/ca.key
default_days    = 3650
default_md      = sha1
preserve        = no
policy          = policy_match

[ policy_match ]
organizationName        = match
commonName              = supplied
emailAddress            = optional

[ req ]
distinguished_name      = req_distinguished_name

[ req_distinguished_name ]
organizationName                = Organisation
organizationName_default        = Herve Schauer Consultants
commonName                      = Nom ou URL
commonName_max                  = 64
emailAddress                    = Adresse Email
emailAddress_max                = 40

[CA]
nsComment                       = "[Breve HSC] CA"
subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
basicConstraints                = critical,CA:TRUE,pathlen:0
keyUsage                        = keyCertSign, cRLSign

[SERVEUR]
nsComment                       = "Certificat Test"
subjectKeyIdentifier            = hash
authorityKeyIdentifier          = keyid,issuer:always
issuerAltName                   = issuer:copy
basicConstraints                = critical,CA:FALSE
keyUsage                        = digitalSignature, nonRepudiation, keyEncipherment
nsCertType                      = server
extendedKeyUsage                = serverAuth
subjectAltName                  = @ALIASES

[ALIASES]
DNS.1 = foo.hsc.fr
DNS.2 = bar.hsc.fr
8< ---------------------------------------------------------------------------

La génération de l'ensemble est classique -- avec le fichier de configuration
openssl.cnf copiée dans le répertoire courant :
$ mkdir -p ./ca/newcerts && touch ./ca/index.txt && echo '01' > ./ca/serial
$ openssl req -new -x509 -config ./openssl.cnf -extensions CA -sha1 \
-newkey rsa:1024 -nodes -days 3650 -keyout ca/ca.key -out ca/ca.pem
$ openssl req -new -config ./openssl.cnf -newkey rsa:1024 -nodes \
-keyout serveur.key -out serveur.csr
$ openssl ca -config ./openssl.cnf -extensions SERVEUR -in serveur.csr \
-out serveur.pem


4. Conclusion

Au final, la gestion des certificats multivalués s'est améliorée et uniformisée
ces dernières années, et les principaux navigateurs (IE, Firefox) gèrent
dorénavant de façon similaire les champs commonName et subjectAltName (dans le
sens : « leur appliquent respectivement les mêmes traitements »), là où les
subtiles différences entre IE et Netscape compliquaient la tâche et rendaient
la manipulation quelque peu exotique. 

L'utilisation d'un protocole comme SSL est donc flexible à première vue, car
permet l'introduction de tunnels chiffrés et authentifiés à moindre effort (pour
tout applicatif supporté par TCP du moins), sans pour autant être adaptée à
l'applicatif supporté. Un protocole tel que SHTTP est sur ce point supérieur à
HTTPS, permettant notamment la montée d'un tunnel en cours de connexion (à la
manière d'un SMTP-TLS, ce qui permet notamment d'écouter sur un port unique). On
notera, par ailleurs, le support de la RFC 2817 par Apache dans la branche 2.2
(« Upgrading to TLS Within HTTP/1.1» ), qui permet de résoudre ce type de
problème, i.e. de s'adresser à l'hôte virtuel par nom adapté avant toute
négociation SSL/TLS (http://www.ietf.org/rfc/rfc2817.txt).

$Id: ssl_virtualhosts.tip,v 1.5 2007/01/02 13:57:21 poggi Exp $



Dernière modification le 2 janvier 2007 à 16:18:11 CET - webmaster@hsc.fr
Mentions légales - Informations sur ce serveur - © 1989-2013 Hervé Schauer Consultants