certbot hooks for gandi.net v5 DNS API
Daniel Holth
Posted on November 13, 2022
I wanted to use gandi.net's API to update DNS for certbot/letsencrypt. I wasn't able to get TSIG (a standard DNS update method) to work. There is a plugin for gandi's API, but I wanted to make my own.
First, I went to https://account.gandi.net/en/users/USERNAME/security to generate an API key.
I saved the key as HTTP headers in /etc/letsencrypt/gandi-api-key.txt
and chmod 600 gandi-api-key.txt
to keep it secret:
Authorization: Apikey SECRET-API-KEY
Content-Type: application/json
and created two hooks:
/etc/letsencrypt/gandi_hook.py
:
#!/usr/bin/env python3
import os
import json
import subprocess
import time
domain = os.environ["CERTBOT_DOMAIN"] # "domain.example.com"
domain, zone, tld = domain.split(".")
zone = ".".join((zone, tld))
command = f"curl -H @gandi-api-key.txt https://api.gandi.net/v5/livedns/domains/{zone}/records/_acme-challenge.{domain}/TXT -X PUT -d".split()
payload = json.dumps(
{"rrset_ttl": 300, "rrset_values": [os.environ["CERTBOT_VALIDATION"]]}
)
subprocess.run(command + [payload], cwd="/etc/letsencrypt", check=True)
# https://www.gandi.net/en-US/domain/dns '250 ms'
time.sleep(1)
and the cleanup script, /etc/letsencrypt/gandi_cleanup.py
:
#!/usr/bin/env python3
import os
import json
import subprocess
import time
domain = os.environ["CERTBOT_DOMAIN"] # "fedora.monotreme.club"
domain, zone, tld = domain.split(".")
zone = ".".join((zone, tld))
command = f"curl -H @gandi-api-key.txt https://api.gandi.net/v5/livedns/domains/{zone}/records/_acme-challenge.{domain}/TXT -X DELETE".split()
subprocess.run(command, cwd="/etc/letsencrypt", check=True)
chmod +x gandi_hook.py gandi_cleanup.py
To run certbot, certbot certonly --manual --preferred-challenge=dns --manual-auth-hook /etc/letsencrypt/gandi_hook.py --manual-cleanup-hook /etc/letsencrypt/gandi_cleanup.py -d test.monotreme.club --test-cert
.
Modern Linux includes a systemd timer to automatically renew the certificates. Enable it with systemctl enable certbot-renew.timer
and systemctl start certbot-renew.timer
.
Unlike cron, the systemd timer has a random start time to avoid DDOS'ing letsencrypt's servers.
[Timer]
OnCalendar=*-*-* 00/12:00:00
RandomizedDelaySec=12hours
Persistent=true
Posted on November 13, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.