zimbra-management/zimbra-man.sh

290 lines
7.9 KiB
Bash

#!/usr/bin/env bash
# DESCRIPTION:
# print length of all zimbra queues
# or
# letsencrypt update certificate procedure
#
# DEPENDENCIES:
# - privileged rights
# - zimbra zmcontrol, zmqstat, zmcertmgr
# - curl
# - openssl
# - cerbot
# - Python 3
# - existing /usr/local/bin/sendmail.py
#
# PARAMETERS:
# 1: "qn" - execution without pauses
# 2: "que" - print length of all zimbra queues
# 2: "svc" - print number of stopped services
# 2: "ssl" - letsencrypt certificate update procedure
# 3: custom configuration file path
#
# FUNCTIONS:
#
#######################################
# Print message and add to log.
# Globals:
# logs
# Arguments:
# 1: message to print and logging
#######################################
addtologs() {
echo "$(date +'%Y.%m.%d-%H:%M:%S') $1" | tee -a "${logs}"
}
#######################################
# Waiting for press [ENTER].
# Globals:
# None
# Arguments:
# None
#######################################
execpause() {
read -r -p "Press [ENTER] to continue... "
}
#######################################
# Exit procedure.
# Globals:
# show
# Arguments:
# None
#######################################
execquite() {
addtologs "execution time is $(($(date +%s)-time)) seconds, exit"
if [ "${show}" != "qn" ]; then
execpause
fi
exit
}
#######################################
# Error exit procedure
# Globals:
# None
# Arguments:
# 1: message to print and logging
#######################################
execerror() {
addtologs "error: $1"
execquite
}
#######################################
# Parsing config file and creating global vars.
# Globals:
# None
# Arguments:
# None
#######################################
getconfig() {
logs=$(grep "logs=" "${conf}" | cut -d= -f2)
python3=$(grep "python3=" "${conf}" | cut -d= -f2)
certemail=$(grep "certemail=" "${conf}" | cut -d= -f2)
certfirst=$(grep "certfirst=" "${conf}" | cut -d= -f2)
IFS=" " read -r -a certalias <<< "$(grep "certalias=" "${conf}" | cut -d= -f2)"
}
#######################################
# Checking user rights.
# Globals:
# None
# Arguments:
# None
# return:
# 0 - if privileged rights, 1 - if not privileged rights
#######################################
checkroot() {
if [ "${EUID}" -ne 0 ]; then
return 1 # false
else
return 0 # true
fi
}
#######################################
# Counting zimbra queues.
# Globals:
# None
# Arguments:
# None
# return:
# length of all queues
#######################################
calcqueue(){
object=0
while read -r QUE; do
object=$(( object + $(echo "${QUE}" | cut -d= -f2) ))
done <<< "$(/opt/zimbra/libexec/zmqstat)"
printf "%s\n" "${object}"
return "${object}"
}
#######################################
# Counting zimbra stopped services.
# Globals:
# None
# Arguments:
# None
# return:
# number of stopped services
#######################################
isrunning(){
counter=0
while read -r service; do
if ! grep -q "$(cat /etc/hostname)" <<< "${service}"; then
if grep -q "Stopped" <<< "${service}"; then
(( counter++ ))
fi
fi
done <<< "$(su - zimbra -c '/opt/zimbra/bin/zmcontrol status')"
printf "%s\n" "${counter}"
return "${counter}"
}
#######################################
# Print certificate expiration date in epoch
# Globals:
# None
# Arguments:
# 1: certificate path or site url
#######################################
certcheck() {
if [ -e "${1}" ]; then
printf '%s\n' "$(date -d "$(openssl x509 -text -noout -in "${1}" | grep 'Not After' | cut -d':' -f2-)" +%s)"
else
export LANG=C
printf '%s\n' "$(date -d "$(curl --insecure -vvI "${1}" 2>&1 | grep "expire date" | cut -d':' -f2-)" +%s)"
fi
}
#######################################
# Renew and deploy certificate
# Globals:
# certfirst
# certalias
# certemail
# Arguments:
# None
#######################################
certrenew() {
# letsencrypt request
su - zimbra -c "/opt/zimbra/bin/zmcontrol stop"
certarray="-d ${certfirst}"
if [ ${#certalias[@]} -ne 0 ]; then
for domain in "${certalias[@]}"; do
certarray+=" -d ${domain}"
done
fi
certbot certonly --standalone --email "${certemail}" --key-type rsa --rsa-key-size 2048 --preferred-chain "ISRG Root X1" "${certarray}"
wget -O - https://letsencrypt.org/certs/isrgrootx1.pem.txt --no-check-certificate >> "/etc/letsencrypt/live/${certfirst}/chain.pem"
su - zimbra -c "/opt/zimbra/bin/zmcontrol start"
# zimbra cert deploy
cp "/etc/letsencrypt/live/${certfirst}/privkey.pem" /opt/zimbra/ssl/zimbra/commercial/commercial.key
cp "/etc/letsencrypt/live/${certfirst}/chain.pem" /opt/zimbra/ssl/zimbra/commercial/chain.pem
cp "/etc/letsencrypt/live/${certfirst}/cert.pem" /opt/zimbra/ssl/zimbra/commercial/cert.pem
chown -R zimbra:zimbra /opt/zimbra/ssl/zimbra/commercial/
su - zimbra -c "/opt/zimbra/bin/zmcertmgr verifycrt comm /opt/zimbra/ssl/zimbra/commercial/commercial.key /opt/zimbra/ssl/zimbra/commercial/cert.pem /opt/zimbra/ssl/zimbra/commercial/chain.pem"
su - zimbra -c "/opt/zimbra/bin/zmcertmgr deploycrt comm /opt/zimbra/ssl/zimbra/commercial/cert.pem /opt/zimbra/ssl/zimbra/commercial/chain.pem"
su - zimbra -c "/opt/zimbra/bin/zmcontrol restart"
}
#######################################
# Send email information about deployed certificate
# Globals:
# python3
# certfirst
# Arguments:
# None
#######################################
startsendmail() {
subj="[SSL Status] $(cat /etc/hostname): certificates renewed"
(
"${python3}" /usr/local/bin/sendmail.py \
-u "$(grep "from=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
-p "$(grep "pass=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
-d "$(grep "dest=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
--smtp "$(grep "smtp=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
--port "$(grep "port=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
--stls "True" \
--subj "${subj}" \
--text "$(curl --insecure -vvI "${certfirst}" 2>&1 | awk 'BEGIN { cert=0 } /^\* SSL connection/ { cert=1 } /^\*/ { if (cert) print }')" \
>> /dev/null 2>&1 &
)
addtologs "sent mail with subject '${subj}'"
}
#
# VARIABLES:
#
show=$1
does=$2
conf=$3
if [ -z "${conf}" ] || [ "${conf}" == "-" ]; then
conf="$(dirname "$(realpath "$0")")/$(basename -s .sh "$0").conf"
fi
time=$(date +%s)
cd "$(dirname "$(realpath "$0")")" || execerror
if [ ! -e "${conf}" ]; then
:
else
getconfig
fi
if [ -z "${logs}" ]; then
logs=/dev/null
elif [ ! -e "${logs}" ]; then
touch "${logs}"
fi
if ! command -v curl &> /dev/null || \
! command -v openssl &> /dev/null || \
! command -v certbot &> /dev/null || \
! command -v /opt/zimbra/bin/zmcontrol &> /dev/null || \
! command -v /opt/zimbra/bin/zmcertmgr &> /dev/null || \
! command -v /opt/zimbra/libexec/zmqstat &> /dev/null || \
! command -v /usr/local/bin/sendmail.py &> /dev/null || \
! command -v "${python3}" &> /dev/null; then
execerror "Not found dependencies"
fi
#
# MAIN:
#
if checkroot; then
if [ "${does}" = "ssl" ]; then
expired=$(certcheck "/etc/letsencrypt/live/${certfirst}/cert.pem")
targets=$(( expired - 2592000 ))
if [[ "${time}" -le "${targets}" ]]; then
addtologs "${certfirst} expired $(date -d "1970-01-01 UTC $expired seconds" +"%Y.%m.%d %T")"
addtologs "${certfirst} certificates renew delayed"
else
certrenew && addtologs "${certfirst} certificates renewed"
startsendmail
fi
elif [ "${does}" = "que" ]; then
result=$(calcqueue)
addtologs "Zimbra queue has ${result} objects" > /dev/null
printf "%s\n" "${result}"
execquite > /dev/null
elif [ "${does}" = "svc" ]; then
result=$(isrunning)
addtologs "Zimbra has ${result} stopped services" > /dev/null
printf "%s\n" "${result}"
execquite > /dev/null
else
printf "%s\n" "Usage example: $0 qn ssl"
printf "%s\n" "Usage example: $0 - que"
fi
execquite
else
execerror "Restart this as root!"
fi