Tuto : Gestion du renouvellement d'un certificat Let's Encrypt via scenario Jeedom

Bonjour à tous,

Ayant été confronté récemment (et pendant mes vacances, loin de chez moi) à un pb de renouvellement du certificat https de mon Jeedom, je me suis lancé dans la réalisation d’un scenario de vérification, de renouvellement et de notification de pbs de renouvellement du certificat de mon jeedom.
je poste ici la procédure si ceci intéresse du monde.

Prerequis : une configuration HTTPS foncitonnelle avec un certificat let’s encrypt et cerbot installé
J’utilisse pour notifier le plugin-jeedomconnect mais vous pouvez bien sur personnaliser avec un autre plugin de notification
Rappel 1 concernant les certificat Let’s Encrypt : ils sont valables 90 jours et peuvent etre renouveler au bout de 60 jours, soit lorsqu’il reste 30jours
Rappel 2 : le renouvellement necessite un accès http exterieur au serveur (port 80) pour fonctionner
(en bonus, comment paramétrer son Jeedom pou rne plus avoir besoin d’ouvri le port 80 avec OVH - challenge DNS : Tuto : Gestion du renouvellement d'un certificat Let's Encrypt via scenario Jeedom - #37 par ngrataloup)

Et le scenario à telecharger et installer avec le modele ci-après :
Renouvellement_certificat.json.txt (8,3 Ko)

Fonctionnement du scenario
Une première partie pour les « variables ». NORMALEMENT, vous n’avez que ca à modifier (pour les utilisateurs du plugin plugin-jeedomconnect)

  • domaine : le domaine à gerer (en fait, le nom du certificat)
  • expirationAlerte : le nb de jours restants pour le certificat avant d’etre alerté d’un pb de renouvellement
  • renewAuto : l’activation (1) ou non (0) du renouvellement auto
  • renewDate : le nb de jours restants pour réaliser un renouvellement
  • cmdNotifOK et cmdNotifErreur : les commandes de notification

Pour le fonctionnement du scenario :
Il commence par vérifier pour le certificat en question la date d’expiration et le nb de jours restants
il renvoie une erreur si le nb de jours restant est inferieur à $expirationAlerte ou n’est pas numérique (erreur avec la commande ssh !)
si le nb de jours restants est inferieur à renewDate et que le renouvellement auto est activé, il renouvelle le certificat et envoie une notif en fonction du résultat.

Ex d’une notif JC de renouvellement en erreur :

le bloc code brut pour ceux qui preferent plutot que le template de scenario :

$tags=$scenario->getTags(); // récupération des tag du scénario
$domaine=$tags['#domaine#'];
$alerte=$tags['#expirationAlerte#'];
$renewAuto =$tags['#renewAuto#'];
$renewDate =$tags['#renewDate#'];
$cmdNotifOK = cmd::byString('#'.$tags['#cmdNotifOK#'].'#');
$cmdNotifErreur = cmd::byString('#'.$tags['#cmdNotifErreur#'].'#');

// Execution de commandes SSH pour determination de la date de renouvellement
$expirationDate = date("d/m/Y",strtotime(str_replace(CHR(10),"",shell_exec ("sudo certbot certificates --cert-name ".$domaine." | grep 'Expiry Date'| awk '{print $3}'"))));
$expirationDay = str_replace(CHR(10),"",shell_exec ("sudo certbot certificates --cert-name ".$domaine." | grep 'Expiry Date'| awk '{print $6}'"));


if ( $expirationDay <= $alerte || is_numeric($expirationDay) == 0 ) {
  $msgErreur = 'Erreur de renouvellement du certificat pour le domaine '.$domaine.', Pas de date d\'expiration ou date d\'expiration inferieure à '.$alerte.'<br>verifier la commande ci-dessous en ssh<br>sudo certbot certificates --cert-name '.$domaine ;
  $scenario->setlog($msgErreur);
  $cmdNotifErreur->execCmd($options = array('title' => 'title=Erreur renouvellement du certificat', 'message' => $msgErreur , $cache   = 0));
}
else {
  if ( $renewAuto == 1 ) {
    if ( $expirationDay <= $renewDate ) {
      // Renouvellement auto si necessaire
  	  $statutRenew = shell_exec ("sudo certbot renew --cert-name ".$domaine." | grep -c 'Congratulations, all renewals succeeded'");
  	  if ( $statutRenew == 1 ) { 
        $expirationDate = date("d/m/Y",strtotime(str_replace(CHR(10),"",shell_exec ("sudo certbot certificates --cert-name ".$domaine." | grep 'Expiry Date'| awk '{print $3}'"))));
        $expirationDay = str_replace(CHR(10),"",shell_exec ("sudo certbot certificates --cert-name ".$domaine." | grep 'Expiry Date'| awk '{print $6}'"));
        $msgOK='Renouvellement du certificat pour le domaine '.$domaine.', nouvelle expiration dans '.$expirationDay.' jours ('.$expirationDate.')';
        $scenario->setlog($msgOK);
        $cmdNotifOK->execCmd($options = array('title' => 'title=Renouvellement du certificat', 'message' => $msgOK , $cache   = 0));
      }
  	  else {
        $msgErreur = 'Erreur de renouvellement du certificat pour le domaine '.$domaine.', expiration dans '.$expirationDay.' jours ('.$expirationDate.')<br>Essayer la commande ci-dessous en SSH<br>sudo certbot renew --cert-name '.$domaine;
        $scenario->setlog($msgErreur);
        $cmdNotifErreur->execCmd($options = array('title' => 'title=Erreur renouvellement du certificat', 'message' => $msgErreur , $cache   = 0));
      }
    }
    else $scenario->setlog('Aucun renouvellement de certificat à réaliser pour le domaine '.$domaine.', expiration dans '.$expirationDay.' jours ('.$expirationDate.')');
  }
  else {
    $scenario->setlog('Renouvellement automatique desactivé pour le domaine '.$domaine.', Expiration dans '.$expirationDay.' jours ('.$expirationDate.')') ;
    if ( $expirationDay <= $renewDate ) {
      $msgRenew = 'Renouvellement nécessaire du certificat pour le domaine '.$domaine.', Expiration dans '.$expirationDay.' jours ('.$expirationDate.')' ;
      $scenario->setlog($msgRenew) ;
      $cmdNotifErreur->execCmd($options = array('title' => 'title=renouvellement nécessaire du certificat', 'message' => $msgRenew , $cache   = 0));
    }
  }
}

Esperant que ca puisse aider quelques jeedomiens

Norbert

11 « J'aime »

Hello,

Perso j’utilise plus en passant directement via jeedom, mais si quelqu’un pouvait confirmer, ça serait sympa :wink:

Confirmer quoi ?

1 « J'aime »

Re,

la procédure, pour le commun des mortels :wink:

sinon merci pour le tuto :wink:

Comment cela fonctionne quand nous sommes sur une période où le port 80 est nécessaire ?
Merci

Un reverse proxy comme haproxy par exemple, sinon un autre port peut être utilisé, à passer en paramètre sur la commande certbot

2 « J'aime »

J’essayerai ceci ! t je mettrai à jour le tuto en conséquence.
Merci pour le tuyau

Bonjour,

Certbot peut faire ça pour toi tous les jours en automatique.
Pourquoi tu n’utilises pas ?

1 « J'aime »

Parceque justement, la dernière fois, il n’a pas mis à jour parceque je n’avais pas ouvert le port (et oui, le pb est toujours au même endroit :disappointed_relieved:)
Du coup, je le fais toujours via cerbot, mais pas par le cron, par scénario, avec une gestion de notifications d’alerte si le renouvellement ne passe pas.

Norbert

1 « J'aime »

Ah OK.
Il n’y a pas le problème avec ngnix par exemple, Certbot adapte la config pour la verif et en temps normal le traffic sur le 80 est forcé sur le 443.

Pas moyen de faire ça avec apache ?

Aucune idée, mais je suis preneur d’une solution pour éviter d’avoir à ouvrir un port sur ma box simplement pour un renouvellement de certificat. Donc, les avis/solution de chacun sont les bienvenues.

Norbert

Salut,

Le port 80 devra nécessaire être ouvert mais @Mips parle de faire en sorte qu’Apache redirige les requêtes sur le port 443 pour basculer en HTTPS.

super basique comme question, voir trivial. Avec apache on peut très simplement rediriger le flux sur le port 80 vers 443 via une règle dans les définitions de site. De cette manière on peut laisser le port 80 du serveur ouvert sans souci.

<VirtualHost *:80> 
  ServerName monjeedom.fr
  ServerAlias www.monjeedom.fr

  Redirect permanent / https://monjeedom.fr/
</VirtualHost>
2 « J'aime »

Fait et opérationnel, effectivement, je n’y avais jamais pensé !!! :thinking:
Reste plus qu’à tester que le renouvellement foncitonne, (mais il faut que j’attende 3 jours, j’ai grillé toutes mes cartouches coté let’s encrypt et j’ai été banni pour quelques heures avec mes tests)
Merci pour l’astuce (c’ets toujours basique lorsqu’on l’a en tete :sweat_smile:)

pas de bol, mais bon d’ici 3 jours tu auras résolu ton souci :slight_smile:

petit détail complémentaire, je ne sais pas si tu utilises DDNS, l’adresse au moment du renouvellement devra également être bien prise en compte. C’est un gag possible, j’ai déjà vu le cas de figure où l’adresse IP change pendant la nuit, DDNS ne le voit pas tout de suite et du coup les redirections ne marchent plus (d’ailleurs aussi en https). depuis ce temps là je dépense 10 euros par an pour avoir mon nom de domaine.

1 « J'aime »

C’est exactement pour tout ces trucs que j’ai mis en place ce scenario qui me permets de (en fonction de mes paramétrages !):
1 - Renouveler automatiquement le certif à partir de J-25, et m’alerter lorsqu’il a été renouvelé
2 - M’alerter si le renouvellement ne marche pas (alerte quotidienne)
3 - M’alerter si il ne reste que 10jours avant l’expiration du certificat
Les alertes arrivent via Jeedom Connect, donc comme notif Android, impossible à rater !

Bonjour,

Pour ceux qui on leur propre nom de domaine, vous pouvez aussi utiliser le challenge dns ce qui évite d’avoir à ouvrir le port 80 pour le renouvellement

3 « J'aime »

Est-ce possible avec un domaine ovh?

Antoine

1 « J'aime »

Oui. Il y a beaucoup de fournisseurs de supportés dont ovh

3 « J'aime »

C’est quoi le challenge dns ?