mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2024-12-23 02:04:46 +02:00
Add ECDSA support
This is a squashed commit of the following: commit db8051bc234c5fa67aa87a7a94f9e89eaf0e7dac Merge: 2634fdf004020685
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Tue May 24 20:44:38 2022 +0200 Merge branch 'master' into add-ecdsa-support commit 2634fdf0e942c50220d6ea22319610327bd4127e Merge: 0962b90d116c7919
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Wed Nov 10 08:53:21 2021 +0100 Merge branch 'master' into add-ecdsa-support commit 0962b90db51586b30a20d8c5310c1b09dbfe96e3 Merge: 61522713d90d4f96
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Wed Jun 9 11:33:34 2021 +0200 Merge branch 'master' into add-ecdsa-support commit 61522713f1916ac8062fd7b717984d142a395c26 Merge: 72261e6064264767
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Fri Feb 26 18:20:30 2021 +0100 Merge branch 'master' into add-ecdsa-support commit 72261e60f0c147287fb312c51982030f69674e6a Merge: 3a1cce210846013e
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Wed Dec 16 21:33:55 2020 +0100 Merge branch 'master' into add-ecdsa-support commit 3a1cce2105b377410a4c4aff00d44db7fea76e85 Merge: 6a01796ec1034b89
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Tue Sep 15 10:51:32 2020 +0200 Merge branch 'master' into add-ecdsa-support commit 6a01796e7ecbae78b89a2067080886bb59a394a1 Merge: 812adb0f9685b4b5
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Tue Jul 21 14:07:56 2020 +0200 Merge branch 'master' into add-ecdsa-support commit 812adb0fe1bdb5d5d832bcaf09c2c8543c71914b Author: Aaron Larisch <aaron-github@openlarry.de> Date: Sun Jul 5 00:12:21 2020 +0200 Fix TLSA records for ECDSA and RSA certs in DNS diagnostics Disables TLS 1.3 for the test connection to limit to RSA or ECDSA ciphers. commit 83c976999bf1da178ed9363f79ff772f9bffab93 Merge: 6fb29ab5becc5059
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Sat Jul 4 23:03:45 2020 +0200 Merge branch 'master' into add-ecdsa-support commit 6fb29ab554e55bac17fa3087da4580d224e95e6f Merge: 3131e171b933a309
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Thu May 21 11:34:30 2020 +0200 Merge branch 'master' into add-ecdsa-support commit 3131e1717f48488a81979206df6d67e6f55c10a7 Merge: 1929216e7fa10cc3
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Thu Apr 16 18:20:39 2020 +0200 Merge branch 'master' into add-ecdsa-support commit 1929216e6a8eff0a110bfc28425987c548e12fa0 Merge: a0edf841a9947e99
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Sat Mar 21 08:38:07 2020 +0100 Merge branch 'master' into add-ecdsa-support commit a0edf841427b093b03597ba231e5c6b228c0ee60 Merge: 6152b426b5c844d7
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Thu Feb 13 13:52:09 2020 +0100 Merge branch 'master' into add-ecdsa-support commit 6152b42616cfa9df483dee6047fdca2517b1b245 Merge: 85b791bfe6bb3069
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Wed Jan 15 10:14:18 2020 +0100 Merge branch 'master' into add-ecdsa-support commit 85b791bf07391217a1c00d957b6eb8eff091a7b0 Merge: c2339931ff74b8aa
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Tue Dec 17 15:21:10 2019 +0100 Merge branch 'master' into add-ecdsa-support commit c2339931c5c8ec646e1ae8ebc148b75f06c904dc Merge: eee0238b4e8b2bfc
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Sat Dec 7 17:17:05 2019 +0100 Merge branch 'master' into add-ecdsa-support commit eee0238b6b9c97bcfae2b4183ade3575d0b97563 Merge: 9e1ff3321d1a9a27
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Fri Nov 8 12:53:51 2019 +0100 Merge branch 'master' into add-ecdsa-support commit 9e1ff332d163c9c2a9140bbe7388021a930dc759 Merge: ab164253ea4da60c
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Fri Nov 1 16:06:41 2019 +0100 Merge branch 'master' into add-ecdsa-support commit ab164253306e6bf696ef1cbf2235f2de3f05e9f5 Merge: c0499263573e62f1
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Thu Oct 31 13:57:01 2019 +0100 Merge branch 'master' into add-ecdsa-support commit c0499263455d49a807ff4d79b9d439dfd8e66137 Merge: 6a6d6c4a c4316150 Author: Aaron Larisch <aaron-github@openlarry.de> Date: Thu Oct 31 13:55:28 2019 +0100 Merge pull request #1 from mhofer117/tls-sni-ecdsa Change line endings in functions.inc.php back to CRLF commit c43161507bcb48750b865a657e6fe80c02812c83 Author: Marcel Hofer <m.hofer117@gmail.com> Date: Sun Oct 20 19:02:17 2019 +0200 remove empty docker-entrypoint.sh commit efd6cd1847f718900be72d20fa6361fda975bf1c Merge: a2a0821a 6a6d6c4a Author: Marcel Hofer <m.hofer117@gmail.com> Date: Sun Oct 20 19:00:07 2019 +0200 Merge remote-tracking branch 'OpenLarry/add-ecdsa-support' into tls-sni-ecdsa # Conflicts: # data/Dockerfiles/acme/docker-entrypoint.sh # data/conf/dovecot/dovecot.conf # data/conf/nginx/site.conf # data/conf/postfix/main.cf # data/web/inc/ajax/dns_diagnostics.php # data/web/inc/functions.inc.php # docker-compose.yml # generate_config.sh # update.sh commit a2a0821a38a55cb99ba1dd32383344ed6504f451 Merge: 4a62809d05e7c958
Author: Marcel Hofer <m.hofer117@gmail.com> Date: Sun Oct 20 18:50:16 2019 +0200 Merge branch 'tls-sni' into tls-sni-ecdsa commit 4a62809d33d1ef88c09f89cf1168a1f01f578e6f Author: Marcel Hofer <m.hofer117@gmail.com> Date: Sat Oct 19 13:04:02 2019 +0200 [SSL] add optional ecdsa certs in addition to rsa certs commit 6a6d6c4a604cb5d310308e1adf1b709febe2460d Merge: 351abd299f66b83a
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Tue Oct 1 11:01:28 2019 +0200 Merge branch 'master' into add-ecdsa-support commit 351abd29b2f41f97a57681dccb042d9c2321498d Merge: eddb269304853794
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Mon Sep 9 17:40:47 2019 +0200 Merge branch 'master' into add-ecdsa-support commit eddb26938d04dee6e2dd29ab65a3fefd1d07732d Merge: 9d13ead46e82a359
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Thu Aug 29 11:36:03 2019 +0200 Merge branch 'master' into add-ecdsa-support commit 9d13ead450239a1408937e85aeed36afdd48631e Merge: 478c4d1ff21cf134
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Thu Aug 8 13:22:58 2019 +0200 Merge branch 'master' into add-ecdsa-support commit 478c4d1f6364d60e58205656e8d0dd784ce0f088 Merge: 46dbf3bc7665cc2a
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Thu Jun 27 14:49:09 2019 +0200 Merge branch 'master' into add-ecdsa-support commit 46dbf3bc5e454b7bf74d1886f42e73b7d5b46d7b Merge: 680a272669fb7f7a
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Fri May 31 12:33:32 2019 +0200 Merge branch 'master' into add-ecdsa-support commit 680a272664c451323dbc58f7dcbe17f96d387f1c Merge: f69559f0b20ff13e
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Tue May 7 12:29:34 2019 +0200 Merge branch 'master' into add-ecdsa-support commit f69559f03bd25752c2c526c1ac1b475a02508377 Merge: 3e8a9583cd881652
Author: Aaron Larisch <aaron-github@openlarry.de> Date: Mon Apr 15 12:55:41 2019 +0200 Merge branch 'master' into add-ecdsa-support commit 3e8a9583826d8e413e3f21c12fef0e116ad11b54 Merge: 956a487f4aae7277
Author: Aaron <OpenLarry@users.noreply.github.com> Date: Mon Mar 18 16:52:37 2019 +0100 Merge branch 'master' into add-ecdsa-support commit 956a487f822580314186de7b0332e7f8ffaf289f Author: Aaron Larisch <aaron-github@openlarry.de> Date: Sun Mar 17 12:34:56 2019 +0100 Set SKIP_ECDSA_CERT to y by default commit 7103fe7e89b8ba8d45d59e65a6823c7c160565c4 Author: Aaron Larisch <aaron-github@openlarry.de> Date: Sun Mar 17 11:05:05 2019 +0100 Add SKIP_ECDSA_CERT config parameter commit 91fca4fa3835f146571d9e5546c37fceffec2a42 Author: Aaron Larisch <aaron-github@openlarry.de> Date: Sat Mar 16 18:48:28 2019 +0100 Show TLSA records for ECDSA certificates in DNS diagnostics commit cc521b02501f03f692686f3dedc43339b342aa96 Author: Aaron Larisch <aaron-github@openlarry.de> Date: Sat Mar 16 13:04:03 2019 +0100 Add ECDSA support Co-authored-by: Marcel Hofer <m.hofer117@gmail.com>
This commit is contained in:
parent
deb6f0babc
commit
dbfeed5c3a
@ -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)"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
1
data/assets/ssl-example/ecdsa-cert.pem
Symbolic link
1
data/assets/ssl-example/ecdsa-cert.pem
Symbolic link
@ -0,0 +1 @@
|
||||
cert.pem
|
1
data/assets/ssl-example/ecdsa-key.pem
Symbolic link
1
data/assets/ssl-example/ecdsa-key.pem
Symbolic link
@ -0,0 +1 @@
|
||||
key.pem
|
@ -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
|
||||
|
@ -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}';
|
||||
|
||||
|
@ -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
|
||||
|
@ -97,12 +97,23 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
|
||||
$mailcow_hostname
|
||||
);
|
||||
}
|
||||
$digest = generate_tlsa_digest($autodiscover_config['smtp']['server'], 25, 1, 'aRSA');
|
||||
if($digest !== false) {
|
||||
$records[] = array(
|
||||
'_25._tcp.' . $autodiscover_config['smtp']['server'],
|
||||
'TLSA',
|
||||
generate_tlsa_digest($autodiscover_config['smtp']['server'], 25, 1)
|
||||
$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(
|
||||
$domain,
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
11
update.sh
11
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"
|
||||
|
Loading…
Reference in New Issue
Block a user