#sysadmin


Let's Encrypt - Comment se faciliter la vie ?

Mon serveur web est composé d'un frontend nginx et d'un backend apache. L'ensemble de mes certificats (à l'exception du wildcard deblan.org) est géré par Let's Encrypt. Mon problème jusqu'à aujourd'hui était que lors de la création ou le renouvellement d'un certificat, mon service nginx devait être coupé pour réaliser l'authentification nécessaire à la validation faite par Let's Encrypt.

Le service nginx, tel que je l'ai configuré, possède un fichier de configuration unique qui écoute sur le port 80. Ce fichier permet :

  • d'indiquer mon backend apache
  • de gérer les problématiques de cache des assets (images, css, javascripts, etc.)

Vous pouvez remarquer l'include à la ligne 20. Voici le contenu du snippet :

Il identifie un répertoire unique où seront générés les fichiers d'authentification de Let's Encrypt. Il aura fallu créer ce répertoire au préalable (sudo mkdir -p /var/www/letsencrypt/).

Reste à présent 2 scripts :

  • celui qui permet de générer un certificat
  • celui qui permet de renouveler les certificats qui vont expirer

Pour la génération d'un certificat, j'ai souhaité une ligne de commande simple : le-get-certificate monsite.com www.monsite.com foo.monsite.com. Voici son contenu :

Edit : la commande cerbot renew fait le travail tout seul. L'intérêt de mon script pourrait d'ajouter rapidement des domaines à certifier en augmentant le CSR automatiquement.

Concernant le renouvellement, le script suivant s'appuie sur un fichier de configuration que vous devrez alimenter à chaque création de certificat. Il doit être créé à cet emplacement : /etc/letsencrypt/domains.conf. Voici à quoi il ressemble chez moi et j'ai ajouté la ligne nécessaire pour l'exemple de la commande de création :

Voici à présent le script que devra être exécuté périodiquement pour le renouvellement :

J'espère que cela pourra vous être utile et si vous avez des remarques, n'hésitez pas à m'en faire part :)


Domaines de développement - Apache2

Aujourd'hui j'ai eu besoin d'une configuration particulière d'Apache : j'ai décidé que les sous-domaines de deblan.org de type "dev-XXX" devaient être gérés de tel sorte que "XXX" corresponde à un sous-répertoire de dev.deblan.org. Ainsi, dev-01.deblan.org est l'équivalent de dev.deblan.org/01/.

Jusque là, rien de bien méchant sauf que j'ai une contrainte : je souhaite que ce soit automatique (ou le plus possible). Donc je ne souhaite pas ajouter/modifier des Virtualhost, je veux qu'un sous-domaine puisse être supprimé dans me prendre la tête.

La solution est au final simple (mais un peu tordue) :

Etape 1. Créer un fichier de mapping

L'idée est la suivante : comme tout ne sera pas automatique, je m'autorise l'édition d'un seul fichier pour traiter la correspondance d'un nom et de son répertoire de destination (en quelque sorte son DocumentRoot).

Ce fichier sera placé à la racine du compte associé à dev.deblan.org. Sur mon serveur, c'est le chemin suivant :

Afficher/masquer le code
/services/web/www/dev-xx.deblan.org/vhost.map

Ce fichier contient ces informations :

Afficher/masquer le code
dev.deblan.org /var/www/service-web/www/dev-xx.deblan.org/public_html/
dev-01.deblan.org /var/www/service-web/www/dev-xx.deblan.org/public_html/01
dev-foo.deblan.org /var/www/service-web/www/dev-xx.deblan.org/public_html/foo

On a donc à gauche le nom de domaine et à droite le répertoire web associé.

A travers une connexion au compte dev.deblan.org (via SSH ou en FTP par exemple), je peux modifier ce fichier.

Etape 2. Création du VirtualHost d'Apache

Afficher/masquer le code
<VirtualHost *:80>
	# On définit le domaine de base
	ServerName dev.deblan.org
	# On indique les alias de domaine à prendre en compte 
	ServerAlias dev-*.deblan.org

	# La partie la plus importante : les règles qui permettront de traiter ma demande
	RewriteEngine on

	# C'est ici que tout se passe
	RewriteMap lowercase int:tolower
	# On charge le fichier pour le mapping
	RewriteMap vhost txt:/services/web/www/dev-xx.deblan.org/vhost.map
	# On prend le soin de travailler de tout mettre en minuscules (donc attention à la casse !)
	RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
	RewriteCond ${vhost:%1} ^(/.*)$
	# On "simule" le DocumentRoot du domaine
	RewriteRule ^/(.*)$ %1/$1

	[...]
</VirtualHost>

Etape 3. Création d'un script de mise à jour d'Apache

Le fichier de mapping n'est chargé qu'une seule fois et c'est quand on relance ou reload Apache. Il faut donc, à des temps réguliers, vérifier si le fichier de mapping a été modifié et si on doit relancer Apache.

Il existe plusieurs méthodes, moi je vous propose un truc très simple :

(Fichier /root/apache2/reload)

Afficher/masquer le code
#!/bin/sh

# On indique le fichier de mapping
MAPPING=/services/web/www/dev-xx.deblan.org/vhost.map

# On indique le fichier qui va contenir le retour de "ls -l" sur le fichier de mapping
LS_FILE=/root/apache2/ls

[ -f "$LS_FILE" ] || touch "$LS_FILE"

LS=$(ls -l "$MAPPING")

# Si il y une différence entre le "nouveau" ls et l'ancien ls, alors le fichier à été modifié
# Donc on relance apache et on met à jour $LS_FILE
if [ "$LS" != "$(cat "$LS_FILE")" ]; then
	/usr/sbin/service apache2 reload
	echo "$LS" > "$LS_FILE"
fi

Il ne vous reste plus qu'à placer ça dans un crontab avec par exemple cette ligne de conf :

Afficher/masquer le code
*/1 * * * * /root/apache2/reload 2>&1 >/dev/null

Ici le script est exécuté toutes les minutes.

Normalement tout devrait fonctionner :)

Si vous avez d'autres solutions, je suis prenneur !