SCRIPT UPDATED TO RELOAD SERVICES IF ANY CERTIFICATE IS RENEWED OR MODIFIED!! SCRIPT UPDATED TO INCLUDE ISPCONFIG SAVED CERTIFICATES IF LETSENCRYPT IS NOT CONFIGURED!! Hi all, Thanks to the developers of this great panel. I attach a simple bash script which: Read every Letsencrypt certificate currently configured/installed at /etc/letsencrypt/live directly. If there is not a Letsencrypt certificate for the domain, it will try to configure those saved from Ispconfig. Build up the dovecot SNI configuration Build up the postfix SNI configuration Insert / update the SNI configurations to include every LE/Ispconfig certificated domain Only reload services if necessary Almost no CPU/IO, so you could schedulle via cron to run every 1/5 minutes if you will... Currently being used in my servers without problems Cons: No pure-ftpd SNI yet If your hostname has its own LE certificate, it will be included in the SNI configuration, as every other domain. Just give thanks if you like it. Name it as you like... I usually run it from "/root/scripts/sni-dovecot-postfix.sh" Code: #!/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 letsencrypt="/etc/letsencrypt/live" 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 for domain in $(echo -e "$(find /var/www/ -maxdepth 1 -mindepth 1 -type l | awk -F"/var/www/" '{print $2}')\n$(find ${letsencrypt}/ -maxdepth 1 -mindepth 1 -type d -exec ba sename {} \; | sort)" | sort | uniq) do # Check for LE certificate if [ -e ${letsencrypt}/${domain}/fullchain.pem ]; then cert="${letsencrypt}/${domain}/fullchain.pem" key="${letsencrypt}/${domain}/privkey.pem" generate="Letsencrypt" # Check for ISPCONFIG installed certificate elif [ -e /var/www/${domain}/ssl/${domain}.crt ]; then cert="/var/www/${domain}/ssl/${domain}.crt" key="/var/www/${domain}/ssl/${domain}.key" generate="Ispconfig" # There is no certificate anywhere for this domain else generate="false" fi if [ "${generate}" == "Letsencrypt" ] || [ "${generate}" == "Ispconfig" ]; then echo "Processing ${domain} SNI (detected ${generate} certificate)" # Dovecot SNI echo "local_name \"*.${domain} ${domain}\" {" >> ${dovecotsni}.new echo " ssl_cert = <${cert}" >> ${dovecotsni}.new echo " ssl_key = <${key}" >> ${dovecotsni}.new echo "}" >> ${dovecotsni}.new # Postfix SNI Chains if [ -e ${postfixchains}/${domain}.pem ]; then awk '{print $0}' ${key} ${cert} > ${postfixchains}/${domain}.pem.new if [ $(diff ${postfixchains}/${domain}.pem.new ${postfixchains}/${domain}.pem | wc -l) -eq 0 ]; then rm -f ${postfixchains}/${domain}.pem.new else mv ${postfixchains}/${domain}.pem.new ${postfixchains}/${domain}.pem echo "(${domain} 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}' ${key} ${cert} > ${postfixchains}/${domain}.pem reload="true" fi chmod 600 ${postfixchains}/${domain}.pem echo "${domain} ${postfixchains}/${domain}.pem" >> ${postfixsni}.new echo ".${domain} ${postfixchains}/${domain}.pem" >> ${postfixsni}.new fi 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"
I've shared it on https://git.ispconfig.org/ispconfig/ispconfig3/-/issues/3794 and https://git.ispconfig.org/ispconfig/ispconfig3/-/issues/6074
i've mentioned a few times on here, that pure-ftpd supports sni now, and so should be do-able (at least manually for now) on the latest debian and ubuntu. support should be included from pure-ftpd 1.0.48 onwards, but the debian/ubuntu package pure-ftpd-common doesn't actually include the pure-certd binary. https://answers.launchpad.net/ubuntu/+source/pure-ftpd/+question/696585 pure-ftpd sni configuration - relevant section is custom certificate handlers https://download.pureftpd.org/pub/pure-ftpd/doc/README.TLS
Maybe it would be nice to create a GitHub repo for the script as long as you're updating it, so changes can be tracked easily?
Do I have to create an alias-domain for all my mail-domains to the host-certificate? eg. host = host.abc.test domain1 = aaa.bbb domain2 = xxx.zzz isp-config mail-domain1 = (mail.)aaa.bbb isp-config mail-domain2 = (mail.)xxx.zzz so... do I have to add "mail.aaa.bbb" and "mail.xxx.zzz" to the LE-Cert for "host.abc.test"
Depends. I do not do that. My setup has one e-mail domain for all users, and that domain has certificate. If you must have separate e-mail domain for each customer and use only one e-mail server for all of them, then adding all of the domains to the one certificate is needed if your customers want to avoid warnings. Let's Encrypt allows up to 100 alias certificates, so if you have more customers than that then it does not scale. This method is, in my opinion, worse in other ways too, so I do not use it.
it shouldn't be needed. the sni configuration files should provide the details for each domain and the corresponding certificates and their location.* looking at the provided script, it looks like it's designed for a server where the website and email services are provided by the same server. looks like running a multi-server setup with a dedicated mailserver would be a lot more complicated (manual configuration?) * i haven't actually tried setting up postfix/dovecot sni yet. but everything i've seen and read indicates every domain has it's own certificate. (not sure about email aliasdomains. they may need to be on the same certificate they as the domain they are aliasing to)
as an update to this, it looks like with the release of pure-ftp 1.0.50, the pure-ftpd-common package will finally include the pure-certd binary. doesn't look like the 1.0.50 release has been backported into the 20.04 repo, hopefully with the release of ubuntu 22.04 in a few months, inclusion of sni support for both postfix/dovecot and pure-ftpd in ispconfig will finally become a viable option.