From 4af2f65fb4798bd57c1bfe332fe2d682165e1b39 Mon Sep 17 00:00:00 2001 From: "Hahn Axel (hahn)" <axel.hahn@unibe.ch> Date: Wed, 8 Jan 2025 13:56:06 +0100 Subject: [PATCH] remove bak file --- cm.sh__bak | 963 ----------------------------------------------------- 1 file changed, 963 deletions(-) delete mode 100755 cm.sh__bak diff --git a/cm.sh__bak b/cm.sh__bak deleted file mode 100755 index f44368a..0000000 --- a/cm.sh__bak +++ /dev/null @@ -1,963 +0,0 @@ -#!/usr/bin/env bash -# ====================================================================== -# -# WRAPPER FOR ACME.SH -# Let's Encrypt client -# -# requires -# - bash -# - openssl -# - curl -# - dig (opional) -# - acme.sh client -# -# ---------------------------------------------------------------------- -# 2021-02-02 <axel.hahn@iml.unibe.ch> first lines -# 2021-02-10 <axel.hahn@iml.unibe.ch> compare hashes, logging -# 2021-02-12 <axel.hahn@iml.unibe.ch> added self test -# 2021-02-17 <axel.hahn@iml.unibe.ch> ensure checks list of aliases; new: optional host filter before adding a cert -# 2021-03-12 <axel.hahn@iml.unibe.ch> create file for haproxy -# 2021-03-22 <axel.hahn@iml.unibe.ch> for haproxy: use chained cert instead of server cert -# 2021-04-12 <axel.hahn@iml.unibe.ch> reject multiple usage of fqdn in cli params -# 2021-04-12 <axel.hahn@iml.unibe.ch> optional: force excecution with a given user only -# 2021-06-24 <axel.hahn@iml.unibe.ch> added transfer command; delete files if acme.sh --install-cert ... failes -# 2021-07-14 <axel.hahn@iml.unibe.ch> added _wait_for_free_slot in cert actions to execute multiple processes sequentially -# 2021-09-27 <axel.hahn@iml.unibe.ch> softer behaviour: do not revoke changed certs (add does not stop; ensure does not delete) -# 2021-12-23 <axel.hahn@iml.unibe.ch> added param --trace as 1st param to generate a trace log -# 2022-01-10 <axel.hahn@iml.unibe.ch> _wait_for_free_slot: exclude ssh calls -# 2022-03-30 <axel.hahn@iml.unibe.ch> remove usage of csr and generation of key file -# 2022-03-31 <axel.hahn@iml.unibe.ch> dns authentication with alias domain -# 2022-04-04 <axel.hahn@iml.unibe.ch> Bugfix: copy key from csr folder to ~/.acme/ -# 2022-04-04 <axel.hahn@iml.unibe.ch> added param "list-old" -# 2022-04-07 <axel.hahn@iml.unibe.ch> fix missing key in public_ensure before calling public_add too. -# 2022-04-20 <axel.hahn@iml.unibe.ch> fix multiple domains using domain alias -# 2022-04-21 <axel.hahn@iml.unibe.ch> mix multiple domains using domain alias or not -# 2022-05-19 <axel.hahn@iml.unibe.ch> add timer and debug.log -# 2022-05-20 <axel.hahn@iml.unibe.ch> update _wait_4_free_slot and data in debug.log -# 2023-02-01 <axel.hahn@unibe.ch> skip function _fixKeyfile with former workaround -# 2023-05-08 <axel.hahn@unibe.ch> fix: "key and cert do not match" -# 2024-03-21 <axel.hahn@unibe.ch> shorter sleep times -# 2024-07-09 <axel.hahn@unibe.ch> remove grep: warning: stray \ before white space; add --force for renewal -# ====================================================================== - - -# ---------------------------------------------------------------------- -# -# CONFIG -# -# ---------------------------------------------------------------------- - -_version="2024-07-09" -logdir="./log" -touchfile="$logdir/lastchange.txt" -logfile="$logdir/certmanager.log" -debuglogfile="$logdir/debug.log" - -# CSR USAGE WAS REMOVED -# csrfile="./templates/csr.txt" - -line="_______________________________________________________________________________" - -# flag: show debug infos on console (STDOUT) -CM_showdebug=0 - -# flag: write a log for created/ renewd/ deleted certs -CM_writelog=1 - -# flag: write a log for executed functions with timer and process count -CM_writedebuglog=0 - -CM_timer_start=$( date +%s.%N ) - -# ---------------------------------------------------------------------- -# -# INTERNAL FUNCTIONS -# -# ---------------------------------------------------------------------- - -# BUGFIX: acme.sh does not create a new key file on renew. -# After switching from csr method to param -d we got a 0 byte Keyfile -function _fixKeyfile(){ - echo "SKIP: _fixKeyfile won't be executed anymore." - # local _acme_keyfile=~/.acme.sh/${CM_fqdn}/${CM_fqdn}.key - # if test ! -f "$_acme_keyfile" - # then - # echo "FIX: copy key from csr folder $CM_filekey to $_acme_keyfile" - # if ! cp "$CM_filekey" "$_acme_keyfile" - # then - # exit 1 - # fi - # fi -} - -# internal function; list certificates incl. creation date and renew date -function _listCerts(){ - $ACME --list -} - -# internal function; get a list of fqdn of all existing certs -function _listCertdomains(){ - _listCerts | sed -n '2,$p' | awk '{ print $1 }' -} - -# internal function; checks if a certificate for a given FQDN already exists -# used in _certMustExist, _certMustNotExist -# param string FQDN -function _certExists(){ - # _listCertdomains | grep "^${CM_fqdn}$" >/dev/null - $ACME --info -d "${CM_fqdn}" 2>/dev/null | grep "letsencrypt.org" >/dev/null -} - -# internal function; a certificate of a given FQDN must exist - otherwise -# the script will be aborted -# param string FQDN -function _certMustExist(){ - _certExists - if [ $? -ne 0 ]; then - echo "ERROR: cert ${CM_fqdn} was not added yet." - exit 1 - fi -} - -# internal function; a certificate of a given FQDN must not exist - otherwise -# the script will be aborted -# param string FQDN -function _certMustNotExist(){ - if _certExists - then - echo "ERROR: cert ${CM_fqdn} was added already." - # exit 1 - echo "Press Ctrl+C to abort within the next 3 sec..." - sleep 3 - fi -} - -# internal function: transfer generated/ updated cert data to a -# known directory (based on CM_diracme - see inc_config.sh) -# used in public_add and public_renew -# used in ADD and RENEW action -function _certTransfer(){ - _wd "--- acme internal data - ~/.acme.sh/${CM_fqdn}" - ls -l ~/.acme.sh/${CM_fqdn} - - _wd "--- delete current files in ${CM_dircerts}/ if they already exist." - test -d ${CM_dircerts} && rm -f "${CM_dircerts}/*" 2>/dev/null - - _wd "--- transfer acme.sh files to ${CM_dircerts}/" - if ! $ACME \ - --install-cert \ - -d "${CM_fqdn}" \ - --key-file "${CM_outfile_key}" \ - --cert-file "${CM_outfile_cert}" \ - --fullchain-file "${CM_outfile_chain}" \ - --ca-file "${CM_outfile_ca}" - then - echo "ERROR occured during acme transfer. Removing files in ${CM_dircerts} to prevent strange effects..." - rm -f "${CM_dircerts}/*" - exit 2 - fi - echo "OK." - - # _wd "--- copy key to ${CM_dircerts}" - # cp ${CM_filekey} ${CM_outfile_key} - - _wd "--- create chained file for haproxy" - cat "${CM_outfile_chain}" "${CM_outfile_key}" > "${CM_outfile_haproxy}" - - _wd "--- content of output dir $CM_dircerts:" - if ! ls -l "${CM_outfile_cert}" "${CM_outfile_chain}" "${CM_outfile_key}" "${CM_outfile_haproxy}" - then - echo "ERROR missing a file (or no access?)" - rm -f "${CM_dircerts}/*" - exit 2 - fi -} - -# internal function; show md5 hashsums for certificate and key -# for visual comparison if the match -function _certMatching(){ - # CSR USAGE WAS REMOVED - # local md5_csr=$( test -f ${CM_filecsr} && openssl req -noout -modulus -in ${CM_filecsr} | openssl md5 | cut -f 2 -d " " ) - local md5_key=$( test -f ${CM_outfile_key} && openssl rsa -noout -modulus -in ${CM_outfile_key} | openssl md5 | cut -f 2 -d " " ) - local md5_cert=$( test -f ${CM_outfile_cert} && openssl x509 -noout -modulus -in ${CM_outfile_cert} | openssl md5 | cut -f 2 -d " " ) - - echo - echo "--- compare hashes" - # CSR USAGE WAS REMOVED - # echo "csr : $md5_csr (used for creation of cert)" - echo "key : $md5_key" - echo "cert : $md5_cert" - if [ "$md5_key" = "$md5_cert" ]; then - echo "OK, key and cert match :-)" - else - echo "ERROR: key and cert do NOT MATCH!" - fi - echo -} - -# internal function: dig for given fqdn. -# Function stops if fqdn was not found in DNS. -# If dig is not found the function skips the DNS check. -# This function is used in _dnsCheck -# param string fqdn to check -# param string type of dns entry; one of a|cname -# param string optional filter on output of dig (regex) -function _checkDig(){ - local myfqdn=$1 - local _type=${2:-"a"} - local _verify=${3:-"."} - - if which dig >/dev/null - then - # _wd "[$myfqdn] exists as type [$_type] in DNS?" - if ! dig "${myfqdn}" "${_type}" | grep "^${myfqdn}" | grep -E "${_verify}" - then - echo "ERROR: [$myfqdn] was not found. Maybe there is a typo in the hostname or it does not exist in DNS." - exit 2 - fi - _wd "OK: [$myfqdn] exists in DNS." - else - _wd "SKIP: dig was not found" - fi - echo - -} - -# internal function: check DNS entries -# - the hostname to be added in the certificate must exist -# - if a hostname does not match and CM_challenge_alias was set: -# - _acme-challenge.FQDN must be a cname to _acme-challenge.${CM_challenge_alias} -# Function stops if a fqdn was not found in DNS. -# param string fqdn(s) that are part of the certificate -function _dnsCheck(){ - local altdns= - local _mydomain= - local _subdomain='_acme-challenge' - - for _mydomain in $* - do - _wd "dig check - domain for cert" - _checkDig "$_mydomain" "a" "IN.*(A|CNAME)" # matches A and CNAME records - - if [ -n "${CM_challenge_alias}" ] && ! echo "$_mydomain" | grep "${CM_certmatch}" >/dev/null - then - _wd "dig check - cname ${_subdomain}.${_mydomain} must exist" - _checkDig "${_subdomain}.${_mydomain}" "cname" - _wd "dig check - cname ${_subdomain}.${_mydomain} must point to ${_subdomain}.${CM_challenge_alias}" - _checkDig "${_subdomain}.${_mydomain}" "cname" "${_subdomain}.${CM_challenge_alias}" - fi - done - -} - -# CSR USAGE WAS REMOVED -# internal function; generate a csr file before creating a new certifcate -# this function is used in public_add -# function _UNUSED_gencsr(){ - -# local altdns= - -# for myalt in $* -# do -# altdns="${altdns}DNS:$myalt," -# done -# altdns=$( echo $altdns | sed "s#,\$##" ) -# _wd "--- $CM_fqdn" -# _wd "DNS alternative names: $altdns" - -# rm -f $CM_filecnf $CM_filekey $CM_filecsr -# mkdir -p "${CM_dircsr}" 2>/dev/null - -# cat $csrfile \ -# | sed "s#__FQDN__#$CM_fqdn#g" \ -# | sed "s#__ALTNAMES__#$altdns#g" \ -# > $CM_filecnf || exit 1 - -# # generate csr -# _wd "creating key and csr" -# openssl req -new -config $CM_filecnf -keyout $CM_filekey -out $CM_filecsr || exit 1 - -# # view csr -# # openssl req -noout -text -in $CM_filecsr -# ls -ltr $CM_filecnf $CM_filekey $CM_filecsr -# } - -# internal function; get a sorted list of DNS aliases in the current cert -function _getAliases(){ - _sortWords $( - openssl x509 -noout -text -in ${CM_outfile_cert} \ - | grep -E "(DNS:)" \ - | sed "s#^ *##g" \ - | sed "s#DNS:##g" \ - | sed "s#,##g" - ) -} - -# internal function; check if a required 2nd CLI parameter was given -# if not the script will abort -function _requiresFqdn(){ - if [ -z "$CM_fqdn" ]; then - echo "ERROR: 2nd parameter must be a FQDN for Main_Domain." - exit 1 - fi -} - -# internal function; it shows a message if the current instance uses a stage -# server. It shows a message that it is allowed to test arround ... or to be -# careful with LE requests on a production system -function _testStaging(){ - echo $ACME_Params | grep -- "--staging" >/dev/null - if [ $? -eq 0 ]; then - _wd "Using Let's Encrypt STAGE environment ..." - _wd "You can test and mess around. Do not use certs in production." - else - _wd "Using Let's Encrypt LIVE environment for production." - _wd "Be careful with count of connects to Let's Encrypt servers." - fi - echo -} -# internal function; if a user was set as CM_user then verify it with -# current user -function _testUser(){ - if [ ! -z "$CM_user" ]; then - local _sUser=`id | cut -f 2 -d "(" | cut -f 1 -d ")"` - if [[ $_sUser != "$CM_user" ]]; then - echo "ERROR: Run this script under user [$CM_user] - not as $_sUser." - exit 1 - fi - fi - -} - -# set update message into access log file -# global bool CM_writedebuglog flag to write access log. -# param string(s) message -function _debuglog(){ - if [ ${CM_writedebuglog} -eq 1 ]; then - echo "$( date ) $CM_fqdn [$$] | $(show_timer) | $*" >> ${debuglogfile} - fi -} - - -# set update message in a file -# param string(s) message -function _update(){ - echo "[$( date )] $*" > ${touchfile} - test ${CM_writelog} -ne 0 && echo "[$( date )] $*" >> ${logfile} -} - -# "neverending" loop that waits until the current process is -# the one with lowest PID -function _wait_for_free_slot(){ - local _bWait=true - _debuglog "start in _wait_for_free_slot" - typeset -i local _iFirstPID=0 - typeset -i local _iPos=0 - local _sProcesses - - _wd "--- Need to wait until own process PID $$ is on top ... " - while [ $_bWait = true ]; - do - _sProcesses=$( ps -ef | grep "bash.*$0" | grep -v "ssh.*@" | grep -v "grep" | sort -k 2 -n ) - _iPos=$( echo "$_sProcesses" | grep -n " $$ " | head -1 | cut -f 1 -d ':' ) - - _wd "instances: $_iProcesses" - test ${CM_showdebug} -ne 0 && echo "$_sProcesses" - - # if [ $_iFirstPID -eq $$ ]; then - if [ $_iPos -eq 1 ]; then - _bWait=false - _debuglog "GO from _wait_for_free_slot" - _wd "OK. Go!" - else - _iProcesses=$( echo "$_sProcesses" | wc -l ) - _iFirstPID=$( echo "$_sProcesses" | head -1 | awk '{ print $2}' ) - _debuglog "zzz ... waiting in _wait_for_free_slot ... $_iFirstPID is first ... my pos is $_iPos of $_iProcesses" - sleep $((3 + RANDOM % 3)); - fi - done - _debuglog "end _wait_for_free_slot" -} - -# write debug output if CM_showdebug is set to 1 -function _wd(){ - test ${CM_showdebug} -ne 0 && echo "DEBUG: $*" -} - -# set environment for a single certificate based on FQDN -# param string FQDN -function _setenv(){ - CM_fqdn=$1 - # CSR USAGE WAS REMOVED - # keeping vars to delete files of existing certs that used a csr - CM_filecsr="${CM_dircsr}/${CM_fqdn}.csr" - CM_filecnf="${CM_dircsr}/${CM_fqdn}.cnf" - CM_filekey="${CM_dircsr}/${CM_fqdn}.key" - - CM_dircerts="${CM_diracme}/${CM_fqdn}" - CM_outfile_cert=${CM_dircerts}/${CM_fqdn}.cert.cer - CM_outfile_chain=${CM_dircerts}/${CM_fqdn}.fullchain.cer - CM_outfile_key=${CM_dircerts}/${CM_fqdn}.key.pem - CM_outfile_haproxy=${CM_dircerts}/${CM_fqdn}.haproxy.pem - CM_outfile_ca=${CM_dircerts}/${CM_fqdn}.ca.cer - - # echo $CM_fqdn; set | grep "^CM_"; echo - -} -# internal function; helper: sort words in alphabetic order -function _sortWords(){ - echo $* | tr " " "\n" | sort | tr "\n" " " -} - -# internal function; verify fqdn in cli params - each fqdn is allowed only once. -# on error it shows the count of usage of each fqdn -function _testFqdncount(){ - typeset -i local iHostsInParam=$( echo $* | wc -w ) - typeset -i iHostsUniq=$( echo $* | tr " " "\n" | sort -u | wc -w ) - if [ $iHostsInParam -ne $iHostsUniq ]; then - echo "ERROR: each given FQDN is allowed only once. You need to remove double entries." - - for myhost in $( echo $* | tr " " "\n" | sort -u ) - do - typeset -i iHostcount=$( echo $* | tr " " "\n" | grep "^$myhost$" | wc -l ) - test $iHostcount -gt 1 && echo " $iHostcount x $myhost" - done - echo - exit 1 - fi -} - -# get time in sec and milliseconds since start -# no parameter is required -function show_timer(){ - local timer_end=$( date +%s.%N ) - local totaltime=$( awk "BEGIN {print $timer_end - $CM_timer_start }" ) - - local sec_time=$( echo $totaltime | cut -f 1 -d "." ) - test -z "$sec_time" && sec_time=0 - - local ms_time=$( echo $totaltime | cut -f 2 -d "." | cut -c 1-3 ) - - echo "$sec_time.$ms_time sec" -} - -# ---------------------------------------------------------------------- -# -# PUBLIC FUNCTIONS -# -# ---------------------------------------------------------------------- - -# -# pulic function ADD certificate -# -function public_add(){ - local _params="" - - _debuglog "start public_add" - _wait_for_free_slot - _requiresFqdn - _certMustNotExist - - _dnsCheck $CM_fqdn $* - - for _mydomain in $CM_fqdn $* - do - _params+="-d $_mydomain --challenge-alias " - - if [ -n "${CM_challenge_alias}" ] && ! echo "$_mydomain" | grep "${CM_certmatch}" >/dev/null - then - _params+="${CM_challenge_alias} " - else - _params+="no " - fi - done - - # 2023-05-08: Specifies the domain key length - _params+="--keylength 2048 " - - _wd "--- create output dir $dircerts" - mkdir -p "${CM_dircerts}" 2>/dev/null - - _wd "--- create certificate" - echo "$ACME --issue $_params $ACME_Params" - if ! $ACME --issue $_params $ACME_Params - then - echo "ERROR: adding cert failed. Trying to delete internal data ..." - public_delete $CM_fqdn - exit 1 - fi - # $ACME --issue -d $CM_fqdn $ACME_Params || exit 1 - - _certTransfer - _certMatching - - _update "added $CM_fqdn $*" - _debuglog "end public_add" -} - -# CSR USAGE WAS REMOVED -# function OLD__public_add(){ -# _wait_for_free_slot -# _requiresFqdn -# _certMustNotExist - -# for myhost in $( echo $CM_fqdn $*) -# do -# echo $myhost | grep "$CM_certmatch" >/dev/null -# if [ $? -ne 0 ]; then -# echo "ERROR: host $myhost does not match [$CM_certmatch]." -# exit 1 -# fi -# done -# _gencsr $CM_fqdn $* - -# _wd "--- create output dir $dircerts" -# mkdir -p "${CM_dircerts}" 2>/dev/null - -# _wd "--- csr data" -# $ACME --showcsr --csr $CM_filecsr || exit 1 - -# _wd "--- create certificate" -# echo $ACME --signcsr --csr $CM_filecsr $ACME_Params -# $ACME --signcsr --csr $CM_filecsr $ACME_Params -# if [ $? -ne 0 ]; then -# echo "ERROR: adding cert failed. Trying to delete internal data ..." -# public_delete $CM_fqdn -# exit 1 -# fi -# # $ACME --issue -d $CM_fqdn $ACME_Params || exit 1 - -# _certTransfer -# _certMatching - -# _update "added $CM_fqdn $*" -# } - -# -# pulic function ADD OR RENEW certificate -# -function public_ensure(){ - _wait_for_free_slot - _requiresFqdn - _certExists - if [ $? -eq 0 ]; then - _wd "--- cert $CM_fqdn was found ... compare aliases" - local _newAliases=$( _sortWords $CM_fqdn $* ) - local _certAliases=$( _getAliases ) - - _wd "from params: $_newAliases" - _wd "inside cert: $_certAliases" - if [ "$_newAliases" = "$_certAliases" ]; then - _wd "--- DNS aliases match ... renew it (ignore --force - it comes from acme.sh)" - public_renew $* - else - # _wd "--- DNS aliases do NOT match ... deleting cert and create a new one" - # public_delete $* - _wd "--- DNS aliases do NOT match ... creating a new one" - _fixKeyfile - public_add $* - fi - else - _wd "--- cert does mot exist ... add it" - public_add $* - fi -} - -# -# public function to delete a cert -# -function public_delete(){ - _debuglog "start public_delete" - _wait_for_free_slot - _requiresFqdn - _certMustExist - - # TODO: revoke it too?? - _wd "--- revoke cert" - $ACME --revoke -d ${CM_fqdn} $ACME_Params - _wd "--- delete ACME.SH data" - $ACME --remove -d ${CM_fqdn} $ACME_Params - _wd "--- delete local data" - - # CSR USAGE WAS REMOVED - rm -rf ${CM_dircerts} ${CM_filecnf} ${CM_filekey} ${CM_filecsr} ~/.acme.sh/${CM_fqdn} && echo OK - _update "deleted ${CM_fqdn}" - _debuglog "end public_delete" -} - - -# -# public function; list certificates incl. creation date and renew date -# -function public_list(){ - _listCerts - -} -# -# public function; list old / outdated certificates -# -function public_list-old(){ - - local _iRuntime=90 - local _iWarn=65 - typeset -i local _rc=0 - - cd "${CM_dircerts}" || exit 1 - - echo - echo "Cert dir is $( pwd )" - echo - echo "---- Certificates expiring soon - with age $_iWarn ... $_iRuntime days:" - if find -type f -name "*.cert.cer" -mtime +$_iWarn -mtime -$_iRuntime | grep . >/dev/null - then - find -type f -name "*.cert.cer" -mtime +$_iWarn -mtime -$_iRuntime -exec ls -ld {} \; | nl - _rc=1 - else - echo " NONE." - fi - echo - echo "---- Certificate list ... older $_iRuntime days:" - if find -type f -name "*.cert.cer" -mtime +$_iRuntime | grep . >/dev/null - then - find -type f -name "*.cert.cer" -mtime +$_iRuntime -exec ls -ld {} \; | nl - _rc=2 - else - echo " NONE." - fi - - echo - cd - >/dev/null - - _wd "Exiting with rc=$_rc" - exit $_rc -} - - -# -# public function - renew a certificate -# param string fqdn of domain to renew -function public_renew(){ - _debuglog "start public_renew" - _wait_for_free_slot - _requiresFqdn - _certMustExist - - _fixKeyfile - - $ACME $CM_force --renew -d ${CM_fqdn} $ACME_Params - local _rc=$? - - case $_rc in - 0) - _certTransfer - _certMatching - _update "renewed ${CM_fqdn}" - ;; - 2) - _wd "renew was skipped ... we need to wait a while." - ;; - *) - _wd "Error ocured." - exit $_rc - esac - _debuglog "end public_renew" -} - -# -# public function - renew all certificates (to be used in a cronjob) -# no params -function public_renew-all(){ - - _listCertdomains | while read mydomain - do - _wd "--- renew $mydomain" - _setenv ${mydomain} - public_renew - done - -} - - -# internal function; helper for selftest to handle a single selftest -# if a given command is successful it shows "OK" or "ERROR" followed -# by the label inparam 2. -# The value _iErrors will be incremented by 1 if an error occured. -# param string command to verify -# param string output label -function _selftestItem(){ - local _check=$1 - local _label=$2 - local _status="OK:" - - eval "$_check" - if [ $? -ne 0 ]; then - _status="ERROR: the check failed for the test of -" - _iErrors=$_iErrors+1 - fi - - echo "$_status $_label" -} - -# -# list existing certs -# no params -function public_selftest(){ - - typeset -i _iErrors=0 - - echo - echo --- dependencies - _selftestItem "which openssl" "openssl was found" - _selftestItem "which curl" "curl was found" - echo - - echo --- acme.sh client - _selftestItem "ls -ld ${ACME}" "${ACME} exits" - _selftestItem "test -x ${ACME}" "${ACME} is executable" - echo - - echo --- acme.sh installation \(may fail in future releases of acme.sh\) - _selftestItem "ls -ld ~/.acme.sh" "internal acme data were found = [acme.sh --install] was done" - _selftestItem "test -w ~/.acme.sh/" "it is writable" - echo - - # CSR USAGE WAS REMOVED - # echo --- csr template - # _selftestItem "ls -ld ${csrfile}" "csr base template exists" - # _selftestItem "test -r ${csrfile}" "it is readable" - # echo - # - # echo --- output directory for csr and key - # _selftestItem "ls -ld ${CM_dircsr}" "data dir for csr exists" - # _selftestItem "test -w ${CM_dircsr}" "it is writable" - # echo - - echo --- output dir for centralized place of certificates - _selftestItem "ls -ld ${CM_diracme}" "central output dir for certificate data exists" - _selftestItem "test -w ${CM_diracme}" "it is writable" - echo - - - echo --- logs - _selftestItem "ls -ld ./log/" "Logdir exists" - _selftestItem "test -w" "Logdir is writable" - test -f $logfile && _selftestItem "test -w $logfile" "Logfile $logfile is writable" - test -f $touchfile && _selftestItem "test -w $touchfile" "Logfile $touchfile is writable" - echo - - echo --- Errors: $_iErrors - test $_iErrors -eq 0 && echo "OK, this looks fine." - echo - exit $_iErrors -} - -# -# list existing certs -# no params -function public_show(){ - _requiresFqdn - _certMustExist - - # CSR USAGE WAS REMOVED - # ls -l ${CM_filecsr} ${CM_dircerts}/* - ls -l ${CM_dircerts}/* - _certMatching - - # CSR USAGE WAS REMOVED - # echo $line - # echo CSR $CM_filecsr - # openssl req -noout -text -in $CM_filecsr | grep -E "(Subject:|DNS:)" | sed "s#^\ *##g" - - for myfile in ${CM_outfile_cert} ${CM_outfile_haproxy} - do - echo $line - echo Cert ${myfile} - # openssl x509 -noout -text -in ${CM_outfile_cert} - openssl x509 -noout -text -in ${myfile} | grep -E "(Issuer:|Subject:|Not\ |DNS:)"| sed "s#^\ *##g" - done -} - -# Transfer cert from acme.sh internal cache to our output dir again -function public_transfer(){ - _wait_for_free_slot - _requiresFqdn - _certExists - - _certTransfer -} - -# ---------------------------------------------------------------------- -# -# main -# -# ---------------------------------------------------------------------- - -cd $( dirname $0 ) - -CM_force= -while [[ "$#" -gt 0 ]]; do case $1 in - --trace) - tracelog="$logdir/trace__$2__$3__`date +%Y-%m-%d__%H-%M-%S`.log" - exec > >(tee -a ${tracelog} ) - exec 2> >(tee -a ${tracelog} >&2) - echo "TRACELOG was triggered." - echo "TIME : $(date)" - echo "COMMAND: $0 $*" - echo "LOG : $tracelog" - - # set -vx - shift 1 - ;; - - --force) - echo "INFO: enable --force (for renewal)" - CM_force="--force" - shift 1 - ;; - *) if grep "^-" <<< "$1" >/dev/null ; then - echo; echo "ERROR: Unknown parameter: $1"; echo; _showHelp; exit 2 - fi - break; - ;; -esac; done -if [ "$1" = "--trace" ]; then - tracelog="$logdir/trace__$2__$3__`date +%Y-%m-%d__%H-%M-%S`.log" - exec > >(tee -a ${tracelog} ) - exec 2> >(tee -a ${tracelog} >&2) - echo "TRACELOG was triggered." - echo "TIME : $(date)" - echo "COMMAND: $0 $*" - echo "LOG : $tracelog" - - # set -vx - shift 1 -fi - -cat <<ENDOFHEADER -$line - - - - - - ---===>>> CERT MANAGER - v$_version <<<===--- - - - - -$line - -ENDOFHEADER - -which openssl >/dev/null || exit 1 - -. ./inc_config.sh -if [ $? -ne 0 ]; then - echo "ERROR: loading the config failed." - echo "Copy the inc_config.sh.dist to inc_config.sh and make your settings in it." - echo - exit 1 -fi - -_testUser -_testStaging - -test -z "${CM_diracme}" && CM_diracme=./certs -test -z "${CM_dircsr}" && CM_dircsr=./csr - -grep "function public_$1" $( basename $0 ) >/dev/null -if [ $# -gt 0 -a $? -eq 0 ]; then - # _wd $* - action=$1 - CM_fqdn=$2 - shift 2 - - _testFqdncount $CM_fqdn $* - - test -z "${ACME}" && ACME=$( which acme.sh ) - if [ ! -x "${ACME}" ]; then - echo "ERROR: acme.sh not found. You need to install acme.sh client and configure it in inc_config.sh." - exit 1 - fi - - _setenv $CM_fqdn - - _wd "A C T I O N -->> $action <<--" - _debuglog ">>> START public_$action $CM_fqdn $*" - eval "public_$action $*" - _debuglog ">>> DONE public_$action $CM_fqdn $*" - -else - self=$( basename $0 ) - cat <<EOF - -HELP - - The basic syntax is - $self [OPTIONS] ACTION [FQDN] [ALIAS_1 [.. ALIAS_N]] - -OPTIONS - --trace - the output additionally will be written into a tracelog file - below $logdir. - --force - Use "--force" prameter for renewal of certificates - -The ACTIONs for SINGLE certificate handlings are: - - add FQDN [.. FQDN-N] - create new certificate - The first FQDN is a hostname to generate the certificate for. - Following multiple hostnames will be used as DNS aliases in the - same certificate. - It updates files in ${CM_diracme} - - ensure FQDN [.. FQDN-N] - It ensures that a certificate with given aliases exists and is up to date. - This param is for simple usage in automation tools like Ansible or Puppet. - It is required to add all aliases as parameters what is unhandy for - direct usage on cli. - - If the cert does not exist it will be created (see "add"). - If fqdn and aliases are the same like in the certificate it performs a renew. - If fqdn and aliases differ: - - the current certificate will be rejected + deleted (see "delete") - - a new certificate will be added () - - delete FQDN - delete all files of a given certificate - - renew FQDN - renew (an already added) certificate - and update files in ${CM_diracme} - - show FQDN - show place of certificate data and show basic certificate data - (issuer, subject, aliases, ending date) - - transfer FQDN - Transfer cert from acme.sh internal cache to our output dir again. - It is done during add or renew. With transfer command you can repeat it. - -ACTIONs for ALL certs - - list - list all certificates including creation and renew date - - list-old - list all certificates older 65 and older 90 days and exit. - Exitcodes: - 0 - all certs are up to date. - 1 - certificates to renew were found - 2 - outdatedt certificates were found - - renew-all - renew all certificates (fast mode - without --force) - and update files in ${CM_diracme} - It is useful for a cronjob. - -other ACTIONs - - selftest - check of health with current setup and requirements. - This command is helpful for initial setups. - -EOF -fi - -echo -_testStaging -- GitLab