DEV Community

Daniel Holth
Daniel Holth

Posted on

certbot hooks for gandi.net v5 DNS API

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Top comments (0)