I switched to the new chain from letsencrypt (good thru 2035) which uses their own root to sign their certificates in contrast to the IdenTrust intermediate that was used previously and is expiring in Sept 2021. First a little background but the switch is only 3 lines and listed below for TL;DR folks - find your option to your acme client to pull the alternative chain.
https://letsencrypt.org/2020/12/21/extending-android-compatibility.html wrote:
IdenTrust has agreed to issue a 3-year cross-sign for our ISRG Root X1 from their DST Root CA X3. The new cross-sign will be somewhat novel because it extends beyond the expiration of DST Root CA X3. This solution works because Android intentionally does not enforce the expiration dates of certificates used as trust anchors. ISRG and IdenTrust reached out to our auditors and root programs to review this plan and ensure there weren’t any compliance concerns.
When you do the following command with zmcertmgr which /opt/zimbra/.acme.sh/deploy/zimbra.sh does for you when you issue the deploy-hook with acme.sh or automatically via cron using acme.sh - it does this for you.
Code: Select all
# su - zimbra
% cd .acme.sh/mail.example.com
% zmcertmgr verifycrt comm mail.example.com.key mail.example.com.cer ca.cer.real
it validates that your public cert and your private key are valid AND IT verifies the chain has a valid signature from the CA issuing your certificate - letsencrypt proving that mail.example.com is you. To validate the chain, we had to add the IdenTrust pem because when letsencrypt first started many browsers, MUA's didn't include letsencrypt in their keystores so they had IdenTrust who was present everywhere cross sign for them and verify that Letsencrypt was who they said they were. To allow this verification to work, we either had to add the IdenTrust pem manually or in the case of acme.sh we had the zimbra.sh deploy script pull the chain, cache it and add it whenever you needed to issue or renew you certificates.
Behind the scenes, zmcertmgr verifycrt validating that CA chain is accomplished by this where ca.cer.real contains that IdentTrust public key that was created by the zimbra.sh script.
Code: Select all
# su - zimbra
# cd .acme.sh/mail.example.com
% openssl verify -purpose sslserver -CAfile ca.cer.real mail.example.com.cer
Valid certificate chain: mail.example.com.cer: OK
If you add this option '-show_chain' it will tell you which of the letsencrypt chains (there are 2 currently) you have.
Code: Select all
# su - zimbra
# cd .acme.sh/mail.example.com
% openssl verify -show_chain -purpose sslserver -CAfile ca.cer.real mail.example.com.cer
/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer: OK
Chain:
depth=0: CN = mail.example.com (untrusted)
depth=1: C = US, O = Let's Encrypt, CN = R3
depth=2: C = US, O = Internet Security Research Group, CN = ISRG Root X1
The previous chain from IdentTrust would look like:
Code: Select all
...
depth=0: CN = mail.example.com (untrusted)
depth=1: C = US, O = Let's Encrypt, CN = R3
depth=2: O = Digital Signature Trust Co., CN = DST Root CA X3
With this background, it is fairly easy to switch chains using the option --preferred-chain which will modify this file - mail.example.conf for future renewals also.
So this is what you need to do to switch chains. Note: we are assuming you are using deploy/zimbra.sh and acme.sh because the zimbra.sh script will only pull a new PEM if the file doesn't exist.
Code: Select all
# su - zimbra
# cd .acme.sh
% ./acme.sh --force --issue --preferred-chain "ISRG" --dns dns_cf -d mail.example.com -d mail.example.net -d mail.example.org
% wget -O IdentTrust.pem 'https://letsencrypt.org/certs/isrgrootx1.pem.txt'
% ./acme.sh --issue --deploy --deploy-hook zimbra -d mail.example.com
For a cleaner solution because we are reusing the name IdentTrust.pem or you start from scratch a lot and the mail.example.com directory doesn't exist as a result, you can modify zimbra.sh and update the wget and name of IdentTrust.pem ... So basically do this:
Code: Select all
#_IdentTrust="$(dirname "$_cca")/../IdentTrust.pem"
_IdentTrust="$(dirname "$_cca")/..ISGTrust.pem"
_debug _IdentTrust "$_IdentTrust"
# grab it if we don't have it
if [ ! -f "$_IdentTrust" ]; then
_debug No "$_IdentTrust"
# older IdentTrust cross signed chain
# wget -q "https://ssl-tools.net/certificates/dac9024f54d8f6df94935fb1732638ca6ad77c13.pem" -O "$_IdentTrust" || return 1
# --preferred-chain "ISRG"
wget -q "https://letsencrypt.org/certs/isrgrootx1.pem.txt" -O "$_IdentTrust" || return 1
fi
If you just want to test what would happen after getting your new certificate, modify zimbra.sh and add the return 0 below the zmcertmgr verifycrt command. Note: there are 2 zmcertmgr commands in zimbra.sh so above the deploycrt one.
Code: Select all
# append Intermediate
cat "$_cfullchain" "$(dirname "$_cca")/../IdentTrust.pem" > "${_cca}.real"
/opt/zimbra/bin/zmcertmgr verifycrt comm "$_ckey" "$_ccert" "${_cca}.real" || return 1
return 0
Now you can test your new chain without installing it.
Code: Select all
# su - zimbra
% ./acme.sh --issue --deploy --deploy-hook zimbra -d mail.example.com
If you did it manually or are using Certbot, see this thread:
viewtopic.php?f=15&t=69600
HTH,
Jim