#!/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"