acmesh-official / acme.sh

A pure Unix shell script implementing ACME client protocol
https://acme.sh
GNU General Public License v3.0
38.67k stars 4.91k forks source link

Using multiple DNS Aliases donesn't work in some circumstances #1876

Open scheying opened 5 years ago

scheying commented 5 years ago

Summary

It seems there is a problem correctly assigning domain aliases to the corresponding domains.

Steps to reproduce

For example if I do this:

  /opt/acme.sh/acme.sh --issue --dns dns_nsupdate --dnssleep 5 -d ssl-proxy02.acme.mydomain.com -d mobil.jobs.mydomain.com -d www.jobs.mydomain.com --domain-alias ssl-proxy.acme-challenge.mydomainchallengedomain.com -d mydomain.com -d \*.mydomain.com --domain-alias myapex.acme-challenge.mydomainchallengedomain.com

I get an "Incorrect TXT record" verify error for the second domain:

Debug log

[Thu Oct 11 09:12:38 CEST 2018] vlist='ssl-proxy02.acme.mydomain.com#_MVh9NtI_F2acllGvUmBoFbTSYWBbj4f0lC10TZkni0.MAtIRK3NuPuKJ3Mr-tsV9brC2ypj2fx-C50qVwbm5mw#https://acme-v02.api.letsencrypt.org/acme/challenge/XgY6UMFxyInczg97QZo3eae8R3L_XP4RAC9OnFY_N6w/8176094717#dns-01#dns_nsupdate,mobil.jobs.mydomain.com#C1omRgKpWLe8wzf3LYYRtkUcPuYSM43RWq-ET5HgOT0.MAtIRK3NuPuKJ3Mr-tsV9brC2ypj2fx-C50qVwbm
5mw#https://acme-v02.api.letsencrypt.org/acme/challenge/ulCLs3Zj1Y99tQ_lwzIl3ZacaI7c3SuOpuNLGB39HH4/8176094715#dns-01#dns_nsupdate,www.jobs.mydomain.com#bkMWcKUZ1LZNGQke3N369uh6QTiShzFEcUUZ9tj3lgg.MAtIRK3NuPuKJ3Mr-tsV9brC2ypj2fx-C50qVwbm5mw#https://acme-v02.api.letsencrypt.org/acme/challenge/v3g1xSmzWvsvP8Ep0S1fvjntixHOTa3rpVZsyfqdqOM/8176094722#dns-01#dns_nsupdate,mydomain.com#HxWhTJ8eA5a
7AjWQl2wZbnZPdQzHPNT8SuTdep3jUw8.MAtIRK3NuPuKJ3Mr-tsV9brC2ypj2fx-C50qVwbm5mw#https://acme-v02.api.letsencrypt.org/acme/challenge/0gCJ-fAWwvFYRhaBxP1kM-axSH8yj-g3dF6_iOPt8Xo/8176094727#dns-01#dns_nsupdate,*.mydomain.com#epLPhBx0rN56axOzEi41o25CfqhJVbNPyW7dTNhVQuw.MAtIRK3NuPuKJ3Mr-tsV9brC2ypj2fx-C50qVwbm5mw#https://acme-v02.api.letsencrypt.org/acme/challenge/tz6OW6RBIGlSskVAsDHGpHkT869I
-UGU1tBOcJZVubI/8176094712#dns-01#dns_nsupdate,'
[Thu Oct 11 09:12:38 CEST 2018] d='ssl-proxy02.acme.mydomain.com'
[Thu Oct 11 09:12:38 CEST 2018] _d_alias='=ssl-proxy.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:38 CEST 2018] txtdomain='ssl-proxy.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:38 CEST 2018] txt='MqgpfsiiX5vCzrgGVEXbpt7FhCRFUEAfihJhWKCeosk'
[Thu Oct 11 09:12:38 CEST 2018] d_api='/opt/acme.sh/dnsapi/dns_nsupdate.sh'
[Thu Oct 11 09:12:38 CEST 2018] Found domain api file: /opt/acme.sh/dnsapi/dns_nsupdate.sh
[Thu Oct 11 09:12:38 CEST 2018] adding ssl-proxy.acme-challenge.mydomainchallengedomain.com. 60 in txt "MqgpfsiiX5vCzrgGVEXbpt7FhCRFUEAfihJhWKCeosk"
[Thu Oct 11 09:12:39 CEST 2018] d='mobil.jobs.mydomain.com'
[Thu Oct 11 09:12:39 CEST 2018] _d_alias='=myapex.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:39 CEST 2018] txtdomain='myapex.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:39 CEST 2018] txt='8E3vmNC0rbUgMRy_i4tCHF-thnuJ_SoP1Xg61WNc3KY'
[Thu Oct 11 09:12:39 CEST 2018] d_api='/opt/acme.sh/dnsapi/dns_nsupdate.sh'
[Thu Oct 11 09:12:39 CEST 2018] Found domain api file: /opt/acme.sh/dnsapi/dns_nsupdate.sh
[Thu Oct 11 09:12:39 CEST 2018] adding myapex.acme-challenge.mydomainchallengedomain.com. 60 in txt "8E3vmNC0rbUgMRy_i4tCHF-thnuJ_SoP1Xg61WNc3KY"
[Thu Oct 11 09:12:39 CEST 2018] d='www.jobs.mydomain.com'
[Thu Oct 11 09:12:39 CEST 2018] _d_alias='=myapex.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:39 CEST 2018] txtdomain='myapex.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:39 CEST 2018] txt='PgoEjvfnCP2w-pqTOiraGSAo7PDNBLoA_dIuxIk3WhU'
[Thu Oct 11 09:12:39 CEST 2018] d_api='/opt/acme.sh/dnsapi/dns_nsupdate.sh'
[Thu Oct 11 09:12:39 CEST 2018] Found domain api file: /opt/acme.sh/dnsapi/dns_nsupdate.sh
[Thu Oct 11 09:12:39 CEST 2018] adding myapex.acme-challenge.mydomainchallengedomain.com. 60 in txt "PgoEjvfnCP2w-pqTOiraGSAo7PDNBLoA_dIuxIk3WhU"
[Thu Oct 11 09:12:39 CEST 2018] d='mydomain.com'
[Thu Oct 11 09:12:39 CEST 2018] _d_alias='=myapex.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:39 CEST 2018] txtdomain='myapex.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:39 CEST 2018] txt='2xn0N0zvQJxVMFZwNCqKWCkuDqmuYlbm6YkCbmxejR0'
[Thu Oct 11 09:12:39 CEST 2018] d_api='/opt/acme.sh/dnsapi/dns_nsupdate.sh'
[Thu Oct 11 09:12:39 CEST 2018] Found domain api file: /opt/acme.sh/dnsapi/dns_nsupdate.sh
[Thu Oct 11 09:12:39 CEST 2018] adding myapex.acme-challenge.mydomainchallengedomain.com. 60 in txt "2xn0N0zvQJxVMFZwNCqKWCkuDqmuYlbm6YkCbmxejR0"
[Thu Oct 11 09:12:39 CEST 2018] d='*.mydomain.com'
[Thu Oct 11 09:12:39 CEST 2018] _d_alias='=myapex.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:39 CEST 2018] txtdomain='myapex.acme-challenge.mydomainchallengedomain.com'
[Thu Oct 11 09:12:39 CEST 2018] txt='G0jKcRdFbmcbPyDgQEyOprQA7ooqoCzlT_pNXOmYyaQ'
[Thu Oct 11 09:12:39 CEST 2018] d_api='/opt/acme.sh/dnsapi/dns_nsupdate.sh'
[Thu Oct 11 09:12:39 CEST 2018] Found domain api file: /opt/acme.sh/dnsapi/dns_nsupdate.sh
[Thu Oct 11 09:12:40 CEST 2018] adding myapex.acme-challenge.mydomainchallengedomain.com. 60 in txt "G0jKcRdFbmcbPyDgQEyOprQA7ooqoCzlT_pNXOmYyaQ"
[Thu Oct 11 09:12:40 CEST 2018] Sleep ESC[1;31;32m5ESC[0m seconds for the txt records to take effect
[Thu Oct 11 09:12:46 CEST 2018] ok, let's start to verify
[Thu Oct 11 09:12:46 CEST 2018] Verifying:ssl-proxy02.acme.mydomain.com
[Thu Oct 11 09:12:46 CEST 2018] d='ssl-proxy02.acme.mydomain.com'
[Thu Oct 11 09:12:46 CEST 2018] keyauthorization='_MVh9NtI_F2acllGvUmBoFbTSYWBbj4f0lC10TZkni0.MAtIRK3NuPuKJ3Mr-tsV9brC2ypj2fx-C50qVwbm5mw'
[Thu Oct 11 09:12:46 CEST 2018] uri='https://acme-v02.api.letsencrypt.org/acme/challenge/XgY6UMFxyInczg97QZo3eae8R3L_XP4RAC9OnFY_N6w/8176094717'
[Thu Oct 11 09:12:46 CEST 2018] _currentRoot='dns_nsupdate'
[Thu Oct 11 09:12:46 CEST 2018] url='https://acme-v02.api.letsencrypt.org/acme/challenge/XgY6UMFxyInczg97QZo3eae8R3L_XP4RAC9OnFY_N6w/8176094717'
[Thu Oct 11 09:12:46 CEST 2018] payload='{"keyAuthorization": "_MVh9NtI_F2acllGvUmBoFbTSYWBbj4f0lC10TZkni0.MAtIRK3NuPuKJ3Mr-tsV9brC2ypj2fx-C50qVwbm5mw"}'
[Thu Oct 11 09:12:46 CEST 2018] POST
[Thu Oct 11 09:12:46 CEST 2018] _post_url='https://acme-v02.api.letsencrypt.org/acme/challenge/XgY6UMFxyInczg97QZo3eae8R3L_XP4RAC9OnFY_N6w/8176094717'
[Thu Oct 11 09:12:46 CEST 2018] _CURL='curl -L --silent --dump-header /opt/acme.sh/http.header  -g '
[Thu Oct 11 09:12:46 CEST 2018] _ret='0'
[Thu Oct 11 09:12:46 CEST 2018] code='200'
[Thu Oct 11 09:12:46 CEST 2018] trigger validation code: 200
[Thu Oct 11 09:12:46 CEST 2018] sleep 2 secs to verify
[Thu Oct 11 09:12:48 CEST 2018] checking
[Thu Oct 11 09:12:48 CEST 2018] GET
[Thu Oct 11 09:12:48 CEST 2018] url='https://acme-v02.api.letsencrypt.org/acme/challenge/XgY6UMFxyInczg97QZo3eae8R3L_XP4RAC9OnFY_N6w/8176094717'
[Thu Oct 11 09:12:48 CEST 2018] timeout=
[Thu Oct 11 09:12:48 CEST 2018] _CURL='curl -L --silent --dump-header /opt/acme.sh/http.header  -g '
[Thu Oct 11 09:12:48 CEST 2018] ret='0'
[Thu Oct 11 09:12:48 CEST 2018] ESC[1;31;32mSuccessESC[0m
[Thu Oct 11 09:12:48 CEST 2018] pid
[Thu Oct 11 09:12:48 CEST 2018] Skip for removelevel:
[Thu Oct 11 09:12:48 CEST 2018] Verifying:mobil.jobs.mydomain.com
[Thu Oct 11 09:12:48 CEST 2018] d='mobil.jobs.mydomain.com'
[Thu Oct 11 09:12:48 CEST 2018] keyauthorization='C1omRgKpWLe8wzf3LYYRtkUcPuYSM43RWq-ET5HgOT0.MAtIRK3NuPuKJ3Mr-tsV9brC2ypj2fx-C50qVwbm5mw'
[Thu Oct 11 09:12:48 CEST 2018] uri='https://acme-v02.api.letsencrypt.org/acme/challenge/ulCLs3Zj1Y99tQ_lwzIl3ZacaI7c3SuOpuNLGB39HH4/8176094715'
[Thu Oct 11 09:12:48 CEST 2018] _currentRoot='dns_nsupdate'
[Thu Oct 11 09:12:48 CEST 2018] url='https://acme-v02.api.letsencrypt.org/acme/challenge/ulCLs3Zj1Y99tQ_lwzIl3ZacaI7c3SuOpuNLGB39HH4/8176094715'
[Thu Oct 11 09:12:48 CEST 2018] payload='{"keyAuthorization": "C1omRgKpWLe8wzf3LYYRtkUcPuYSM43RWq-ET5HgOT0.MAtIRK3NuPuKJ3Mr-tsV9brC2ypj2fx-C50qVwbm5mw"}'
[Thu Oct 11 09:12:48 CEST 2018] POST
[Thu Oct 11 09:12:48 CEST 2018] _post_url='https://acme-v02.api.letsencrypt.org/acme/challenge/ulCLs3Zj1Y99tQ_lwzIl3ZacaI7c3SuOpuNLGB39HH4/8176094715'
[Thu Oct 11 09:12:48 CEST 2018] _CURL='curl -L --silent --dump-header /opt/acme.sh/http.header  -g '
[Thu Oct 11 09:12:49 CEST 2018] _ret='0'
[Thu Oct 11 09:12:49 CEST 2018] code='200'
[Thu Oct 11 09:12:49 CEST 2018] trigger validation code: 200
[Thu Oct 11 09:12:49 CEST 2018] sleep 2 secs to verify
[Thu Oct 11 09:12:51 CEST 2018] checking
[Thu Oct 11 09:12:51 CEST 2018] GET
[Thu Oct 11 09:12:51 CEST 2018] url='https://acme-v02.api.letsencrypt.org/acme/challenge/ulCLs3Zj1Y99tQ_lwzIl3ZacaI7c3SuOpuNLGB39HH4/8176094715'
[Thu Oct 11 09:12:51 CEST 2018] timeout=
[Thu Oct 11 09:12:51 CEST 2018] _CURL='curl -L --silent --dump-header /opt/acme.sh/http.header  -g '
[Thu Oct 11 09:12:51 CEST 2018] ret='0'
[Thu Oct 11 09:12:51 CEST 2018] mobil.jobs.mydomain.com:Verify error:Incorrect TXT record

Observations

I tried several combinations and it seems to me that the following work or don't work:

Exactly one Domain for the first alias and one alias for the remaining domains WORKS ✅

-d a.com --domain-alias alias-a.com -d b.com -d c.com --domain -alias alias-b-and-c.com

One Alias per domain WORKS ✅

-d a.com --domain-alias alias-a.com -d b.com -alias alias-b.com-d c.com --domain -alias alias-c.com

One alias for more than one domain in the beginning DOES NOT WORK ❌

-d a.com -d b.com --domain-alias alias-a-and-b.com -d -d c.com --domain -alias alias-c.com

One Alias per domain but reusing domain-alias alias-a-and-c.com DOES NOT WORK ❌

-d a.com --domain-alias alias-a-and-c.com -d b.com --domain -alias alias-b.com -d c.com --domain -alias alias-a-and-c.com

Why not use CNAMEs directly?

One could question if the whole domain alias thing is neccessary at all. In allmost any cases where the _acme-challenge.something.com Record is a CNAME, the thing you want to update is the value of that CNAME. I think at least an option to automatically follow CNAMEs to get the the validation "aliases" would be really cool :-) (Getssl seems to have done that: https://github.com/srvrco/getssl/issues/381)

Neilpang commented 5 years ago

One Alias per domain WORKS

Yes, if you have different alias for different domains, this is the only correct way.

I think at least an option to automatically follow CNAMEs to get the the validation

Yes, I agree that this would be cool, but it will need dependency to dig or nslookup command etc. acme.sh is a posix compatible shell script, crossing platforms like: BSD, Linux, Solaris, Mac and even Windows. It will be a lot of work to support all the platforms.

scheying commented 5 years ago

Thanks you for your reply, Neil (and for making acme.sh!). I modified our scripts (that use acme.sh) to use the "one alias per domain" scheme but I still got verification errors. When debugging I came to the conclusion that Domains that are skipped because they are already verified (line 3776) do not increase _alias_index. I added that and now it works. Should I open a PR for that or is that either too easy or not as easy as I think?

Neilpang commented 5 years ago

@scheying Yes, please send me your PR.

Thanks.