Renouvellement de certificats LetsEncrypt avec systemd

Qu'est-ce que c'est donc ?

« Let's Encrypt (abrégé LE) est une autorité de certification lancée le 3 décembre 2015 (Bêta Version Publique). Cette autorité fournit des certificats gratuits X.509 pour le protocole cryptographique TLS au moyen d'un processus automatisé destiné à se passer du processus complexe actuel impliquant la création manuelle, la validation, la signature, l'installation et le renouvellement des certificats pour la sécurisation des sites internet1. » (Contenu soumis à la licence CC-BY-SA 3.0. Source : Article Let's Encrypt de Wikipédia en français (auteurs) )

Bref, c'est bien pratique pour faire du HTTPS (entre autres) et on peut automatiser le renouvellement des certificats. Il y a plusieurs années, j'aurais fait un cron, mais comme j'ai appris que systemd pouvait gérer des tâches répétitives, je me suis dit que c'était l'occasion de m'y mettre ! 😉

Comment on fait ?

Voici les étapes suivies, détaillées ci-dessous puis quelques documents qui m'ont permis de le faire, sans compter le conseil d'un ami: « T'as qu'à faire un timer ! » :

  • Copier certbot sur le serveur, logiciel (libre, non-copyleft) de gestion des certificats de Let's Encrypt
  • Créer un script pour renouveler les certificats avec certbot
  • Créer un service systemd pour lancer le script
  • Créer une minuterie (timer) systemd pour lancer le service à intervalles réguliers

Enfin, activer et lancer la minuterie puis vérifier que ça fonctionne.

1. Copier certbot sur le serveur

Je le copie dans le dossier /opt du serveur:

root@serveur:~# cd /opt/ && git clone https://github.com/certbot/certbot
[…]

2. Créer le script pour utiliser certbot

Le script se nomme certbot-renew, il est créé dans /opt/certbot/, au même endroit que certbot. Créez aussi le dossier pour les journaux avec la commande mkdir /var/log/letsencrypt/.

Si vous utilisez le serveur web apache, changez le service que systemd doit arrêter et redémarrer, en gras dans le code ci-dessous:

root@serveur:~# cat > /opt/certbot/certbot-renew << EOF
#!/bin/sh
# Inspired by <https://letsencrypt.org/getting-started/>
systemctl stop nginx.service
/opt/certbot/certbot-auto renew -nvv --standalone > /var/log/letsencrypt/renew.log 2>&1
LE_STATUS=$?
systemctl start nginx.service
if [ "$LE_STATUS" != 0 ]; then
echo Automated renewal failed:
tail -n 200 /var/log/letsencrypt/renew.log
exit 1
fi
EOF

3. Créer le service systemd

C'est ce service qui va lancer le script /opt/certbot/certbot-renew créé à l'étape précédente:

root@serveur:~# cat > /etc/systemd/system/certbot-renew.service << EOF
# Voir <https://mjanja.ch/2015/06/replacing-cron-jobs-with-systemd-timers/>
[Unit]
Description=Renouvellement des certificats letsencrypt

[Service]
Type=simple
nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
ExecStart=/opt/certbot/certbot-renew
EOF

4. Créer la minuterie systemd

C'est cette minuterie qui va lancer le service créé à l'étape précédente. Notez que la valeur daily pour OnCalendar lance le service à minuit. Comme le serveur était programmé pour faire d'autres choses à minuit, j'ai utilisé un autre moment. ^^

root@serveur:~# cat > /etc/systemd/system/certbot-renew.timer << EOF
# Voir <https://mjanja.ch/2015/06/replacing-cron-jobs-with-systemd-timers/>
[Unit]
Description=Renouvellement des certificats letsencrypt

[Timer]
#OnCalendar=daily
OnCalendar=*-*-* 04:20:42

[Install]
WantedBy=timers.target
EOF

 

Il ne reste plus qu'à activer cette minuterie pour qu'elle soit lancée à chaque démarrage du serveur:  systemctl enable certbot-renew.timer

Pour éviter un redémarrage, la minuterie peut être lancée manuellement: systemctl start certbot-renew.timer

Pour vérifier que tout fonctionne bien le service peut aussi être lancé manuellement: systemctl start certbot-renew.service. Vérifiez alors les journaux pour voir si tout s'est bien déroulé.

 

Voici donc comment j'ai procédé, il doit exister bien d'autres façons de faire, n'hésitez-pas à m'en faire part et/ou à améliorer ce que je présente ici.

Documentation, ressources:

Manuels de systemd: systemd.exec, systemd.service et systemd.timer.
Manuel de ioprio_set.
Remplacer les cron jobs par des minuteries systemd (en anglais).
Pour débuter avec Let's Encrypt (en anglais).

Un brin de persévérance, un tonneau de tests et quelques couplets de corrections. 😉

 

La brique en voyage

La situation

Il se trouve que j'ai déménagé récemment. J'en ai profité pour demander un abonnement Internet à l'association de la Fédération FDN de mon coin: Rézine. J'ai donc mis ma brique Internet chez quelqu'un, le temps que l'accès Internet soit en place.

Le problème

Quand j'ai connecté la brique depuis un autre accès Internet, plus rien n'a fonctionné : pas de nouvelles de la brique sur Internet, ni sur le réseau local ! 🙁

La solution

Note pour les avocats: cette solution a fonctionné chez moi, mais il y a un risque de perdre des données. Rien ne garanti qu'elle fonctionnera chez vous ! Je ne peux pas être tenu pour responsable des actions que vous faites. En cas de doute, demandez de l'aide au membre FFDN le plus proche de chez vous !

 

"Malheureusement", j'ai un modèle de brique datant de juillet 2015 (avec la migration du blog sur la brique fin 2015). Et une fois fonctionnelle, je ne me suis pas occupé de son entretien: ne pas toucher à quelque chose qui fonctionne me semble un bon conseil à suivre en informatique.

Mais là, je n'avais pas vu qu'il y avait des erreurs sur le disque. Ces erreurs n'ont été gênantes qu'une fois la brique éteinte et rallumée. J'ai donc pris le disque dur de la brique (la carte microSD) et je l'ai mis dans mon PC.

Puis, avec la commande lsblk j'ai vu que la partition de ce disque était /dev/sdc1; j'ai alors pu lancer une vérification du disque avec la commande suivante:

# fsck /dev/sdc1
[…là, ça défile et des fois ça pose des questions…]

Quand la question était posée de corriger les erreurs, j'ai répondu oui. Une fois toutes les erreurs corrigées, j'ai relancé la commande pour vérifier qu'il n'y avait plus d'erreur:

# fsck /dev/sdc1
fsck de util-linux 2.25.2
e2fsck 1.42.12 (29-Aug-2014)
/dev/sdc1 : propre, 93335/917568 fichiers, 848399/3859968 blocs

C'est alors, plein d'espoir que j'ai remis le disque dur dans la brique pour la brancher et l'allumer: ça marchait à nouveau ! 🙂

Deuxième problème

Tout content que la brique refonctionne, j'ai payé un coup à boire à la personne qui l'héberge et je suis rentré chez moi. C'est avec un peu de déception que j'ai réalisé le lendemain que la brique ne fonctionnait plus ! :'-(

Ce deuxième problème est aussi lié au fait que j'ai mis en place ma brique en juillet 2015: à partir du moment où l'application vpnclient mettait en place le tunnel chiffré, la brique n'avait plus accès aux DNS (dont on parle dans cette superbe conférence) !

Après demande d'information à mon fournisseur de tunnels, c'est normal pour pleins de raisons diffèrentes, bref je dois utiliser leur DNS.

Deuxième solution

Une fois le problème identifié, la solution n'est pas loin ! Ici, j'ai mis à jour l'application vpnclient et le tour était joué: la dernière version de cette application prends en compte les DNS ! \o/

Je peux donc maintenant bloguer à nouveau, par exemple pour indiquer comment j'ai déplacé ma brique ! 🙂

Prochaines étapes: mise en place de sauvegardes… Stay tuned for more info

 

Agendas dans La Brique Internet

Après avoir installé une brique Internet (notamment pour héberger ce blog),  je viens d'y ajouter l'application gérant les agendas. J'ai "tellement" galéré (j'y suis depuis ~1h30), que je note ici comment j'ai fait (même si j'espère bien ne pas avoir à le refaire de si tôt ! 🙂 ).

 

Installation de l'application des Agendas

L'application YUnoHost prévue pour les agendas s'appelle Baikal « Serveur CalDAV + CardDAV léger ».

Pas de souci de ce côté-là, juste un étonnement:

  • je configure le DNS pour un domaine dédié aux agendas: agenda.trankil.info (je préfère les sous-domaines aux sous-dossiers, chacun ses goûts)
  • je me connecte en administrateur,
  • j'indique le domaine (dans Domaines, puis Ajouter un domaine)
  • j'ai dû me déconnecter puis me reconnecter (soit je ne suis pas assez patient, soit c'est nécessaire 😉 )
  • j'installe l'application (dans Applications, puis +Installer j'ai choisi Baikal)
    Les paramètres sont assez clairs.
    Seul le chemin m'a étonné: bien que je veuille que l'application n'ait pas de sous-dossier, j'ai été obligé d'indiquer « / » pour son chemin (cela aura un impact sur la configuration, que j'explique un peu plus tard).
  • Au bout d'un moment, tout semble correct: je me déconnecte du compte administrateur.

Configuration de l'application

Pour configurer cette application, il faut ajouter /admin à son adresse. Cela semble évident dit comme ça, mais ça m'a bien pris 1/4 d'heure pour m'en rendre compte, grâce à ce message des forums de Yunohost.

Du coup, je vais sur https://agenda.trankil.info/admin en utilisant le mot de passe que j'ai choisi à l'installation.

L'identification par LDAP soit automatiquement configurée, ce qui m'a semblé logique pour utiliser les comptes YUnoHost existants sur ma brique (c'est le cas pour d'autres applications). Mais il semble que cela n'est pas implémenté dans Baikal !

Bref, après moults tests et tentatives d'utiliser mon compte habituel, en utilisant les menu en haut de page, j'ai configuré les éléments suivants:

  1. Dans la partie Users and resources, j'ajoute un compte utilisateur (un calendrier et un carnet d'adresses sont créés automatiquement)
  2. Dans la partie Settings, je change WebDAV authentication type pour utiliser Basic
  3. Dans la partie System Settings, je change CalDAV base URI et CardDAV base URI pour laisser "/cal.php/" en lieu et place du "//cal.php/" (avec les guillemets) apparaissant de prime abord (souvenez-vous mon étonnement ^_^)

Une fois l'application prête à l'emploi, je configure mon client CalDAV pour afficher mon agenda tout nouveau tout beau !

Utilisation de mes Agendas

Personnellement, j'utilise Lightning un module de Thunderbird, comme nous le recommandons à Demo-TIC. 😉

Pour ajouter mon nouvel agenda aux autres, j'ai tout simplement utilisé l'adresse indiquée dans la documentation de Baikal,(branche master: la version stable et pas celle en cours de développement) dans mon cas: https://agenda.trankil.info/cal.php/calendars/compte_utilisateur/default/ ce qui a enfin fonctionné !

 

Ça y est, mes collègues de Demo-TIC ne seront plus attirés par mes rendez-vous libres pour sauver le monde, mais seulement encouragés par ma dévotion à notre (future) Société Coopérative d'Intérêt Collectif Loi 2001 à but non lucratif en Informatique Libre, car j'aurai déplacé tous ces évènements dans mon agenda personnel ! 😀

Même si cela m'aura pris ~2h30 au final, que l'empire se tienne à carreau: la rébellion grandi chaque jour et les pingouins écrivent l'histoiremême en PDF !