diff --git a/data/Dockerfiles/acme/acme.sh b/data/Dockerfiles/acme/acme.sh index 1cd456a49..d6ededd1c 100755 --- a/data/Dockerfiles/acme/acme.sh +++ b/data/Dockerfiles/acme/acme.sh @@ -44,6 +44,17 @@ if [[ "${SKIP_LETS_ENCRYPT}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then exec $(readlink -f "$0") fi +if [[ "${SKIP_ECDSA_CERT}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then + SKIP_ECDSA_CERT=y +fi + +ACME_BASE=/var/lib/acme +SSL_EXAMPLE=/var/lib/ssl-example + +# Symlink ECDSA to RSA certificate if not present +[[ ! -f ${ACME_BASE}/ecdsa-cert.pem ]] && [[ ! -L ${ACME_BASE}/ecdsa-cert.pem ]] && ln -s cert.pem ${ACME_BASE}/ecdsa-cert.pem +[[ ! -f ${ACME_BASE}/ecdsa-key.pem ]] && [[ ! -L ${ACME_BASE}/ecdsa-key.pem ]] && ln -s key.pem ${ACME_BASE}/ecdsa-key.pem + log_f "Waiting for Docker API..." until ping dockerapi -c1 > /dev/null; do sleep 1 @@ -62,9 +73,6 @@ until ping dovecot -c1 > /dev/null; do done log_f "Dovecot OK" -ACME_BASE=/var/lib/acme -SSL_EXAMPLE=/var/lib/ssl-example - mkdir -p ${ACME_BASE}/acme # Migrate @@ -92,6 +100,18 @@ if [[ -f ${ACME_BASE}/cert.pem ]] && [[ -f ${ACME_BASE}/key.pem ]] && [[ $(stat ISSUER=$(openssl x509 -in ${ACME_BASE}/cert.pem -noout -issuer) if [[ ${ISSUER} != *"Let's Encrypt"* && ${ISSUER} != *"mailcow"* && ${ISSUER} != *"Fake LE Intermediate"* ]]; then log_f "Found certificate with issuer other than mailcow snake-oil CA and Let's Encrypt, skipping ACME client..." + + # Make sure we do not combine Letsencrypt ECDSA with another RSA certificate + # Remove ECDSA if that is the case + if [[ -f ${ACME_BASE}/ecdsa-cert.pem ]] && [[ -f ${ACME_BASE}/ecdsa-key.pem ]] && [[ ! -L ${ACME_BASE}/ecdsa-cert.pem ]] && [[ ! -L ${ACME_BASE}/ecdsa-key.pem ]]; then + ISSUER=$(openssl x509 -in ${ACME_BASE}/ecdsa-cert.pem -noout -issuer) + if [[ ${ISSUER} == *"Let's Encrypt"* || ${ISSUER} == *"mailcow"* || ${ISSUER} == *"Fake LE Intermediate"* ]]; then + log_f "Remove Let's Encrypt ECDSA certificate in favour of a custom RSA one" + ln -sf cert.pem ${ACME_BASE}/ecdsa-cert.pem + ln -sf key.pem ${ACME_BASE}/ecdsa-key.pem + fi + fi + sleep 3650d exec $(readlink -f "$0") fi @@ -100,17 +120,27 @@ else log_f "Restoring previous acme certificate and restarting script..." cp ${ACME_BASE}/${MAILCOW_HOSTNAME}/cert.pem ${ACME_BASE}/cert.pem cp ${ACME_BASE}/${MAILCOW_HOSTNAME}/key.pem ${ACME_BASE}/key.pem + + if [[ -f ${ACME_BASE}/${MAILCOW_HOSTNAME}/ecdsa-cert.pem ]] && [[ -f ${ACME_BASE}/${MAILCOW_HOSTNAME}/ecdsa-key.pem ]] && verify_hash_match ${ACME_BASE}/${MAILCOW_HOSTNAME}/ecdsa-cert.pem ${ACME_BASE}/${MAILCOW_HOSTNAME}/ecdsa-key.pem; then + # Remove symlink before copying + cp --remove-destination ${ACME_BASE}/${MAILCOW_HOSTNAME}/ecdsa-cert.pem ${ACME_BASE}/ecdsa-cert.pem + cp --remove-destination ${ACME_BASE}/${MAILCOW_HOSTNAME}/ecdsa-key.pem ${ACME_BASE}/ecdsa-key.pem + fi # Restarting with env var set to trigger a restart, exec env TRIGGER_RESTART=1 $(readlink -f "$0") else + ISSUER="mailcow" log_f "Restoring mailcow snake-oil certificates and restarting script..." cp ${SSL_EXAMPLE}/cert.pem ${ACME_BASE}/cert.pem cp ${SSL_EXAMPLE}/key.pem ${ACME_BASE}/key.pem + ln -sf cert.pem ${ACME_BASE}/ecdsa-cert.pem + ln -sf key.pem ${ACME_BASE}/ecdsa-key.pem exec env TRIGGER_RESTART=1 $(readlink -f "$0") fi fi chmod 600 ${ACME_BASE}/key.pem +chmod 600 ${ACME_BASE}/ecdsa-key.pem log_f "Waiting for database..." while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent > /dev/null; do @@ -142,10 +172,14 @@ log_f "OK" no_date log_f "Initializing, please wait..." while true; do - POSTFIX_CERT_SERIAL="$(echo | openssl s_client -connect postfix:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" - DOVECOT_CERT_SERIAL="$(echo | openssl s_client -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" - POSTFIX_CERT_SERIAL_NEW="$(echo | openssl s_client -connect postfix:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" - DOVECOT_CERT_SERIAL_NEW="$(echo | openssl s_client -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + POSTFIX_CERT_SERIAL="$(echo | openssl s_client -tls1_2 -cipher 'aRSA' -connect postfix:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + DOVECOT_CERT_SERIAL="$(echo | openssl s_client -tls1_2 -cipher 'aRSA' -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + POSTFIX_CERT_SERIAL_ECDSA="$(echo | openssl s_client -tls1_2 -cipher 'aECDSA' -connect postfix:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + DOVECOT_CERT_SERIAL_ECDSA="$(echo | openssl s_client -tls1_2 -cipher 'aECDSA' -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + POSTFIX_CERT_SERIAL_NEW="$(echo | openssl s_client -tls1_2 -cipher 'aRSA' -connect postfix:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + DOVECOT_CERT_SERIAL_NEW="$(echo | openssl s_client -tls1_2 -cipher 'aRSA' -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + POSTFIX_CERT_SERIAL_NEW_ECDSA="$(echo | openssl s_client -tls1_2 -cipher 'aECDSA' -connect postfix:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + DOVECOT_CERT_SERIAL_NEW_ECDSA="$(echo | openssl s_client -tls1_2 -cipher 'aECDSA' -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" # Re-using previous acme-mailcow account and domain keys if [[ ! -f ${ACME_BASE}/acme/key.pem ]]; then log_f "Generating missing domain private rsa key..." @@ -153,6 +187,12 @@ while true; do else log_f "Using existing domain rsa key ${ACME_BASE}/acme/key.pem" fi + if [[ ! -f ${ACME_BASE}/acme/ecdsa-key.pem ]]; then + log_f "Generating missing domain private ecdsa key..." + openssl ecparam -genkey -name secp384r1 -noout > ${ACME_BASE}/acme/ecdsa-key.pem + else + log_f "Using existing domain ecdsa key ${ACME_BASE}/acme/ecdsa-key.pem" + fi if [[ ! -f ${ACME_BASE}/acme/account.pem ]]; then log_f "Generating missing Lets Encrypt account key..." if [[ ! -z ${ACME_CONTACT} ]]; then @@ -173,6 +213,7 @@ while true; do fi chmod 600 ${ACME_BASE}/acme/key.pem + chmod 600 ${ACME_BASE}/acme/ecdsa-key.pem chmod 600 ${ACME_BASE}/acme/account.pem unset EXISTING_CERTS @@ -309,6 +350,24 @@ while true; do cp ${ACME_BASE}/${CERT_NAME}/cert.pem ${ACME_BASE}/cert.pem cp ${ACME_BASE}/${CERT_NAME}/key.pem ${ACME_BASE}/key.pem fi + + if [[ "${SKIP_ECDSA_CERT}" != "y" ]]; then + DOMAINS=${SERVER_SAN_VALIDATED[@]} /srv/obtain-certificate.sh ecdsa + RETURN="$?" + if [[ "$RETURN" == "0" ]]; then # 0 = cert created successfully + CERT_AMOUNT_CHANGED=1 + CERT_CHANGED=1 + elif [[ "$RETURN" == "1" ]]; then # 1 = cert renewed successfully + CERT_CHANGED=1 + elif [[ "$RETURN" == "2" ]]; then # 2 = cert not due for renewal + : + else + CERT_ERRORS=1 + fi + # create relative symbolic link as server certificate + ln -sf ${CERT_NAME}/ecdsa-cert.pem ${ACME_BASE}/ecdsa-cert.pem + ln -sf ${CERT_NAME}/ecdsa-key.pem ${ACME_BASE}/ecdsa-key.pem + fi fi # individual certificates for SNI [@] @@ -345,6 +404,21 @@ while true; do else CERT_ERRORS=1 fi + + if [[ "${SKIP_ECDSA_CERT}" != "y" ]]; then + DOMAINS=${VALIDATED_DOMAINS_SORTED[@]} /srv/obtain-certificate.sh ecdsa + RETURN="$?" + if [[ "$RETURN" == "0" ]]; then # 0 = cert created successfully + CERT_AMOUNT_CHANGED=1 + CERT_CHANGED=1 + elif [[ "$RETURN" == "1" ]]; then # 1 = cert renewed successfully + CERT_CHANGED=1 + elif [[ "$RETURN" == "2" ]]; then # 2 = cert not due for renewal + : + else + CERT_ERRORS=1 + fi + fi fi done fi @@ -364,9 +438,19 @@ while true; do DATE=$(date +%Y-%m-%d_%H_%M_%S) log_f "Found orphaned certificate: ${EXISTING_CERT} - archiving it at ${ACME_BASE}/backups/${EXISTING_CERT}/" BACKUP_DIR=${ACME_BASE}/backups/${EXISTING_CERT}/${DATE} + BACKUP_DIR_ECDSA=${ACME_BASE}/backups/${EXISTING_CERT}/ecdsa-${DATE} + + # archive ecdsa cert (if exists) + mkdir -p ${BACKUP_DIR_ECDSA}/ + [[ -f ${ACME_BASE}/${EXISTING_CERT}/ecdsa-cert.pem && -f ${ACME_BASE}/${EXISTING_CERT}/domains ]] && cp ${ACME_BASE}/${EXISTING_CERT}/domains ${BACKUP_DIR_ECDSA}/ + [[ -f ${ACME_BASE}/${EXISTING_CERT}/ecdsa-cert.pem ]] && mv ${ACME_BASE}/${EXISTING_CERT}/ecdsa-cert.pem ${BACKUP_DIR_ECDSA}/ + [[ -f ${ACME_BASE}/${EXISTING_CERT}/ecdsa-key.pem ]] && mv ${ACME_BASE}/${EXISTING_CERT}/ecdsa-key.pem ${BACKUP_DIR_ECDSA}/ + [[ -f ${ACME_BASE}/${EXISTING_CERT}/ecdsa-acme.csr ]] && mv ${ACME_BASE}/${EXISTING_CERT}/ecdsa-acme.csr ${BACKUP_DIR_ECDSA}/ + # archive rsa cert and any other files mkdir -p ${ACME_BASE}/backups/${EXISTING_CERT} mv ${ACME_BASE}/${EXISTING_CERT} ${BACKUP_DIR} + CERT_CHANGED=1 CERT_AMOUNT_CHANGED=1 fi @@ -377,7 +461,7 @@ while true; do if [[ "${CERT_CHANGED}" == "1" ]]; then rm -f "${ACME_BASE}/force_renew" 2> /dev/null RELOAD_LOOP_C=1 - while [[ "${POSTFIX_CERT_SERIAL}" == "${POSTFIX_CERT_SERIAL_NEW}" ]] || [[ "${DOVECOT_CERT_SERIAL}" == "${DOVECOT_CERT_SERIAL_NEW}" ]] || [[ ${#POSTFIX_CERT_SERIAL_NEW} -ne 36 ]] || [[ ${#DOVECOT_CERT_SERIAL_NEW} -ne 36 ]]; do + while [[ "${POSTFIX_CERT_SERIAL}" == "${POSTFIX_CERT_SERIAL_NEW}" ]] || [[ "${DOVECOT_CERT_SERIAL}" == "${DOVECOT_CERT_SERIAL_NEW}" ]] || [[ "${POSTFIX_CERT_SERIAL_ECDSA}" == "${POSTFIX_CERT_SERIAL_NEW_ECDSA}" ]] || [[ "${DOVECOT_CERT_SERIAL_ECDSA}" == "${DOVECOT_CERT_SERIAL_NEW_ECDSA}" ]] || [[ ${#POSTFIX_CERT_SERIAL_NEW} -ne 36 ]] || [[ ${#DOVECOT_CERT_SERIAL_NEW} -ne 36 ]] || [[ ${#POSTFIX_CERT_SERIAL_NEW_ECDSA} -ne 36 ]] || [[ ${#DOVECOT_CERT_SERIAL_NEW_ECDSA} -ne 36 ]]; do log_f "Reloading or restarting services... (${RELOAD_LOOP_C})" RELOAD_LOOP_C=$((RELOAD_LOOP_C + 1)) CERT_AMOUNT_CHANGED=${CERT_AMOUNT_CHANGED} /srv/reload-configurations.sh @@ -389,8 +473,10 @@ while true; do until nc -z postfix 25; do sleep 1 done - POSTFIX_CERT_SERIAL_NEW="$(echo | openssl s_client -connect postfix:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" - DOVECOT_CERT_SERIAL_NEW="$(echo | openssl s_client -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + POSTFIX_CERT_SERIAL_NEW="$(echo | openssl s_client -tls1_2 -cipher 'aRSA' -connect postfix:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + DOVECOT_CERT_SERIAL_NEW="$(echo | openssl s_client -tls1_2 -cipher 'aRSA' -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + POSTFIX_CERT_SERIAL_NEW_ECDSA="$(echo | openssl s_client -tls1_2 -cipher 'aECDSA' -connect postfix:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" + DOVECOT_CERT_SERIAL_NEW_ECDSA="$(echo | openssl s_client -tls1_2 -cipher 'aECDSA' -connect dovecot:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -serial | cut -d "=" -f 2)" if [[ ${RELOAD_LOOP_C} -gt 3 ]]; then log_f "Some services do return old end dates, something went wrong!" ${REDIS_CMDLINE} SET ACME_FAIL_TIME "$(date +%s)" diff --git a/data/Dockerfiles/acme/obtain-certificate.sh b/data/Dockerfiles/acme/obtain-certificate.sh index 743441197..2f223b602 100644 --- a/data/Dockerfiles/acme/obtain-certificate.sh +++ b/data/Dockerfiles/acme/obtain-certificate.sh @@ -15,8 +15,9 @@ ACME_BASE=/var/lib/acme TYPE=${1} PREFIX="" -# only support rsa certificates for now -if [[ "${TYPE}" != "rsa" ]]; then +if [[ "${TYPE}" == "ecdsa" ]]; then + PREFIX="ecdsa-" +elif [[ "${TYPE}" != "rsa" ]]; then log_f "Unknown certificate type '${TYPE}' requested" exit 5 fi diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh index f1e2e9668..b27012bc4 100755 --- a/data/Dockerfiles/dovecot/docker-entrypoint.sh +++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh @@ -274,6 +274,13 @@ for cert_dir in /etc/ssl/mail/*/ ; do echo 'local_name '${domain}' {' >> /etc/dovecot/sni.conf; echo ' ssl_cert = <'${cert_dir}'cert.pem' >> /etc/dovecot/sni.conf; echo ' ssl_key = <'${cert_dir}'key.pem' >> /etc/dovecot/sni.conf; + if [[ -f ${cert_dir}ecdsa-cert.pem && -f ${cert_dir}ecdsa-key.pem ]]; then + echo ' ssl_alt_cert = <'${cert_dir}'ecdsa-cert.pem' >> /etc/dovecot/sni.conf; + echo ' ssl_alt_key = <'${cert_dir}'ecdsa-key.pem' >> /etc/dovecot/sni.conf; + else + echo ' ssl_alt_cert = <'${cert_dir}'cert.pem' >> /etc/dovecot/sni.conf; + echo ' ssl_alt_key = <'${cert_dir}'key.pem' >> /etc/dovecot/sni.conf; + fi echo '}' >> /etc/dovecot/sni.conf; done done diff --git a/data/Dockerfiles/postfix/postfix.sh b/data/Dockerfiles/postfix/postfix.sh index b3098d3af..7e98e288e 100755 --- a/data/Dockerfiles/postfix/postfix.sh +++ b/data/Dockerfiles/postfix/postfix.sh @@ -36,6 +36,9 @@ else IFS=" " read -r -a domains <<< "$(cat "${cert_dir}domains")" for domain in "${domains[@]}"; do echo -n "${domain} ${cert_dir}key.pem ${cert_dir}cert.pem" >> /opt/postfix/conf/sni.map; + if [[ -f ${cert_dir}ecdsa-cert.pem && -f ${cert_dir}ecdsa-key.pem ]]; then + echo -n " ${cert_dir}ecdsa-key.pem ${cert_dir}ecdsa-cert.pem" >> /opt/postfix/conf/sni.map; + fi echo "" >> /opt/postfix/conf/sni.map; done done diff --git a/data/assets/ssl-example/ecdsa-cert.pem b/data/assets/ssl-example/ecdsa-cert.pem new file mode 120000 index 000000000..f9bcc09fc --- /dev/null +++ b/data/assets/ssl-example/ecdsa-cert.pem @@ -0,0 +1 @@ +cert.pem \ No newline at end of file diff --git a/data/assets/ssl-example/ecdsa-key.pem b/data/assets/ssl-example/ecdsa-key.pem new file mode 120000 index 000000000..9ba3d1b8c --- /dev/null +++ b/data/assets/ssl-example/ecdsa-key.pem @@ -0,0 +1 @@ +key.pem \ No newline at end of file diff --git a/data/conf/dovecot/dovecot.conf b/data/conf/dovecot/dovecot.conf index 159e39f41..ccd67b8ef 100644 --- a/data/conf/dovecot/dovecot.conf +++ b/data/conf/dovecot/dovecot.conf @@ -167,6 +167,8 @@ service lmtp { listen = *,[::] ssl_cert = &$current) { if ($current['type'] == 'TXT' && stripos($current['txt'], 'v=dmarc') === 0 && $record[2] == $dmarc_link) { @@ -368,6 +379,21 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm } elseif ($current['type'] != 'TXT' && isset($data_field[$current['type']]) && $state != state_good) { + // Ignore $current TLSA record if it already matches another one in $records. + // E.g. hide found TLSA records for an RSA certificate in the status column + // of missing TLSA records for an ECDSA certificate. + if($current['type'] == 'TLSA' && $record[1] == 'TLSA') { + foreach($records as $other_record) { + if($record != $other_record && + $other_record[1] == 'TLSA' && + $other_record[0] == $current['host'] && + $other_record[2] == $current[$data_field[$current['type']]]) { + unset($currents[$i]); + continue 2; + } + } + } + $state = state_nomatch; if ($current[$data_field[$current['type']]] == $record[2]) { $state = state_good; diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 3cff09b95..784e6d010 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -629,13 +629,16 @@ function expand_ipv6($ip) { $ip = substr(preg_replace("/([A-f0-9]{4})/", "$1:", $hex['hex']), 0, -1); return $ip; } -function generate_tlsa_digest($hostname, $port, $starttls = null) { +function generate_tlsa_digest($hostname, $port, $starttls = null, $ciphers = 'DEFAULT') { if (!is_valid_domain_name($hostname)) { return "Not a valid hostname"; } if (empty($starttls)) { - $context = stream_context_create(array("ssl" => array("capture_peer_cert" => true, 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true))); - $stream = stream_socket_client('ssl://' . $hostname . ':' . $port, $error_nr, $error_msg, 5, STREAM_CLIENT_CONNECT, $context); + $context = stream_context_create(array("ssl" => array("ciphers" => $ciphers, "capture_peer_cert" => true, 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true))); + $stream = stream_socket_client('tcp://' . $hostname . ':' . $port, $error_nr, $error_msg, 5, STREAM_CLIENT_CONNECT, $context); + if(stream_socket_enable_crypto($stream, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT) === false) { + return false; // negotiation failed + } if (!$stream) { $error_msg = isset($error_msg) ? $error_msg : '-'; return $error_nr . ': ' . $error_msg; @@ -674,7 +677,10 @@ function generate_tlsa_digest($hostname, $port, $starttls = null) { stream_context_set_option($stream, 'ssl', 'verify_peer', false); stream_context_set_option($stream, 'ssl', 'verify_peer_name', false); stream_context_set_option($stream, 'ssl', 'allow_self_signed', true); - stream_socket_enable_crypto($stream, true, STREAM_CRYPTO_METHOD_ANY_CLIENT); + stream_context_set_option($stream, 'ssl', 'ciphers', $ciphers); + if(stream_socket_enable_crypto($stream, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT) === false) { + return false; // negotiation failed + } stream_set_blocking($stream, false); } $params = stream_context_get_params($stream); diff --git a/docker-compose.yml b/docker-compose.yml index c1883f907..a3be18172 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -414,6 +414,7 @@ services: - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized} - DIRECTORY_URL=${DIRECTORY_URL:-} - ENABLE_SSL_SNI=${ENABLE_SSL_SNI:-n} + - SKIP_ECDSA_CERT=${SKIP_ECDSA_CERT:-y} - SKIP_IP_CHECK=${SKIP_IP_CHECK:-n} - SKIP_HTTP_VERIFICATION=${SKIP_HTTP_VERIFICATION:-n} - ONLY_MAILCOW_HOSTNAME=${ONLY_MAILCOW_HOSTNAME:-n} diff --git a/generate_config.sh b/generate_config.sh index e62d16892..16de3006c 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -355,6 +355,10 @@ SKIP_LETS_ENCRYPT=n # see https://doc.dovecot.org/admin_manual/ssl/sni_support ENABLE_SSL_SNI=n +# Skip issuing Let's Encrypt ECDSA certificates - y/n + +SKIP_ECDSA_CERT=n + # Skip IPv4 check in ACME container - y/n SKIP_IP_CHECK=n diff --git a/update.sh b/update.sh index 5df32e00e..6cb336b0a 100755 --- a/update.sh +++ b/update.sh @@ -468,6 +468,7 @@ CONFIG_ARRAY=( "SOLR_HEAP" "SKIP_SOLR" "ENABLE_SSL_SNI" + "SKIP_ECDSA_CERT" "ALLOW_ADMIN_EMAIL_LOGIN" "SKIP_HTTP_VERIFICATION" "SOGO_EXPIRE_SESSION" @@ -614,6 +615,16 @@ for option in ${CONFIG_ARRAY[@]}; do echo '# see https://wiki.dovecot.org/SSL/SNIClientSupport' >> mailcow.conf echo "ENABLE_SSL_SNI=n" >> mailcow.conf fi + elif [[ ${option} == "SKIP_ECDSA_CERT" ]]; then + if ! grep -q ${option} mailcow.conf; then + echo "Adding new option \"${option}\" to mailcow.conf" + echo "# Skip issuing Let's Encrypt ECDSA certificates - y/n" >> mailcow.conf + echo "# ECDSA certificates are disabled by default after upgrading." >> mailcow.conf + echo "# This should only be enabled if either" >> mailcow.conf + echo "# * you haven't set any TLSA DNS records or" >> mailcow.conf + echo "# * you will add additional TLSA DNS records for the ECDSA certificate. (See domain's DNS config in Mailcow UI after enabling.)" >> mailcow.conf + echo "SKIP_ECDSA_CERT=y" >> mailcow.conf + fi elif [[ ${option} == "SKIP_SOGO" ]]; then if ! grep -q ${option} mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf"