#!/bin/bash #set -x # --------------------- # Version: 1.2 # Update: 2017/05/31 # --------------------- # 2017/05/31 # Version: 1.2 # Bug mineur. # 2016/05/31 # Version: 1.1 # Donne la priorité au fichier sans prefixe numérique (000_xxx) # Nécessaire depuis la version 0.7.0 de letsencrypt-auto # 2016/04/15 # Version: 1.0 # 1er version publique usage() { cat - << __EoF__ Usage: $0 {check|renew} " check Test la validité des certificats, sinon, force un renouvellement immediat. (le renouvellement est forcé à partir de 10 jours avant expiration) renew Force un renouvellement immediat. Répertoire de travail, comprenant un fichier de nommé "certs.ini" Testé avec letsencrypt-auto version 0.7.0 . La configuration "let's encrypt" est dans le fichier nommé "config.ini" Le sous-répertoire "cur" contient les certificats valides: Soit: /cur/cert.pem /cur/chain.pem /cur/fullchain.pem La configuration doit préciser que les certificats générer doivent être stockés dans: /tmp_new ... et avec le bon nom pour chaque certificat, soit: cert.pem chain.pem fullchain.pem Exemple de configuration (.ini): # Requête de signature csr = /root/le_certs/webmail.tjaouen.fr/request.csr # Il faut que les fichiers généres arrivent dans le dossier temporaire cert-path = /root/le_certs/webmail.tjaouen.fr/tmp_new/cert.pem fullchain-path = /root/le_certs/webmail.tjaouen.fr/tmp_new/fullchain.pem chain-path = /root/le_certs/webmail.tjaouen.fr/tmp_new/chain.pem email = noreply@eez.fr authenticator = webroot webroot-path = /var/www/letsencrypt-challenge text = true non-interactive = true agree-tos = true no-self-upgrade = true # ------------ #staging = true quiet = true Exemples: # $0 check /root/le_certs/www.eez.fr Forcer un renouvellement immediat (non recommandé, sauf si 'staging = true' # $0 renew /root/le_certs/webmail.eez.fr Idem # EXP_NOW=y $0 check /root/le_certs/reload.eez.fr Changer le nom du fichier a 'toucher' # TOUCH_FILE='/tmp/newcerts' $0 check /root/le_certs/domain1 Si on ne veut rien 'toucher' # TOUCH_FILE=/dev/null $0 check /root/le_certs/domain1 __EoF__ exit 1 } MODE=$1 [ -n "$MODE" ] || usage DIR=$2 [ -n "$DIR" ] || usage # --------------------------------- LE_INI="$DIR/config.ini" if [ ! -d "$DIR" ]; then echo "Répertoire inexistant: $DIR" >&2 exit 1 fi if [ ! -f "$LE_INI" ]; then echo "Configuration introuvable: $LE_INI" >&2 exit 1 fi [ -n "$TOUCH_FILE" ] || TOUCH_FILE="/var/run/~newcerts" [ -n "$EXP_SECONDS" ] || EXP_SECONDS=$(( 10*24*60*60 )) ; # 10 jours... #EXP_NOW='y' ; # non vide -> renouvelle la clé TMPDIR="$DIR/tmp_new" NEWDIR="$DIR/new" CURDIR="$DIR/cur" OLDDIR="$DIR/trash" [ -d "$TMPDIR" ] || mkdir "$TMPDIR" NAME_CERT_PEM='cert.pem' NAME_CHAIN_PEM='chain.pem' NAME_FULLCHAIN_PEM='fullchain.pem' if [ "$MODE" = "renew" ]; then # 2017/05/31 : vider le répertoire temporaire [ -d "$TMPDIR" ] && rm -f "$TMPDIR/"* >/dev/null 2>&1 letsencrypt-auto certonly --config "$LE_INI" || exit exec "$0" "check" "${DIR}" exit fi final_newcerts() { touch "$TOUCH_FILE" echo "---------------------" echo "Nouveaux certificats:" echo "---------------------" echo "$CUR_cert_pem" echo "$CUR_chain_pem" echo "$CUR_fullchain_pem" echo "---------------------" } get_new_cert() { for N in "$@" do # ---------------------------- # Update: 2016/05/31 # Suite a m-a-j letsencrypt-auto > 0.5 # Verifier d'abord si le fichier n'existe pas déjà # sans le prefix de numerotation. # ----------------------------- C="" if [ -f "$TMPDIR/$N" ]; then # Existe sans prefixe C="$TMPDIR/$N" else # N'existe pas: recherche par prefix numeroté... C=$( ls -1 "$TMPDIR/0"*"_$N" 2>/dev/null | sort | tail -n 1 ) fi # ---------------------------- if [ -n "$C" ]; then [ -d "$NEWDIR" ] || mkdir "$NEWDIR" || exit cp -fpl "$C" "$NEWDIR/$N" || exit fi done } install_cur() { # Backup d'abord... if [ -d "$CURDIR" ]; then [ -d "$OLDDIR" ] || mkdir "$OLDDIR" || exit # Purge d'abord find "$OLDDIR"/ -mindepth 1 -mtime +180 \( -type f -delete \) -o \( -type d -empty -delete \) # Puis mv mv -f --backup=t "$CURDIR" "$OLDDIR"/ || exit fi # Et puis on installe les nouveaux certificat if [ -d "$NEWDIR" ]; then mv -T "$NEWDIR" "$CURDIR" || exit # on vide si tout va bien. rm -f "$TMPDIR/"* >/dev/null 2>&1 fi } if [ "$MODE" != "check" ]; then echo "Commande inconnue: $MODE" >&2 exit 1 fi CUR_cert_pem="$CURDIR/$NAME_CERT_PEM" CUR_chain_pem="$CURDIR/$NAME_CHAIN_PEM" CUR_fullchain_pem="$CURDIR/$NAME_FULLCHAIN_PEM" get_new_cert $NAME_CERT_PEM $NAME_CHAIN_PEM $NAME_FULLCHAIN_PEM NEW_CERTS= if [ ! -f "$CUR_cert_pem" ] || [ ! -f "$CUR_chain_pem" ] || [ ! -f "$CUR_fullchain_pem" ] ; then install_cur if [ ! -f "$CUR_cert_pem" ]; then # Aucun certificat dans la file... # En créer... exec "$0" "renew" "${DIR}" exit fi NEW_CERTS=y fi if [ -f "$NEWDIR/$NAME_CERT_PEM" ] && [ "$NEWDIR/$NAME_CERT_PEM" -nt "$CUR_cert_pem" ]; then # new remplace cur... # Tester d'abord... if ! openssl x509 -in "$NEWDIR/$NAME_CERT_PEM" -noout -checkend 0 >/dev/null ; then echo "La nouvelle clé ne passe pas le checkend" >&2 exit 1 fi install_cur final_newcerts exit 0 fi # La clé va expirer ? if [ -z "$EXP_NOW" ] && openssl x509 -in "$CUR_cert_pem" -noout -checkend "$EXP_SECONDS" ; then [ -z "$NEW_CERTS" ] || final_newcerts exit 0 fi # La clé a expirée... # En créer une nouvelle: exec "$0" "renew" "${DIR}" exit # ------------------------------ # EOF