LetsEncypt est une autorité de certification utilisant une API basée sur des appels HTTP et un client côté serveur qui va générer des tokens lus par les serveurs LetsEncrypt. Nous allons ici voir une architecture LetsEncrypt typique dans laquelle nous allons utiliser le client acme-client d’OpenBSD disponible dans les ports et les packages FreeBSD.
Dans un premier temps installez le client sur votre machine hôte (et pas votre jail web):
pkg install acme-client
Nous allons maintenant configurer nginx afin de pouvoir interagir avec l’API letsencrypt. Créez tout d’abord le répertoire suivant dans votre jail avec l’utilisateur et le groupe nobody
mkdir /usr/local/www/.well-known && chown nobody:nobody /usr/local/www/.well-known
Ensuite configurez vos virtual hosts afin de faire pointer les appels vers /.well-known dans ce répertoire:
server {
listen 80;
server_name www.unix-experience.fr;
location /.well-known {
alias /usr/local/www/.well-known;
}
location / {
return 301 https://www.unix-experience.fr$request_uri;
}
add_header X-Frame-Options "DENY";
add_header Strict-Transport-Security "max-age=86400; preload";
}
Note: nous ajoutons ici le support du protocole HSTS avec un TTL d'1 journée spécifiant aux navigateurs que le site supporte SSL et qu’il faudrait passer dessus. Vous pouvez sans souci faire pointer plusieurs de vos virtual hosts dans ce même répertoire.
Retournez maintenant sur votre hôte et créez le fichier /usr/local/etc/acme/domains.txt puis ajoutez y un domaine par ligne:
www.unix-experience.fr
ftp.unix-experience.fr
Créez ensuite le script ci-dessous (basé sur le script présent dans le même répertoire sous forme d’exemple) dans /usr/local/etc/acme/acme-client.sh
#!/bin/sh -e
WEBJAIL="web"
BASEDIR="/usr/local/etc/acme"
SSLDIR="/usr/local/etc/ssl/acme"
DOMAINSFILE="${BASEDIR}/domains.txt"
CHALLENGEDIR="/jails/${WEBJAIL}/usr/local/www/.well-known/acme-challenge"
[ ! -d "${SSLDIR}/private" ] && mkdir -pm700 "${SSLDIR}/private"
cat "${DOMAINSFILE}" | while read domain line ; do
CERTSDIR="${SSLDIR}/${domain}"
[ ! -d "${CERTSDIR}" ] && mkdir -pm755 "${CERTSDIR}"
set +e # RC=2 when time to expire > 30 days
acme-client -b -C "${CHALLENGEDIR}" \
-k "${SSLDIR}/private/${domain}.pem" \
-c "${CERTSDIR}" \
-n -N -v \
${domain} ${line}
RC=$?
set -e
[ $RC -ne 0 -a $RC -ne 2 ] && exit $RC
done
Ce script lit les domaines présents dans le fichier domains.txt puis il va s’occuper de créer vos clefs privées et de les faire signer par LetsEncrypt, en se basant sur le répertoire .well-known présent dans votre jail. Une fois ce script exécuté, si tout s’est passé correctement vous trouverez votre clef privée dans le répertoire /usr/local/etc/ssl/acme/private/example.org et votre clef publique et les chaînes de certificats dans le répertoire /usr/local/etc/ssl/acme/example.org. Ces répertoires sont situés sur votre hôte et non dans votre jail web. Pour déployer les scripts un script d’exemple est présent dans le répertoire **/usr/local/etc/**acme, mais nous allons légèrement le modifier. Créez le fichier /usr/local/etc/acme/deploy.sh:
#!/bin/sh
set -e
BASEDIR="/usr/local/etc/acme"
DOMAINSFILE="${BASEDIR}/domains.txt"
LEDIR="/usr/local/etc/ssl/acme"
JAILSDIR="/jails"
TARGETS="web"
cat "${DOMAINSFILE}" | while read domain line ; do
for jail in ${TARGETS}; do
targetdir="${JAILSDIR}/${jail}/etc/ssl"
# Check if the certificate has changed
[[ -z "`diff -rq ${LEDIR}/${domain}/fullchain.pem ${targetdir}/certs/${domain}.pem`" ]] && continue
cp -L "${LEDIR}/private/${domain}.pem" "${targetdir}/private/${domain}.pem"
cp -L "${LEDIR}/${domain}/fullchain.pem" "${targetdir}/certs/${domain}.pem"
chmod 400 "${targetdir}/private/${domain}.pem"
chmod 644 "${targetdir}/certs/${domain}.pem"
# Restart/-load relevant services
[[ "${jail}" = "web" ]] && jexec ${jail} service nginx restart
done
done
Ce script va copier tous les certificats associés à vos dernières négociations LetsEncrypt et va les déployer dans votre jail web puis redémarrer nginx.
Pour finir il ne reste plus qu’à configurer le cron ajouté par le paquet acme-client afin de configurer la tâche hebdomadaire. Pour se faire, éditez le fichier /usr/local/etc/periodic.conf et ajoutez les entrées suivantes:
# letsencrypt
weekly_acme_client_enable="YES"
weekly_acme_client_user="nobody"
weekly_acme_client_deployscript="/usr/local/etc/acme/deploy.sh"
Cela va vous permettre d’activer le cron, et de lancer le déploiement automatiquement toutes les semaines.
Vous pouvez désormais faire des demandes de certificats LetsEncrypt facilement et les renouveler automatiquement via un cron fourni par acme-client.