This commit is contained in:
Aaron 2023-09-14 00:39:56 +02:00 committed by GitHub
commit 929f650c09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 181 additions and 22 deletions

View File

@ -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)"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
cert.pem

View File

@ -0,0 +1 @@
key.pem

View File

@ -167,6 +167,8 @@ service lmtp {
listen = *,[::]
ssl_cert = </etc/ssl/mail/cert.pem
ssl_key = </etc/ssl/mail/key.pem
ssl_alt_cert = </etc/ssl/mail/ecdsa-cert.pem
ssl_alt_key = </etc/ssl/mail/ecdsa-key.pem
userdb {
driver = passwd-file
args = /etc/dovecot/dovecot-master.userdb

View File

@ -6,6 +6,8 @@ server {
ssl_certificate /etc/ssl/mail/cert.pem;
ssl_certificate_key /etc/ssl/mail/key.pem;
ssl_certificate /etc/ssl/mail/ecdsa-cert.pem;
ssl_certificate_key /etc/ssl/mail/ecdsa-key.pem;
include /etc/nginx/conf.d/server_name.active;
@ -29,6 +31,12 @@ server {
ssl_certificate '${cert_dir}'cert.pem;
ssl_certificate_key '${cert_dir}'key.pem;
';
if [[ -f ${cert_dir}ecdsa-cert.pem && -f ${cert_dir}ecdsa-key.pem ]]; then
echo -n '
ssl_certificate '${cert_dir}'ecdsa-cert.pem;
ssl_certificate_key '${cert_dir}'ecdsa-key.pem;
';
fi
echo -n '
server_name '${domains}';

View File

@ -5,6 +5,8 @@ biff = no
append_dot_mydomain = no
smtpd_tls_cert_file = /etc/ssl/mail/cert.pem
smtpd_tls_key_file = /etc/ssl/mail/key.pem
smtpd_tls_eccert_file = /etc/ssl/mail/ecdsa-cert.pem
smtpd_tls_eckey_file = /etc/ssl/mail/ecdsa-key.pem
tls_server_sni_maps = hash:/opt/postfix/conf/sni.map
smtpd_tls_received_header = yes
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

View File

@ -97,11 +97,22 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
$mailcow_hostname
);
}
$records[] = array(
'_25._tcp.' . $autodiscover_config['smtp']['server'],
'TLSA',
generate_tlsa_digest($autodiscover_config['smtp']['server'], 25, 1)
);
$digest = generate_tlsa_digest($autodiscover_config['smtp']['server'], 25, 1, 'aRSA');
if($digest !== false) {
$records[] = array(
'_25._tcp.' . $autodiscover_config['smtp']['server'],
'TLSA',
$digest
);
}
$digest = generate_tlsa_digest($autodiscover_config['smtp']['server'], 25, 1, 'aECDSA');
if($digest !== false) {
$records[] = array(
'_25._tcp.' . $autodiscover_config['smtp']['server'],
'TLSA',
$digest
);
}
}
$records[] = array(
@ -340,7 +351,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
}
}
foreach ($currents as &$current) {
foreach ($currents as $i => &$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;

View File

@ -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);

View File

@ -406,6 +406,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}

View File

@ -340,6 +340,10 @@ SKIP_LETS_ENCRYPT=n
# see https://wiki.dovecot.org/SSL/SNIClientSupport
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

View File

@ -458,6 +458,7 @@ CONFIG_ARRAY=(
"SOLR_HEAP"
"SKIP_SOLR"
"ENABLE_SSL_SNI"
"SKIP_ECDSA_CERT"
"ALLOW_ADMIN_EMAIL_LOGIN"
"SKIP_HTTP_VERIFICATION"
"SOGO_EXPIRE_SESSION"
@ -603,6 +604,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"