diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..66bed3a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +vol/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0551afd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM certbot/certbot:v2.10.0 + +# Add register.sh and acme-dns-auth.py to bin (mostly to make register.sh easier to run) +ENV PATH="${PATH}:/opt/certbot-acme-dns/bin" + +# Install supercronic so we can auto renew the certs +RUN apk add --no-cache supercronic shadow + +# Add the certbot hook/register script +ADD src /opt/certbot-acme-dns/bin/ +# and crontab into container +ADD crontab /opt/certbot-acme-dns/ + +VOLUME ["/etc/letsencrypt", "/var/lib/letsencrypt"] +ENTRYPOINT ["/usr/bin/supercronic", "/opt/certbot-acme-dns/crontab"] \ No newline at end of file diff --git a/README.md b/README.md index 731f60f..aae8ecd 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,23 @@ An example [Certbot](https://certbot.eff.org) client hook for [acme-dns](https:/ This authentication hook automatically registers acme-dns accounts and prompts the user to manually add the CNAME records to their main DNS zone on initial run. Subsequent automatic renewals by Certbot cron job / systemd timer run in the background non-interactively. -Requires Certbot >= 0.10, Python requests library. +Requires either + * Docker + * Certbot >= 0.10, Python requests library. ## Installation +### Docker +1) Clone repo + +2) Modify the ACMEDNS_URL environment variable (or any other config) + +3) Run docker compose to start the container (with the current working directory in the root of the project) +``` +docker compose up +``` + +### Manual 1) Install Certbot using instructions at [https://certbot.eff.org](https://certbot.eff.org) 2) Make sure you have the [python-requests](http://docs.python-requests.org/en/master/) library installed. @@ -19,30 +32,40 @@ $ chmod 0700 /etc/letsencrypt/acme-dns-auth.py ``` 4) Configure the variables in the beginning of the hook script file to point to your acme-dns instance. The only value that you must change is the `ACMEDNS_URL`, other values are optional. + + a) Alternitively you can use environment variables to configure the hook. ``` ### EDIT THESE: Configuration values ### # URL to acme-dns instance -ACMEDNS_URL = "https://auth.acme-dns.io" +ACMEDNS_URL = os.environ.get("ACMEDNS_URL", "https://auth.acme-dns.io") # Path for acme-dns credential storage -STORAGE_PATH = "/etc/letsencrypt/acmedns.json" +STORAGE_PATH = os.environ.get("STORAGE_PATH", "/etc/letsencrypt/acmedns.json") # Whitelist for address ranges to allow the updates from # Example: ALLOW_FROM = ["192.168.10.0/24", "::1/128"] -ALLOW_FROM = [] +ALLOW_FROM = os.environ.get("ALLOW_FROM", []) # Force re-registration. Overwrites the already existing acme-dns accounts. -FORCE_REGISTER = False +FORCE_REGISTER = os.environ.get("FORCE_REGISTER", False) ``` ## Usage +### Docker +On initial run: +``` +docker compose exec certbot-acme-dns register.sh -d example.org -d \*.example.org +``` + +### Manual On initial run: ``` -$ certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py \ - --preferred-challenges dns --debug-challenges \ +certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py \ + --preferred-challenges dns --debug-challenges \ -d example.org -d \*.example.org ``` Note that the `--debug-challenges` is mandatory here to pause the Certbot execution before asking Let's Encrypt to validate the records and let you to manually add the CNAME records to your main DNS zone. +### Common steps After adding the prompted CNAME records to your zone(s), wait for a bit for the changes to propagate over the main DNS zone name servers. This takes anywhere from few seconds up to a few minutes, depending on the DNS service provider software and configuration. Hit enter to continue as prompted to ask Let's Encrypt to validate the records. -After the initial run, Certbot is able to automatically renew your certificates using the stored per-domain acme-dns credentials. +After the initial run, Certbot is able to automatically renew your certificates using the stored per-domain acme-dns credentials. This can be done manualy with the `cerbot renew` command or letting certbot's auto renewal run. diff --git a/crontab b/crontab new file mode 100644 index 0000000..74a2305 --- /dev/null +++ b/crontab @@ -0,0 +1 @@ +0 */12 * * * certbot renew \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..0f0b20a --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,10 @@ +services: + certbot-acme-dns: + build: + context: . + dockerfile: Dockerfile + volumes: + - ./vol/etc:/etc/letsencrypt + - ./vol/varlib:/var/lib/letsencrypt + environment: + ACMEDNS_URL: https://auth.acme-dns.io \ No newline at end of file diff --git a/acme-dns-auth.py b/src/acme-dns-auth.py old mode 100755 new mode 100644 similarity index 95% rename from acme-dns-auth.py rename to src/acme-dns-auth.py index 2913db0..b942271 --- a/acme-dns-auth.py +++ b/src/acme-dns-auth.py @@ -7,14 +7,14 @@ ### EDIT THESE: Configuration values ### # URL to acme-dns instance -ACMEDNS_URL = "https://auth.acme-dns.io" +ACMEDNS_URL = os.environ.get("ACMEDNS_URL", "https://auth.acme-dns.io") # Path for acme-dns credential storage -STORAGE_PATH = "/etc/letsencrypt/acmedns.json" +STORAGE_PATH = os.environ.get("STORAGE_PATH", "/etc/letsencrypt/acmedns.json") # Whitelist for address ranges to allow the updates from # Example: ALLOW_FROM = ["192.168.10.0/24", "::1/128"] -ALLOW_FROM = [] +ALLOW_FROM = os.environ.get("ALLOW_FROM", []) # Force re-registration. Overwrites the already existing acme-dns accounts. -FORCE_REGISTER = False +FORCE_REGISTER = os.environ.get("FORCE_REGISTER", False) ### DO NOT EDIT BELOW THIS POINT ### ### HERE BE DRAGONS ### diff --git a/src/register.sh b/src/register.sh new file mode 100644 index 0000000..3cab5a0 --- /dev/null +++ b/src/register.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh + +# Helper script to make initial registration of domains easier +certbot certonly --manual \ + --manual-auth-hook /opt/certbot-acme-dns/bin/acme-dns-auth.py \ + --preferred-challenges dns \ + --debug-challenges \ + "$@" + + +##### Explanation of flags #### +# --manual -- run certbot in manual mode +# --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py -- Tell certbot about the acme-dns auth hook +# --preferred-challenges dns -- dns challenge is the only one that will work with acme-dns +# --debug-challenges -- We need to pause execution before Let's Encrypt validates the records so you can manually add the CNAME records +# "$@" -- Pass any args that are passed to us. This will normally be the domains you want to set up ie -d example.org -d *.example.org