I didn't test this yet, as I did everything manually so far. Feel free to test. I used AI to summarize my thoughts. Thank you. Hello everyone, after running several ISPConfig servers I ran into a common issue: mail clients sometimes show SSL warnings because the server delivers the hostname certificate instead of the correct domain certificate. Managing certificates for multiple domains with mail.* and webmail.* subdomains can also become complicated. So I created a small automation setup that: - collects mail.* and webmail.* domains from the ISPConfig database - generates a SAN certificate - updates Apache ServerAlias automatically - reloads Postfix and Dovecot - protects against Let's Encrypt rate limits - creates configuration backups The system is now running stable in production and maybe it helps someone with a similar setup. -------------------------------------------------- PROBLEM -------------------------------------------------- Typical issues on multi-domain ISPConfig setups: - mail clients show SSL warnings - Postfix / Dovecot deliver the hostname certificate - new domains must be manually added to certificates - Apache sometimes serves the wrong SSL vhost Example structure: example-host.tld mail.example-host.tld webmail.example-host.tld mail.customer-domain1.tld webmail.customer-domain1.tld mail.customer-domain2.tld webmail.customer-domain2.tld -------------------------------------------------- PART 1 — BASIC SETUP -------------------------------------------------- DNS configuration Each domain needs: Code: mail.example-domain.tld -> server-ip webmail.example-domain.tld -> server-ip -------------------------------------------------- Apache webmail vhost File: Code: /etc/apache2/sites-available/webmail.example-host.tld.vhost Add ServerAlias entries: Code: ServerAlias webmail.example-host.tld webmail.example-domain.tld Then test and reload Apache: Code: apache2ctl configtest systemctl reload apache2 -------------------------------------------------- Create certificate using acme.sh Code: /root/.acme.sh/acme.sh --issue --force --keylength ec-256 \ -d example-host.tld \ -d mail.example-host.tld \ -d webmail.example-host.tld \ -d mail.example-domain.tld \ -d webmail.example-domain.tld \ -w /var/www/example-host.tld/web \ --reloadcmd "systemctl restart dovecot postfix && systemctl reload apache2" -------------------------------------------------- Configure mail services Dovecot config: Code: /etc/dovecot/conf.d/10-ssl.conf Code: ssl_cert = </root/.acme.sh/example-host.tld_ecc/fullchain.cer ssl_key = </root/.acme.sh/example-host.tld_ecc/example-host.tld.key Postfix config: Code: postconf -e 'smtpd_tls_cert_file = /root/.acme.sh/example-host.tld_ecc/fullchain.cer' postconf -e 'smtpd_tls_key_file = /root/.acme.sh/example-host.tld_ecc/example-host.tld.key' Restart services: Code: systemctl restart dovecot postfix -------------------------------------------------- PART 2 — AUTOMATION SCRIPT -------------------------------------------------- The following script: - reads domains from ISPConfig database - updates Apache ServerAlias automatically - creates SAN certificates - avoids Let's Encrypt rate limits - creates configuration backups Script location: Code: /usr/local/bin/run_master_ssl.sh Code: #!/bin/bash set -e DYNAMIC_WEBROOT=$1 VHOST_FILE="/etc/apache2/sites-available/webmail.example-host.tld.vhost" DOVECOT_SSL="/etc/dovecot/conf.d/10-ssl.conf" HASH_FILE="/root/.master_ssl_domain_hash" BACKUP_DIR="/root/backup_configs/$(date +%Y-%m-%d)" [ -z "$DYNAMIC_WEBROOT" ] && { echo "ERROR: Webroot variable empty"; exit 1; } [ ! -d "$DYNAMIC_WEBROOT" ] && { echo "ERROR: Webroot path missing"; exit 1; } [ ! -f "$VHOST_FILE" ] && { echo "ERROR: Apache vhost missing"; exit 1; } [ ! -f "$DOVECOT_SSL" ] && { echo "ERROR: Dovecot SSL config missing"; exit 1; } DB_PASS=$(grep password /usr/local/ispconfig/server/lib/mysql_clientdb.conf | cut -d\' -f2) DB_DOMAINS=$(mysql -u root -p"$DB_PASS" dbispconfig -e \ "SELECT domain FROM web_domain WHERE active = 'y' AND (domain LIKE 'mail.%' OR domain LIKE 'webmail.%')" -N | sort) ALIAS_LIST="webmail.example-host.tld" ACME_DOMAINS="-d example-host.tld -d mail.example-host.tld -d webmail.example-host.tld" for d in $DB_DOMAINS; do if [[ $d == "mail.example-host.tld" || $d == "webmail.example-host.tld" ]]; then continue; fi ACME_DOMAINS="$ACME_DOMAINS -d $d" if [[ $d == webmail.* ]]; then ALIAS_LIST="$ALIAS_LIST $d"; fi done NEW_HASH=$(echo "$ACME_DOMAINS" | md5sum | cut -d' ' -f1) OLD_HASH=$(cat "$HASH_FILE" 2>/dev/null || echo "") if [ "$NEW_HASH" = "$OLD_HASH" ]; then exit 0 fi mkdir -p "$BACKUP_DIR" cp "$VHOST_FILE" "$BACKUP_DIR/" cp "$DOVECOT_SSL" "$BACKUP_DIR/" sed -i "s/ServerAlias .*/ServerAlias $ALIAS_LIST/" "$VHOST_FILE" if apache2ctl configtest > /dev/null 2>&1; then systemctl reload apache2 else cp "$BACKUP_DIR/$(basename $VHOST_FILE)" "$VHOST_FILE" apache2ctl configtest && systemctl reload apache2 exit 1 fi if /root/.acme.sh/acme.sh --issue --force --keylength ec-256 $ACME_DOMAINS -w "$DYNAMIC_WEBROOT" --reloadcmd "systemctl restart dovecot postfix && systemctl reload apache2"; then echo "$NEW_HASH" > "$HASH_FILE" else echo "ERROR: certificate generation failed" exit 1 fi sed -i "s|^ssl_cert =.*|ssl_cert = </root/.acme.sh/example-host.tld_ecc/fullchain.cer|" "$DOVECOT_SSL" sed -i "s|^ssl_key =.*|ssl_key = </root/.acme.sh/example-host.tld_ecc/example-host.tld.key|" "$DOVECOT_SSL" postconf -e "smtpd_tls_cert_file = /root/.acme.sh/example-host.tld_ecc/fullchain.cer" postconf -e "smtpd_tls_key_file = /root/.acme.sh/example-host.tld_ecc/example-host.tld.key" systemctl restart dovecot postfix -------------------------------------------------- RESULT -------------------------------------------------- This setup ensures: - mail clients always receive the correct certificate - new domains are automatically included - Apache configuration stays clean - Let's Encrypt rate limits are avoided - configuration backups are created