From d306462124b61e9d06063ab86e6b1594fe015711 Mon Sep 17 00:00:00 2001 From: Brian Candler <44789+candlerb@users.noreply.github.com> Date: Thu, 23 Nov 2017 16:13:13 +0000 Subject: [PATCH] nsupdate doesn't need "zone" statement in normal operation. Explain creating separate _acme-challenge zones. --- example-dns-01-nsupdate-script.md | 47 ++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/example-dns-01-nsupdate-script.md b/example-dns-01-nsupdate-script.md index 8217a54..28d870d 100644 --- a/example-dns-01-nsupdate-script.md +++ b/example-dns-01-nsupdate-script.md @@ -17,18 +17,18 @@ set -o pipefail NSUPDATE="nsupdate -k /path/to/Kdnsupdatekey.private" DNSSERVER="127.0.0.1" -ZONE="mydomain.com" TTL=300 case "$1" in "deploy_challenge") - printf "server %s\nzone %s.\nupdate add _acme-challenge.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${ZONE}" "${2}" "${TTL}" "${4}" | $NSUPDATE + printf "server %s\nupdate add _acme-challenge.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${2}" "${TTL}" "${4}" | $NSUPDATE ;; "clean_challenge") - printf "server %s\nzone %s.\nupdate delete _acme-challenge.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${ZONE}" "${2}" "${TTL}" "${4}" | $NSUPDATE + printf "server %s\nupdate delete _acme-challenge.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${2}" "${TTL}" "${4}" | $NSUPDATE ;; "deploy_cert") - # do nothing for now + # optional: + # /path/to/deploy_cert.sh "${1}" "${2}" "${3}" "${4}" ;; "unchanged_cert") # do nothing for now @@ -47,16 +47,49 @@ esac exit 0 ``` -If you are using CNAMEs to put all your dynamic updates into a single zone, then you can modify it: +The file `/path/to/Kdnsupdatekey.private` looks like this: + +``` +key "" { + algorithm hmac-md5; + secret ""; +}; +``` + +To avoid making your entire production DNS subject to dynamic DNS updates, then for each certificate domain you want: + +1. In your main DNS infrastructure create a delegation: `_acme-challenge.. NS .` +2. Create a new zone `_acme-challenge.` on ``, with an empty zonefile (just an SOA and NS record), writeable by the nameserver +3. Create a new TSIG key: `dnssec-keygen -r /dev/urandom -a hmac-md5 -b 128 -n HOST ` +4. Enable dynamic updates on the `_acme-challenge.` zone with this key + +e.g. for bind9: + +~~~ +key "" { + algorithm hmac-md5; + secret ""; +}; +zone "_acme-challenge." { + type master; + file "/var/cache/bind/_acme-challenge."; + masterfile-format text; + allow-update { key ""; }; +}; +~~~ + +This is the most 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\nzone %s.\nupdate add _acme-challenge.%s.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${ZONE}" "${2}" "${ZONE}" "${TTL}" "${4}" | $NSUPDATE + 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\nzone %s.\nupdate delete _acme-challenge.%s.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${ZONE}" "${2}" "${ZONE}" "${TTL}" "${4}" | $NSUPDATE + 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.` pointing at `_acme-challenge..acme.mydomain.com` for each certificate you want to issue. \ No newline at end of file