joohoi / acme-dns-certbot-joohoi Goto Github PK
View Code? Open in Web Editor NEWCertbot client hook for acme-dns
License: MIT License
Certbot client hook for acme-dns
License: MIT License
The documentation stresses the Python requests library is needed.
Yet, this plugin is for certbot, which (i) needs requests (ii) relies on acme Python package, which also need requests.
Is there a use case where this plugin could be used standalone without acme/certbot not installed (e.g. for CI purpose)?
References:
I have an experimental setup of acme-dns under auth.basjes.nl
When I run this against a different domain I own I see this:
Output from acme-dns-auth.py:
Please add the following CNAME record to your main DNS zone:
_acme-challenge.somedomain.nl CNAME 963ab1da-54bc-4301-9f89-d1393729e78e.auth.basjes.nl
The subtle problem is that if I do it exactly as instructed a dns lookup for
_acme-challenge.somedomain.nl
results in
963ab1da-54bc-4301-9f89-d1393729e78e.auth.basjes.nl.somedomain.nl
The problem lies in the fact that because the '.' is missing in the CNAME dns assumes it is a subdomain of the current zone.
The simple fix for this is to add a '.' in the instructions.
May I suggest to add inn the documentation the exact command required for the renewal and also where "critical" information is stored to avoid deleting a required file. Even after RTFM, oe figures out how to proceed but it would nice to have explicit instructions in the README.
On a different topic, in instances were there is a complex configuration of name servers, the propagation of the CNAME might take quite a while. It would be nice to have the option of exiting at the "Press enter to continue" point and restart the command later. It would be more elegant than having to do a to abort the script. Upon restart, the credentials and the CNAME are already in place and everything works smoothly.
Hey there!
thanks for providing acme-dns, I used and loved it so far.
One Question is left (from the readme): How would i call the manual auth hook in my cron script? Afaik I cannot use --manual as method in certbot renew.
Would I call certonly without --debug-challenges all the time? So no renew
? command?
Thanks in advance
I think this is the relevant place to post this...
Some DNS systems, such as the ones people would use acme-dns instead of, don't allow a leading underscore in CNAME records.
why? a leading underscore is prohibited in hostnames, but allowed in other dns records. Some systems are trying to safeguard users, others are confused in implementations, and others... who knows.
anways, _acme-challenge.
is hardcoded here:
I believe you can supply an alternate. there's a bit of a discussion here https://community.letsencrypt.org/t/acme-sh-support-domain-alias-mode-now/52700/5
I saw the a new certificate got issued on renewal but was not showing up online, I reloaded Apache and there it was. Is it possible to reload apache after successful cert renewal?
Hi,
I'm using certbot and acme-dns-auth.py for getting letsencrypt wildcard certificates.
/var/log/syslog is growing at high speed until /var/ is full (and the machine is frozen) due to the following repeated error message:
Jun 1 17:54:55 test acme-dns[555]: time="2022-06-01T17:54:55+02:00" level=info msg="2022/06/01 17:54:55 [INFO][FileStorage:api-certs] Lock for 'cert_acme_auth.example.org_https://acme-staging-v02.api.letsencrypt.org/directory' is stale; removing then retrying: api-certs/locks/cert_acme_auth.example.org_httpsacme-staging-v02.api.letsencrypt.orgdirectory.lock"
What is the cause? Is --dry-run option a possible cause?
What is the reference and complete documentation for using certbot and acme-dns (acme-dns-auth.py) on linux?
Thanks
Best regards
on first execution, this shows the required CNAME configuration
it would be nice to show the existing/expected configuration on renewal
if a DNS record gets wiped, it's kind of a pain to dig this information out. the easiest way to renew is to delete the acme-dns config data, which can have repercussions.
Since Python 2.7 End Of Life is coming soon, any foreseen issue with the Python code in acme-dns?
When i try to follow this article
https://www.digitalocean.com/community/tutorials/how-to-acquire-a-let-s-encrypt-certificate-using-dns-validation-with-acme-dns-certbot-on-ubuntu-18-04
with this command line
sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d *.your-domain -d your-domain
i get the error with this stack trace:
"type": "urn:ietf:params:acme:error:rateLimited",
"detail": "Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/failed-validation-limit/",
"status": 429
}
2023-11-03 18:35:50,508:DEBUG:certbot._internal.log:Exiting abnormally:
Traceback (most recent call last):
File "/usr/bin/certbot", line 33, in
sys.exit(load_entry_point('certbot==1.21.0', 'console_scripts', 'certbot')())
File "/usr/lib/python3/dist-packages/certbot/main.py", line 15, in main
return internal_main.main(cli_args)
File "/usr/lib/python3/dist-packages/certbot/_internal/main.py", line 1574, in main
return config.func(config, plugins)
File "/usr/lib/python3/dist-packages/certbot/_internal/main.py", line 1434, in certonly
lineage = _get_and_save_cert(le_client, config, domains, certname, lineage)
File "/usr/lib/python3/dist-packages/certbot/_internal/main.py", line 133, in _get_and_save_cert
lineage = le_client.obtain_and_enroll_certificate(domains, certname)
File "/usr/lib/python3/dist-packages/certbot/_internal/client.py", line 459, in obtain_and_enroll_certificate
cert, chain, key, _ = self.obtain_certificate(domains)
File "/usr/lib/python3/dist-packages/certbot/_internal/client.py", line 389, in obtain_certificate
orderr = self._get_order_and_authorizations(csr.data, self.config.allow_subset_of_names)
File "/usr/lib/python3/dist-packages/certbot/_internal/client.py", line 421, in _get_order_and_authorizations
orderr = self.acme.new_order(csr_pem)
File "/usr/lib/python3/dist-packages/acme/client.py", line 936, in new_order
return cast(ClientV2, self.client).new_order(csr_pem)
File "/usr/lib/python3/dist-packages/acme/client.py", line 702, in new_order
response = self._post(self.directory['newOrder'], order)
File "/usr/lib/python3/dist-packages/acme/client.py", line 101, in _post
return self.net.post(*args, **kwargs)
File "/usr/lib/python3/dist-packages/acme/client.py", line 1269, in post
return self._post_once(*args, **kwargs)
File "/usr/lib/python3/dist-packages/acme/client.py", line 1283, in _post_once
response = self._check_response(response, content_type=content_type)
File "/usr/lib/python3/dist-packages/acme/client.py", line 1128, in _check_response
raise messages.Error.from_json(jobj)
acme.messages.Error: urn:ietf:params:acme:error:rateLimited :: There were too many requests of a given type :: Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/failed-validation-limit/
2023-11-03 18:35:50,508:ERROR:certbot._internal.log:An unexpected error occurred:
2023-11-03 18:35:50,508:ERROR:certbot._internal.log:There were too many requests of a given type :: Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/failed-validation-limit/
What has been wrong ?
Hey,
thanks for this. It would be great if AcmeDnsClient and Storage would be extracted to their own files, so we can independently use them in hooks for other letsencrypt clients. (I for one don't use certbot, but would like to migrate my hook to your AcmeDnsClient implementation)
While requests is awesome, there's a major benefit in not having any dependencies outside of the standard library. The refactored code should support both, Python 2 and 3. The refactoring will flow down to the published library https://github.com/joohoi/pyacmedns as well.
I would be grateful if someone is up for the task, but will handle it myself in the future if nobody is interested.
the script fails when the acme-dns service is running against staging which is the default.
config.cfg: tls = "letsencryptstaging"
2021-11-04 23:17:22,598:ERROR:certbot.hooks:Error output from manual-auth-hook command acme-dns-auth.py:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py", line 485, in wrap_socket
cnx.do_handshake()
File "/usr/lib/python3/dist-packages/OpenSSL/SSL.py", line 1915, in do_handshake
self._raise_ssl_error(self._ssl, result)
File "/usr/lib/python3/dist-packages/OpenSSL/SSL.py", line 1647, in _raise_ssl_error
_raise_current_error()
File "/usr/lib/python3/dist-packages/OpenSSL/_util.py", line 54, in exception_from_error_queue
raise exception_type(errors)
OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]
One way to hack around this would be to skip TLS-cert verification. The calls to requests.post can be changed in three places. A better solution would be of course for acme-dns to get certs from standard letsencrypt during the initial setup
even when running against staging.
Need compose example to properly run docker joohoi/certbot,
Thank you
I have ran:
certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenge dns --debug-challenges -d domain.tld -d *.domain.tld
and for some reason, the *.domain.tld
is not added to SAN, hence the generated certificate is invalid for something.domain.tld
.
Am I doing something wrong or is this a bug?
when I try to get a wildcard cert for my mydomain.com and *.mydomain.com, the certbot comes back with asking me to add 2 CNAMES with the same name to different hosts. Ive searched and this doesn't seem to be a valid DNS option.
Output from acme-dns-auth.py:
Please add the following CNAME record to your main DNS zone:
_acme-challenge.mydomain.com CNAME 34b62d67-4a60-4cc5-a30e-ceddf6f61cf0.auth.mydomain.com.
Output from acme-dns-auth.py:
Please add the following CNAME record to your main DNS zone:
_acme-challenge.mydomain.com CNAME 7879f9a9-1fd4-44a0-bc76-048390ffec62.auth.mydomain.com.
This doesnt seem right, am I really supposed to put 2 CNAMES in like this?
-db
i'd be willing to write a PR for this.
This way the file can just be synced against the upstream source as needed, and customization would be via...
export ACMEDNSAUTH_ACMEDNS_URL=string
export ACMEDNSAUTH_STORAGE_PATH=string
export ACMEDNSAUTH_ALLOW_FROM=json encoded string
export ACMEDNSAUTH_STORAGE_PATH=String Bool (1/True) or (0/False)
When I run certbot with the suggested command line I receive the following error:
Hook command "/etc/letsencrypt/acme-dns-auth.py" returned error code 1
Error output from acme-dns-auth.py:
Traceback (most recent call last):
File "/etc/letsencrypt/acme-dns-auth.py", line 145, in <module>
account = client.register_account(ALLOW_FROM)
File "/etc/letsencrypt/acme-dns-auth.py", line 47, in register_account
res = requests.post(self.acmedns_url+"/register")
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 116, in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 514, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='localhost', port=81): Max retries exceeded with url: /register (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_record', 'wrong version number')],)",),))
These are the versions I have on python-requests. Do you have any suggestion?
# python -m requests.help
{
"chardet": {
"version": "3.0.4"
},
"cryptography": {
"version": "2.6.1"
},
"idna": {
"version": "2.6"
},
"implementation": {
"name": "CPython",
"version": "2.7.16"
},
"platform": {
"release": "4.19.0-6-amd64",
"system": "Linux"
},
"pyOpenSSL": {
"openssl_version": "1010102f",
"version": "19.0.0"
},
"requests": {
"version": "2.21.0"
},
"system_ssl": {
"version": "1010103f"
},
"urllib3": {
"version": "1.24.1"
},
"using_pyopenssl": true
}
Well, when i found the proper way to add the DNS as TXT not as CNAME it finally read it, but it says it's wrong :(
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Challenges loaded. Press continue to submit to CA. Pass "-v" for more info about
challenges.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Challenge failed for domain subdomain.here
dns-01 challenge for subdomain.here
Cleaning up challenges
Some challenges have failed.
IMPORTANT NOTES:
- The following errors were reported by the server:
Domain: subdomain.here
Type: unauthorized
Detail: Incorrect TXT record
"hash-hash-hash.auth.acme-dns.io." found at
_acme-challenge.subdomain.here
To fix these errors, please make sure that your domain name was
entered correctly and the DNS A/AAAA record(s) for that domain
contain(s) the right IP address.
(i masked the sensitive data)
using command:
sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d subdomain.here
Whats wrong now?
Hi,
certbot and acme-dns-certbot.py work well to get certificates for several domains, wildcard or not.
I have a problem to renew one wildcard TLS certificate (foo.org,*.foo.org)
IMPORTANT NOTES:
- The following errors were reported by the server:
Domain: foo.org
Type: dns
Detail: During secondary validation: DNS problem: NXDOMAIN looking
up TXT for _acme-challenge.foo.org - check that a DNS record
exists for this domain
Domain: foo.org
Type: dns
Detail: DNS problem: NXDOMAIN looking up TXT for
_acme-challenge.foo.org - check that a DNS record exists for
this domain
The only cause I can see is a limited propagation of the CNAME record for _acme-challenge.foo.org (with a value like 47fc-****.auth.acme-dns.io.):
Only cloudflare shows the expected resourced record while other domain names are propagated on all main nameservers (cloudflare opendns yandex quad9 google).
1/ Have you experienced such problem?
2/ Can you check if some settings could be done on auth.acme-dns.io. to improve propagation ?
3/ Is here an option to force using a nameserver which is known to deliver the expected CNAME record?
Side question: is running one's own instance of acme-dns (with the go program, etc. instead of using auth.acme-dns.io.) is known to improve this issue?
Thanks.
EDIT
I could have the DNS cache flushed for google, etc.
Now _acme-challenge.foo.org has correct CNAME record.
But stil the following errors
- The following errors were reported by the server:
Domain: foo.org
Type: dns
Detail: DNS problem: NXDOMAIN looking up TXT for
_acme-challenge.foo.org - check that a DNS record exists for
this domain
Domain: foo.org
Type: dns
Detail: DNS problem: NXDOMAIN looking up TXT for
_acme-challenge.foo.org - check that a DNS record exists for
this domain
then simply:
- The following errors were reported by the server:
Domain: foo.org
Type: dns
Detail: DNS problem: NXDOMAIN looking up TXT for
_acme-challenge.foo.org - check that a DNS record exists for
this domain
or again and mainly the 2 items error.
I don't understand why there is a "DNS problem: NXDOMAIN looking up TXT for _acme-challenge.foo.org" because there is a CNAME record for _acme-challenge.foo.org to ****.auth.acme-dns.io. where 2 TXT records are generated with a TTL of 1 s.
Is it an incorrect message from cerbot ?
Running pre-hook command: /etc/letsencrypt/renewal-hooks/pre/acme-dns-auth.py
Hook 'pre-hook' reported error code 1
Hook 'pre-hook' ran with error output:
Traceback (most recent call last):
File "/etc/letsencrypt/renewal-hooks/pre/acme-dns-auth.py", line 22, in
DOMAIN = os.environ["CERTBOT_DOMAIN"]
File "/usr/local/lib/python3.10/os.py", line 680, in getitem
raise KeyError(key) from None
KeyError: 'CERTBOT_DOMAIN
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.