DEV Community

Daniel Holth
Daniel Holth

Posted on

2

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

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs