Overview
Securing my website with HTTPS is crucial, and Certbot makes it straightforward for many domains. However, when it comes to wildcard domains (like *.domain.com
), there’s a bit more work involved—particularly if I want to automate renewals.
This post explains how I set up a manual DNS hook for Certbot that integrates with my domain name provider’s API (in this example, GoDaddy), so I no longer have to manually add DNS TXT records every time I need to renew my wildcard certificate.
Why Do We Need This?
Certbot automates the HTTPS setup for many domain configurations. However, wildcard certificates require DNS-based validation—meaning I must add a TXT record to prove domain ownership. Certbot does not automatically update DNS for every provider. Thus, without automation, I’d be forced to:
- Run Certbot.
- Grab the
_acme-challenge
TXT record details. - Log in to my DNS panel and manually create the TXT record.
- Wait for DNS to propagate.
- Resume the Certbot process.
- Finally, clean up the TXT record.
Doing this every few months quickly becomes tedious, especially if I manage multiple wildcard domains. Luckily, Certbot’s --manual-auth-hook
parameter can help me automate these steps.
The Goal
- Automate the DNS validation process for wildcard certificate renewals using Certbot hooks.
- Utilize my DNS provider’s API (in my case, GoDaddy) to create and remove the required
_acme-challenge
TXT record automatically. - Integrate this process into a
crontab
so renewals happen on schedule without manual intervention.
Current (Manual) Process
Here’s what I was doing without automation:
- Run Certbot:
certbot certonly --manual ...
- Certbot tells me which TXT record to create, e.g.
"_acme-challenge.domain.com"
. - I log into GoDaddy (or another provider) and create the TXT record with the provided value.
- I wait for DNS propagation (a few minutes).
- Certbot verifies and finalizes the certificate issuance.
- I remove or empty out the TXT record.
This process, while doable, is time-consuming and must be repeated every 60–90 days (depending on my renewal schedule).
Godaddy API endpoint
Automating the Workflow
To automate the renewal of my wildcard domain certificate, I leverage my domain provider’s API to manage DNS TXT records programmatically. I use GoDaddy.
Prerequisites
- API Access: Ensure GoDaddy supports DNS management via API.
- API Credentials: Obtain my API key and secret from the GoDaddy Developer Portal.
GoDaddy API Endpoint
I use the following endpoint to manage TXT records:
https://api.godaddy.com/v1/domains/${GODADDY_DOMAIN}/records/TXT/${RECORD_NAME}
Parameters:
${GODADDY_DOMAIN}
: My root domain (e.g.,example.com
).${RECORD_NAME}
: Typically_acme-challenge
for Certbot.
Using the API
Testing Create/Update TXT Record Endpoints
curl -s -X PUT \
-H "Authorization: sso-key ${GODADDY_KEY}:${GODADDY_SECRET}" \
-H "Content-Type: application/json" \
-d "[{\"data\": \"${CERTBOT_VALIDATION}\", \"ttl\": 600}]" \
"https://api.godaddy.com/v1/domains/${GODADDY_DOMAIN}/records/TXT/${RECORD_NAME}"
- Headers:
Authorization
:sso-key MY_API_KEY:MY_API_SECRET
Content-Type
:application/json
- Data:
"data"
: Validation string from Certbot."ttl"
: Time-to-live (e.g.,600
seconds).
Remove TXT Record
curl -s -X PUT \
-H "Authorization: sso-key ${GODADDY_KEY}:${GODADDY_SECRET}" \
-H "Content-Type: application/json" \
-d "[]" \
"https://api.godaddy.com/v1/domains/${GODADDY_DOMAIN}/records/TXT/${RECORD_NAME}"
Integration with Certbot Hooks
- Auth Hook (
godaddy-auth.sh
): Adds the TXT record before validation. - Cleanup Hook (
godaddy-cleanup.sh
): Removes the TXT record after validation.
I ensure my scripts use the above curl
commands with the appropriate environment variables (GODADDY_KEY
, GODADDY_SECRET
, GODADDY_DOMAIN
, RECORD_NAME
, CERTBOT_VALIDATION
).
The Automated Solution
Certbot offers hooks that run custom scripts to automate these exact steps:
1. Command with Hooks
certbot certonly \
--manual \
--preferred-challenges dns \
--manual-auth-hook /etc/letsencrypt/scripts/godaddy-auth.sh \
--manual-cleanup-hook /etc/letsencrypt/scripts/godaddy-cleanup.sh \
--agree-tos \
-d '*.wild.card.domain' \
--preferred-chain "ISRG Root X1"
--manual-auth-hook
: Runs a script before Certbot attempts to validate the domain (to set up the TXT record).--manual-cleanup-hook
: Runs a script after validation completes (to remove or clear the TXT record).
2. GoDaddy Auth Script
The following script (godaddy-auth.sh
) is triggered by the --manual-auth-hook
. It reads environment variables set by Certbot—like CERTBOT_DOMAIN
and CERTBOT_VALIDATION
—and then updates the DNS record via the GoDaddy API.
#!/usr/bin/env bash
# /etc/letsencrypt/scripts/godaddy-auth.sh
# Certbot environment variables:
# - CERTBOT_DOMAIN (the domain being authenticated)
# - CERTBOT_VALIDATION (the validation string for TXT record)
GODADDY_KEY="domain_name_provider_key"
GODADDY_SECRET="domain_name_provider_secret"
GODADDY_DOMAIN="your_root_domain" # e.g., "example.com"
TTL=600
# Subdomain that needs to be updated
RECORD_NAME="_acme-challenge"
# Build request payload
DATA="[{\"data\": \"${CERTBOT_VALIDATION}\", \"ttl\": ${TTL}}]"
curl -s -X PUT \
-H "Authorization: sso-key ${GODADDY_KEY}:${GODADDY_SECRET}" \
-H "Content-Type: application/json" \
-d "${DATA}" \
"https://api.godaddy.com/v1/domains/${GODADDY_DOMAIN}/records/TXT/${RECORD_NAME}"
echo "GoDaddy AUTH-HOOK: Created TXT record for ${CERTBOT_DOMAIN}."
# Sleep to allow DNS propagation
sleep 60
Note: If I have a subdomain or different domain structure, I adjust
RECORD_NAME
accordingly.
3. GoDaddy Cleanup Script
This script (godaddy-cleanup.sh
) runs after verification succeeds. It removes (or resets) the _acme-challenge
TXT record, keeping my DNS tidy.
#!/usr/bin/env bash
# /etc/letsencrypt/scripts/godaddy-cleanup.sh
# Certbot environment variables:
# - CERTBOT_DOMAIN (the domain being authenticated)
GODADDY_KEY="domain_name_provider_key"
GODADDY_SECRET="domain_name_provider_secret"
GODADDY_DOMAIN="your_root_domain"
RECORD_NAME="_acme-challenge"
# Empty the TXT record (or remove it altogether)
DATA="[]"
curl -s -X PUT \
-H "Authorization: sso-key ${GODADDY_KEY}:${GODADDY_SECRET}" \
-H "Content-Type: application/json" \
-d "${DATA}" \
"https://api.godaddy.com/v1/domains/${GODADDY_DOMAIN}/records/TXT/${RECORD_NAME}"
echo "GoDaddy CLEANUP-HOOK: Removed TXT record for ${CERTBOT_DOMAIN}."
Scheduling With Crontab
After confirming the manual hooks work, I automate the renewal checks using crontab:
10 0 * * * /usr/bin/certbot renew --preferred-chain "ISRG Root X1" >> /folder/to/save/cronlog.log 2>&1
10 0 * * * /etc/letsencrypt/scripts/certbot-renew-dns.sh >> /folder/to/save/cronlog-manualhook.log 2>&1
Pro Tips
- DNS Propagation: Sometimes DNS changes can take longer than expected, especially if my DNS TTL is high. I might adjust my
sleep
time or TTL in the script if validations fail. - Permissions: I ensure my hook scripts are executable by using
chmod +x /path/to/script.sh
. - Security: I keep my API keys secret. Storing them in environment variables or a secure file is best.
- Testing: I run
certbot renew --dry-run
to verify that my hooks and scripts work before scheduling them in production.
Conclusion
Using Certbot’s DNS challenge manual hook scripts, I can seamlessly automate the issuance and renewal of wildcard certificates. Gone are the days of logging into my DNS provider’s dashboard every few months. With minimal scripting and a few Cron entries, my wildcard certificates can renew without me lifting a finger.
Leave a comment below to share your experience or ask questions!
Merry Christmas & A Happy New Year, See ya soon~