We are fond of the Let’s Encrypt DNS challenge process instead of alternative processes. The Let’s Encrypt DNS challenge using the certbot allows businesses to scale their replacements of certs that are not exposed directly to the internet. The certbot tool has switches that allow custom scripts to be run, which allows for a lot of flexibility.

Installation of certbot

Review the website for https://certbot.eff.org/, and there are sections per OS on how to use “snap” to install this tool. Example with CentOS7. https://certbot.eff.org/instructions?ws=other&os=centosrhel7

sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

We have used certbot with manual steps every 90 days with our development DNS domains but wanted to automate these steps. Unfortunately, we noticed a challenge with using Google Domains not having an API available to update DNS records. After research, we did find that Google Cloud does have the APIs available.

We had several options:

a) Move the DNS domains from Google Domains to Google Cloud,

b) redirect CNAME records from Google Domains to Google Cloud,

c) move to another Domain Register that has APIs available,

d) redirect CNAME records from Google Domain to another Domain Register.

Since we had another Domain register offering APIs, we decided to choose option d. This entry will review our steps and how we leverage certbot and the two (2) DNS Domains Registers.

Step 1: Google Domains – Create _acme-challenge CNAME records.

Step 2: 2nd Domain Register – GoDaddy – Create _acme-challenge TXT records.

Step 3: Enable the API Key on the 2nd Domain Register and the API Password Code

https://developer.godaddy.com/keys?hbi_code=1

Step 4: Validate via CURL the ability to update the TXT records through the 2nd Domain Register’s API.

curl -s -X PUT \
"https://api.godaddy.com/v1/domains/anapartner.in/records/TXT/_acme-challenge.aks.iam.anapartner.dev" \
-H  "accept: application/json" -H  "Content-Type: application/json" \
-H  "Authorization: sso-key ${GODADDY_API_KEY}:${GODADDY_API_SECRET}" \
-d "[{ \"data\": \"TESTING THIS STRING FIELD", \"name\": \"_acme-challenge.aks.iam.anapartner.dev", \"ttl\": 600 }]"

Finally, we will create a script that will be executed by crontab every 85 days. Please note that the scripts to be called by certbot are created as HERE DOCS to allow portability within a single script.

#!/bin/bash
###############################################################################
#
#  Update Google DNS via round-about way through 2nd DNS Register DNS API (anapartner.in)
#
#
#  Pre-work:
#     1. Use existing or purchase a domain from 2nd DNS register
#
#     2. Create Google Domain CNAME records for each of the wildcard domain to a remote DNS TXT Record
#     _acme-challenge.gke.iam.anapartner.org CNAME _acme-challenge.gke.iam.anapartner.org.anapartner.in
#     _acme-challenge.aks.iam.anapartner.org CNAME _acme-challenge.aks.iam.anapartner.org.anapartner.in
#     _acme-challenge.eks.iam.anapartner.org CNAME _acme-challenge.eks.iam.anapartner.org.anapartner.in
#
#     3. Create 2nd DNS Register Domain TXT records for each of the object to be updated
#     _acme-challenge.gke.iam.anapartner.org.baugher.net
#     _acme-challenge.aks.iam.anapartner.org.baugher.net
#     _acme-challenge.eks.iam.anapartner.org.baugher.net
#
#     4. Enable the 2nd DNS Register API for Production Access (Developer) & store the KEY & SECRET for use
#        https://developer.godaddy.com/keys?hbi_code=1
#
#     5. Install certbot     dnf -y install certbot
#         Note:  certbot will use two (2) variables of:  CERTBOT_DOMAIN (after the -d switch)
#         and  CERTBOT_VALIDATION (the text string to be used for TXT records)
#
#  ANA 07/2022
#
###############################################################################

GODADDY_API_KEY="XXXXXXXXXXXXXy"
GODADDY_API_SECRET="XXXXXXXXXXXXXXX"
DOMAIN="anapartner.in"


echo ""
echo "Create wildcard domain list"
echo "This may be any TXT record for a remote domain FQDN that is mapped in the anapartner.in"
echo "#####################################################################"

#cat << 'EOF' > wildcard-domains.txt
#*.gke.iam.anapartner.in
#*.aks.iam.anapartner.in
#*.eks.iam.anapartner.in
#EOF

cat << 'EOF' > wildcard-domains.txt
*.gke.iam.anapartner.dev
*.aks.iam.anapartner.dev
*.eks.iam.anapartner.dev
EOF

WILDCARD_DOMAIN=anapartner.dev

echo ""
echo "Create godaddy.sh script to update TXT records"
echo "#####################################################################"
cat <<  EOF > godaddy.sh
#!/bin/bash
if [[ "\$CERTBOT_DOMAIN" =~ .*anapartner.in* ]];then
    echo "If domain contains anapartner.in, we need to remove the last part to avoid duplicates during registration"
    CERTBOT_DOMAIN="\${CERTBOT_DOMAIN/".anapartner.in"//}"
    echo \$CERTBOT_DOMAIN
fi

DNS_REC_NAME="_acme-challenge.\$CERTBOT_DOMAIN"


curl -s -X PUT \
"https://api.godaddy.com/v1/domains/${DOMAIN}/records/TXT/\${DNS_REC_NAME}" \
-H  "accept: application/json" -H  "Content-Type: application/json" \
-H  "Authorization: sso-key ${GODADDY_API_KEY}:${GODADDY_API_SECRET}" \
-d "[{ \"data\": \"\$CERTBOT_VALIDATION\", \"name\": \"\${DNS_REC_NAME}\", \"ttl\": 600 }]"

sleep 30
EOF

chmod 555 godaddy.sh

echo ""
echo "Create godaddy-clean.sh script to wipe TXT records - as needed"
echo "#####################################################################"
cat << EOF > godaddy-clean.sh
#!/bin/bash

if [[ "\$CERTBOT_DOMAIN" =~ .*anapartner.in* ]];then
    echo "If domain contains anapartner.in, we need to remove the last part to avoid duplicates during registration"
    CERTBOT_DOMAIN="\${CERTBOT_DOMAIN/".anapartner.in"//}"
    echo \$CERTBOT_DOMAIN
fi

DNS_REC_NAME="_acme-challenge.\$CERTBOT_DOMAIN"

curl -s -X PUT \
"https://api.godaddy.com/v1/domains/${DOMAIN}/records/TXT/\${DNS_REC_NAME}" \
-H  "accept: application/json" -H  "Content-Type: application/json" \
-H  "Authorization: sso-key ${GODADDY_API_KEY}:${GODADDY_API_SECRET}" \
-d "[{ \"data\": \"clean\", \"name\": \"\${DNS_REC_NAME}\", \"ttl\": 600 }]"

EOF
chmod 555 godaddy-clean.sh


echo ""
echo "Start Loop to use Let's Encrypt's certbot tool"
echo "#####################################################################"
while read -r domain;
do

echo "#####################################################################"
echo "$domain"
echo ""
certbot -d $domain --agree-tos --register-unsafely-without-email --manual \
--preferred-challenges dns --manual-auth-hook ./godaddy.sh \
--manual-cleanup-hook ./godaddy-clean.sh --manual-public-ip-logging-ok \
--force-renewal certonly

echo ""

done < wildcard-domains.txt
# Add logic to handle the certs/keys when they are issued.

echo ""
echo "#####################################################################"
ls -lart /etc/letsencrypt/archive/*

#rm -rf godaddy.sh godaddy-clean.sh &>/dev/null
echo ""

echo ""
echo "After validation, the TXT records will be marked with the 'clean' string "
echo "#####################################################################"
echo "nslookup  -type=txt _acme-challenge.eks.iam.$WILDCARD_DOMAIN 8.8.8.8 | head -6"
echo "nslookup  -type=txt _acme-challenge.aks.iam.$WILDCARD_DOMAIN 8.8.8.8 | head -6"
echo "nslookup  -type=txt _acme-challenge.gke.iam.$WILDCARD_DOMAIN 8.8.8.8 | head -6"

View of the script being executed

Files generated by Let’s Encrypt certbot [certN.pem, privkeyN.pem, chainN.pem, and fullchainN.pem]

Leave a Reply

%d bloggers like this: