Dernier article :
Mise en place de certificat SSL wildcard avec Let's Encrypt
Comment mettre en place un serveur Web pour plusieurs sous-domaines avec un certificat SSL auto-renouvelé ? Ce n'est pas exactement un mystère mais la documentation est dispersée donc un HOWTO pas à pas peut être utile (à au moins une personne, coucou Vincent).
Voici comment j'ai procédé sur un serveur Ubuntu 24.04 LTS avec Gandi comme fournisseur DNS, mais c'est généralisable à d'autres distributions et registrars.
Prérequis
Une zone DNS a été configurée pour faire pointer son apex domaine.exemple et un sous-domaine www.domaine.exemple vers le serveur. On peut généraliser ensuite pour plus de sous-domaines.
Installation du serveur Apache
J'ai mes habitudes avec Apache, qui s'installe en un tour de main :
sudo apt install apache2
Configuration du firewall
Sur ce serveur je ne veux laisser passer que le trafic HTTP/HTTPS, et le trafic SSH pour l'administration à distance. Avec ufw et ses profils c'est grandement simplifié.
On vérifie quels profils sont effectivement disponibles, on doit avoir au moins les profils OpenSSH et Apache qui ont été ajoutés automatiquement pendant l'installation :
sudo ufw app list
Il faut activer le profil OpenSSH pour ne pas se faire jeter une fois le firewall activé, et le profil Apache Full c'est-à-dire HTTP et HTTPS :
sudo ufw allow OpenSSH
sudo ufw allow "Apache Full"
Ensuite on active le firewall et on confirme qu'il est activé :
sudo ufw enable
sudo ufw status
On peut déjà pointer un navigateur sur http://domaine.exemple pour avoir la page par défaut d'Apache et confirmer que jusqu'ici tout fonctionne.
Virtual Hosts
"Virtual Hosts" est le terme Apache pour une configuration permettant plusieur (sous-)domaines pour un seul serveur. Chez Nginx on dit "server blocks", si jamais.
Créons un répertoire et un fichier de test :
cd /var/www
sudo mkdir www.domaine.exemple
echo "yay" | sudo tee www.domaine.exemple/index.html
sudo chown --recursive www-data:www-data *
sudo chmod --recursive u-rwX,go=rX *
On peut ensuite créer un fichier de configuration pour ce virtual host :
sudoedit /etc/apache2/sites-available/www.domaine.exemple.conf
C'est toujours une bonne idée d'avoir des fichiers logs séparés par virtual host :
<VirtualHost *:80>
ServerName www.domaine.exemple
ServerAlias domaine.exemple
DocumentRoot /var/www/www.domaine.exemple
ErrorLog ${APACHE_LOG_DIR}/www.domaine.exemple_error.log
CustomLog ${APACHE_LOG_DIR}/www.domaine.exemple_access.log combined
</VirtualHost>
On peut ensuite désactiver la configuration Apache par défaut, et activer celle qu'on vient d'ajouter :
sudo a2dissite 000-default.conf
sudo a2ensite www.domaine.exemple.conf
sudo apache2ctl configtest
sudo systemctl restart apache2
Si maintenant on pointe un navigateur sur http://www.domaine.exemple on a notre "yay" de test.
Configuration de Certbot pour l'obtention et le renouvellement de certificats
On va utiliser l'utilitaire certbot pour obtenir du projet Let's Encrypt un certificat SSL pour notre domaine. Si on veut un certificat juste pour un domaine ou un sous-domaine spécifique sa mise en place est très simple, mais comme ici c'est un "wildcard" qu'on veut afin qu'il couvre le domaine et n'importe quel sous-domaine c'est un tout petit peu plus élaboré et ça implique de lui donner un accès à la zone DNS concernée.
La première étape dans mon cas est donc d'aller chez Gandi y générer un jeton d'accès personnel ayant les droits "voir et renouveler les domaines" et "gérer la configuration technique des domaines".
Ensuite sur le serveur on peut installer certbot et le plugin qui va lui permettre d'utiliser l'API de Gandi :
sudo apt install certbot
sudo apt install python3-full
sudo apt install python3-certbot-dns-gandi
On va ensuite lui renseigner le jeton qu'on vient de générer :
sudoedit /etc/letsencrypt/gandi.ini
dns_gandi_token=MON_JETON_PERSONNEL
Un peu de vie privée, ne fut-ce que pour le principe :
sudo chmod u=rw,go= /etc/letsencrypt/gandi.ini
Obtention des certificats
On peut maintenant utiliser certbot pour obtenir un certificat qui couvre à la fois domaine.exemple et *.domaine.exemple :
sudo certbot certonly --authenticator dns-gandi --dns-gandi-credentials /etc/letsencrypt/gandi.ini -d domaine.exemple -d \*.domaine.exemple --server https://acme-v02.api.letsencrypt.org/directory
Cette opération va créer deux fichiers sur le serveur :
- le certificat à
/etc/letsencrypt/live/domaine.exemple/fullchain.pem - sa clé privée à
/etc/letsencrypt/live/domaine.exemple/privkey.pem
Les certificats fournis par Let's Encrypt expirent en quelques mois, mais l'installation de certbot ajoute une tâche planifiée pour leur renouvellement automatique.
On peut vérifier que la tâche est bien planifiée et qu'elle s'exécutera correctement :
sudo systemctl status certbot.timer
sudo certbot renew --dry-run
Activation du SSL dans Apache
Il ne reste plus qu'à activer le SSL dans Apache et adapter sa configuration :
sudo a2enmod ssl
sudo systemctl restart apache2
sudoedit /etc/apache2/sites-available/www.domaine.exemple.conf
Dans la configuration on ajoute un section pour le HTTPS, qui utilise les fichiers créés par certbot :
<VirtualHost *:443>
ServerName www.domaine.exemple
ServerAlias domaine.exemple
DocumentRoot /var/www/www.domaine.exemple
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/domaine.exemple/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domaine.exemple/privkey.pem
ErrorLog ${APACHE_LOG_DIR}/www.domaine.exemple_error.log
CustomLog ${APACHE_LOG_DIR}/www.domaine.exemple_access.log combined
</VirtualHost>
<VirtualHost *:80>
ServerName www.domaine.exemple
ServerAlias domaine.exemple
DocumentRoot /var/www/domaine.exemple
ErrorLog ${APACHE_LOG_DIR}/domaine.exemple_error.log
CustomLog ${APACHE_LOG_DIR}/domaine.exemple_access.log combined
</VirtualHost>
Reste à valider ces changements et recharger la configuration pour les activer :
sudo apache2ctl configtest
sudo systemctl reload apache2
On peut confirmer le tout en pointant un navigateur sur https://domaine.exemple.
Et voilà, simple et efficace.