diff --git a/ispconfig-sni.sh b/ispconfig-sni.sh new file mode 100644 index 0000000..c7c0f9b --- /dev/null +++ b/ispconfig-sni.sh @@ -0,0 +1,108 @@ +#!/bin/bash + + +if [ $(grep -E "^indexed = " /etc/postfix/main.cf | wc -l) -eq 0 ]; then + echo 'indexed = ${default_database_type}:${config_directory}/' >> /etc/postfix/main.cf +fi +if [ $(grep -E "^tls_server_sni_maps = " /etc/postfix/main.cf | wc -l) -eq 0 ]; then + echo 'tls_server_sni_maps = ${indexed}sni' >> /etc/postfix/main.cf +fi +[[ ! -f /etc/dovecot/conf.d/99-ispconfig-custom-config.conf ]] && touch /etc/dovecot/conf.d/99-ispconfig-custom-config.conf + +if [ $(grep -E "^\!include_try /etc/dovecot/sni.conf" /etc/dovecot/conf.d/99-ispconfig-custom-config.conf | wc -l) -eq 0 ] \ +&& [ $(grep -E "^\!include_try /etc/dovecot/sni.conf" /etc/dovecot/dovecot.conf | wc -l) -eq 0 ] +then + echo '!include_try /etc/dovecot/sni.conf' >> /etc/dovecot/conf.d/99-ispconfig-custom-config.conf +fi + +dovecotsni="/etc/dovecot/sni.conf" +postfixchains="/etc/postfix/sni-chains" +postfixsni="/etc/postfix/sni" +reload="false" + +[ ! -d "${postfixchains}" ] && mkdir ${postfixchains} +[ ! -f "${dovecotsni}" ] && touch ${dovecotsni} +[ ! -f "${postfixsni}" ] && touch ${postfixsni} +[ -f "${dovecotsni}.new" ] && rm -f "${dovecotsni}.new" +[ -f "${postfixsni}.new" ] && rm -f "${postfixsni}.new" + +echo "# Generated automatically by /root/scripts/sni-dovecot-postfix.sh" >> ${dovecotsni}.new + +# Evaluate installed/acme certificates from /var/www/./ssl directories, and also old certbot Letsencrypt directories for retro-compatility +for crt in $(find /var/www/*/ssl/ -type f -name "*.crt" && find /etc/letsencrypt/live/ -type l -name "fullchain.pem") +do + if [ "$(basename ${crt})" == "fullchain.pem" ]; then + # Letsencrypt/certbot certificate + certpath="${crt%/*}" + basename="${certpath##*/}" + certfile="${crt}" + keyfile="${certpath}/privkey.pem" + else + # This is not a letsencrypt/certbot certificate + certpath="${crt%/*}" + basename="$(basename ${crt} .crt)" + certfile="${crt}" + keyfile="${certpath}/${basename}.key" + fi + + # Clear Dovecot one line list of domains + dovecotchain="" + + # Postfix SNI create certificate file + if [ -e ${postfixchains}/${basename}.pem ]; then + awk '{print $0}' ${keyfile} ${certfile} > ${postfixchains}/${basename}.pem.new + if [ $(diff ${postfixchains}/${basename}.pem.new ${postfixchains}/${basename}.pem | wc -l) -eq 0 ]; then + rm -f ${postfixchains}/${basename}.pem.new + else + mv ${postfixchains}/${basename}.pem.new ${postfixchains}/${basename}.pem + echo "(${basename} certificate has been modified)" + reload="true" + fi + else + # Need to do it in two lines because ispconfig key file does not end with \r\n + awk '{print $0}' ${keyfile} ${certfile} > ${postfixchains}/${basename}.pem + reload="true" + fi + chmod 600 ${postfixchains}/${basename}.pem + + for domain in $(openssl x509 -text < ${certfile} | grep DNS | tr ',' '\n' | sed 's/DNS://g'); do + + # Build Dovecot one line + if [ "${dovecotchain}" == "" ]; then + dovecotchain="${domain}" + else + dovecotchain="${dovecotchain} ${domain}" + fi + + # Build Postfix sni file. For postfix, wildcards are ommited so "*.domain.tld" may be replaced to ".domain.tld" + [[ ${domain} == \** ]] && domain=$(echo ${domain} | sed 's/*//g') + echo "${domain} ${postfixchains}/${basename}.pem" >> ${postfixsni}.new + + done + + # Build Dovecot sni file with the one line variable (direct link) + echo "local_name \"${dovecotchain}\" {" >> ${dovecotsni}.new + echo " ssl_cert = <${certfile}" >> ${dovecotsni}.new + echo " ssl_key = <${keyfile}" >> ${dovecotsni}.new + echo "}" >> ${dovecotsni}.new + +done + + +if [ $(diff ${dovecotsni}.new ${dovecotsni} | wc -l) -gt 0 ] || [ ${reload} == "true" ]; then + echo "" + echo "Detected changes in Dovecot SNI: executing reload" + cat ${dovecotsni}.new > ${dovecotsni} + systemctl reload dovecot.service +fi + +if [ $(diff ${postfixsni}.new ${postfixsni} | wc -l) -gt 0 ] || [ ${reload} == "true" ]; then + echo "" + echo "Detected changes in Postfix SNI: executing postmap and reload" + cat ${postfixsni}.new > ${postfixsni} + /usr/sbin/postmap -F /etc/postfix/sni + systemctl reload postfix +fi + +[ -f "${dovecotsni}.new" ] && rm -f "${dovecotsni}.new" +[ -f "${postfixsni}.new" ] && rm -f "${postfixsni}.new" \ No newline at end of file