Apache : utiliser de multiples certificats SSL pour https - support de webdav sécurisé

Présentation

Avant d’accéder à une page web cryptée (protocole https), le navigateur va réaliser deux vérifications :

  • d’une part, la signature du certificat présenté par le site web est vérifiée par rapport à un certificat « sûr » , à savoir le certificat de signature délivré par l’autorité de certification (certificat racine), certificat qui est intégré dans le navigateur ;
  • d’autre part, le nom présenté dans le certificat est confronté au nom du site auquel on cherche à accéder : s’il n’y a pas concordance, le navigateur le signale.

Dans le protocole SSL v.2, les concepteurs ont prévu qu’à un site correspond un certificat. Mais avec le déploiement des « virtual hosts », qui permettent de faire héberger de multiples sites dans le même serveur, cette approche ne tient plus.

Cette situation ne serait, en soi, pas vraiment problématique, si le protocole ne prévoyait pas que le serveur doit fournir le certificat, basée sur l’adresse IP de destination, avant qu’il ne puisse lire le nom du domaine (le nom du site). Ainsi, il n’est pas possible de fournir plusieurs certificats pour une même adresse IP.

Pour remédier à ce problème, deux évolutions ont été mises en œuvre. La première consiste à autoriser la création de certificats « génériques », où le nom du domaine contiendrait des caractères génériques ; par exemple, on pourrait créer un certificat *.mondomaine.com. Tous les sites de ce domaine pourraient alors utiliser le même certificat. Cette solution présente des avantages, mais également pas mal d’inconvénients, et notamment le fait de ne pas avoir la liste exhaustive des sites rattachés. Les risques de rajout « intempestif » d’un site à partir d’un certificat générique pourraient être assez importants.

La seconde solution a consisté à faire évoluer la norme SSL-TLS, en autorisant le serveur à lire le nom du domaine pendant la négociation SSL, et donc d’envoyer le bon certificat correspondant à un vhost particulier.

Cette extension s’appelle Server Name Indication (SNI), et est implémentée dans tous les navigateurs récents. Elle n’est pas supportée dans Internet Explorer 7 dans Windows XP, mais l’est dans les versions des OS de Microsoft à partir de Vista.

Configuration d’Apache pour le mode WEBDAV

Dans notre configuration, nous avons mis en place un accès à une arborescence bureautique, qui plus est accessible avec le protocole WEBDAV, protocole qui permet de modifier les fichiers en accédant à l’arborescence en mode http ou https. Dans notre cas de figure, l’accès n’est possible qu’en https.

Apache n’est capable d’accéder à un fichier qu’à partir du moment où le compte www-data (dans Ubuntu) dispose des droits d’accès. Nous devons donc, pour l’arborescence considérée, donner les droits d’accès à ce compte.

Si vous avez activé les ACL, il suffit de lancer les commandes :

setfacl -R -m u:www-data:rwx /monArborescence
setfacl -R -m d:u:www-data:rwx /monArborescence

pour que le compte www-data puisse écrire dans celle-ci. Si vous n’avez pas activé les acl, il faut mettre le compte www-data dans le groupe propriétaire de votre arborescence.

Nous allons activer le support de webdav dans Apache, ainsi que le support ldap :

a2enmod authnz_ldap
a2enmod ldap
a2enmod dav_fs

Il faut également que les fichiers créés par webdav aient le bon masque. Pour cela, rajoutez la ligne suivante dans /etc/apache2/envvars :

umask 007

Les fichiers seront créés avec le masque 770

Redémarrez ensuite Apache...

Configuration d’Apache pour le support de SSL et SNI

Le support de SNI est implémenté dans Apache à partir de la version 2.2.12, mais nécessite également que OpenSSL soit en version 0.9.8j. Pour Ubuntu 10.04, le support est total.

Vérifiez qu’openssl soit installé dans votre machine, de même qu’Apache. A titre d’exemple, voici les paquets installés sur ma machine :

aptitude search ssl|grep ^i
i   libnet-ssleay-perl              - Perl module for Secure Sockets Layer (SSL)
i   libssl0.9.8                     - SSL shared libraries                      
i   openssl                         - Secure Socket Layer (SSL) binary and relat
i A ssl-cert                        - simple debconf wrapper for OpenSSL 
aptitude search apache2|grep ^i
i A apache2                         - Apache HTTP Server metapackage            
i A apache2-mpm-worker              - Apache HTTP Server - high speed threaded m
i A apache2-utils                   - utility programs for webservers           
i A apache2.2-bin                   - Apache HTTP Server common binary files    
i A apache2.2-common                - Apache HTTP Server common files

Création des certificats d’identification pour chacun des sites hébergés

Cette opération dépasse le cadre de ce document. En voici, en quelques mots, le principe :

  • créez votre couple clé privée/clé publique avec la commande :
openssl genrsa -out monserveur.pem 1024

(1024 pour une clé d’une longueur de 1024 bits).

pour chacun des sites hébergés, créez une requête de demande de signature de certificat avec la commande :

openssl req -new -key monserveur.pem -out monsiteweb.csr
  • remplissez les champs avec les informations adéquates (consultez votre autorité d’enregistrement). Le champ Common name doit contenir le nom DNS de votre site web
  • envoyez le fichier généré (monsiteweb.csr) à votre autorité d’enregistrement, qui vous retournera votre clé publique signée.
  • Pensez également à créer un certificat pour votre site par défaut (le nom de votre serveur) !
  • Déplacez ensuite votre clé privée (monserveur.pem) dans le dossier /etc/ssl/private, et mettez les clés publiques signées dans le dossier /etc/ssl/certs/. La clé privée doit être en 600 ou 640 (jamais en 644), les clés publiques en 644.

Activation du support ssl avec sni dans Apache

Pour activer le support SSL et SNI, il faut activer le site par défaut ssl-default. Voici l’ensemble des opérations à réaliser (commandes effectuées avec Ubuntu 10.04, à adapter le cas échéant) :

cd /etc/apache2/sites-available
mv default-ssl 00_default-ssl
Editez le fichier 00_default-ssl :
<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerAdmin adresse_admin@monsite.com
        DocumentRoot /var/www
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>
        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
        ErrorLog /var/log/apache2/error.log
        LogLevel warn
        CustomLog /var/log/apache2/ssl_access.log combined
        Alias /doc/ "/usr/share/doc/"
        <Directory "/usr/share/doc/">
                Options Indexes MultiViews FollowSymLinks
                AllowOverride None
                Order deny,allow
                Deny from all
                Allow from 127.0.0.0/255.0.0.0 ::1/128
        </Directory>
        SSLEngine on
        SSLCertificateFile    {{/etc/ssl/certs/monsitepardefaut.pem}}
        SSLCertificateKeyFile {{/etc/ssl/private/monserveur.pem}}
        SSLCACertificatePath /etc/ssl/certs/
        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>
        BrowserMatch "MSIE [2-6]" \
                nokeepalive ssl-unclean-shutdown \
                downgrade-1.0 force-response-1.0
</VirtualHost>
NameVirtualHost *:443
# Go ahead and accept connections for these vhosts
# from non-SNI clients
SSLStrictSNIVHostCheck off
</IfModule>

Activez maintenant le mode ssl :

a2enmod ssl
a2ensite 00_default-ssl
service apache2 restart

Pour information, les commandes a2enmod et a2ensite ne font que créer des liens dans les dossiers apache2/sites-enabled et apache2/mods-enabled vers les fichiers déclarés dans apache2/sites-available et apache2/mods-available. Les commandes inverses sont a2dissite et a2dismod.

Vérifiez que votre serveur Apache fonctionne bien, sinon regardez votre configuration. En particulier, assurez-vous que vous n’avez bien qu’une seule commande listen 443...

Création des vhosts

Nous allons maintenant créer un vhost par site. Ces vhosts sont déclarés dans le dossier /etc/apache2/sites-available.

Pour chaque site, nous allons créer un fichier, par exemple 50_informatique.conf. Voici les différentes informations à déclarer.

Tout d’abord, nous protégeons l’accès au dossier qui héberge notre site. Dans notre cas de figure, il s’agit d’une arborescence bureautique, dont l’accès est limité aux membre du groupe INFORMATIQUE du domaine DOMAINE, déclaré dans un annuaire LDAP. L’accès est réalisé avec l’adresse https://informatique.masociete.fr :

<directory /opt/donnees/informatique>

Nous autorisons, pour ce dossier, la possibilité de suivre les liens (pas recommandé, il faut savoir ce que l’on fait) :

options Indexes FollowSymLinks
order allow,deny
allow from all
allowOverride all

Activons le mode webdav pour ce dossier :

dav on

Puis gérons l’identification :

authType basic

Nous indiquons le nom du domaine (l’information sera affichée dans le navigateur) :

 AuthName DOMAINE
 AuthBasicProvider ldap

Ici, deux serveurs ldap sont déclarés, en redondance :

 AuthLDAPURL "ldaps://serveurldap1 serveurldap2 /ou=people,o=societe,c=fr?uid?sub"
 AuthLDAPGroupAttributeIsDN off
 AuthLDAPGroupAttribute memberUid

Nous allons maintenant gérer les droits d’accès selon deux modes : les droits en lecture, et les droits en écriture. Ici, le groupe draf pourra lire les fichiers, et le groupe msi les modifier.

# lecture-ecriture
<Limit GET POST OPTIONS PROPFIND PUT DELETE PROPPATCH MKCOL COPY MOVE LOCK UNLOCK HEAD>
require ldap-group cn=msi,ou=Group,o=societe,c=fr
</Limit>
# Lecture
<Limit GET POST OPTIONS PROPFIND>
require ldap-group cn=draf,ou=Group,o=societe,c=fr
</limit>

Il est possible d’autoriser autant de groupes que nécessaires, en dupliquant les lignes require. Avec ce mécanisme, il est facile de redéfinir les accès pour une arborescence complète, en complément des ACL classiques.

</directory>

Nous allons maintenant rediriger les appels en http vers https. Dans la première partie, nous redirigeons les adresses sans suffixe (accès depuis l’intranet, avec un suffixe DNS rajouté automatiquement) :

<VirtualHost *:80>
ServerName informatique
RewriteEngine On
RewriteRule ^ https://informatique.masociete.fr/%{REQUEST_URI} [R]
</VirtualHost>
<VirtualHost *:80>
ServerName informatique.masociete.fr
ServerPath /informatique.masociete.fr
RewriteEngine On
RewriteRule ^ https://informatique.masociete.fr/%{REQUEST_URI} [R]
</VirtualHost>

Et nous paramétrons maintenant notre accès en mode https:

<VirtualHost *:443>
ServerAdmin administrateur@masociete.fr
ServerName informatique.masociete.fr
ServerPath /informatique.masociete.fr
DocumentRoot /opt/donnees/informatique
SSLEngine on

Nous indiquons maintenant la clé publique signée, envoyée par l’autorité de certification :

SSLCertificateFile /etc/ssl/certs/informatique_masociete_fr.pem

et la clé privée, commune pour l’ensemble du serveur :

SSLCertificateKeyFile /etc/ssl/private/monserveur.pem

ainsi que le certificat de l’autorité racine (ici, celle de l’administration) :

SSLCACertificateFile /etc/ssl/certs/igca-racine-serveur.crt
</VirtualHost>

Il reste à activer notre site :

a2ensite 50_informatique.conf
service apache2 reload

Correction d’un bug Ubuntu

Pour une raison inconnue, Ubuntu n’applique pas la directive umask définie dans le fichier envvars (cf. paragraphe 2 , Configuration d’Apache pour le mode WEBDAV). Il crée les fichiers en mode 600, ce qui limite les capacités de modifications par des tierces personnes...

Pour corriger ça, nous allons exécuter un script à intervalle régulier, qui va modifier les fichiers dont le mode est égal à 600. Pour cela, éditons le crontab :

crontab -e
00,10,20,30,40,50 * * * * find /opt/donnees/informatique -perm 600 -exec chmod 660 {} \;

Ainsi, toutes les 10’, le système va rechercher les fichiers en mode 600 pour les transformer en 660 dans notre arborescence.

Si cela pose des problèmes de performance, il faut alors modifier le déclenchement du script, pour qu’il ne s’exécute que 1 à 2 fois par jour, aux heures creuses...

Utilisation de webdav avec les systèmes d’exploitation courants

Le mode webdav n’a été implémenté que très récemment par Microsoft. Il ne fonctionne, et encore de manière très imparfaite, qu’à partir de Windows XP (pas testé sous Windows 2000, mais il ne doit plus rester beaucoup de machines avec cet OS...). De plus, Windows XP ne supporte pas le mode webdav sécurisé en https...

Avec Windows Seven, théoriquement, le support est complet, mais il faut impérativement modifier une clé de registres pour qu’il puisse travailler avec un serveur webdav Apache :

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\WebClient\Parameters]
"BasicAuthLevel"=dword:00000002

Dans la pratique, ça ne fonctionne pas... Je conseille d’utiliser un logiciel client dédié : bitKinex, qui fonctionne parfaitement, bien qu’en anglais : http://www.bitkinex.com/

Le support dans Linux est complètement pris en charge (testé avec Ubuntu 10).

Pour Mac, je ne sais pas... mais je présume que ça doit fonctionner !