Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible with wildcards #1

Open
levinuss opened this issue Jul 10, 2018 · 9 comments
Open

Incompatible with wildcards #1

levinuss opened this issue Jul 10, 2018 · 9 comments

Comments

@levinuss
Copy link

Hey,
the script does not work for me anymore when requesting wildcards from LE. If I want to get a cert for example.org and *.example.org LE will use two separate challenges and also two different TXT record values for this. acme.sh will call the script two times, one time for the base domain and the second time, with the same name but a different content, for the wildcard (https://community.letsencrypt.org/t/base-domain-validation/59009). The servercow API will override the first record when the script tries to place the second (see DNSAPIv1 documentation). content has to be an array to transfer multiple records with the same name. The script would have to get a list of all records and copy the existing ones into the content array.
In my python script for the API I solved it like this (get_record_list is self-explanatory..):

def add_record(domain, record_type, record_name, record_content, record_ttl,                                                                                                                                
               keep_record):                                                                                                                                                                                
    record_list = get_record_list(domain, 0, 0)                                                                                                                                                             
    existing_records_content = []                                                                                                                                                                           
    for record in record_list:                                                                                                                                                                              
        if record['name'] == record_name:                                                                                                                                                                   
            existing_records_content.append(record['content'])                                                                                                                                                                                                                                                                                     
    if (keep_record == 1):                                                                                                                                                                                  
        if (isinstance(record_content, list)):                                                                                                                                                              
            for content in record_content:                                                                                                                                                                  
                existing_records_content.append(content)                                                                                                                                                    
        else:                                                                                                                                                                                               
            existing_records_content.append(record_content)                                                                                                                                                 
        records_contents = existing_records_content
        .....

Maybe this is helpful. I'm not that experienced, esp with shell, that's why I didn't create a PR.
My current workaround is to use the manual mode or to first request a separate cert for each domain I wan't in my final cert and then issue my final cert. The successful challenges will be cached for some time.

@jhartlep
Copy link
Owner

Hi,
thanks. I haven´t used wildcards with LE yet.
But I will try to fix this issue.

@jhartlep
Copy link
Owner

Hi @Levinus
I just analysed this issue.
The Servercow API currently does not support adding two DNS entries with different values.
I am in contact with servercow to get a solution for this.
If the Servercow API supports this, I will update my skript.

@levinuss
Copy link
Author

Afaik it does. See this document from the servercow knowledgebase. If you look at the pyhton snippet above, you can see that I just add all values to an array.

@baswag
Copy link

baswag commented Jul 10, 2019

Any update on the issue?

protree added a commit to protree/servercow-dns-api that referenced this issue Sep 11, 2019
As discussed here (jhartlep#1) validating wildcard domains requires multiple acme challenges as TXT records with the same name to be set in domain. Servercow's Domain API v1 replaces a TXT entry if another TXT entry with the same name is sent. To set multiple TXT records with the same name Servercow's Domain API v1 needs all of them in one request. To accomplish this a simple Key=Value Cache is needed, so that consecutive requests include acme-Challanges of previous requests.

I didn't see any other solution to cache acme-challanges than using a cache file because of acme.sh's plugin design...

Greatest downside of my solution is that it requires BASH and doesn't work with posix SH which makes it impossible to add it to acme.sh official plugins according to their dev guidelines (https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide)... I may look into this later but as of now I am satisfied with my solution because I don't need posix SH support.

I tested it against staging and production servers with and without wildcards and multiple subdomains.

I know my solution isn't perfect but it should work (at least in BASH environments) and I wanted to share it with you!
@anom-human
Copy link

#acmesh-official/acme.sh#3449
The PR should close the issue.

@Miyamoto72
Copy link

Somehow this again is an issue. Trying to issue a cert for '*.mydomain.com' and mydomain.com, but I always get the following error:

acme.sh --issue --dns dns_servercow --keylength 4096 -d '*.mydomain.com' -d mydomain.com -f --debug

[...]

[Mo 27. Sep 08:51:33 CEST 2021] Getting webroot for domain='.mydomain.com'
[Mo 27. Sep 08:51:33 CEST 2021] _w='dns_servercow'
[Mo 27. Sep 08:51:33 CEST 2021] _currentRoot='dns_servercow'
[Mo 27. Sep 08:51:33 CEST 2021] entry='"type":"dns-01","status":"pending","url":"https://acme-v02.api.letsencrypt.org/acme/chall-v3/34735927400/Km8dEA","token":"CqAfsHgCvloTMi3tnhyed9clsbT_A6DDEKi2jNQleRc"'
[Mo 27. Sep 08:51:33 CEST 2021] token='CqAfsHgCvloTMi3tnhyed9clsbT_A6DDEKi2jNQleRc'
[Mo 27. Sep 08:51:33 CEST 2021] uri='https://acme-v02.api.letsencrypt.org/acme/chall-v3/34735927400/Km8dEA'
[Mo 27. Sep 08:51:33 CEST 2021] keyauthorization='CqAfsHgCvloTMi3tnhyed9clsbT_A6DDEKi2jNQleRc.yvIO2X0CtpshXNFS0MKSABMjwoPMndKDdmTch_Y1bWU'
[Mo 27. Sep 08:51:33 CEST 2021] dvlist='
.mydomain.com#CqAfsHgCvloTMi3tnhyed9clsbT_A6DDEKi2jNQleRc.yvIO2X0CtpshXNFS0MKSABMjwoPMndKDdmTch_Y1bWU#https://acme-v02.api.letsencrypt.org/acme/chall-v3/34735927400/Km8dEA#dns-01#dns_servercow'
[Mo 27. Sep 08:51:33 CEST 2021] d='mydomain.com'
[Mo 27. Sep 08:51:33 CEST 2021] Getting webroot for domain='mydomain.com'
[Mo 27. Sep 08:51:33 CEST 2021] _w='dns_servercow'
[Mo 27. Sep 08:51:33 CEST 2021] _currentRoot='dns_servercow'
[Mo 27. Sep 08:51:33 CEST 2021] entry
[Mo 27. Sep 08:51:33 CEST 2021] Not a wildcard domain, lets check whether the validation is already valid.
[Mo 27. Sep 08:51:33 CEST 2021] mydomain.com is already valid.
[Mo 27. Sep 08:51:33 CEST 2021] keyauthorization='verified_ok'
[Mo 27. Sep 08:51:33 CEST 2021] dvlist='mydomain.com#verified_ok#https://acme-v02.api.letsencrypt.org/acme/chall-v3/34735927400/Km8dEA#dns-01#dns_servercow'
[Mo 27. Sep 08:51:33 CEST 2021] d
[Mo 27. Sep 08:51:33 CEST 2021] vlist='.mydomain.com#CqAfsHgCvloTMi3tnhyed9clsbT_A6DDEKi2jNQleRc.yvIO2X0CtpshXNFS0MKSABMjwoPMndKDdmTch_Y1bWU#https://acme-v02.api.letsencrypt.org/acme/chall-v3/34735927400/Km8dEA#dns-01#dns_servercow,mydomain.com#verified_ok#https://acme-v02.api.letsencrypt.org/acme/chall-v3/34735927400/Km8dEA#dns-01#dns_servercow,'
[Mo 27. Sep 08:51:33 CEST 2021] d='
.mydomain.com'
[Mo 27. Sep 08:51:33 CEST 2021] _d_alias
[Mo 27. Sep 08:51:33 CEST 2021] txtdomain='_acme-challenge.mydomain.com'
[Mo 27. Sep 08:51:33 CEST 2021] txt='s_E_Rff3TS0uJDkmvjQp6qaoFZrZEBj-KBNlAtEZ9AU'
[Mo 27. Sep 08:51:33 CEST 2021] d_api='/home/acmeuser/.acme.sh/dnsapi/dns_servercow.sh'
[Mo 27. Sep 08:51:33 CEST 2021] Found domain api file: /home/acmeuser/.acme.sh/dnsapi/dns_servercow.sh
[Mo 27. Sep 08:51:33 CEST 2021] Adding txt value: s_E_Rff3TS0uJDkmvjQp6qaoFZrZEBj-KBNlAtEZ9AU for domain: _acme-challenge.mydomain.com
[Mo 27. Sep 08:51:33 CEST 2021] Using servercow
[Mo 27. Sep 08:51:33 CEST 2021] fulldomain='_acme-challenge.mydomain.com'
[Mo 27. Sep 08:51:33 CEST 2021] txtvalue='s_E_Rff3TS0uJDkmvjQp6qaoFZrZEBj-KBNlAtEZ9AU'
[Mo 27. Sep 08:51:33 CEST 2021] First detect the root zone
[Mo 27. Sep 08:51:33 CEST 2021] _domain='mydomain.com'
[Mo 27. Sep 08:51:33 CEST 2021] Retrying GET
[Mo 27. Sep 08:51:33 CEST 2021] GET
[Mo 27. Sep 08:51:33 CEST 2021] url='https://api.servercow.de/dns/v1/domains/mydomain.com'
[Mo 27. Sep 08:51:33 CEST 2021] timeout=
[Mo 27. Sep 08:51:33 CEST 2021] displayError='1'
[Mo 27. Sep 08:51:33 CEST 2021] _CURL='curl --silent --dump-header /home/acmeuser/.acme.sh/http.header -L '
[Mo 27. Sep 08:51:37 CEST 2021] ret='0'
[Mo 27. Sep 08:51:37 CEST 2021] _hcode='0'
[Mo 27. Sep 08:51:37 CEST 2021] _sub_domain='_acme-challenge'
[Mo 27. Sep 08:51:37 CEST 2021] _domain='mydomain.com'
[Mo 27. Sep 08:51:37 CEST 2021] There is no txt record with the name yet.
[Mo 27. Sep 08:51:37 CEST 2021] data='{"type":"TXT","name":"_acme-challenge.mydomain.com","content":"s_E_Rff3TS0uJDkmvjQp6qaoFZrZEBj-KBNlAtEZ9AU","ttl":20}'
[Mo 27. Sep 08:51:37 CEST 2021] Retrying post
[Mo 27. Sep 08:51:37 CEST 2021] POST
[Mo 27. Sep 08:51:37 CEST 2021] _post_url='https://api.servercow.de/dns/v1/domains/mydomain.com'
[Mo 27. Sep 08:51:37 CEST 2021] _CURL='curl --silent --dump-header /home/acmeuser/.acme.sh/http.header -L '
[Mo 27. Sep 08:51:44 CEST 2021] _ret='0'
[Mo 27. Sep 08:51:44 CEST 2021] _hcode='0'
[Mo 27. Sep 08:51:44 CEST 2021] add txt record error.
[Mo 27. Sep 08:51:44 CEST 2021] Error add txt for domain:_acme-challenge.mydomain.com
[Mo 27. Sep 08:51:44 CEST 2021] _on_issue_err
[Mo 27. Sep 08:51:44 CEST 2021] Please check log file for more details: /home/acmeuser/.acme.sh/acme.sh.log
[Mo 27. Sep 08:51:44 CEST 2021] url='https://acme-v02.api.letsencrypt.org/acme/chall-v3/34735927400/Km8dEA'
[Mo 27. Sep 08:51:44 CEST 2021] payload='{}'

[...]

Using acme.sh v3.0.1 on Debian Buster with NGinx 1.21.3 (from nginx.org)

Setup worked before flawlessly (acme.sh 2.8.6 for long time), but now I wasn't able to get a wildcard cert - got only the mydomain.com cert when issueing it alone

Happy to help track this down - pls let me know if I can be of help.

@anom-human
Copy link

I'll have a look at it in the next few days and make some improvements. But I can't promise anything, I'm a bit busy right now.

@Miyamoto72
Copy link

Some more infos:
Apparenly I had a problem with the authentication at times - this is solved. Trying to issue a new combined cert with a defined keylength of 4096 bits throws an error:

[Do 30. Sep 19:32:04 CEST 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Do 30. Sep 19:32:04 CEST 2021] Creating domain key
[Do 30. Sep 19:32:04 CEST 2021] error ecc key name: mydomain.com
[Do 30. Sep 19:32:04 CEST 2021] Can not create domain key
[Do 30. Sep 19:32:04 CEST 2021] Create domain key error.

Apparently acme.sh now tries to create ECC keys, too, by default, and those have other keylengths. In my opinion this is an error in acme.sh, of course.

Trying to issue an RSA key by command line options should be possible, I'd say, but I didn't find a way. So I tried to issue a new combined cert from the backup of the old CSR:

[Do 30. Sep 19:39:19 CEST 2021] Copy csr to: /home/acmeuser/.acme.sh/*.mydomain.com/*.mydomain.com.csr
[Do 30. Sep 19:39:19 CEST 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Do 30. Sep 19:39:19 CEST 2021] Signing from existing CSR.
[Do 30. Sep 19:39:19 CEST 2021] Getting domain auth token for each domain
[Do 30. Sep 19:39:22 CEST 2021] Getting webroot for domain='*.mydomain.com'
[Do 30. Sep 19:39:23 CEST 2021] Error, can not get domain token entry *.mydomain.com for http-01
[Do 30. Sep 19:39:23 CEST 2021] The supported validation types are: dns-01 , but you specified: http-01

Here's the log:

[Do 30. Sep 19:53:44 CEST 2021] Running cmd: signcsr
[Do 30. Sep 19:53:44 CEST 2021] _csrsubj='*.mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] _csrsubj='*.mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] _dnsAltnames='DNS:*.mydomain.com,DNS:mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] AltNames contains subject
[Do 30. Sep 19:53:44 CEST 2021] _excapedAlgnames='DNS:#.mydomain.com,DNS:mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] _escapedSubject='#.mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] _dnsAltnames='DNS:mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] _csrdomainlist='mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] RSA CSR
[Do 30. Sep 19:53:44 CEST 2021] Using config home:/home/acmeuser/.acme.sh
[Do 30. Sep 19:53:44 CEST 2021] default_acme_server='https://acme-v02.api.letsencrypt.org/directory'
[Do 30. Sep 19:53:44 CEST 2021] ACME_DIRECTORY='https://acme-v02.api.letsencrypt.org/directory'
[Do 30. Sep 19:53:44 CEST 2021] DOMAIN_PATH='/home/acmeuser/.acme.sh/*.mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] Copy csr to: /home/acmeuser/.acme.sh/*.mydomain.com/*.mydomain.com.csr
[Do 30. Sep 19:53:44 CEST 2021] _main_domain='*.mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] _alt_domains='mydomain.com'
[Do 30. Sep 19:53:44 CEST 2021] Using config home:/home/acmeuser/.acme.sh
[Do 30. Sep 19:53:44 CEST 2021] ACME_DIRECTORY='https://acme-v02.api.letsencrypt.org/directory'
[Do 30. Sep 19:53:44 CEST 2021] Using ACME_DIRECTORY: https://acme-v02.api.letsencrypt.org/directory
[Do 30. Sep 19:53:44 CEST 2021] _init api for server: https://acme-v02.api.letsencrypt.org/directory
[Do 30. Sep 19:53:44 CEST 2021] Retrying GET
[Do 30. Sep 19:53:44 CEST 2021] GET
[Do 30. Sep 19:53:44 CEST 2021] url='https://acme-v02.api.letsencrypt.org/directory'
[Do 30. Sep 19:53:44 CEST 2021] timeout=
[Do 30. Sep 19:53:44 CEST 2021] displayError='1'
[Do 30. Sep 19:53:44 CEST 2021] _CURL='curl --silent --dump-header /home/acmeuser/.acme.sh/http.header  -L '
[Do 30. Sep 19:53:45 CEST 2021] ret='0'
[Do 30. Sep 19:53:45 CEST 2021] _hcode='0'
[Do 30. Sep 19:53:45 CEST 2021] ACME_KEY_CHANGE='https://acme-v02.api.letsencrypt.org/acme/key-change'
[Do 30. Sep 19:53:45 CEST 2021] ACME_NEW_AUTHZ
[Do 30. Sep 19:53:45 CEST 2021] ACME_NEW_ORDER='https://acme-v02.api.letsencrypt.org/acme/new-order'
[Do 30. Sep 19:53:45 CEST 2021] ACME_NEW_ACCOUNT='https://acme-v02.api.letsencrypt.org/acme/new-acct'
[Do 30. Sep 19:53:45 CEST 2021] ACME_REVOKE_CERT='https://acme-v02.api.letsencrypt.org/acme/revoke-cert'
[Do 30. Sep 19:53:45 CEST 2021] ACME_AGREEMENT='https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf'
[Do 30. Sep 19:53:45 CEST 2021] ACME_NEW_NONCE='https://acme-v02.api.letsencrypt.org/acme/new-nonce'
[Do 30. Sep 19:53:45 CEST 2021] Le_NextRenewTime
[Do 30. Sep 19:53:45 CEST 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Do 30. Sep 19:53:45 CEST 2021] _on_before_issue
[Do 30. Sep 19:53:45 CEST 2021] _chk_main_domain='*.mydomain.com'
[Do 30. Sep 19:53:45 CEST 2021] _chk_alt_domains='mydomain.com'
[Do 30. Sep 19:53:45 CEST 2021] Le_LocalAddress
[Do 30. Sep 19:53:45 CEST 2021] d='*.mydomain.com'
[Do 30. Sep 19:53:45 CEST 2021] Check for domain='*.mydomain.com'
[Do 30. Sep 19:53:45 CEST 2021] _currentRoot='/var/www/letsencrypt/'
[Do 30. Sep 19:53:45 CEST 2021] d='mydomain.com'
[Do 30. Sep 19:53:45 CEST 2021] Check for domain='mydomain.com'
[Do 30. Sep 19:53:45 CEST 2021] _currentRoot='dns_servercow'
[Do 30. Sep 19:53:45 CEST 2021] d
[Do 30. Sep 19:53:45 CEST 2021] _saved_account_key_hash is not changed, skip register account.
[Do 30. Sep 19:53:45 CEST 2021] Signing from existing CSR.
[Do 30. Sep 19:53:45 CEST 2021] Getting domain auth token for each domain
[Do 30. Sep 19:53:45 CEST 2021] d='mydomain.com'
[Do 30. Sep 19:53:45 CEST 2021] d
[Do 30. Sep 19:53:45 CEST 2021] url='https://acme-v02.api.letsencrypt.org/acme/new-order'
[Do 30. Sep 19:53:45 CEST 2021] payload='{"identifiers": [{"type":"dns","value":"*.mydomain.com"},{"type":"dns","value":"mydomain.com"}]}'
[Do 30. Sep 19:53:45 CEST 2021] RSA key
[Do 30. Sep 19:53:45 CEST 2021] Retrying post
[Do 30. Sep 19:53:45 CEST 2021] HEAD
[Do 30. Sep 19:53:45 CEST 2021] _post_url='https://acme-v02.api.letsencrypt.org/acme/new-nonce'
[Do 30. Sep 19:53:45 CEST 2021] _CURL='curl --silent --dump-header /home/acmeuser/.acme.sh/http.header  -L  -I  '
[Do 30. Sep 19:53:46 CEST 2021] _ret='0'
[Do 30. Sep 19:53:46 CEST 2021] _hcode='0'
[Do 30. Sep 19:53:46 CEST 2021] Retrying post
[Do 30. Sep 19:53:46 CEST 2021] POST
[Do 30. Sep 19:53:46 CEST 2021] _post_url='https://acme-v02.api.letsencrypt.org/acme/new-order'
[Do 30. Sep 19:53:46 CEST 2021] _CURL='curl --silent --dump-header /home/acmeuser/.acme.sh/http.header  -L '
[Do 30. Sep 19:53:47 CEST 2021] _ret='0'
[Do 30. Sep 19:53:47 CEST 2021] _hcode='0'
[Do 30. Sep 19:53:47 CEST 2021] code='201'
[Do 30. Sep 19:53:47 CEST 2021] Le_LinkOrder='https://acme-v02.api.letsencrypt.org/acme/order/219267140/28406525630'
[Do 30. Sep 19:53:47 CEST 2021] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/219267140/28406525630'
[Do 30. Sep 19:53:47 CEST 2021] url='https://acme-v02.api.letsencrypt.org/acme/authz-v3/35793653770'
[Do 30. Sep 19:53:47 CEST 2021] payload
[Do 30. Sep 19:53:47 CEST 2021] Retrying post
[Do 30. Sep 19:53:47 CEST 2021] POST
[Do 30. Sep 19:53:47 CEST 2021] _post_url='https://acme-v02.api.letsencrypt.org/acme/authz-v3/35793653770'
[Do 30. Sep 19:53:47 CEST 2021] _CURL='curl --silent --dump-header /home/acmeuser/.acme.sh/http.header  -L '
[Do 30. Sep 19:53:47 CEST 2021] _ret='0'
[Do 30. Sep 19:53:47 CEST 2021] _hcode='0'
[Do 30. Sep 19:53:47 CEST 2021] code='200'
[Do 30. Sep 19:53:47 CEST 2021] url='https://acme-v02.api.letsencrypt.org/acme/authz-v3/35793653780'
[Do 30. Sep 19:53:47 CEST 2021] payload
[Do 30. Sep 19:53:48 CEST 2021] Retrying post
[Do 30. Sep 19:53:48 CEST 2021] POST
[Do 30. Sep 19:53:48 CEST 2021] _post_url='https://acme-v02.api.letsencrypt.org/acme/authz-v3/35793653780'
[Do 30. Sep 19:53:48 CEST 2021] _CURL='curl --silent --dump-header /home/acmeuser/.acme.sh/http.header  -L '
[Do 30. Sep 19:53:48 CEST 2021] _ret='0'
[Do 30. Sep 19:53:48 CEST 2021] _hcode='0'
[Do 30. Sep 19:53:48 CEST 2021] code='200'
[Do 30. Sep 19:53:48 CEST 2021] d='*.mydomain.com'
[Do 30. Sep 19:53:48 CEST 2021] Getting webroot for domain='*.mydomain.com'
[Do 30. Sep 19:53:48 CEST 2021] _w='/var/www/letsencrypt/'
[Do 30. Sep 19:53:48 CEST 2021] _currentRoot='/var/www/letsencrypt/'
[Do 30. Sep 19:53:48 CEST 2021] entry
[Do 30. Sep 19:53:48 CEST 2021] Error, can not get domain token entry *.mydomain.com for http-01
[Do 30. Sep 19:53:48 CEST 2021] The supported validation types are: dns-01 , but you specified: http-01
[Do 30. Sep 19:53:48 CEST 2021] pid
[Do 30. Sep 19:53:48 CEST 2021] No need to restore nginx, skip.
[Do 30. Sep 19:53:48 CEST 2021] _clearupdns
[Do 30. Sep 19:53:48 CEST 2021] dns_entries
[Do 30. Sep 19:53:48 CEST 2021] skip dns.
[Do 30. Sep 19:53:48 CEST 2021] _on_issue_err

@Miyamoto72
Copy link

I'll have a look at it in the next few days and make some improvements. But I can't promise anything, I'm a bit busy right now.

Not trying to push - any advances with this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants