renew-cert.sh/renew-cert.sh
2025-09-11 20:29:10 +02:00

385 lines
14 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
############################################################
# Decription: Renew certificate
# Author: Gilles Mouchet (gilles.mouchet@gmail.com)
# Creation Date: 11-Sep-2025
# Version: 1.0.0
#
# Changelog:
# V1.0.0 - 25-Sep-2025 - GMo
# Added
# - Creation of script from scratch
#
############################################################
#-----------------------------------------------------------------
# DON'T CHANGE ANYTHING FROM HERE
#-----------------------------------------------------------------
version="1.0.0"
# config
progName=`echo $0 | sed -e 's|.*/||g' | cut -f1 -d.`
confDir=/etc/$progName
cfgFile=$confDir/$progName.conf
logPath=/var/log/$progName
logFile=$logPath/$progName.log
# mail
mailSubject="[SUCCESS] - script result on `hostname`"
mailHeader="my_hdr From: GMO Check System <exploit.gmotech@gmail.com>"
mailBody=""
mailFooter="\n\n$progName script V$version on `hostname` by Exploit GMoTech"
tmpFile=/tmp/$progName.log
#-----------------------------------------------------------
# FUNCTIONS
#-----------------------------------------------------------
function usage() {
cat << EOF
Usage: ./$(basename "$0") options
Renew wilcard certificat
Options:
-d, --domain - domain name
-p, --param - display parameters
-h, --help - display this help
-v, --version - display script version
Example
Renew wildcard certificat for domain gmolab.net
./$(basename "$0") --domain gmolab.net
EOF
}
#-----------------------------------------------------------
function renewCertificate(){
log I "renew certificate"
log D "ca key file use $fullpkiRootPath/$caKeyFile"
log D "ca crt file use $fullpkiRootPath/$caCrtFile"
log D "ca csr file use $fullpkiRootPath/$certDomain.csr"
log D "bakup path file use $fullpkiRootPath/backup/"
# backup crt file
log I "copy $certFile to $fullpkiRootPath/backup/$certFile"
cp $fullpkiRootPath/$certFile $fullpkiRootPath/backup/$certFile-$(date +"%Y-%m-%d-%H-%M-%S") > $tmpFile
rc=$?
if [ "$rc" != "0" ];then
log I "send error message"
log E "a problem occurred while copying $certDomain certificate on $fullpkiRootPath/backup/$certFile ($rc)"
mailSubject="[ERROR] - a problem occurred while copying $certDomain certificate on $fullpkiRootPath/backup/$certFile ($rc)"
mailBody="Bad new!\n A problem occurred while copying $certDomain certificate on $fullpkiRootPath/backup/$certFile ($rc).\nHave a good day"
sendMail
endScript
fi
# renewal certificate
openssl x509 -req -in $fullpkiRootPath/$certDomain.csr \
-passin file:$caKeyCredFile \
-CA $fullpkiRootPath/$caCrtFile \
-CAkey $fullpkiRootPath/$caKeyFile \
-CAcreateserial \
-extfile $fullpkiRootPath/wilcard.cnf -out $fullpkiRootPath/$certFile \
-days $certDaysValidity -sha256 > $tmpFile 2>&1
rc=$?
if [ "$rc" != "0" ]; then
log I "send error message"
log E "a problem occurred while renewing $certDomain certificate ($rc)"
mailSubject="[ERROR] - a problem occurred while renewing $certDomain certificate ($rc)"
mailBody="Bad new!\n A problem occurred while renewing $certDomain certificate ($rc).\nHave a good day"
sendMail
rm -rf $tmpFile
else
endDateFo=$(openssl x509 -in $fullpkiRootPath/$certFile -noout -enddate | awk -F'=' '{print $2}' | xargs -I {} date -d "{}" '+%Y-%m-%d')
log I "certificate successfully renewed. New expiry date: $endDateFo"
log I "send a success mesaage"
mailSubject="[SUCCESS] - certificate for $certDomain successfully renewed. New expiry date: $endDateFo"
mailBody="Bad new!\n Certificate or $certDomain successfully renewed. New expiry date: $endDateFo.\nHave a good day"
sendMail
rm -rf $tmpFile
fi
}
#-----------------------------------------------------------
function sendMail() {
if [ -f "$tmpFile" ];then
echo -e "$mailBody $mailFooter" | mutt -e "$mailHeader" -s "${mailSubject}" $msgRecipient -a $tmpFile
else
echo -e "$mailBody $mailFooter" | mutt -e "$mailHeader" -s "${mailSubject}" $msgRecipient
fi
}
#-----------------------------------------------------------
# Function write log in file log
# parameter
# $1 define entry type (info, warning, error)
# $2 define text
function log() {
case "$1" in
I)
logType="[info]"
;;
W)
logType="[warning]"
;;
E)
logType="[error]"
;;
C)
logType="[critical]"
;;
D)
logType="[debug]"
;;
esac
# write all entries except [debug]
if [ "$logType" != "[debug]" ]; then
echo "[$(date "+%Y-%m-%d")-$(date "+%H:%M:%S")] - $logType - $2" >> "$logFile"
# display log entry on screen if onScreen is enabled
if [ "$onScreen" -eq 1 ];then
echo "[$(date "+%Y-%m-%d")-$(date "+%H:%M:%S")] - $logType - $2"
fi
fi
# write [debug] entries only if debug is enabled
if [ "$logType" == "[debug]" ] && [ "$debug" -eq 1 ]; then
echo "[$(date "+%Y-%m-%d")-$(date "+%H:%M:%S")] - $logType - $2" >> "$logFile"
# display log entry on screen if onScreen is enabled
if [ "$onScreen" -eq 1 ];then
echo "[$(date "+%Y-%m-%d")-$(date "+%H:%M:%S")] - $logType - $2"
fi
fi
}
#-----------------------------------------------------------
function endScript(){
log I "----- end script -----"
exit
}
#-----------------------------------------------------------
# MAIN
#-----------------------------------------------------------
# check if the effective user ID is 0 (root)
#if [[ $EUID -ne 0 ]]; then
# echo "This script must be run as root or with sudo."
# exit 1
#fi
# check if conf file or passphrase file exist
if [ ! -f $cfgFile ]; then
echo "$progName not installed correctly. Please run install.sh script"
exit 1
fi
# read config file
. $cfgFile
log I "----- script start -----"
# check if logPath exist
if [ ! -d $logPath ]; then
echo "$progName not installed correctly. Please run install.sh script"
endScript
fi
# check param exist. Uncomment if your script need parameters
if [ -z "$1" ]; then
usage
endScript
fi
while [[ "$#" -gt 0 ]]; do
case "$1" in
-d|--domain)
if [ -z "$2" ]; then
usage
endScript
else
certFile=$2.crt
certDomain=$2
log I "cert file $certFile"
fi
shift 2
;;
-p|--param)
log I "script run with -p or --param option"
cat << EOF
-------------------------------------------------------------------------------
Parameters
-------------------------------------------------------------------------------
Defined in script
-------------------------------------------------------------------------------
script name: $progName
config folder: $confDir
config file: $cfgFile
log path: $logPath
log file: $logFile
-------------------------------------------------------------------------------
Defined in $cfgFile
-------------------------------------------------------------------------------
message recipient: $msgRecipient
pki path: $pkiRootPath
display log on screen: $onScreen
debug mode: $debug
send warning mail
x days before
the end of validity: $warningDays
send critical mail
x days before
the end of validity: $criticalDays
certificate renewal
x days before
before the end of
the certificate validity: $renewDays
number of days
the certificate
is valid upon renewal: $certDaysValidity
sending an infor email: $infoMail
sending a warning email: $warningMail
sending a critical email: $criticalMail
sending a renewal email: $renewMail
EOF
endScript
;;
-v|--version)
log I "script run with -v or --verion option"
cat << EOF
$(basename "$0") v$version (c) 1990 - $(date +%Y) by Gilles Mouchet
Non-Commercial Use License See LICENSE for details
EOF
endScript
;;
# must be in the last block of the case because of *
*|help|-h|--help)
log I "script run with -h, --help option"
usage
endScript
;;
esac
shift
done
# check if pki folder and pki files for domain
fullpkiRootPath="$pkiRootPath/`echo $certFile | sed -e 's|.*/||g' | cut -f1 -d.`"
# check if backupcrtpath exist
if [ ! -d "$fullpkiRootPath/backup" ]; then
mkdir $fullpkiRootPath/backup
fi
# set credFile and check if exist
caKeyCredFile=$credFilePath/.$certDomain
if [ ! -e "$caKeyCredFile" ]; then
log E "$caKeyCredFile doesn't exist !"
log I "send error message"
mailSubject="[ERROR] - $caKeyCredFile doesn't exist !"
mailBody="Oups !\n$caKeyCredFile doesn't exist !.\nHave a good day"
sendMail
endScript
fi
log I "cred file $caKeyCredFile"
# set CA file name
caCrtFile="`echo $certFile | sed -e 's|.*/||g' | cut -f1 -d.`CA.crt"
caKeyFile="`echo $certFile | sed -e 's|.*/||g' | cut -f1 -d.`CA.key"
log I "ca files $caCrtFile and $caKeyFile are used"
# check if cert exist
if [ ! -f "$fullpkiRootPath/$certFile" ] || [ ! -f "$fullpkiRootPath/$caCrtFile" ] || [ ! -f "$fullpkiRootPath/$caKeyFile" ]; then
log E "$certFile, $caCrtFile or $caKeyFile on $fullpkiRootPath doesn't exist."
log I "send error message"
mailSubject="[ERROR] - $certFile, $caCrtFile or $caKeyFile on $fullpkiRootPath doesn't exist"
mailBody="Problem !\nT$certFile, $caCrtFile or $caKeyFile on $fullpkiRootPath doesn't exist.\nHave a good day"
sendMail
endScript
fi
log I "all files are present on $fullpkiRootPath"
# set end cert expiration date an convert in timestamp
endDateFo=$(openssl x509 -in $fullpkiRootPath/$certFile -noout -enddate | awk -F'=' '{print $2}' | xargs -I {} date -d "{}" '+%Y-%m-%d')
endDateTs=$(date -d "$endDateFo" +%s)
# set current date and convert it in timestamp
currentDateFo=$(date "+%Y-%m-%d")
currentDateTs=$(date -d "$currentDateFo" +%s)
#--------------------------------------------------------------------------------------------------------------------
#FOR DEV
# set debug=1 and onScreen=1 in /etc/renew-cert/renew-cert.conf
#endDateFo="2025-11-14"
#endDateTs=$(date -d "$endDateFo" +%s)
#currentDateFo="2025-10-10"
#currentDateTs=$(date -d "$currentDateFo" +%s)
# END FOR DEV
#--------------------------------------------------------------------------------------------------------------------
# set the low and the hight threshold for warning message
warningMsgLowDateTs=$((endDateTs - (warningDays * 86400)))
warningMsgLowDateFo=$(date -d "@$warningMsgLowDateTs" "+%Y-%m-%d")
warningMsgHighDateTs=$((endDateTs - (criticalDays * 86400)- 86400))
warningMsgHighDateFo=$(date -d "@$warningMsgHighDateTs" "+%Y-%m-%d")
# set the low and the hight threshold for critical message
criticalMsgLowDateTs=$((endDateTs - (criticalDays * 86400)))
criticalMsgLowDateFo=$(date -d "@$criticalMsgLowDateTs" "+%Y-%m-%d")
criticalMsgHighDateTs=$((endDateTs - (renewDays * 86400)))
criticalMsgHighDateFo=$(date -d "@$criticalMsgHighDateTs" "+%Y-%m-%d")
# set the renewal dat
tmpNbrDaysTd=$((renewDays * 86400 ))
renewDateTs=$((endDateTs-tmpNbrDaysTd))
renewDateFo=$(date -d "@$renewDateTs" "+%Y-%m-%d")
# set number days before end today and expiration date
daysLeftTs=$((endDateTs-currentDateTs))
daysLeftFo=$((daysLeftTs / 86400))
daysPassTs=$((currentDateTs-endDateTs))
daysPassFo=$((daysPassTs / 86400))
log D "current date : $currentDateFo ($currentDateTs)" $onScreen
log D "certificate expiration date : $endDateFo ($endDateTs)" $onScreen
log D "nbr. of days before cert expires : $daysLeftFo ($daysLeftTs)" $onScreen
log D "warning mail will be send from $warningMsgLowDateFo ($warningMsgLowDateTs) to $warningMsgHighDateFo ($warningMsgHighDateTs)" $onScreen
log D "critical mail will be send from $criticalMsgLowDateFo ($criticalMsgLowDateTs) to $criticalMsgHighDateFo ($criticalMsgHighDateTs)" $onScreen
log D "certificate renew date to $renewDateFo ($renewDateTs)" $onScreen
# actions to do based on the number of days remaining
# Warning
if [ "$daysLeftFo" -le "$warningDays" ] && [ "$daysLeftFo" -gt "$criticalDays" ]; then
log W "the $certDomain certificate will expire in $daysLeftFo days ($endDateFo)."
if [ "$warningMail" -eq 1 ]; then
log I "send warning message"
mailSubject="[WARNING] - the $certDomain certificate will expire in $daysLeftFo days ($endDateFo)."
mailBody="Demands your attention!\nThe $certDomain certificate will expire in $daysLeftFo days ($endDateFo).\nHave a good day"
sendMail
fi
# critical
elif [ "$daysLeftFo" -le "$criticalDays" ] && [ "$daysLeftFo" -gt "$renewDays" ]; then
log C "the $certDomain certificate will expire in $daysLeftFo days ($endDateFo). Urgent renewal required."
if [ "$criticalMail" -eq 1 ]; then
log I "send critical message"
mailSubject="[CRITICAL] - the $certDomain certificate will expire in $daysLeftFo days ($endDateFo). Urgent renewal required."
mailBody="ATTENTION!\nThe $certDomain certificate will expire in $daysLeftFo days ($endDateFo). Urgent renewal required.\nHave a good day"
sendMail
fi
# renew
elif [ "$daysLeftFo" -eq "$renewDays" ]; then
log C "the '$certDomain' certificate expires in $daysLeftFo ($endDateFo) day. Renew immediately!"
renewCertificate
# expired
elif [ "$daysLeftFo" -le 0 ]; then
log C "the '$certDomain' certificate expired $daysPassFo ($endDateFo) days ago."
log I "send error message"
mailSubject="[CRITICAL] - the '$certDomain' certificate expired $daysPassFo ($endDateFo) days ago."
mailBody="Bad new !\nThe '$certDomain' certificate expired $daysPassFo ($endDateFo) days ago. \nHave a good day"
sendMail
else
# certificat ok
log I "the '$certDomain' certificate is valid. There are $daysLeftFo days left before expiration ($endDateFo)."
if [ "$infoMail" -eq 1 ]; then
log I "send info message"
mailSubject="[INFO] - the '$certDomain' certificate is valid. There are $daysLeftFo days left before expiration ($endDateFo)."
mailBody="All is ok!\nThe '$certDomain' certificate is valid. There are $daysLeftFo days left before expiration ($endDateFo).\nHave a good day"
sendMail
fi
fi
log I "----- end script -----"