robin-thoni / certbot-pdns Goto Github PK
View Code? Open in Web Editor NEWAuthenticator plugin for certbot
Authenticator plugin for certbot
Using the latest certbot and certbot-pdns. Tried both Python2 and Python3 modules. Command used to renew the certificate:
certbot --agree-tos --text --renew-by-default --server https://acme-v02.api.letsencrypt.org/directory --authenticator certbot-pdns:auth -m [email protected] -d *.something.domain.eu renew
Traceback:
Cleaning up challenges
Encountered exception during recovery
Expecting value: line 1 column 1 (char 0)
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/certbot/error_handler.py", line 100, in _call_registered
self.funcs[-1]()
File "/usr/local/lib/python3.5/dist-packages/certbot/auth_handler.py", line 303, in _cleanup_challenges
self.auth.cleanup(achalls)
File "/usr/local/lib/python3.5/dist-packages/certbot_pdns/authenticator.py", line 72, in cleanup
self.backend.cleanup(achall)
File "/usr/local/lib/python3.5/dist-packages/certbot_pdns/PdnsApiAuthenticator.py", line 101, in cleanup
res = self.api.delete_record(zone["name"], "_acme-challenge." + domain + ".", "TXT", 1, None, False, False)
File "/usr/local/lib/python3.5/dist-packages/certbot_pdns/pdnsapi.py", line 77, in delete_record
"set-prt": set_ptr
File "/usr/local/lib/python3.5/dist-packages/certbot_pdns/pdnsapi.py", line 38, in _query
return None if request.status_code == 204 else request.json()
File "/usr/local/lib/python3.5/dist-packages/requests/models.py", line 892, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.5/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Seems that the requests Response object returned doesn't contain an .json() method which decodes properly.
I've experimented a bit and if you replace line 38 (in certbot_pdns/pdnsapi.py):
return None if request.status_code == 204 else request.json()
with:
return None if request.status_code == 204 or request.status_code == 400 else request.json()
you can workaround this issue and renew the wildcard certificate.
Hi
Using certbot-pdns 1.2.0 installed via pip3 on an ubuntu 22.04 system with certbot 2.1.0. Same results on an ubuntu 20.04 system with identical certbot and certbot-pdns versions.
Obtaining a certificate works, but an error is thrown at the end, which seems to result in the renewal file being empty.
Note that the syntax seems to have changed with for the --authenticator
parameter, as it only works if I specify auth
and not when I specify certbot-pdns:auth
. This is consistent with how the plugin is now listed in certbot plugins --text
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator auth, Installer None
Requesting a certificate for redacted.domain.eu
Performing the following challenges:
dns-01 challenge for redacted.domain.eu
Notifying zone domain.eu....
Waiting 5 seconds...
Waiting for verification...
Cleaning up challenges
usage:
certbot [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...
Certbot can obtain and install HTTPS/TLS/SSL certificates. By default,
it will attempt to use a webserver both for obtaining and installing the
certificate.
certbot: error: argument -a/--authenticator: expected one argument
Seems like a compatibility issue with the syntax of certbot 2.1.0?
First - I have to say this is a super incredible wonderful terrific bit of code! But I've got one little issue...
I have a cert for my mail server, which has three hostnames (smtp, imap, mail). So that means three DNS entries. As a result, when running a renewal for my mailserver - this certification plugin gets asked to prepare for three challenges. This it does...one at a time. Both watching the interactive client and viewing the logs show this. If I had a single DNS server, or control over the slaves, then this might work. But...I'm using BuddyNS.com. Replication is triggered by a change in the SOA record - which of course this program does fine. But...this authenticator triggers an update after each challenge is prepared. Which means add the authentication TXT record, increment SOA, add TXT record, increment SOA, add TXT record...you see where this is going.
So that's three updates. Which means the slave DNS servers need to update themselves three times in succession - which might get throttled by the remotes. Especially since I have no control over them. So what would be magical would be to have the SOA record get updated once - after all the TXT records have been done.
As a stopgap, setting "axfr-time" to 120 appears to be functional. Just not elegant.
Hi my api is working fine with pdns it returns all zones successfully just that when u try with certbot-pdns it gives me follwing error there is no http basic auth enabled to server and the api fund just fine on same server with http://127.0.0.1 if i use curl command .
Encountered exception during recovery:
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/certbot/error_handler.py", line 108, in _call_registered
self.funcs-1
File "/usr/lib/python2.7/site-packages/certbot/auth_handler.py", line 323, in _cleanup_challenges
self.auth.cleanup(achalls)
File "/usr/lib/python2.7/site-packages/certbot_pdns/authenticator.py", line 75, in cleanup
self.backend.cleanup(achall)
File "/usr/lib/python2.7/site-packages/certbot_pdns/PdnsApiAuthenticator.py", line 112, in cleanup
self.update_soa(zone["name"])
File "/usr/lib/python2.7/site-packages/certbot_pdns/PdnsApiAuthenticator.py", line 48, in update_soa
raise errors.PluginError("Bad return from PDNS API when getting zone %s: %s" % (zone_name, zone))
PluginError: Bad return from PDNS API when getting zone designyoga.eu.: {u'error': u'Internal Server Error'}
Request a certificate for example.com, *.example.com
I get a certificate with SAN example.com and *.example.com
I request a certificate for example.com and *.example.com (because I use the main domain and a handful of subdomians) and the plugin adds the challenges to PDNS, except the PDNS API only has options to replace and delete RRSets, not add, so the first challenge gets overwritten. The challenge fails and the certificate isn't issued.
It should be possible when adding a challenge record to first check if TXT records with the same name already exist in that zone and roll those records into the API request that submits the new challenge.
I've managed to work around this issue for the moment by requesting a certificate with only the domain and then running the request a second time with with the domain plus the wildcards, which apparently works because after the challenge is validated, it remains valid for some period of time afterwards so the second request (and all it's new challenges) get validated fine and the original challenges are still valid so the cert gets issued, but scheduling two separate runs of certbot to work around this is less than ideal.
Hey,
When I try to issue a wildcard certificate with certbot and this plugin, the plugin crash as follow:
$ sudo certbot --authenticator certbot-pdns:auth --cert-name phpbb-fr.com -d domain.com,*.domain.com --server https://acme-v02.api.letsencrypt.org/directory
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator certbot-pdns:auth, Installer apache
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for domain.com
dns-01 challenge for domain.com
Cleaning up challenges
Encountered exception during recovery
Bad return from PDNS API when deleting record: {u'error': u'Internal Server Error'}
Traceback (most recent call last):
File "/opt/eff.org/certbot/venv/local/lib/python2.7/site-packages/certbot/error_handler.py", line 103, in _call_registered
self.funcs[-1]()
File "/opt/eff.org/certbot/venv/local/lib/python2.7/site-packages/certbot/auth_handler.py", line 308, in _cleanup_challenges
self.auth.cleanup(achalls)
File "/opt/eff.org/certbot/venv/local/lib/python2.7/site-packages/certbot_pdns/authenticator.py", line 72, in cleanup
self.backend.cleanup(achall)
File "/opt/eff.org/certbot/venv/local/lib/python2.7/site-packages/certbot_pdns/PdnsApiAuthenticator.py", line 103, in cleanup
raise errors.PluginError("Bad return from PDNS API when deleting record: %s" % res)
PluginError: Bad return from PDNS API when deleting record: {u'error': u'Internal Server Error'}
Bad return from PDNS API when adding record: {u'error': u'Internal Server Error'}
certbot 0.23.0
If the Powerdns returns a 403 Access Denied (e.g. if the API key is "User", not "Operator") it will just return an error:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/certbot/error_handler.py", line 124, in _call_registered
self.funcs[-1]()
File "/usr/lib/python3/dist-packages/certbot/auth_handler.py", line 243, in _cleanup_challenges
self.auth.cleanup(achalls)
File "/usr/local/lib/python3.8/dist-packages/certbot_pdns/authenticator.py", line 75, in cleanup
self.backend.cleanup(achall)
File "/usr/local/lib/python3.8/dist-packages/certbot_pdns/PdnsApiAuthenticator.py", line 113, in cleanup
self.flush_zone(zone["name"])
File "/usr/local/lib/python3.8/dist-packages/certbot_pdns/PdnsApiAuthenticator.py", line 36, in flush_zone
res = self.api.flush_zone_cache(zone_name)
File "/usr/local/lib/python3.8/dist-packages/certbot_pdns/pdnsapi.py", line 110, in flush_zone_cache
return self._query("/servers/localhost/cache/flush?domain=%s" % zone_name, "PUT")
File "/usr/local/lib/python3.8/dist-packages/certbot_pdns/pdnsapi.py", line 61, in _query
return None if request.status_code == 204 else request.json()
File "/usr/lib/python3/dist-packages/requests/models.py", line 897, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib/python3.8/json/__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.8/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
After changing the role to "Operator" it worked.
Also maybe adding a hint to the README that the Operator Role is required would help others, too :)
Using certbot-pdns 1.1.0 installed via pip3. Can't get an wildcard certificate:
# certbot --agree-tos --text --renew-by-default --server https://acme-v02.api.letsencrypt.org/directory --authenticator certbot-pdns:auth -m [email protected] -d *.sub.domain.eu
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator certbot-pdns:auth, Installer apache
/usr/local/lib/python3.5/dist-packages/josepy/jwa.py:107: CryptographyDeprecationWarning: signer and verifier have been deprecated. Please use sign and verify instead.
signer = key.signer(self.padding, self.hash)
Performing the following challenges:
dns-01 challenge for sub.domain.eu
Cleaning up challenges
An unexpected error occurred:
TypeError: Can't convert 'bytes' object to str implicitly
Please see the logfiles in /var/log/letsencrypt for more details.
PdnsApiAuthenticator update_soa increments the serial in the SOA content even if the value is 0. 0 is a special value where the serial is bases on the latest change_date from the records for the domain. If split[2] == 0 this method shouldn't do anything to the SOA record.
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.