-
-
Notifications
You must be signed in to change notification settings - Fork 716
example dns 01 nsupdate script
This hook script uses the nsupdate utility from the bind package to solve dns-01 challenges.
#!/usr/bin/env bash
#
# Example how to deploy a DNS challenge using nsupdate
#
set -e
set -u
set -o pipefail
NSUPDATE="nsupdate -k /path/to/Kdnsupdatekey.private"
DNSSERVER="127.0.0.1"
TTL=300
case "$1" in
"deploy_challenge")
printf "server %s\nupdate add _acme-challenge.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${2}" "${TTL}" "${4}" | $NSUPDATE
;;
"clean_challenge")
printf "server %s\nupdate delete _acme-challenge.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${2}" "${TTL}" "${4}" | $NSUPDATE
;;
"deploy_cert")
# optional:
# /path/to/deploy_cert.sh "$@"
;;
"unchanged_cert")
# do nothing for now
;;
"startup_hook")
# do nothing for now
;;
"exit_hook")
# do nothing for now
;;
esac
exit 0
The file /path/to/Kdnsupdatekey.private
looks like this:
key "<keyname>" {
algorithm hmac-sha512;
secret "<key>";
};
To avoid making your entire production DNS subject to dynamic DNS updates, then for each certificate domain you want:
- In your main DNS infrastructure create a delegation:
_acme-challenge.<domain>. NS <your-nameserver>.
- Create a new zone
_acme-challenge.<domain>
on<your-nameserver>
, with an empty zonefile (just an SOA and NS record), writeable by the nameserver - Create a new TSIG key:
tsig-keygen -a sha512 <keyname>
- Enable dynamic updates on the
_acme-challenge.<domain>
zone with this key
e.g. for bind9:
key "<keyname>" {
algorithm hmac-sha512;
secret "<key>";
};
zone "_acme-challenge.<domain>" {
type master;
file "/var/cache/bind/_acme-challenge.<domain>";
masterfile-format text;
allow-update { key "<keyname>"; };
};
This is a secure approach because each host will have its own key, and hence can only obtain certificates for those domains you have explicitly authorized it for.
An alternative approach is to use CNAMEs to put all your dynamic updates into a single zone. You will need to modify the script:
ZONE="acme.mydomain.com"
...
"deploy_challenge")
printf "server %s\nupdate add _acme-challenge.%s.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${2}" "${ZONE}" "${TTL}" "${4}" | $NSUPDATE
;;
"clean_challenge")
printf "server %s\nupdate delete _acme-challenge.%s.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${2}" "${ZONE}" "${TTL}" "${4}" | $NSUPDATE
You then only need to create a single zone acme.mydomain.com
which accepts dynamic DNS updates, but you will need to add static CNAMEs for _acme-challenge.<certname>
pointing at _acme-challenge.<certname>.acme.mydomain.com
for each certificate you want to issue.