I am new to SSL certificate installation. I am trying to do the dns-01 validation using acme-python library. Below is the code I am using. I have added the TXT record also in domain, but in answer challenge i am getting error as "acme.messages.Error: urn:ietf:params:acme:error:malformed :: The request message was malformed :: Unable to update challenge :: authorization must be pending"
After adding the generated TXT record in my DNS and waited till propagated. I ran below command
client_acme.answer_challenge(challenge, response)
Then I got an error saying "acme.messages.Error: urn:ietf:params:acme:error:malformed :: The request message was malformed :: Unable to update challenge :: authorization must be pending"
My web server is (include version):
The operating system my web server runs on is (include version):
My hosting provider, if applicable, is:
I can login to a root shell on my machine (yes or no, or I don't know):
I'm using a control panel to manage my site (no, or provide the name and version of the control panel):
The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot):
Your code does not appear to be checking the status of the authorizations returned. The error message is basically telling you that the authorization isn't in the right state to answer the challenge. If you had previously successfully validated a challenge, it is now probably cached and the status of those authorizations is valid when you create a new order for the same names.
@Bruce5051 & @rmbolger Thanks for the info. I am able to issue a certificate with your update.
I have a couple of doubts, it would be great if you will be able to give some heads up.
Do I need to register the customer each time (with same Email) to form client_acme (in above code)
When should I do the client_acme.answer_challenge(challenge, response). Apparently, I am able to do only one time and getting error if I execute the same command second time (if not successful in the first time).
Is there a way if I can customise "_acme-challenge" to a custom value.
Once customer gives his domain, generate a unique UUID for the domain and store it in my DB and ask the customer to add a CNAME record with name ".<client_domain>" and value "<my_domain>". (if possible to give custom key else will ask to add "_acme-challenge.<client_domain>")
Once customer confirms he added the CNAME, check whether the CNAME is added or not using some python packages. (Not sure how to do this. would be great if you have any inputs)
Request for challenge from ACME.
Add the TXT record in my DNS as ".<client_domain>" and value generate by the challenge
As I am beginner with the process, you may find some of the questions are basic. But, would really appreciate your help in this regard.
It sounds like you need to review the actual ACME spec, RFC 8555, to get a better understanding of how the protocol works and how you should be using it in your code. It answers a lot of your questions in more detail than I'll try to give below.
No, you should be saving the account key you generated and subsequent account metadata so you can re-use it with future orders.
Whenever an authorization object associated with an order has status pending
No, that's a fundamental part of the spec. Though there is a draft spec that is still in development that could offer an account specific FQDN alternative.
Yes, having your customers create a CNAME to a DNS record you control will allow you to authorize certificates on their behalf.
The TXT record goes wherever they have their CNAME pointing to. You won't want to have all of your customers point their CNAME to the same place in your DNS zone.
Now , as part of ACME challenge verification, I am asking my client to add one more CNAME with below details.
Name : _acme-challenge.help.abc.com , Value : help.xyz.com
I am adding a TXT record in my DNS settings as below
Name: _acme-challenge.help.abc.com , Value : "Digest Value Given by ACME"
After following the above process, Once I answer the challenge then I am getting as "No TXT record found at _acme-challenge.help.abc.com"
Unless you intend on getting a wildcard cert, that should always be _acme-challenge.&{FQDN}
So: _acme-challenge.help.abc.com
NOT: _acme-challenge.abc.com
But, if you already have a CNAME for help.abc.com that might not be possible [nor necessary].
Once you have CNAMEd an FQDN, you may no longer be able to add anything to the left of it. Thus: CNAME help.abc.com is effectively doing: CNAME of all help.abc.com entries. [ i.e. *.help.abc.com ]
You simply need to look for: _acme-chalenge.help.abc.com
at: _acme-challeng.help.xyz.com [without any extra CNAME]
If you will be hosting their content, then they will need the CNAME: help.their-site CNAME help.your-site
If you can, use that to obtain a cert via HTTP-01 authentication.
[it's much simpler than DNS-01 authentication]
If you must use DNS-01 authentication, then (for simplicity) I'd keep the entire FQDN similar: _acme-challenge.help.their-site CNAME _acme-challenge.help.your-site
OR maybe more like _acme-challenge.help.their-site CNAME _acme-challenge.customers.your-site
[so as not to be confused with your own help sites' acme challenge TXT records]