Apache2 et sites multiples avec SSL SNI

Posted on July 13, 2014

Notre objectif est d’avoir plusieurs sites web avec du SSL sur une seule machine, avec un serveur apache2, et qui ne possède qu’une seule adresse IP publique. Ceci est un cas typique dans un cas d’autohébergement (comme chez moi). Le problème c’est que pour SSL, il faut sélectionner la bonne paire de clés du côté du serveur et ensuite on peut envoyer des données, comme par exemple, le nom de domaine sur lequel on veut se connecter. Problème, pour sélectionner la bonne paire de clés il faut connaître le nom de domaine sur lequel on souhaite se connecter.

La solution à ça c’est le SNI qui est une extension de TLS qui permet d’envoyer le nom de domaine sur lequel vous souhaitez vous connecter avant d’entâmer la connexion SSL.

Il n’y a rien à faire pour l’activer concrêtement, par contre il faut activer le SSL avec la bonne configuration des hôtes virtuels, donc on va voir ça ici (c’est simple, mais pas intuitif).

Certificat auto-signé

on créé un répertoire dédié

mkdir -p /etc/apache2/ssl/

Il faut copier son /etc/ssl/openssl.cnf dans le répertoire puis on le modifie pour y modifier ou ajouter les quelques valeurs suivantes (elles sont toutes plus ou moins au même endroit) :

default_bits                = 4096
countryName_default         = FR
stateOrProvinceName_default = Alsace
localityName_default        = Strasbourg
organizationName_default    = ""
commonName_default          = fqdn.de.votre.machine
emailAddress_default        = votre.adresse@mail

On crée un fichier d’extension pour ajouter des noms de domaines qui seront gérés par votre certificat, comme par exemple:

[ monutilisateur ]
subjectAltName = DNS:example.com, DNS:www.example.com, DNS:blog.example.com

création d’une clé autosignée

openssl req -nodes -newkey rsa:4096 -new -out ca.csr -config openssl.cnf
openssl rsa -in privkey.pem -out ca.key
openssl x509 -req -days 365 -in ca.csr -signkey ca.key \
    -out ca.cert -extfile monutilisateur.ext \
    -extensions monutilisateur
chmod 400 ca.key ca.cert

Configuration d’un hôte virtuel

Tout d’abord, il faut prendre en compte la configuration des hôtes virtuels, donc on va modifier le fichier /etc/apache2/ports.conf et lui indiquer qu’on va regarder les hôtes virtuels en ssl, avec une configuration basique on devrait avoir :

NameVirtualHost *:80
Listen 80

<IfModule mod_ssl.c>
    NameVirtualHost *:443 # sites configurés avec SSL
    Listen 443
</IfModule>

<IfModule mod_gnutls.c>
NameVirtualHost *:443 # sites configurés avec SSL
    Listen 443
</IfModule>

On va créer le fichier /etc/apache2/sites-available/blog.example.com-ssl puis l’activer :

        SSLEngine On
        SSLCertificateFile /etc/apache2/ssl/ca.cert
        SSLCertificateKeyFile /etc/apache2/ssl/ca.key

        ServerAdmin me@example.com
        ServerName blog.example.com
        ServerAlias www.example.com

        DocumentRoot /path/to/website/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /path/to/website/>
                Options FollowSymLinks Indexes
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/blog.example.com-ssl.err

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/blog.example.com-ssl.log combined

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>

</VirtualHost>
</IfModule>

on active le module ssl puis le nouveau site dans apache

a2enmod ssl
a2ensite blog.example.com-ssl
service apache2 reload

Par la suite, chaque nouveau site devra être configuré de la même manière ; un nouveau fichier dans /etc/apache2/sites-available/ comme on l’a vu tout à l’heure, puis a2ensite fichier et service apache2 reload.

Si j’ai oublié quelque-chose, envoyez-moi un e-mail.

Tags: Apache2, SNI, SSL