Awesome. Thanks for letting me know the proper fix.yvespires wrote: All good now, the problem was my ispconfig master/slave dns servers not working/reloading zone changes properly.
Another Letsencrypt method
- JDunphy
- Outstanding Member
- Posts: 901
- Joined: Fri Sep 12, 2014 11:18 pm
- Location: Victoria, BC
- ZCS/ZD Version: 9.0.0_P39 NETWORK Edition
Re: Another Letsencrypt method
Re: Another Letsencrypt method
Ok, so i have my zimbra lab server Ubuntu 16.04.1 with zimbra 8.8.9.GA.2055.UBUNTU16.64 UBUNTU16_64 FOSS edition running, requested a wildcard cert with acme.sh script using dns api automatic challenge, followed this wiki https://wiki.zimbra.com/wiki/index.php?curid=2441, not a single error, very smooth.
But i have 3 questions
1- acme.sh script only handles cert issue and renew? i see it added crontab job 31 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null, so the cert will renew every 30 days, but i have to install manually, copy to zimbra folder and stop/start services?
2- i have wildcard cert installed(*.yvespires.ml), can i request/install multiples wildcard certs on the same server?
Say, i need to request more wildcard certs for my clients, what command should i run?
this
editing the script domain variable only allow one domain?
But i have 3 questions
1- acme.sh script only handles cert issue and renew? i see it added crontab job 31 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null, so the cert will renew every 30 days, but i have to install manually, copy to zimbra folder and stop/start services?
2- i have wildcard cert installed(*.yvespires.ml), can i request/install multiples wildcard certs on the same server?
Say, i need to request more wildcard certs for my clients, what command should i run?
this
or thisacme.sh --issue --dns dns_ispconfig -d '*.yvespires.ml'
acme.sh --issue --dns dns_ispconfig -d '*.zimbraclient1.com'
acme.sh --issue --dns dns_ispconfig -d '*.zimbraclient2.com'
3 - kinda answering my first question, your script https://github.com/JimDunphy/deploy-zim ... encrypt.sh deal with it zimbra certs installation right? Does it work multiples wildcard certs?acme.sh --issue --dns dns_ispconfig -d '*.zimbraclient1.com' -d '*.zimbraclient2.com'
editing the script domain variable only allow one domain?
min=60 #days for CERT expire before will load new certificate. Make large for testing (ie. 10000)
domain="mail.example.com"
user="/home/YourName" # ~user/.acme.sh --- owner that runs acme.sh
# verbose output
d=1 # change to 0 if run from cron
exit # comment this out after adjusting the top two values
- JDunphy
- Outstanding Member
- Posts: 901
- Joined: Fri Sep 12, 2014 11:18 pm
- Location: Victoria, BC
- ZCS/ZD Version: 9.0.0_P39 NETWORK Edition
Re: Another Letsencrypt method
It won't because the renewal is 60 days I believe before acme.sh would ask for a renewal. It just checks if it would be time unless you specify --force. It should use the same method you initially did. I tend to have my 1-liner added myself so I have never used that --cron --home entry. ... so that entry is running every day to check if its time and if it isn't time will exit.yvespires wrote: But i have 3 questions
1- acme.sh script only handles cert issue and renew? i see it added crontab job 31 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null, so the cert will renew every 30 days, but i have to install manually, copy to zimbra folder and stop/start services?
I am not sure how that syntax would work. This would be my guess.yvespires wrote: 2- i have wildcard cert installed(*.yvespires.ml), can i request/install multiples wildcard certs on the same server?
Say, i need to request more wildcard certs for my clients, what command should i run?
this
or thisacme.sh --issue --dns dns_ispconfig -d '*.yvespires.ml'
acme.sh --issue --dns dns_ispconfig -d '*.zimbraclient1.com'
acme.sh --issue --dns dns_ispconfig -d '*.zimbraclient2.com'
acme.sh --issue --dns dns_ispconfig -d '*.zimbraclient1.com' -d '*.zimbraclient2.com'
Code: Select all
acme.sh --issue --dns dns_ispconfig -d mail.example.com -d '*.example.com' -d '*.example.net'
Those extra -d domains are specified as alternative names in the certficate which is just one certificate so that script would work with your wild card certificate. That is why I believe you would need that -d mail.example.com when you specify the extra wildcards above. Wildcards are new to letsencrypt so I have limited experience with them. I would be curious to know also if that syntax above would handle multiple wildcards per certificate. From letsencrypt, they claim there can be up to 100 wildcards per certificate. https://community.letsencrypt.org/t/mul ... card/58205yvespires wrote: 3 - kinda answering my first question, your script https://github.com/JimDunphy/deploy-zim ... encrypt.sh deal with it zimbra certs installation right? Does it work multiples wildcard certs?
editing the script domain variable only allow one domain?
min=60 #days for CERT expire before will load new certificate. Make large for testing (ie. 10000)
domain="mail.example.com"
user="/home/YourName" # ~user/.acme.sh --- owner that runs acme.sh
# verbose output
d=1 # change to 0 if run from cron
exit # comment this out after adjusting the top two values
There is limited support in Zimbra if you want multiple domains but there are enough bugs against it with imaps/pops that I chose to do it with only one certificate. This is the wiki https://wiki.zimbra.com/wiki/Multiple_S ... _for_HTTPS to explain how that might work if that is what you want. BTW, if you wanted SNI, then you would issue multiple certificates and my script would not handle that.
Re: Another Letsencrypt method
that clears up, one certificate to rule them all.JDunphy wrote:yvespires wrote:I tried that, got errorYou need that first -d mail.example.com because that is the directory for the cert and used in the file name of the certificate.
Domain name \"mx.yvespires.ml\" is redundant with a wildcard domain in the same request. Remove one or the other from the certificate request.","status": 400}root@mx:~# acme.sh --issue --dns dns_ispconfig -d mx.yvespires.ml -d '*.yvespires.ml'
[Tue Aug 7 14:14:30 BRT 2018] Registering account
[Tue Aug 7 14:14:31 BRT 2018] Registered
[Tue Aug 7 14:14:31 BRT 2018] ACCOUNT_THUMBPRINT='oXM6Jz9yLbR-BkuBRiQ'
[Tue Aug 7 14:14:31 BRT 2018] Creating domain key
[Tue Aug 7 14:14:31 BRT 2018] The domain key is here: /root/.acme.sh/mx.yvespires.ml/mx.yvespires.ml.key
[Tue Aug 7 14:14:31 BRT 2018] Multi domain='DNS:mx.yvespires.ml,DNS:*.yvespires.ml'
[Tue Aug 7 14:14:31 BRT 2018] Getting domain auth token for each domain
[Tue Aug 7 14:14:32 BRT 2018] Create new order error. Le_OrderFinalize not found. {"type":"urn:ietf:params:acme:error:malformed","detail":"Error creating new order :: Domain name \"mx.yvespires.ml\" is redundant with a wildcard domain in the same request. Remove one or the other from the certificate request.","status": 400}
[Tue Aug 7 14:14:32 BRT 2018] Please add '--debug' or '--log' to check more details.
[Tue Aug 7 14:14:32 BRT 2018] See: https://github.com/Neilpang/acme.sh/wik ... ug-acme.shworks fineacme.sh --issue --dns dns_ispconfig -d '*.yvespires.ml'
Those extra -d domains are specified as alternative names in the certficate which is just one certificate so that script would work with your wild card certificate. That is why I believe you would need that -d mail.example.com when you specify the extra wildcards above. Wildcards are new to letsencrypt so I have limited experience with them. I would be curious to know also if that syntax above would handle multiple wildcards per certificate. From letsencrypt, they claim there can be up to 100 wildcards per certificate. https://community.letsencrypt.org/t/mul ... card/58205
There is limited support in Zimbra if you want multiple domains but there are enough bugs against it with imaps/pops that I chose to do it with only one certificate. This is the wiki https://wiki.zimbra.com/wiki/Multiple_S ... _for_HTTPS to explain how that might work if that is what you want. BTW, if you wanted SNI, then you would issue multiple certificates and my script would not handle that.
something like this: acme.sh --issue --dns dns_ispconfig -d '*.yvespires.ml' -d '*.zimbraclient1.com' -d '*.zimbraclient2.com' -d '*.zimbraclient3.com' -d '*.zimbraclient4.com' -d '*.zimbraclient5.com' -d '*.zimbraclient4.com' ... -d '*.zimbraclient40.com' -d '*.zimbraclient60.com' ...
should work?
ill runs some test and report back
Thanks.
Re: Another Letsencrypt method
JDunphy's approach is great and my personal favorite.
Looking at the forum, Let's Encrypt certificates are an important topic for the community. However, looking at related bug tracker entries, these only have a few votes, so I wonder to which extend the Zimbra product managers are aware of the importance of this topic.
So, it order to eventually have native support in the ZCS software itself in the future, I recommend to vote for the following tickets in Zimbra's bug tracker:
https://bugzilla.zimbra.com/show_bug.cgi?id=99387
https://bugzilla.zimbra.com/show_bug.cgi?id=99549
Best regards
Florian
Looking at the forum, Let's Encrypt certificates are an important topic for the community. However, looking at related bug tracker entries, these only have a few votes, so I wonder to which extend the Zimbra product managers are aware of the importance of this topic.
So, it order to eventually have native support in the ZCS software itself in the future, I recommend to vote for the following tickets in Zimbra's bug tracker:
https://bugzilla.zimbra.com/show_bug.cgi?id=99387
https://bugzilla.zimbra.com/show_bug.cgi?id=99549
Best regards
Florian
Re: Another Letsencrypt method
I also use acme.sh, but I decided I would rather use the standard deploy mechanism of it. Thus, I run acme.sh as zimbra user, and use --deploy and --deploy-hook zimbra with this file saved as .acme.sh/deploy/zimbra.sh:
It needs the IdenTrust root certificate saved as .acme.sh/root_ca.cer. Probably could download it every time afresh, but this was easier
Hope it is useful to some. The script could also be slightly modified to use su if acme.sh should not run as zimbra user.
Stefan
Code: Select all
#!/bin/bash
######## Public functions #####################
#domain keyfile certfile cafile fullchain
zimbra_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
cp -f "$_ckey" /opt/zimbra/ssl/zimbra/commercial/commercial.key
cat "$_cca" "$(dirname "$_cca")/../root_ca.cer" > "${_cca}.real"
/opt/zimbra/bin/zmcertmgr deploycrt comm "$_ccert" "${_cca}.real" || return 1
/opt/zimbra/bin/zmmailboxdctl restart
/opt/zimbra/bin/zmproxyctl restart
/opt/zimbra/bin/zmmtactl restart
return 0
}
Hope it is useful to some. The script could also be slightly modified to use su if acme.sh should not run as zimbra user.
Stefan
- JDunphy
- Outstanding Member
- Posts: 901
- Joined: Fri Sep 12, 2014 11:18 pm
- Location: Victoria, BC
- ZCS/ZD Version: 9.0.0_P39 NETWORK Edition
Re: Another Letsencrypt method
Great Stuff!
I have not tested this but the DST Root CA X3 might not be required so you may not have to add the IdentTrust in the future.
This link discusses it further.
https://letsencrypt.org/2018/08/06/trus ... grams.html
Adding a verification and check might allow you to ride out any problems should the verification method be revoked as what happened with TLS-SNI-01 by letsencrypt but I suspect that acme.sh would not call that hook so it probably works perfectly is my guess. Clever way to handle not getting a valid certificate because your script/hook wouldn't be called.
https://community.letsencrypt.org/t/imp ... sues/50811
I think your method might become my new goto for environments where we generate certs on the same host as the zimbra services.
Did you try reload vs restarts... I do reloads on my non zimbra servers all the time so only remaining question is would mailboxd load a new certificate without being restarted? That would be awesome as no more outages if we could use reload. In any event, you method isn't a zmcontrol restart so is much faster. I need to try this.
I have not tested this but the DST Root CA X3 might not be required so you may not have to add the IdentTrust in the future.
This link discusses it further.
https://letsencrypt.org/2018/08/06/trus ... grams.html
Adding a verification and check might allow you to ride out any problems should the verification method be revoked as what happened with TLS-SNI-01 by letsencrypt but I suspect that acme.sh would not call that hook so it probably works perfectly is my guess. Clever way to handle not getting a valid certificate because your script/hook wouldn't be called.
https://community.letsencrypt.org/t/imp ... sues/50811
I think your method might become my new goto for environments where we generate certs on the same host as the zimbra services.
Did you try reload vs restarts... I do reloads on my non zimbra servers all the time so only remaining question is would mailboxd load a new certificate without being restarted? That would be awesome as no more outages if we could use reload. In any event, you method isn't a zmcontrol restart so is much faster. I need to try this.
- JDunphy
- Outstanding Member
- Posts: 901
- Joined: Fri Sep 12, 2014 11:18 pm
- Location: Victoria, BC
- ZCS/ZD Version: 9.0.0_P39 NETWORK Edition
Re: Another Letsencrypt method
I tried your hook script and it works perfectly. I added the verification step which has limited value ... I forced a few error cases and the deploy failed so you exit before it would attempt to issue the zimbra restart commands ... In the end, I don't think me adding the verification step buys you much. I also moved the cp below my verification step so if it failed, there would be no cleanup to do but that is limited value because if deploy fails you still have to make it work as you have already committed to replacing the cert with commercial.key being overwritten.
A few things for others:
1) You need to issue the certificate the very first time at least with v2.8 without the --deploy --deploy-hook
2) From then on you can use the --deploy --deploy-hooks as it appears to be looking for the directory of your first -d argument
3) reload vs restart
4) Still need the IdentTrust with zimbra 8.7 at least on Centos 6 to verify
Here are results of using 'reload' vs 'restart' on 8.7. nginx works but everything else appears to be restarted... But this is progress vs zmcontrol restart and much faster.
Or the complete process for others running with the zimbra user with acme.sh installed as the zimbra user. Note: I am using a challenge-alias as example.com and example.net are not managed by Cloud Flare but I still want an automatic DNS method.
Followed by this:
I am going to leave reload in my deploy-hook script thinking that eventually Zimbra will offer reload's and not aliases for restart as is the current case. Big HINT!
A few things for others:
1) You need to issue the certificate the very first time at least with v2.8 without the --deploy --deploy-hook
2) From then on you can use the --deploy --deploy-hooks as it appears to be looking for the directory of your first -d argument
3) reload vs restart
4) Still need the IdentTrust with zimbra 8.7 at least on Centos 6 to verify
Here are results of using 'reload' vs 'restart' on 8.7. nginx works but everything else appears to be restarted... But this is progress vs zmcontrol restart and much faster.
Code: Select all
...
...
...
** Creating /opt/zimbra/conf/ca/commercial_ca_3.crt
** Creating CA hash symlink '2e5ac55d.0' -> 'commercial_ca_3.crt'
Stopping mailboxd...done.
Starting mailboxd...done.
Reloading proxy...done.
Rewriting configuration files...done.
Stopping saslauthd...done.
Starting saslauthd...done.
/postfix-script: refreshing the Postfix mail system
[Thu Sep 6 19:28:34 PDT 2018] Success
Code: Select all
./acme.sh --issue --dns dns_cf --challenge-alias someCFdomain.com -d mail.example.com -d mail.example.net -d tmail.example.com
Code: Select all
% ./acme.sh --issue --deploy --deploy-hook zimbra --dns dns_cf --challenge-alias someCFdomain.com -d mail.example.com -d mail.example.net -d tmail.example.com
** Verifying '/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer' against '/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.key'
Certificate '/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer' and private key '/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.key' match.
** Verifying '/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer' against '/opt/zimbra/.acme.sh/mail.example.com/ca.cer.real'
Valid certificate chain: /opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer: OK
** Verifying '/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer' against '/opt/zimbra/ssl/zimbra/commercial/commercial.key'
Certificate '/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer' and private key '/opt/zimbra/ssl/zimbra/commercial/commercial.key' match.
** Verifying '/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer' against '/opt/zimbra/.acme.sh/mail.example.com/ca.cer.real'
Valid certificate chain: /opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer: OK
** Copying '/opt/zimbra/.acme.sh/mail.example.com/mail.example.com.cer' to '/opt/zimbra/ssl/zimbra/commercial/commercial.crt'
** Copying '/opt/zimbra/.acme.sh/mail.example.com/ca.cer.real' to '/opt/zimbra/ssl/zimbra/commercial/commercial_ca.crt'
** Appending ca chain '/opt/zimbra/.acme.sh/mail.example.com/ca.cer.real' to '/opt/zimbra/ssl/zimbra/commercial/commercial.crt'
** Importing cert '/opt/zimbra/ssl/zimbra/commercial/commercial_ca.crt' as 'zcs-user-commercial_ca' into cacerts '/opt/zimbra/common/lib/jvm/java/jre/lib/security/cacerts'
** NOTE: restart mailboxd to use the imported certificate.
** Saving config key 'zimbraSSLCertificate' via zmprov modifyServer mail.example.net...ok
** Saving config key 'zimbraSSLPrivateKey' via zmprov modifyServer mail.example.net...ok
** Installing ldap certificate '/opt/zimbra/conf/slapd.crt' and key '/opt/zimbra/conf/slapd.key'
** Copying '/opt/zimbra/ssl/zimbra/commercial/commercial.crt' to '/opt/zimbra/conf/slapd.crt'
** Copying '/opt/zimbra/ssl/zimbra/commercial/commercial.key' to '/opt/zimbra/conf/slapd.key'
** Creating file '/opt/zimbra/ssl/zimbra/jetty.pkcs12'
** Creating keystore '/opt/zimbra/mailboxd/etc/keystore'
** Installing mta certificate '/opt/zimbra/conf/smtpd.crt' and key '/opt/zimbra/conf/smtpd.key'
** Copying '/opt/zimbra/ssl/zimbra/commercial/commercial.crt' to '/opt/zimbra/conf/smtpd.crt'
** Copying '/opt/zimbra/ssl/zimbra/commercial/commercial.key' to '/opt/zimbra/conf/smtpd.key'
** Installing proxy certificate '/opt/zimbra/conf/nginx.crt' and key '/opt/zimbra/conf/nginx.key'
** Copying '/opt/zimbra/ssl/zimbra/commercial/commercial.crt' to '/opt/zimbra/conf/nginx.crt'
** Copying '/opt/zimbra/ssl/zimbra/commercial/commercial.key' to '/opt/zimbra/conf/nginx.key'
** NOTE: restart services to use the new certificates.
** Cleaning up 9 files from '/opt/zimbra/conf/ca'
** Removing /opt/zimbra/conf/ca/f9724573.0
** Removing /opt/zimbra/conf/ca/2e5ac55d.0
** Removing /opt/zimbra/conf/ca/commercial_ca_2.crt
** Removing /opt/zimbra/conf/ca/ca.key
** Removing /opt/zimbra/conf/ca/ca.pem
** Removing /opt/zimbra/conf/ca/4f06f81d.0
** Removing /opt/zimbra/conf/ca/commercial_ca_3.crt
** Removing /opt/zimbra/conf/ca/f85883ac.0
** Removing /opt/zimbra/conf/ca/commercial_ca_1.crt
** Copying CA to /opt/zimbra/conf/ca
** Copying '/opt/zimbra/ssl/zimbra/ca/ca.key' to '/opt/zimbra/conf/ca/ca.key'
** Copying '/opt/zimbra/ssl/zimbra/ca/ca.pem' to '/opt/zimbra/conf/ca/ca.pem'
** Creating CA hash symlink 'f9724573.0' -> 'ca.pem'
** Creating /opt/zimbra/conf/ca/commercial_ca_1.crt
** Creating CA hash symlink 'f85883ac.0' -> 'commercial_ca_1.crt'
** Creating /opt/zimbra/conf/ca/commercial_ca_2.crt
** Creating CA hash symlink '4f06f81d.0' -> 'commercial_ca_2.crt'
** Creating /opt/zimbra/conf/ca/commercial_ca_3.crt
** Creating CA hash symlink '2e5ac55d.0' -> 'commercial_ca_3.crt'
Stopping mailboxd...done.
Starting mailboxd...done.
Reloading proxy...done.
Rewriting configuration files...done.
Stopping saslauthd...done.
Starting saslauthd...done.
/postfix-script: refreshing the Postfix mail system
[Thu Sep 6 19:55:20 PDT 2018] Success
[zimbra@tmail .acme.sh]$
- JDunphy
- Outstanding Member
- Posts: 901
- Joined: Fri Sep 12, 2014 11:18 pm
- Location: Victoria, BC
- ZCS/ZD Version: 9.0.0_P39 NETWORK Edition
Re: Another Letsencrypt method
I have added your method to the wiki and updated the script to match wiki's examples. Here is the updated code:
I guess the next step is to get some more testing on this and have it included with acme.sh in its deploy directory. Anyone see any improvements or corrections? Do we need to support any other hooks?
Code: Select all
#!/bin/bash
# Zimbra Assumptions:
# 1) acme.sh is installed as Zimbra
# 2) see: https://wiki.zimbra.com/wiki/index.php?curid=2441
######## Public functions #####################
#domain keyfile certfile cafile fullchain
zimbra_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
# Zimbra's javastore still needs DST Root CA X3 to verify on some versions
_IdentTrust="$(dirname "$_cca")/../IdentTrust.pem"
_debug _IdentTrust "$_IdentTrust"
# grab it if we don't have it
if [ ! -f "$_IdentTrust" ]; then
_debug No "$_IdentTrust"
wget -q "https://ssl-tools.net/certificates/dac9024f54d8f6df94935fb1732638ca6ad77c13.pem" -O "$_IdentTrust" || return 1
fi
# append Intermediate
cat "$_cfullchain" "$(dirname "$_cca")/../IdentTrust.pem" > "${_cca}.real"
/opt/zimbra/bin/zmcertmgr verifycrt comm "$_ckey" "$_ccert" "${_cca}.real" || return 1
#if it verifies we can deploy it
cp -f "$_ckey" /opt/zimbra/ssl/zimbra/commercial/commercial.key
/opt/zimbra/bin/zmcertmgr deploycrt comm "$_ccert" "${_cca}.real" || return 1
/opt/zimbra/bin/zmmailboxdctl reload
/opt/zimbra/bin/zmproxyctl reload
/opt/zimbra/bin/zmmtactl reload
return 0
}
Re: Another Letsencrypt method
Thanks JDunphy ! I know the Root CA is not needed for the browser or other clients (in fact, if you include it most verification tools will complain), but I think Zimbra needs it to verify that is has the whole chain. I *think* I tried adding the root CA to the system store (/etc/ssl) but that didn't work. Not sure if there is a way to make zmcertmgr not require it (oh, now that I come to think of it, one could try adding it to the Java Keystore).
I'll try your updated script some time soon.
I'll try your updated script some time soon.