Je suis en train de travailler sur un projet web pour lequel j’ai voulu que toutes les connexions soient sécurisée par défaut en SSL. Avec une subtilité : Il faut pouvoir gérer des sous-domaines multiples, que l’on ne connait pas par avance.
Je vais vous expliquer point par point comment j’ai procédé, depuis la génération des certificats « wildcard » jusqu’à la configuration Apache.
Pré-requis et informations préalables
Considérons que nous avons déjà un serveur Linux avec Apache qui tourne dessus. Dans mon cas, j’ai travaillé sur une distribution Ubuntu 11.04, mais j’imagine que les mêmes étapes s’appliqueront à l’identique sur Fedora, Suse, ou autres.
Les certificats SSL représentent un business important. Des entreprises se font beaucoup d’argent en vendant très cher une prestation technique qui est automatisée. Chaque option supplémentaire est facturée à prix d’or. Suivant l’entreprise qui fournit le certificat, les tarifs peuvent aller de 12$ à 150$ pour sécuriser un unique nom de domaine, et les certificats wildcard − qui permettent de sécuriser tous les sous-domaines d’un domaine donné − peuvent atteindre les 500$.
Et encore, si vous allez vers un grand nom comme VeriSign, vous dépassez allègrement le millier de dollars. Par an !
J’ai donc choisi de me tourner vers StartSSL. Cette autorité de certification fournit gratuitement des certificats de classe 1 (sans vérification d’identité). Pour les certificats de classe 2 − intégrant les wildcard − ils facturent uniquement l’opération humaine de vérification d’identité. On peut ensuite générer autant de certificats que nécessaire, c’est gratuit ; il suffit d’abord de prouver que l’on est propriétaire des domaines ciblés (la procédure est automatisée, je vais revenir dessus).
Ce fonctionnement est au final complètement logique. L’ensemble de la chaîne est automatisé et ne génère aucun coût pour StartSSL, à part la vérification d’identité qui est manuelle. Cette opération est facturée 60$ (47,80 € au cours d’hier) et est valable pendant deux ans.
La génération de certificat
Je me suis largement inspiré d’une documentation trouvée sur le site Biapy. La procédure est au finale assez simple.
Si OpenSSL n’est pas installé, c’est le moment de le faire :
$> apt-get install openssl
Idem pour l’activation du module SSL d’Apache :
$> a2enmod ssl
Imaginons que l’on possède le nom de domaine xyz.com, et que l’on souhaite en sécuriser tous les sous-domaine grâce à un certificat wildcard *.xyz.com.
Commençons par créer la clé privée :
$> openssl genrsa -out /etc/ssl/private/xyz.com.key 2048 $> chmod 400 /etc/ssl/private/xyz.com.key
On va ensuite créer le CSR (certificate signing request), qui sera transmis par la suite à StartSSL pour récupérer la clé publique :
$> mkdir /etc/ssl/reqs $> openssl req -new -key /etc/ssl/private/xyz.com.key \ -out /etc/ssl/reqs/xyz.com.csr
Le programme va demander plusieurs informations :
- Notre pays, sur deux lettres (“FR” dans mon cas).
- Le nom de notre province, état ou région (“Ile-de-France” pour moi).
- Le nom de notre ville (“Paris” si vous êtes parisien).
- Le nom de notre entreprise ou de votre organisation.
- Le nom de notre unité organisationnelle (moi je laisse vide).
- Le “Common Name”, c’est-à-dire le nom de domaine à sécuriser (“*.xyz.com”, attention à bien mettre l’étoile au début quand on crée un wildcard).
- Notre adresse email.
- Un mot de passe pour sécuriser le certificat. Il faut le laisser vide, sinon StartSSL ne saura pas générer la clé publique.
Si on regarde le fichier /etc/ssl/reqs/xyz.com.csr, il devrait contenir quelque chose comme ça :
-----BEGIN CERTIFICATE REQUEST----- ... (plusieurs lignes encodées en base64) ... -----END CERTIFICATE REQUEST-----
Il faut le garder sous le coude, nous devrons ensuite le copier-coller dans l’interface de StartSSL.
La vérification d’identité
La procédure d’inscription sur le site StartSSL peut sembler un peu compliquée. Le site va générer un certificat qui va vous identifier personnellement. Ce certificat s’installe automatiquement sur votre navigateur (cela fonctionne avec Firefox mais pas avec Chrome) ; si vous voulez utiliser un autre ordinateur, il faudra exporter le certificat sur le navigateur d’origine, et l’importer sur le navigateur de destination.
Ce certificat se contente de vous identifier. Pour le générer, il faut suivre la procédure du site, qui inclut la vérification de votre adresse email.
Une fois que l’on est connecté et identifié, on peut utiliser le « Validation Wizard » pour demander à valider notre identité en cliquant sur « Personal Identity Validation ». Cette validation nécessite que l’on scanne − ou que l’on prenne en photo − notre passeport (couverture, première page, page avec nom et photo) et une autre pièce d’identité comme la carte d’identité ou le permis de conduire (recto et verso). L’interface permet d’envoyer les fichiers correspondants. Dans la foulée, j’ai reçu un email me demandant une copie d’une facture récente de téléphone fixe ou mobile. Je me suis exécuté, et dans les minutes qui ont suivies j’ai reçu un coup de téléphone très aimable (en anglais) ; pour vérifier mon identité, Eddy m’a demandé ma date et mon lieu de naissance.
En parallèle de ça, il faut aller dans l’onglet « Tool Box » de l’interface, pour enregistrer une carte bancaire ou un compte Paypal. Si vous choisissez Paypal, vous recevrez rapidement une demande de paiement correspondant aux 60$ facturés pour la vérification d’identité ; si vous choisissez la carte bancaire, le prélèvement se fera automatiquement.
Notre identité est vérifiée, maintenant il faut prouver que l’on est bien propriétaire du domaine xyz.com. Pour cela, il faut retourner dans l’onglet « Validation Wizard », en choisissant cette fois l’option « Domain Name Validation ». Après avoir saisi le nom xyz.com, on nous propose de choisir une adresse email à laquelle sera envoyé l’email de validation (postmaster@xyz.com, hostmaster@xyz.com ou webmaster@xyz.com). En menant la procédure à son terme, StartSSL enregistrera que le domaine nous appartient bien.
Clé publique et certificat racine
Nous pouvons maintenant générer la clé publique dont nous avons besoin pour sécuriser notre site. Il faut aller dans l’onglet « Certificates Wizard », et choisir la cible « Web Server SSL/TLS Certificate ». La première étape doit être passée (bouton « Skip »). À l’étape suivante, il faut copier-coller le contenu du fichier /etc/ssl/reqs/xyz.com.csr. Ensuite, il faut ajouter le sous-domaine « * » à la liste de sous-domaines inclus dans le certificat (la liste est vide, il suffit simplement d’insérer l’étoile dans le champ texte et de passer à l’étape suivante). Après quelques dizaines de secondes, on reçoit un email indiquant que le certificat est disponible. Pour cela, il faut aller dans l’onglet « Tool Box », puis dans « Retrieve Certificate ». Il faut sélectionner le certificat qui nous intéresse, puis le copier-copier dans le fichier /etc/ssl/certificates/xyz.com.crt (pensez à créer le répertoire d’abord).
Pour que notre certificat fonctionne, nous devons récupérer sur notre serveur deux fichiers supplémentaires : le certificat racine et le certificat intermédiaire.
$> mkdir /etc/ssl/roots /etc/ssl/chains $> wget https://www.startssl.com/certs/ca.pem \ -O /etc/ssl/roots/xyz.com-root.ca.pem $> wget https://www.startssl.com/certs/sub.class2.server.ca.pem \ -O /etc/ssl/chains/xyz.com.ca.pem
Configuration Apache
Ça y est, nous avons récupéré tous les fichiers nécessaires. Ouf. Nous allons pouvoir configurer nos sites. StartSSL propose une documentation succincte pour la plupart des serveurs HTTP, je me suis inspiré de celle pour Apache.
Nous allons créer deux « virtual hosts » dans Apache. L’un répondra aux requêtes HTTPS, l’autre répondra aux requêtes HTTP et renverra vers l’équivalent sécurisé.
# sites sécurisés <VirtualHost *:443> ServerName www.xyz.com ServerAlias *.xyz.com DocumentRoot /path/to/site SSLEngine on SSLProtocol all -SSLv2 SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM SSLCertificateFile /etc/ssl/certificates/xyz.com.crt SSLCertificateKeyFile /etc/ssl/private/xyz.com.key SSLCertificateChainFile /etc/ssl/chains/xyz.ca.pem SSLCACertificateFile /etc/ssl/roots/xyz.com-root.ca.pem SetEnvIf User-Agent ".*MSIE.*" nokeepalive \ ssl-unclean-shutdown # ... la suite de la configuration habituelle du virtual host </VirtualHost> # sites non sécurisés <VirtualHost *:80> ServerName www.xyz.com ServerAlias *.xyz.com RewriteEngine On RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} </VirtualHost>
Suivant la configuration existante, vous aurez peut-être besoin des directives suivantes (à placer dans le fichier précédent ou dans le fichier contenant le virtual host par défaut) :
NameVirtualHost *:80 NameVirtualHost *:443
On vérifie la configuration et on redémarre Apache :
$> apache2ctl configtest $> apache2ctl restart
Il faut être attentif à ce qu’il se passe dans les fichiers de log, notamment dans /var/log/apache2/error.log
Si tout s’est bien passé, vous pourrez vous connecter à l’URL https://bidule.xyz.com sans problème. Et en allant sur http://machin.xyz.com/truc vous devriez être automatiquement redirigé vers https://machin.xyz.com/truc
Bonjour,
je suis heureux que mon site ai pu vous aider 🙂
Pour ce qui est de la redirection http vers https, j’utilise personnellement un VirtualHost dédié sur le port 80, avec la directive Redirect permanent plutôt qu’utiliser mod_rewrite. Je trouve cela plus clair de séparer l’aspect http et https, mais peut-être est-ce simplement parce-que j’utilise un outil automatisé pour créer mes configurations Apache 2 :).
Merci pour votre travail sur ce blog et bonne continuation 🙂
@Pierre-Yves : Oui, ton article était très bien. Merci à toi !
Pour la redirection HTTP vers HTTPS, tu as en partie raison. La directive Redirect est très pratique lorsqu’on connait le nom du domaine de destination. Mais elle ne peut pas fonctionner quand on ne connait pas le sous-domaine à l’avance, ce qui est mon cas avec le wildcard.
Dans la réalité, j’ai 4 virtual hosts différents :
1. https://www.xyz.com
2. https://*.xyz.com
3. http://xyz.com + http://www.xyz.com => https://www.xyz.com
4. http://*.xyz.com => https://*.xyz.com
Le n°3 effectue sa redirection avec un Redirect.
Par contre, le n°4 ne peut fonctionner qu’avec mod_rewrite.
Bonjour,
merci pour ces précisions :). Je prend note de cette solution intéressante 🙂
Bonjour,
J’ai un projet du même genre en cours. Je vous remercie pour ces explications.
Il y a un détail flou, c’est la redirection de l’URL https://sousdomaine.domaine.com vers le dossier www/sousdomaine/ par exemple.
Il faut utiliser mod_rewrite dans le fichier httpd.conf ou en htaccess ? Ça fonctionnera avec le reste (redirection http->https, certificat SSL wildcard) ?
Merci d’avance,
Wladimir
@Wladimir : Non, d’après ce que je comprends, ce dont tu parles n’est pas une redirection.
Imaginons que, pour l’URL https://sousdomaine.domaine.com, tu veuilles servir les fichiers qui sont présents dans le dossier « /home/www/domain/sousdomaine/ ».
C’est simplement la directive DocumentRoot qui sert à ça. C’est forcément à mettre dans la configuration Apache.
Merci pour votre réponse.
Cependant, comme vous, je ne connais pas à l’avance les sous-domaines.
Le DocumentRoot tel que vous le décrivez va fonctionner ?
Oui, il va fonctionner. Dans mon exemple, la directive « ServerAlias *.xyz.com » aura pour effet que tous les sous-domaines du domaine xyz.com zeront pris en charge. Et, à chaque fois, c’est le contenu du dossier spécifié par le DocumentRoot qui sera servi.
Génial.
(je suis tombé sur cet article en recherchant une solution à ce problème, du coup j’ai parcouru ton blog que j’ai trouvé très intéressant. Nous faisons en gros la même chose, dans le même esprit, j’ai appris beaucoup de choses ici. Merci !)
C’est bon, j’ai suivi ton tuto et tout fonctionne correctement.
Pour info, voici ma config des VirtualHost (fichier /etc/apache2/sites-enabled/000-default sur Ubuntu 10.04 :
ServerName www.mondomaine.com
ServerAlias *.mondomaine.com
DocumentRoot /var/www/htdocs
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM
SSLCertificateFile /etc/ssl/certificates/mondomaine.com.crt
SSLCertificateKeyFile /etc/ssl/private/mondomaine.com.key
SSLCertificateChainFile /etc/ssl/chains/mondomaine.com.ca.pem
SSLCACertificateFile /etc/ssl/roots/mondomaine.com-root-ca.pem
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.* [NC]
RewriteCond %{HTTP_HOST} ^(.*)\.mondomaine.com
RewriteCond /var/www/htdocs/%1 -d
RewriteRule ^(.*) /%1/$1 [L]
# sites non sécurisés
ServerName www.mondomaine.com
ServerAlias *.mondomaine.com
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}
Petite information qui pourra être très utile
Quand on se crée un compte sur StartSSL, on reçoit un certificat qui s’installe automatiquement sur le navigateur. Ainsi, il n’y a pas d’identification par login/mot de passe ; il faut ensuite exporter le certificat, et l’installer sur tous les postes à partir desquels on souhaite se connecter à StartSSL.
Ce certificat est valable 1 an. Une fois que cette durée est dépassée, il devient impossible de se connecter à son compte. Comment faire ?
La réponse se trouve sur leur forum : Il faut créer un nouveau compte, en utilisant la même adresse email que le compte précédent ; il faut valider l’inscription et accepter le nouveau certificat. Ensuite, il faut envoyer un email à l’adresse certmaster@startcom.org pour leur demander de merger les comptes. Ils sont assez réactifs.
Si vous avez besoin de générer un certificat acceptant plusieurs sous-domaines différents (*), la documentation suivante vous sera sûrement très utile : http://apetec.com/support/GenerateSAN-CSR.htm
(*) : Par une bizarrerie du fonctionnement des certificats wildcard, un domaine « aaa.bbb.xyz.com » ne sera pas accepté par le wildcard « *.xyz.com ». Vous serez obligé de créer un certificat prenant en compte à la fois « *.xyz.com » et « *.bbb.xyz.com ».
J’aurais tendance à penser que c’est un moyen bien pratique pour faire encore plus de pognon, pour la plupart des fournisseurs de certificats. Encore une fois, StartSSL joue proprement les choses, en offrant cette possibilité gratuitement avec leurs certificats wildcard.