Recupérer un certificat présent sur PFsense depuis Jeedom

Pourquoi faire cela, me direz vous … tout simplement pour deleger la gestion et la création des certificats a une seule machine sur votre réseau. un autre avantage, vous ne devez pas customiser votre jeedom pour que cela fonctionne, en cas de problème, il ne faut pas installer des packages sur l’os de Jeedom.

on va commencer par se connecter sur le pfsense pour recupéré une info. Allez dans System > Cert. Manager et dans l’onglet Certificates.

si vous mettez votre curseur sur le petit soleil, en bas, apparait une url:

l’info que l’on a besoin, c’est la valeur de l’ID (dans mon cas, 1). On note cette info et l’on va dans le plugin script de jeedom. on crée un nouveau script:

il y a un cron actif dessus, il va tourner 2 fois par mois pour mettre a jour le certificat du jeedom. et dans la partie commande, j’ai ceci:

on pointe vers un script s’appelant Certificat.sh et voila son contenu:
ce qui est important de changer pour vous dans ce script, ce sont les variables,
PFSENSE_HOST : le nom ou l’ip de votre pfsense
PFSENSE_ID : l’id du certificat (récupéré juste avant)
PFSENSE_USER : le user utilisé pour se connecter sur le fw
PFSENSE_PASS : et son password
CERT_DIR : le dossier sur jeedom où seront importés les certificats

#!/bin/sh
#
VERSION="2020.01.01_wget"
RUNDIR="$( cd "$( dirname "$0" )" && pwd )"
#
##############################
######### VARIABLES  #########
#
# pfSense host OR IP (note: do not include the final /)
PFSENSE_HOST=https://192.168.1.1
#
# l'ID du certificat dans pfsense (System > Certificate Manager > Certificates)
PFSENSE_ID=6
# login - password
PFSENSE_USER=CompteUtilisateur
PFSENSE_PASS=MotDePasseUtilisateur
#
# where to store backups
CERT_DIR="/var/www/html/plugins/script/core/ressources"

######## END VARIABLES ########
###############################
#
#########################################
#
#
wget -V $i >/dev/null 2>&1 || { echo "ERROR : wget MUST be installed to run this script."; exit 1; }
#
echo "*1*"

COOKIE_FILE="`mktemp $CERT_DIR/pfsbck.XXXXXXXX`"
CSRF1_TOKEN="`mktemp $CERT_DIR/csrf1.XXXXXXXX`"
CSRF2_TOKEN="`mktemp $CERT_DIR/csrf2.XXXXXXXX`"
CONFIG_TMP="`mktemp $CERT_DIR/config-tmp-xml.XXXXXXXX`"

#
unset RRD PWD PKG
#
#
if [ "$BACKUP_RRD" = "0" ] ;	 then RRD="&donotbackuprrd=yes" ; fi
if [ "$BACKUP_PKGINFO" = "0" ] ; then PKG="&nopackages=yes" ; fi
if [ -n "$BACKUP_PASSWORD" ] ; 	 then PWD="&encrypt_password=$BACKUP_PASSWORD&encrypt_passconf=$BACKUP_PASSWORD&encrypt=on" ; fi
#
mkdir -p "$CERT_DIR"
#
# fetch login
wget -qO- --proxy=off --keep-session-cookies --save-cookies $COOKIE_FILE --no-check-certificate "$PFSENSE_HOST/system_certmanager.php" | grep "name='__csrf_magic'" | sed 's/.*value="\(.*\)".*/\1/' > $CSRF1_TOKEN || echo "ERROR: FETCH"
#
# submit the login
wget -qO- --proxy=off --keep-session-cookies --load-cookies $COOKIE_FILE  --save-cookies $COOKIE_FILE --no-check-certificate  --post-data "login=Login&usernamefld=${PFSENSE_USER}&passwordfld=${PFSENSE_PASS}&__csrf_magic=$(cat $CSRF1_TOKEN)" "$PFSENSE_HOST/system_certmanager.php?act=exp&id=$PFSENSE_ID"  | grep "name='__csrf_magic'" | sed 's/.*value="\(.*\)".*/\1/' > $CSRF2_TOKEN || echo "ERROR: SUBMIT THE LOGIN"
#
# submit download to save config CRT
wget --proxy=off --keep-session-cookies --load-cookies $COOKIE_FILE --no-check-certificate --post-data "__csrf_magic=$(head -n 1 $CSRF2_TOKEN)" "$PFSENSE_HOST/system_certmanager.php?act=exp&id=$PFSENSE_ID" -qO $CONFIG_TMP || echo "ERROR: SAVING CRT FILE"
#
# check if credentials are valid
if grep -qi 'username or password' $CONFIG_TMP; then
        echo ; echo "   !!! AUTHENTICATION ERROR (${PFSENSE_HOST}): PLEASE CHECK LOGIN AND PASSWORD"; echo
        rm -f $CONFIG_TMP
        exit 1
fi
#
#
# crt file contains doctype when the URL is wrong
if grep -qi 'doctype html' $CONFIG_TMP; then
        echo ; echo "   !!! URL ERROR (${PFSENSE_HOST}): HTTP OR HTTPS ?"; echo
        rm -f $CONFIG_TMP
        exit 1
fi
#
cert_file="Certificat.crt"
#
# definitive config file name
mv -f "$CERT_DIR/$cert_file" "$CERT_DIR/Certificat.crt.old" 
mv -f $CONFIG_TMP "$CERT_DIR/$cert_file" && echo "Backup OK : $CERT_DIR/$cert_file" || echo "Backup NOK !!! ERROR !!!"
#
# submit download to save config KEY
wget --proxy=off --keep-session-cookies --load-cookies $COOKIE_FILE --no-check-certificate --post-data "__csrf_magic=$(head -n 1 $CSRF2_TOKEN)" "$PFSENSE_HOST/system_certmanager.php?act=key&id=$PFSENSE_ID" -qO $CONFIG_TMP || echo "ERROR: SAVING KEY FILE"
#
# check if credentials are valid
if grep -qi 'username or password' $CONFIG_TMP; then
        echo ; echo "   !!! AUTHENTICATION ERROR (${PFSENSE_HOST}): PLEASE CHECK LOGIN AND PASSWORD"; echo
        rm -f $CONFIG_TMP
        exit 1
fi
#
#
# key file contains doctype when the URL is wrong
if grep -qi 'doctype html' $CONFIG_TMP; then
        echo ; echo "   !!! URL ERROR (${PFSENSE_HOST}): HTTP OR HTTPS ?"; echo
        rm -f $CONFIG_TMP
        exit 1
fi
#
cert_file="Certificat.key"
#
# definitive config file name
mv -f "$CERT_DIR/$cert_file" "$CERT_DIR/Certificat.key.old" 
mv -f $CONFIG_TMP "$CERT_DIR/$cert_file" && echo "Backup OK : $CERT_DIR/$cert_file" || echo "Backup NOK !!! ERROR !!!"
# submit download to save config Chain
wget --proxy=off --keep-session-cookies --load-cookies $COOKIE_FILE --no-check-certificate --post-data "__csrf_magic=$(head -n 1 $CSRF2_TOKEN)" "$PFSENSE_HOST/system_camanager.php?act=exp&id=0" -qO $CONFIG_TMP || echo "ERROR: SAVING CHAIN FILE"
#
# check if credentials are valid
if grep -qi 'username or password' $CONFIG_TMP; then
        echo ; echo "   !!! AUTHENTICATION ERROR (${PFSENSE_HOST}): PLEASE CHECK LOGIN AND PASSWORD"; echo
        rm -f $CONFIG_TMP
        exit 1
fi
#
#
# chain file contains doctype when the URL is wrong
if grep -qi 'doctype html' $CONFIG_TMP; then
        echo ; echo "   !!! URL ERROR (${PFSENSE_HOST}): HTTP OR HTTPS ?"; echo
        rm -f $CONFIG_TMP
        exit 1
fi
#
cert_file="CertificatChain.crt"
#
# definitive config file name
mv -f "$CERT_DIR/$cert_file" "$CERT_DIR/CertificatChain.crt.old" 
mv -f $CONFIG_TMP "$CERT_DIR/$cert_file" && echo "Backup OK : $CERT_DIR/$cert_file" || echo "Backup NOK !!! ERROR !!!"
#
#
# cleaning tmp and cookie files
rm -f "$COOKIE_FILE" "$CSRF1_TOKEN" "$CSRF2_TOKEN"
#
sudo service apache2 restart
echo
exit 0

Le script va prendre les certificats (clés publiques et clé privée) et les mettre dans le dossier /var/www/html/plugins/script/core/ressources. je les ai placé a cet endroit pour ne pas avoir de problème de droit. Les certificats qui arrivent en fin de vie sont déplacés (CertificatXXxx.crt.old) comme cela en cas d’erreur, il est possible de les remettre en place. Le serveur apache est redémarré pour prendre en compte les nouveaux certificats.

il reste plus qu’une chose a faire si les fichiers sont bien présent, activer le ssl sur le serveur apache et lier ces certificats au serveur:

a2enmod ssl
a2ensite default-ssl.conf
systemctl restart apache2
nano /etc/apache2/sites-enabled/default-ssl.conf

On ajoute le champ

ServerName jeedom.XXxxXxxX.ovh:443

on modifie les champs SSLCertificateFile, SSLCertificateKeyFile et SSLCertificateChainFile avec les nouveaux fichiers.

SSLCertificateFile      /var/www/html/plugins/script/core/ressources/Certificat.crt
SSLCertificateKeyFile /var/www/html/plugins/script/core/ressources/Certificat.key
SSLCertificateChainFile /var/www/html/plugins/script/core/ressources/CertificatChain.crt