Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/catalyst/acmeproxy
PowerDNS backend for serving ACME dns-01 challenge responses
https://github.com/catalyst/acmeproxy
acme-client dns
Last synced: 3 days ago
JSON representation
PowerDNS backend for serving ACME dns-01 challenge responses
- Host: GitHub
- URL: https://github.com/catalyst/acmeproxy
- Owner: catalyst
- License: gpl-3.0
- Created: 2016-10-05T02:02:21.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2022-11-07T01:34:08.000Z (about 2 years ago)
- Last Synced: 2023-04-18T23:29:49.396Z (over 1 year ago)
- Topics: acme-client, dns
- Language: Python
- Size: 102 KB
- Stars: 14
- Watchers: 17
- Forks: 4
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# acmeproxy
This PowerDNS backend only serves [ACME dns-01 challenge responses](https://letsencrypt.org/docs/acme-protocol-updates/), and exposes an HTTPS API to permit those challenge responses to be published by automated certificate renewal tools.
## Dev environment
You can start a dev environemnt with
docker-compose up
The app will now be available at http://localhost:8080
## Use with dehydrated or certbot
Example plugins for [dehydrated](http://dehydrated.de/) and [certbot](https://certbot.eff.org/) are supplied in the `plugins` directory. Edit these plugin to specify the location of your acmeproxy installation and authorisation key registered with the API, then call them as a dns-01 hook.
For instance, with dehydrated:
dehydrated -c -t dns-01 -k ./acmeproxy-dehydrated.sh -d secure.example.com
## Deployment
Install the app in a virtual environemnt with
pip install .
In a new directory make a copy of `example_settings.py` called `acmeproxy_settings.py`. Then fill in all the values.
With your working directory set as the newly created directory you can now run the app as a wsgi app. With the environment variable `DJANGO_SETTINGS_MODULE` set to `acmeproxy_settings`. and the wsgi app at `acmeproxy.acmeproxy.wsgi:application`.
### Example Apache configuration when certbot is used for the API certificate
ServerName acme-proxy-ns1.example.com
DocumentRoot /var/www/htmlErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combinedProxyPass / http://127.0.0.1:8000/
ProxyPassReverse / http://127.0.0.1:8000/
Require ip 127.0.0.1
SSLCertificateFile /etc/letsencrypt/live/acme-proxy-ns1.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/acme-proxy-ns1.example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
### Example PowerDNS configuration
In the directory with your settings file make a new file called `backend`.
In it put
#!/bin/sh
export DJANGO_SETTINGS_MODULE=acmeproxy_settings
/path/to/venv/django-admin pipeapi#### /etc/powerdns/pdns.conf
config-dir=/etc/powerdns
include-dir=/etc/powerdns/pdns.d
setgid=pdns
setuid=pdns#### /etc/powerdns/pdns.d/acmeproxy.conf
launch=pipe
pipe-command=/opt/acmeproxy/backend
pipe-timeout=4000## API documentation
### HTTPS API usage
All API endpoints will return JSON containing a `result` key describing the result of the operation. If an operation fails this will be `false`, and the HTTP response code will indicate the nature of the failure.
#### Authorisations
Before delegating any names an **authorisation** should be requested using the `create_authorisation` endpoint.
$ curl --data "name=secure.example.com" https://acme-proxy-ns1.example.com/create_authorisation
{"result": {"secret": "52f562aedc99383c6af848bc7016380a", "authorisation": "secure.example.com", "suffix_match": false}}If authentication is enabled in your installation (with the `ACMEPROXY_AUTHORISATION_CREATION_SECRETS` setting configured to something other than `None`) you will also need to supply a `secret` field corresponding to the account being used.
The randomly generated `secret` returned by this call is then used to identify this authorisation in further calls to the API.
To re-generate the authentication secret for a given authorisation the `expire_authorisation` endpoint may be used.
$ curl --data "name=secure.example.com&secret=52f562aedc99383c6af848bc7016380a" https://acme-proxy-ns1.example.com/expire_authorisation
{"result": {"secret": "e04541b1d63bc68d296137bc2ee86923", "authorisation": "secure.example.com", "suffix_match": false}}#### Challenge responses
During an ACME dns-01 challenge it is necessary to publish a **challenge response** string supplied by the ACME client. The `publish_response` endpoint allows a response to be published for a name that has been registered with an authorisation.
$ curl --data "name=secure.example.com&response=evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA&secret=52f562aedc99383c6af848bc7016380a" https://acme-proxy-ns1.example.com/publish_response
{"result": {"authorisation": "secure.example.com", "suffix_match": false, "published": true}}Optionally a client may request that all challenge responses for a name be expired once they are no longer required, however the backend will expire them regardless after five minutes.
$ curl --data "name=secure.example.com&secret=52f562aedc99383c6af848bc7016380a" https://acme-proxy-ns1.example.com/expire_response
{"result": {"authorisation": "secure.example.com", "suffix_match": false, "expired": true}}### DNS usage
Suppose you have a domain `example.com` and wish to issue certificates for `secure.example.com` without having an HTTP server running and without giving full control of the `example.com` zone to an ACME client.
By registering an authorisation through the HTTPS API then adding a delegation for the expected challenge, `_acme-challenge.secure.example.com` it is possible to response to those challenges with data supplied using an HTTPS POST to the server.
_acme-challenge.secure.example.com. IN NS acme-proxy-ns1.example.com
It should also be possible to load this backend along side your existing backends, though that functionality is not yet fully tested.
Once the delegation is made a response can be published using the `publish_response` endpoint of the HTTPS API during ACME certification issuance.
### Command line tools
There are several Django management commands available in the `proxy` app.
#### listauthorisations
Lists all authorisations present in the database.
$ python manage.py listauthorisations
name created_by_ip created_at account
--------------------- --------------- -------------------------------- ---------
secure.example.com 192.0.2.1 2016-10-10 03:11:18.525111+00:00 operations
test.example.org 192.0.2.1 2016-10-10 03:50:35.827334+00:00 test
host1.example.com 192.0.2.1 2016-10-10 03:51:38.185688+00:00 operations#### deleteauthorisation
Permanently remove an authorisation from the database.
$ python manage.py deleteauthorisation test.example.org
Successfully deleted authorisation "test.example.org"#### listresponses
List the audit log of challenge responses that have been published, optionally between any two dates.
$ python manage.py listresponses --start=2016-09-01 --end=2016-12-30
name expired_at created_by_ip created_at
------------------- -------------------------------- --------------- --------------------------------
secure.example.com 2016-10-10 03:12:05.984890+00:00 192.0.2.1 2016-10-09 21:47:24.236299+00:00
test.example.org 2016-10-10 03:12:05.984890+00:00 192.0.2.1 2016-10-10 03:12:04.833764+00:00A response will have an `expired_at` value if the ACME client explicitly marked all challenges for a name as complete.