From f2a4f6bfa8b573cb280ff8312cc4f4fa4aa02066 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Mon, 15 May 2017 13:57:22 -0400 Subject: [PATCH 01/18] Initial version of GoDaddy DNS validation support. Uses the GoDaddy "Developer" API to add and remove the ACME challenge records. --- .gitattributes | 3 + .gitignore | 9 + dns_scripts/00GoDaddy-README.txt | 68 ++++++ dns_scripts/dns_add_godaddy | 39 +++ dns_scripts/dns_del_godaddy | 37 +++ dns_scripts/dns_godaddy | 393 +++++++++++++++++++++++++++++++ 6 files changed, 549 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 dns_scripts/00GoDaddy-README.txt create mode 100755 dns_scripts/dns_add_godaddy create mode 100755 dns_scripts/dns_del_godaddy create mode 100755 dns_scripts/dns_godaddy diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..21cd7446 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Files not to include in .zip/.tar.gz archives +# +.git* export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..8317ebfb --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*~ +*# +*.swp +*.tmp +*.bak +*.tdy +*.tar.gz +*.orig +JSON.sh diff --git a/dns_scripts/00GoDaddy-README.txt b/dns_scripts/00GoDaddy-README.txt new file mode 100644 index 00000000..f53ab034 --- /dev/null +++ b/dns_scripts/00GoDaddy-README.txt @@ -0,0 +1,68 @@ +Using GoDaddy DNS for LetsEncrypt domain validation. + +Quick guide to setting up getssl for domain validation of +GoDaddy DNS domains. + +There are two prerequisites to using getssl with GoDaddy DNS: + +1) Obtain an API access key from developer.godaddy.com + At first sign-up, you will be required to take a "test" key. + This is NOT what you need. Accept it, then get a "Production" + key. At this writing, there is no charge - but you must have + a GoDaddy customer account. + + You must get the API key for the account which owns the domain + that you want to get certificates for. If the domains that you + manage are owned by more than one account, get a key for each. + + The access key consists of a "Key" and a "Secret". You need + both. + +2) Obtain JSON.sh - https://github.com/dominictarr/JSON.sh + +With those in hand, the installation procedure is: + +1) Create a "myscripts" directory under ~/.getssl/ + +2) Put JSON.sh in "myscripts" + +3) Copy (or softlink from the distribution directory) the + following files to "myscripts": + dns_godaddy dns_add_godaddy dns_del_godaddy + None of these files need to be customized. + +4) Open your config file (the global file in ~/.getssl/getssl.cfg + or the per-account file in ~/.getssl/example.net/getssl.cfg + +5) Set the following options: + VALIDATE_VIA_DNS="true" + DNS_ADD_COMMAND="/path/to/myscripts/dns_add_godaddy" + DNS_DEL_COMMAND="/path/to/myscripts/dns_del_godaddy" + # The API key for your account/this domain + export GODADDY_KEY="..." GODADDY_SECRET="..." + + Note that ~user/ probably won't work in the path. + +6) Set any other options that you wish (per the standard + directions.) Use the test CA to make sure that + everything is setup correctly. + +That's it. getssl example.net will now validate with DNS. + +To trace record additions and removals, run getssl as +GODADDY_TRACE=Y getssl example.net + +There are additional options, which are documented in the +*godaddy" files and dns_godaddy -h. + +Copyright (2017) Timothe Litt litt at acm _dot org + +This sofware may be freely used providing this notice is included with +all copies. The name of the author may not be used to endorse +any other product or derivative work. No warranty is provided +and the user assumes all responsibility for use of this software. + +Report any issues to https://github.com/tlhackque/getssl/issues. + +Enjoy. + diff --git a/dns_scripts/dns_add_godaddy b/dns_scripts/dns_add_godaddy new file mode 100755 index 00000000..4983ea9a --- /dev/null +++ b/dns_scripts/dns_add_godaddy @@ -0,0 +1,39 @@ +#!/bin/bash + +# Copyright (2017) Timothe Litt litt at acm _dot org + +# Add token to GoDaddy dns using dns_godaddy + +# You do not have to customize this script. +# +# Obtain the Key and Secret from https://developer.godaddy.com/getstarted +# You must obtain a "Production" key - NOT the "Test" key you're required +# to get first. +# +# Obtain JSON.sh from https://github.com/dominictarr/JSON.sh +# Place it in (or softlink it to) the same directory as $GODADDY_SCRIPT, +# or specify its location with GODADDY_JSON +# +# Define GODADDY_KEY and GO_DADDY_SECRET in your account or domain getssl.cfg +# +# See GoDaddy-README.txt for complete instructions. + +fulldomain="$1" +token="$2" + +[ -z "$GODADDY_SCRIPT" ] && GODADDY_SCRIPT="~/.getssl/myscripts/dns_godaddy" +[[ "$GODADDY_SCRIPT" =~ ^~ ]] && \ + eval 'GODADDY_SCRIPT=`readlink -nf ' $GODADDY_SCRIPT '`' + +if [ ! -x "$GODADDY_SCRIPT" ]; then + echo "$GODADDY_SCRIPT: not found. Please install, softlink or set GODADDY_SCRIPT to its full path" + echo "See GoDaddy-README.txt for complete instructions." + exit 3 +fi + +# JSON.sh is not (currently) used by add + +export GODADDY_KEY +export GODADDY_SECRET + +$GODADDY_SCRIPT -q add ${fulldomain} "_acme-challenge.${fulldomain}." "${token}" diff --git a/dns_scripts/dns_del_godaddy b/dns_scripts/dns_del_godaddy new file mode 100755 index 00000000..c2619985 --- /dev/null +++ b/dns_scripts/dns_del_godaddy @@ -0,0 +1,37 @@ +#!/bin/bash + +# Copyright (2017) Timothe Litt litt at acm _dot org + +# Remove token from GoDaddy dns using dns_godaddy + +# You do not have to customize this script. +# +# Obtain the Key and Secret from https://developer.godaddy.com/getstarted +# You must obtain a "Production" key - NOT the "Test" key you're required +# to get first. +# +# Obtain JSON.sh from https://github.com/dominictarr/JSON.sh +# Place it in (or softlink it to) the same directory as $GODADDY_SCRIPT, +# or specify its location with GODADDY_JSON +# +# Define GODADDY_KEY and GO_DADDY_SECRET in your account or domain getssl.cfg +# +# See GoDaddy-README.txt for complete instructions. + +fulldomain="$1" +token="$2" + +[ -z "$GODADDY_SCRIPT" ] && GODADDY_SCRIPT="~/.getssl/myscripts/dns_godaddy" +[[ "$GODADDY_SCRIPT" =~ ^~ ]] && \ + eval 'GODADDY_SCRIPT=`readlink -nf ' $GODADDY_SCRIPT '`' + +if ! [ -x "$GODADDY_SCRIPT" ]; then + echo "$GODADDY_SCRIPT: not found. Please install, softlink or set GODADDY_SCRIPT to its full path" + echo "See GoDaddy-README.txt for complete instructions." + exit 3 +fi + +export GODADDY_KEY +export GODADDY_SECRET + +$GODADDY_SCRIPT -q del ${fulldomain} "_acme-challenge.${fulldomain}." "${token}" diff --git a/dns_scripts/dns_godaddy b/dns_scripts/dns_godaddy new file mode 100755 index 00000000..536fdd12 --- /dev/null +++ b/dns_scripts/dns_godaddy @@ -0,0 +1,393 @@ +#!/bin/bash + +# Copyright (2017) Timothe Litt litt at acm _dot org + +VERSION="1.0.0" + +# This script is used to update TXT records in GoDaddy DNS server +# It depends on JSON.sh from https://github.com/dominictarr/JSON.sh +# Place it in (or softlink it to) the same directory as this script, +# or specify its location with GODADDY_JSON +# +# See the usage text below, 00GoDaddy-README.txt, dns_add_godaddy +# and dns_del_godaddy for additional information. +# +# It may be freely used providing this notice is included with +# all copies. The name of the author may not be used to endorse +# any other product or derivative work. No warranty is provided +# and the user assumes all responsibility for use of this software. +# +# Bug reports are welcome at https://github.com/tlhackque/getssl/issues. + +API='https://api.godaddy.com/v1/domains' +APISIGNUP='https://developer.godaddy.com/getstarted' +GETJSON='https://github.com/dominictarr/JSON.sh' + +VERB="y" +DEBUG="$GODADDY_DEBUG" +[ -z "$JSON" ] && JSON="$GODADDY_JSON" +[ -z "$JSON" ] && JSON="`dirname $0`/JSON.sh" + +while getopts 'dhj:k:s:qv' opt; do + case $opt in + d) DEBUG="Y" ;; + j) JSON="$OPTARG" ;; + k) GODADDY_KEY="$OPTARG" ;; + s) GODADDY_SECRET="$OPTARG" ;; + q) VERB= ;; + v) echo "dns_godaddy version $VERSION"; exit 0 ;; + *) + cat <&2 +$0: requires JSON.sh as "$JSON" + +The full path to JSON.sh can be specified with -j, or the +GODADDY_JSON environment variable. + +You can obtain a copy from $GETJSON + +Then place or softlink it to $JSON or set GODADDY_JSON. +EOF + exit 2 +fi + +if [ -z "$GODADDY_KEY" ] || [ -z "$GODADDY_SECRET" ]; then + echo "GODADDY_KEY and GODADDY secret must be defined" >&2 + exit 3 +fi + +[ -n "$DEBUG" ] && VERB="y" +[ -n "$GODADDY_TRACE" ] && VERB="Y" + +# Get parameters & validate + +op="$1" +if ! [[ "$op" =~ ^(add|del)$ ]]; then + echo "Operation must be \"add\" or \"del\"" >&2 + exit 3 +fi +domain="$2" +domain="${domain%'.'}" +if [ -z "$domain" ]; then + echo "'domain' parameter is required, see -h" >&2 + exit 3 +fi +name="$3" +if [ -z "$name" ]; then + echo "'name' parameter is required, see -h" >&2 + exit 3 +fi +! [[ "$name" =~ [.]$ ]] && name="${name}.${domain}." +data="$4" +if [ -z "$data" ]; then + echo "'data' parameter is required, see -h" >&2 + exit 3 +fi + +if [ "$op" = 'del' ]; then + ttl= +elif [ -z "$5" ]; then + ttl="600" # GoDaddy minimum TTL is 600 +elif ! [[ "$5" =~ ^[0-9]+$ ]]; then + echo "TTL $5 is not numeric" >&2 + exit 3 +elif [ $5 -lt 600 ]; then + [ -n "$VERB" ] && \ + echo "$5 is less than GoDaddy minimum of 600; increased to 600" >&2 + ttl="600" +else + ttl="$5" +fi + +# --- Done with parameters + +[ -n "$DEBUG" ] && \ + echo "`basename $0`: $op $domain $name \"$data\" $ttl" >&2 + +# Authorization header has secret and key +# N.B. These will appear in a 'ps' listing since curl only allows +# headers to be provided on the command line. + +authhdr="Authorization: sso-key $GODADDY_KEY:$GODADDY_SECRET" + +[ -n "$DEBUG" ] && echo "$authhdr" >&2 + +if [ "$op" = "add" ]; then + # May need to retry due to zone cuts + + while [[ "$domain" =~ [^.]+\.[^.]+ ]]; do + + url="$API/$domain/records/TXT/$name" + + request='{"data":"'$data'","ttl":'$ttl'}' + [ -n "$DEBUG" ] && cat >&2 <&2 <&2 + exit $sts + fi + if ! echo "$result" | grep -q '^HTTP/.* 200 '; then + code="`echo "$result" | grep '"code":' | sed -e's/^.*"code":"//; s/\".*$//'`" + msg="`echo "$result" | grep '"message":' | sed -e's/^.*"message":"//; s/\".*$//'`" + if [ "$code" = "DUPLICATE_RECORD" ]; then + if [ -n "$VERB" ]; then + echo "$msg in $domain" >&2 + fi + exit 0 # Duplicate record is still success + fi + if [ "$code" = 'UNKNOWN_DOMAIN' ]; then + if [[ "$domain" =~ ^([^.]+)\.([^.]+\.[^.]+.*) ]]; then + [ -n "$DEBUG" ] && \ + echo "$domain unknown, trying ${BASH_REMATCH[2]}" >&2 + domain="${BASH_REMATCH[2]}" + continue; + fi + fi + echo "Request failed $msg" >&2 + exit 1 + fi + [ -n "$VERB" ] && echo "$domain: added $name $ttl TXT \"$data\"" >&2 + exit 0 + done +fi + + +# ----- Delete + +# There is no delete API +# But, it is possible to replace all TXT records. +# +# So, first query for all TXT records + +# May need to retry due to zone cuts + +while [[ "$domain" =~ [^.]+\.[^.]+ ]]; do + + url="$API/$domain/records/TXT" + [ -n "$DEBUG" ] && echo "Query for TXT records to: $url" >&2 + + current="$(curl -i -s -X GET -H "$authhdr" "$url")" + sts=$? + if [ $sts -ne 0 ]; then + echo "curl error $sts for query" >&2 + exit $sts + fi + [ -n "$DEBUG" ] && cat >&2 <&2 + domain="${BASH_REMATCH[2]}" + continue; + fi + fi + echo "Request failed $msg" >&2 + exit 1 + fi + # Remove headers + + current="$(echo "$current" | sed -e'0,/^\r*$/d')" + break +done + + # The zone cut is known, so the replace can't fail due to UNKNOWN domain + +if [ "$current" = '[]' ]; then # No TXT records in zone + [ -n "$VERB" ] && echo "$domain: $name TXT \"$data\" does not exist" >&2 + [ -n "$DEBUG" ] && echo "No TXT records in $domain" >&2 + exit 1 # Intent was to change, so error status +fi + +[ -n "$DEBUG" ] && echo "Response is valid" + +# Prepare request to replace TXT RRSET + +# Parse JSON and select only the record structures, which are [index] { ...} + +current="$(echo "$current" | $JSON | sed -n -e'/^\[[0-9][0-9]*\]/{ s/^\[[0-9][0-9]*\]//; p}')" +base="$current" + +[ -n "$DEBUG" ] && cat >&2 <&2 + exit 1 # Intent was to change DNS, so this is an error +fi + +# Remove whitespace and insert needed commmas +# +fmtnew="$new" +new=$(echo "$new" | sed -e"s/}/},/g; \$s/},/}/;" | tr -d '\t\n') + +if [ -z "$new" ]; then + [ -n "$VERB" ] && echo "Replacing last TXT record with a dummy (see -h)" >&2 + new='{"type":"TXT","name":"_dummy.record_","data":"_This record is not used_","ttl":601}' + dummy="t" + TAB=$'\t' + fmtnew="${TAB}$new" + if [ "$fmtnew" = "$base" ]; then + [ -n "$VERB" ] && echo "This tool can't delete a placeholder when it is the only TXT record" >&2 + exit 0 # Not really success, but retrying won't help. + fi +fi + +request="[$new]" + +[ -n "$DEBUG" ] && cat >&2 <&2 <&2 <&2 + exit $sts +fi +if ! echo "$result" | grep -q '^HTTP/.* 200 '; then + result="$(echo "$result" | sed -e'0,/^\r*$/d')" + code="`echo "$result" | grep '"code":' | sed -e's/^.*"code":"//; s/\".*$//'`" + msg="`echo "$result" | grep '"message":' | sed -e's/^.*"message":"//; s/\".*$//'`" + echo "Request failed $msg" >&2 + exit 1 +fi + +if [ -n "$VERB" ]; then + if [ -n "$dummy" ]; then + echo "$domain: replaced $name TXT \"$data\" with a placeholder" >&2 + else + echo "$domain: deleted $name TXT \"$data\"" >&2 + fi +fi +exit 0 + From 49d837de532e2cb3d21497248d1f834909035602 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Mon, 15 May 2017 14:40:18 -0400 Subject: [PATCH 02/18] Improve message from curl error code 60 Issue #288 --- getssl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/getssl b/getssl index 7f3713ec..5bce35cd 100755 --- a/getssl +++ b/getssl @@ -429,7 +429,8 @@ check_getssl_upgrade() { # check if a more recent version of code is available a curl --silent "$CODE_LOCATION" --output "$TEMP_UPGRADE_FILE" errcode=$? if [[ $errcode -eq 60 ]]; then - error_exit "curl needs updating, your version does not support SNI (multiple SSL domains on a single IP)" + longmsg=$'Can not authenticate SSL peer. Your ca_bundle.crt and/or curl may need\nupdating. ca_bundle.crt can be updates with mk-ca-bundle. Curl should\nsupport SNI (multiple SSL domains on a single IP)' + error_exit "$longmsg" elif [[ $errcode -gt 0 ]]; then error_exit "curl error : $errcode" fi From 134456b9685f5c9f0d69807a8d0db7eb5c9c9abe Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Mon, 15 May 2017 14:49:15 -0400 Subject: [PATCH 03/18] Fix misleading error message saving certificates to file. --- getssl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getssl b/getssl index 5bce35cd..8b0b7c2e 100755 --- a/getssl +++ b/getssl @@ -814,7 +814,7 @@ get_certificate() { # get certificate for csr, if all domains validated. echo -----BEGIN CERTIFICATE----- > "$gc_certfile" curl --silent "$CertData" | openssl base64 -e >> "$gc_certfile" echo -----END CERTIFICATE----- >> "$gc_certfile" - info "Certificate saved in $CERT_FILE" + info "Certificate saved in $gc_certfile" fi # If certificate wasn't a valid certificate, error exit. From 568e3373fcd6a8b92576f9fc059e3a6c08c313b4 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Mon, 15 May 2017 14:53:07 -0400 Subject: [PATCH 04/18] Add delimiter to INVALID PRIVATE_KEY_ALG message --- getssl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getssl b/getssl index 8b0b7c2e..aadb809d 100755 --- a/getssl +++ b/getssl @@ -336,7 +336,7 @@ check_config() { # check the config files for all obvious errors rsa|prime256v1|secp384r1|secp521r1) debug "checked PRIVATE_KEY_ALG " ;; *) - info "${DOMAIN}: invalid PRIVATE_KEY_ALG - $PRIVATE_KEY_ALG" + info "${DOMAIN}: invalid PRIVATE_KEY_ALG - '$PRIVATE_KEY_ALG'" config_errors=true ;; esac if [[ "$DUAL_RSA_ECDSA" == "true" ]] && [[ "$PRIVATE_KEY_ALG" == "rsa" ]]; then From c80f3c86925f328e5696fa090e57a5f9d3e5a4a3 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Mon, 15 May 2017 17:21:33 -0400 Subject: [PATCH 05/18] Replace dns_*_nsupdate scripts Old versions did not return correct exit status. Did not provide for pre/post processing hooks (e.g. to mount a disk) Required custom edits/copies for each instance. These fix all those issues. --- dns_scripts/dns_add_nsupdate | 35 +++++++++++++++++++++++++++++------ dns_scripts/dns_del_nsupdate | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/dns_scripts/dns_add_nsupdate b/dns_scripts/dns_add_nsupdate index 9e8ebfef..03f73d42 100755 --- a/dns_scripts/dns_add_nsupdate +++ b/dns_scripts/dns_add_nsupdate @@ -2,15 +2,38 @@ # example of script to add token to local dns using nsupdate -dnskeyfile="path/to/bla.key" - fulldomain="$1" token="$2" -updatefile=$(mktemp) +# VARIABLES: +# +# DNS_NSUPDATE_KEYFILE - path to a TSIG key file, if required +# DNS_NSUPDATE_GETKEY - command to execute if access to the key file requires +# some special action: mounting a disk, decrypting a file.. +# Called with the operation 'add' and action 'open" / 'close' + + +if [ -n "${DNS_NSUPDATE_KEYFILE}" ]; then + if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'add' 'open' ; then + exit $(( $? + 128 )) + fi + + options="-k ${DNS_NSUPDATE_KEYFILE}" +fi + +# Note that blank line is a "send" command to nsupdate + +nsupdate ${options} -v < "${updatefile}" +sts=$? -nsupdate -k "${dnskeyfile}" -v "${updatefile}" +if [ -n "${DNS_NSUPDATE_KEYFILE}" ]; then + if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'add' 'close' ; then + exit $(( ${sts} + ( $? * 10 ) )) + fi +fi -rm -f "${updatefile}" +exit ${sts} \ No newline at end of file diff --git a/dns_scripts/dns_del_nsupdate b/dns_scripts/dns_del_nsupdate index 62291b7a..ab9ca281 100755 --- a/dns_scripts/dns_del_nsupdate +++ b/dns_scripts/dns_del_nsupdate @@ -1,15 +1,39 @@ #!/bin/bash -# example of script to add token to local dns using nsupdate +# example of script to remove token from local dns using nsupdate -dnskeyfile="path/to/bla.key" fulldomain="$1" token="$2" -updatefile=$(mktemp) +# VARIABLES: +# +# DNS_NSUPDATE_KEYFILE - path to a TSIG key file, if required +# DNS_NSUPDATE_GETKEY - command to execute if access to the key file requires +# some special action: dismounting a disk, encrypting a +# file... Called with the operation 'del' and action +# 'open" / 'close' -printf "update delete _acme-challenge.%s. 300 in TXT \"%s\"\n\n" "${fulldomain}" "${token}" > "${updatefile}" +if [ -n "${DNS_NSUPDATE_KEYFILE}" ]; then + if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'del' 'open'; then + exit $(( $? + 128 )) + fi -nsupdate -k "${dnskeyfile}" -v "${updatefile}" + options="-k ${DNS_NSUPDATE_KEYFILE}" +fi -rm -f "${updatefile}" +# Note that blank line is a "send" command to nsupdate + +nsupdate ${options} -v < Date: Mon, 15 May 2017 17:38:24 -0400 Subject: [PATCH 06/18] Include domain name in dns_nsupdate hooks --- dns_scripts/dns_add_nsupdate | 4 ++-- dns_scripts/dns_del_nsupdate | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dns_scripts/dns_add_nsupdate b/dns_scripts/dns_add_nsupdate index 03f73d42..55178db1 100755 --- a/dns_scripts/dns_add_nsupdate +++ b/dns_scripts/dns_add_nsupdate @@ -14,7 +14,7 @@ token="$2" if [ -n "${DNS_NSUPDATE_KEYFILE}" ]; then - if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'add' 'open' ; then + if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'add' 'open' ${fulldomain} ; then exit $(( $? + 128 )) fi @@ -31,7 +31,7 @@ EOF sts=$? if [ -n "${DNS_NSUPDATE_KEYFILE}" ]; then - if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'add' 'close' ; then + if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'add' 'close' ${fulldomain}; then exit $(( ${sts} + ( $? * 10 ) )) fi fi diff --git a/dns_scripts/dns_del_nsupdate b/dns_scripts/dns_del_nsupdate index ab9ca281..b3a553e2 100755 --- a/dns_scripts/dns_del_nsupdate +++ b/dns_scripts/dns_del_nsupdate @@ -14,7 +14,7 @@ token="$2" # 'open" / 'close' if [ -n "${DNS_NSUPDATE_KEYFILE}" ]; then - if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'del' 'open'; then + if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'del' 'open' ${fulldomain} ; then exit $(( $? + 128 )) fi @@ -31,7 +31,7 @@ EOF sts=$? if [ -n "${DNS_NSUPDATE_KEYFILE}" ]; then - if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'del' 'close' ; then + if [ -n "${DNS_NSUPDATE_KEY_HOOK}" ] && ! ${DNS_NSUPDATE_KEY_HOOK} 'del' 'close' ${fulldomain} ; then exit $(( ${sts} + ( $? * 10 ) )) fi fi From b579af8552e6d5e329777710511721cf631603ea Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Mon, 15 May 2017 21:04:52 -0400 Subject: [PATCH 07/18] Move GoDaddy scripts to installation directory; use install -v for all files Simplifies installation; private directory no longer required since the scripts don't need to be customized. -v makes sure that the installer knows what is happening. --- Makefile | 7 +++---- dns_scripts/00GoDaddy-README.txt | 22 +++++++--------------- dns_scripts/dns_add_godaddy | 5 +++-- dns_scripts/dns_del_godaddy | 5 +++-- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 4f161264..d88e22c3 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,9 @@ ifneq ($(strip $(DESTDIR)),) mkdir -p $(DESTDIR) endif - install -Dm755 getssl $(DESTDIR)/usr/bin/getssl - - install -dm755 $(DESTDIR)/usr/share/getssl - cp -r *_scripts $(DESTDIR)/usr/share/getssl + install -Dvm755 getssl $(DESTDIR)/usr/bin/getssl + install -dvm755 $(DESTDIR)/usr/share/getssl + for dir in *_scripts; do install -dv $(DESTDIR)/usr/share/getssl/$$dir; install -pv $$dir/* $(DESTDIR)/usr/share/getssl/$$dir/; done .PHONY: install diff --git a/dns_scripts/00GoDaddy-README.txt b/dns_scripts/00GoDaddy-README.txt index f53ab034..d58ba737 100644 --- a/dns_scripts/00GoDaddy-README.txt +++ b/dns_scripts/00GoDaddy-README.txt @@ -22,28 +22,20 @@ There are two prerequisites to using getssl with GoDaddy DNS: With those in hand, the installation procedure is: -1) Create a "myscripts" directory under ~/.getssl/ +1) Put JSON.sh in the getssl DNS scripts directory + Default: /usr/share/getssl/dns_scripts -2) Put JSON.sh in "myscripts" - -3) Copy (or softlink from the distribution directory) the - following files to "myscripts": - dns_godaddy dns_add_godaddy dns_del_godaddy - None of these files need to be customized. - -4) Open your config file (the global file in ~/.getssl/getssl.cfg +2) Open your config file (the global file in ~/.getssl/getssl.cfg or the per-account file in ~/.getssl/example.net/getssl.cfg -5) Set the following options: +3) Set the following options: VALIDATE_VIA_DNS="true" - DNS_ADD_COMMAND="/path/to/myscripts/dns_add_godaddy" - DNS_DEL_COMMAND="/path/to/myscripts/dns_del_godaddy" + DNS_ADD_COMMAND="/usr/share/getssl/dns_scripts/dns_add_godaddy" + DNS_DEL_COMMAND="/usr/share/getssl/dns_scripts/dns_del_godaddy" # The API key for your account/this domain export GODADDY_KEY="..." GODADDY_SECRET="..." - Note that ~user/ probably won't work in the path. - -6) Set any other options that you wish (per the standard + 4) Set any other options that you wish (per the standard directions.) Use the test CA to make sure that everything is setup correctly. diff --git a/dns_scripts/dns_add_godaddy b/dns_scripts/dns_add_godaddy index 4983ea9a..f7a871c6 100755 --- a/dns_scripts/dns_add_godaddy +++ b/dns_scripts/dns_add_godaddy @@ -12,7 +12,8 @@ # # Obtain JSON.sh from https://github.com/dominictarr/JSON.sh # Place it in (or softlink it to) the same directory as $GODADDY_SCRIPT, -# or specify its location with GODADDY_JSON +# or specify its location with GODADDY_JSON The default is +# /usr/share/getssl/dns_scripts/ # # Define GODADDY_KEY and GO_DADDY_SECRET in your account or domain getssl.cfg # @@ -21,7 +22,7 @@ fulldomain="$1" token="$2" -[ -z "$GODADDY_SCRIPT" ] && GODADDY_SCRIPT="~/.getssl/myscripts/dns_godaddy" +[ -z "$GODADDY_SCRIPT" ] && GODADDY_SCRIPT="/usr/share/getssl/dns_scripts/dns_godaddy" [[ "$GODADDY_SCRIPT" =~ ^~ ]] && \ eval 'GODADDY_SCRIPT=`readlink -nf ' $GODADDY_SCRIPT '`' diff --git a/dns_scripts/dns_del_godaddy b/dns_scripts/dns_del_godaddy index c2619985..7ca0da9f 100755 --- a/dns_scripts/dns_del_godaddy +++ b/dns_scripts/dns_del_godaddy @@ -12,7 +12,8 @@ # # Obtain JSON.sh from https://github.com/dominictarr/JSON.sh # Place it in (or softlink it to) the same directory as $GODADDY_SCRIPT, -# or specify its location with GODADDY_JSON +# or specify its location with GODADDY_JSON The default is +# /usr/share/getssl/dns_scripts/ # # Define GODADDY_KEY and GO_DADDY_SECRET in your account or domain getssl.cfg # @@ -21,7 +22,7 @@ fulldomain="$1" token="$2" -[ -z "$GODADDY_SCRIPT" ] && GODADDY_SCRIPT="~/.getssl/myscripts/dns_godaddy" +[ -z "$GODADDY_SCRIPT" ] && GODADDY_SCRIPT="/usr/share/getssl/dns_scripts/dns_godaddy" [[ "$GODADDY_SCRIPT" =~ ^~ ]] && \ eval 'GODADDY_SCRIPT=`readlink -nf ' $GODADDY_SCRIPT '`' From 820dec6d3f7b5c272c9ee43de48a6b94a61b9db5 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Mon, 15 May 2017 22:44:24 -0400 Subject: [PATCH 08/18] Have curl read Authrorizaton header from stdin rather than the command line. Prevents GoDaddy secret and key from exposure via ps. There is still an issue if environment variables can be read. --- dns_scripts/dns_godaddy | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/dns_scripts/dns_godaddy b/dns_scripts/dns_godaddy index 536fdd12..0e6454cf 100755 --- a/dns_scripts/dns_godaddy +++ b/dns_scripts/dns_godaddy @@ -178,8 +178,6 @@ fi echo "`basename $0`: $op $domain $name \"$data\" $ttl" >&2 # Authorization header has secret and key -# N.B. These will appear in a 'ps' listing since curl only allows -# headers to be provided on the command line. authhdr="Authorization: sso-key $GODADDY_KEY:$GODADDY_SECRET" @@ -199,9 +197,12 @@ Add request to: $url $request" -------- EOF - result="$(curl -i -s -X PUT -H "$authhdr" \ - -H "Content-Type: application/json" \ - -d "$request" "$url")" + + result="$(curl -i -s -X PUT -d "$request" --config - "$url" <&2 <&2 - current="$(curl -i -s -X GET -H "$authhdr" "$url")" + current="$(curl -i -s -X GET --config - "$url" <&2 @@ -357,9 +361,11 @@ $request -------- EOF -result="$(curl -i -s -X PUT -H "$authhdr" \ - -H "Content-Type: application/json" \ - -d "$request" "$url")" +result="$(curl -i -s -X PUT -d "$request" --config - "$url" <&2 < Date: Tue, 16 May 2017 08:05:30 -0400 Subject: [PATCH 09/18] Add option for full protocol trace -t FILE (or GODADDY_TFILE=FILE) will append command arguments and all wire traffic to a file. This provides all the information needed for debugging future issues. --- dns_scripts/dns_godaddy | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/dns_scripts/dns_godaddy b/dns_scripts/dns_godaddy index 0e6454cf..ff25449c 100755 --- a/dns_scripts/dns_godaddy +++ b/dns_scripts/dns_godaddy @@ -2,7 +2,8 @@ # Copyright (2017) Timothe Litt litt at acm _dot org -VERSION="1.0.0" +VERSION="1.0.1" +PROG="`basename $0`" # This script is used to update TXT records in GoDaddy DNS server # It depends on JSON.sh from https://github.com/dominictarr/JSON.sh @@ -28,19 +29,20 @@ DEBUG="$GODADDY_DEBUG" [ -z "$JSON" ] && JSON="$GODADDY_JSON" [ -z "$JSON" ] && JSON="`dirname $0`/JSON.sh" -while getopts 'dhj:k:s:qv' opt; do +while getopts 'dhj:k:s:t:qv' opt; do case $opt in d) DEBUG="Y" ;; j) JSON="$OPTARG" ;; k) GODADDY_KEY="$OPTARG" ;; s) GODADDY_SECRET="$OPTARG" ;; + t) TRACE="$OPTARG" ;; q) VERB= ;; v) echo "dns_godaddy version $VERSION"; exit 0 ;; *) cat <&2 + echo "$PROG: $op $domain $name \"$data\" $ttl" >&2 # Authorization header has secret and key authhdr="Authorization: sso-key $GODADDY_KEY:$GODADDY_SECRET" +if [ -n "$TRACE" ]; then + function timestamp { local tm="`date '+%T:%S%N'`" + local class="$1"; shift + echo "${tm:0:15} ** ${class}: $*" >>"$TRACE" + } + timestamp 'Info' "$PROG" "V$VERSION" 'Starting new protocol trace' + timestamp 'Args' "$@" + function curl { + command curl --trace-time --trace-ascii % "$@" 2>>"$TRACE" + } + [ -n "$VERB" ] && echo "Appending protocol trace to $TRACE" +fi + [ -n "$DEBUG" ] && echo "$authhdr" >&2 if [ "$op" = "add" ]; then From e5702045b055c3ba9aba440a0769549db52ab41b Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Tue, 16 May 2017 21:01:11 -0400 Subject: [PATCH 10/18] Support views. Also, avoid hangs interrogating remote. rdbath suggested how to implement a timeout on s_client probes. Unfortunately, wait -n is a bash 4.3 feature. So this requires bash 4.3. CHECK_CERT_TIMEOUT can be used to override the default, which is 4 seconds. Fallback is provided for older versions. Views may require the 'nslookup' process to do somthing special, usually provide a TSIG key or bind to a specific local address. Add a hook for that - export the VARIABLE DNS_CHECK_FUNC_OPTIONS with the desired options._Set DNS_CHECK_FUNC to the desired command, which must be one of the supported ones: 'dig', 'drill', 'host' or 'nslookup'. However, this turned up the fact that the dig/drill code had the domain and record type arguments in the wrong order on the command line. (The domain comes first, see the man page.) Fixed. In some cases defining the previously undocumented PUBLIC_DNS_SERVER may work. This commit adds it to the template file, and exports it for the benefit of DNS_UPDATE scripts. Also AUTH_DNS_SERVER. Squashed awk complaints about curl.header in some cases with debugging on. Support older curl (--trace-time is somewhat recent) --- dns_scripts/dns_godaddy | 3 +- getssl | 103 +++++++++++++++++++++++++++++++--------- 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/dns_scripts/dns_godaddy b/dns_scripts/dns_godaddy index ff25449c..5e9aa0be 100755 --- a/dns_scripts/dns_godaddy +++ b/dns_scripts/dns_godaddy @@ -193,8 +193,9 @@ if [ -n "$TRACE" ]; then } timestamp 'Info' "$PROG" "V$VERSION" 'Starting new protocol trace' timestamp 'Args' "$@" + curl --help | grep -q -- --trace-time && CURL_TFLAGS="--trace-time" # 7.14.0 function curl { - command curl --trace-time --trace-ascii % "$@" 2>>"$TRACE" + command curl ${CURL_TFLAGS} --trace-ascii % "$@" 2>>"$TRACE" } [ -n "$VERB" ] && echo "Appending protocol trace to $TRACE" fi diff --git a/getssl b/getssl index aadb809d..da7f3860 100755 --- a/getssl +++ b/getssl @@ -192,16 +192,20 @@ VERSION="2.10" # defaults ACCOUNT_KEY_LENGTH=4096 ACCOUNT_KEY_TYPE="rsa" +export AUTH_DNS_SERVER="" CA="https://acme-staging.api.letsencrypt.org" CA_CERT_LOCATION="" CHALLENGE_CHECK_TYPE="http" CHECK_ALL_AUTH_DNS="false" +CHECK_CERT_TIMEOUT="4" CHECK_REMOTE="true" CHECK_REMOTE_WAIT=0 CODE_LOCATION="https://raw.githubusercontent.com/srvrco/getssl/master/getssl" CSR_SUBJECT="/" DEACTIVATE_AUTH="false" DEFAULT_REVOKE_CA="https://acme-v01.api.letsencrypt.org" +DNS_CHECK_FUNC="" +DNS_CHECK_OPTIONS="" DNS_EXTRA_WAIT="" DNS_WAIT=10 DOMAIN_KEY_LENGTH=4096 @@ -212,7 +216,7 @@ IGNORE_DIRECTORY_DOMAIN="false" ORIG_UMASK=$(umask) PREVIOUSLY_VALIDATED="true" PRIVATE_KEY_ALG="rsa" -PUBLIC_DNS_SERVER="" +export PUBLIC_DNS_SERVER="" RELOAD_CMD="" RENEW_ALLOW="30" REUSE_PRIVATE_KEY="true" @@ -389,14 +393,14 @@ check_config() { # check the config files for all obvious errors config_errors=true fi # check domain exist - if [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then + if [[ "$DNS_CHECK_FUNC" =~ ^drill ]] || [[ "$DNS_CHECK_FUNC" =~ ^dig ]]; then if [[ "$($DNS_CHECK_FUNC "${d}" SOA|grep -c "^${d}")" -ge 1 ]]; then debug "found IP for ${d}" else info "${DOMAIN}: DNS lookup failed for ${d}" config_errors=true fi - elif [[ "$DNS_CHECK_FUNC" == "host" ]]; then + elif [[ "$DNS_CHECK_FUNC" =~ ^host ]]; then if [[ "$($DNS_CHECK_FUNC "${d}" |grep -c "^${d}")" -ge 1 ]]; then debug "found IP for ${d}" else @@ -716,20 +720,19 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n primary_ns="$all_auth_dns_servers" return fi - - if [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then + if [[ "$DNS_CHECK_FUNC" =~ ^drill ]] || [[ "$DNS_CHECK_FUNC" =~ ^dig ]]; then if [[ -z "$gad_s" ]]; then #checking for CNAMEs - res=$($DNS_CHECK_FUNC CNAME "$gad_d"| grep "^$gad_d") + res=$($DNS_CHECK_FUNC "$gad_d" CNAME| grep "^$gad_d") else - res=$($DNS_CHECK_FUNC CNAME "$gad_d" "@$gad_s"| grep "^$gad_d") + res=$($DNS_CHECK_FUNC "$gad_d" CNAME "@$gad_s"| grep "^$gad_d") fi if [[ ! -z "$res" ]]; then # domain is a CNAME so get main domain gad_d=$(echo "$res"| awk '{print $5}' |sed 's/\.$//g') fi if [[ -z "$gad_s" ]]; then #checking for CNAMEs - res=$($DNS_CHECK_FUNC NS "$gad_d"| grep "^$gad_d") + res=$($DNS_CHECK_FUNC "$gad_d" NS| grep "^$gad_d") else - res=$($DNS_CHECK_FUNC NS "$gad_d" "@$gad_s"| grep "^$gad_d") + res=$($DNS_CHECK_FUNC "$gad_d" NS "@$gad_s"| grep "^$gad_d") fi if [[ -z "$res" ]]; then error_exit "couldn't find primary DNS server - please set AUTH_DNS_SERVER in config" @@ -744,7 +747,7 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n return fi - if [[ "$DNS_CHECK_FUNC" == "host" ]]; then + if [[ "$DNS_CHECK_FUNC" =~ ^host ]]; then if [[ -z "$gad_s" ]]; then res=$($DNS_CHECK_FUNC -t NS "$gad_d"| grep "name server") else @@ -1178,6 +1181,7 @@ send_signed_request() { # Sends a request to the ACME server, signed with your p response=$($CURL -X POST --data "$body" "$url") fi + touch "$CURL_HEADER" responseHeaders=$(cat "$CURL_HEADER") debug responseHeaders "$responseHeaders" debug response "$response" @@ -1325,6 +1329,21 @@ write_domain_template() { # write out a template file for a domain. # an update to confirm correct certificate is running (if CHECK_REMOTE) is set to true #SERVER_TYPE="https" #CHECK_REMOTE="true" + + # Unusual configurations (especially split views) may require these. + # If these (or any variable) apply to all your domains, put them in + # the per-domain getssl.cfg. + # + # If you must use an external DNS Server (e.g. due to split views) + # Specify it here. Otherwise, the default is to find the zone master. + # The default will usually work. + # PUBLIC_DNS_SERVER="8.8.8.8" + + # If getssl is unable to determine the authoritative nameserver for a domain + # it will as you to enter AUTH_DNS_SERVER. This is the primary server that + # getssl will use to check for the acme tokens. It must be visible externally + # as well as internally. It need not be "authoritiative" in the RFC1035 sense. + # AUTH_DNS_SERVER="8.8.8.8" _EOF_domain_ } @@ -1364,6 +1383,19 @@ write_getssl_template() { # write out the main template file #VALIDATE_VIA_DNS="true" #DNS_ADD_COMMAND= #DNS_DEL_COMMAND= + + # Unusual configurations (especially split views) may require these. + # If you have a mixture, these can go in the per-domain getssl.cfg. + # + # If you must use an external DNS Server (e.g. due to split views) + # Specify it here. Otherwise, the default is to find the zone master. + # The default will usually work. + # PUBLIC_DNS_SERVER="8.8.8.8" + + # If getssl is unable to determine the authoritative nameserver for a domain + # it will as you to enter AUTH_DNS_SERVER. This is a server that + # can answer queries for the zone - a master or a slave, not a recursive server. + # AUTH_DNS_SERVER="10.0.0.14" _EOF_getssl_ } @@ -1446,7 +1478,6 @@ get_os requires which requires openssl requires curl -requires nslookup drill dig host DNS_CHECK_FUNC requires awk requires tr requires date @@ -1497,6 +1528,12 @@ if [[ -s "$WORKING_DIR/getssl.cfg" ]]; then . "$WORKING_DIR/getssl.cfg" fi +if [[ -n "$DNS_CHECK_FUNC" ]]; then + requires "${DNS_CHECK_FUNC}" +else + requires nslookup drill dig host DNS_CHECK_FUNC +fi + # Define defaults for variables not set in the main config. ACCOUNT_KEY="${ACCOUNT_KEY:=$WORKING_DIR/account.key}" DOMAIN_STORAGE="${DOMAIN_STORAGE:=$WORKING_DIR}" @@ -1569,11 +1606,17 @@ if [[ ${_CREATE_CONFIG} -eq 1 ]]; then if [[ -s "$DOMAIN_DIR/getssl.cfg" ]]; then info "domain config already exists $DOMAIN_DIR/getssl.cfg" else - info "creating domain config file in $DOMAIN_DIR/getssl.cfg" - # if domain has an existing cert, copy from domain and use to create defaults. - EX_CERT=$(echo \ - | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:443" 2>/dev/null \ - | openssl x509 2>/dev/null) + info "Contacting ${DOMAIN} to inspect current certificate" + EX_CERT=$( { + if [[ "${BASH_VERSINFO[0]}${BASH_VERSINFO[1]}" -ge 43 ]]; then + openssl s_client -servername "$DOMAIN" -connect "$DOMAIN":443 /dev/null & PID=$! + sleep ${CHECK_CERT_TIMEOUT} & PIDW=$! + wait -n # Requires bash 4.3+ + kill -9 "$PID" "$PIDW" 2>/dev/null + else + openssl s_client -servername "$DOMAIN" -connect "$DOMAIN":443 /dev/null + fi + } | openssl x509 2>/dev/null) EX_SANS="www.${DOMAIN}" if [[ ! -z "${EX_CERT}" ]]; then EX_SANS=$(echo "$EX_CERT" \ @@ -1582,6 +1625,7 @@ if [[ ${_CREATE_CONFIG} -eq 1 ]]; then EX_SANS=${EX_SANS//$'\n'/','} fi write_domain_template "$DOMAIN_DIR/getssl.cfg" + info "created domain config file in $DOMAIN_DIR/getssl.cfg" fi TEMP_DIR="$DOMAIN_DIR/tmp" # end of "-c|--create" option, so exit @@ -1609,6 +1653,11 @@ if [[ -s "$DOMAIN_DIR/getssl.cfg" ]]; then . "$DOMAIN_DIR/getssl.cfg" fi +# In case special options are needed for DNS_CHECK_FUNC, add them +# to the command. E.G. if a TSIG key or bound local IP is required... + +DNS_CHECK_FUNC="${DNS_CHECK_FUNC} ${DNS_CHECK_OPTIONS}" + # from SERVER_TYPE set REMOTE_PORT and REMOTE_EXTRA set_server_type @@ -1629,11 +1678,19 @@ URL_new_cert=$(echo "$ca_all_loc" | grep "new-cert" | awk -F'"' '{print $4}') # if check_remote is true then connect and obtain the current certificate (if not forcing renewal) if [[ "${CHECK_REMOTE}" == "true" ]] && [[ $_FORCE_RENEW -eq 0 ]]; then - debug "getting certificate for $DOMAIN from remote server" + info "Contacting $DOMAIN on port ${REMOTE_PORT} to inspect current certificate" # shellcheck disable=SC2086 - EX_CERT=$(echo \ - | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} 2>/dev/null \ - | openssl x509 2>/dev/null) + EX_CERT=$( { + if [[ "${BASH_VERSINFO[0]}${BASH_VERSINFO[1]}" -ge 43 ]]; then + echo | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} 2>/dev/null & PID=$! + sleep ${CHECK_CERT_TIMEOUT} & PIDW=$! + wait -n # Requires bash 4.3+ + kill -9 "$PID" "$PIDW" 2>/dev/null + else + echo | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} 2>/dev/null + fi + } | openssl x509 2>/dev/null ) + if [[ ! -z "$EX_CERT" ]]; then # if obtained a cert if [[ -s "$CERT_FILE" ]]; then # if local exists CERT_LOCAL=$(openssl x509 -noout -fingerprint < "$CERT_FILE" 2>/dev/null) @@ -1980,10 +2037,10 @@ if [[ $VALIDATE_VIA_DNS == "true" ]]; then check_result=$(nslookup -type=txt "_acme-challenge.${d}" "${ns}" \ | grep ^_acme -A2\ | grep '"'|awk -F'"' '{ print $2}') - elif [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then - check_result=$($DNS_CHECK_FUNC TXT "_acme-challenge.${d}" "@${ns}" \ + elif [[ "$DNS_CHECK_FUNC" =~ ^drill ]] || [[ "$DNS_CHECK_FUNC" =~ ^dig ]]; then + check_result=$($DNS_CHECK_FUNC "_acme-challenge.${d}" TXT "@${ns}" \ | grep ^_acme|awk -F'"' '{ print $2}') - elif [[ "$DNS_CHECK_FUNC" == "host" ]]; then + elif [[ "$DNS_CHECK_FUNC" =~ ^host ]]; then check_result=$($DNS_CHECK_FUNC -t TXT "_acme-challenge.${d}" "${ns}" \ | grep ^_acme|awk -F'"' '{ print $2}') else From 676e2cc72d499a1243371ca93872b4600db92b3d Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Thu, 18 May 2017 23:31:20 -0400 Subject: [PATCH 11/18] Correct timestamp in protocol debug. Inadvertently duplicated seconds & truncated fraction. --- dns_scripts/dns_godaddy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dns_scripts/dns_godaddy b/dns_scripts/dns_godaddy index 5e9aa0be..4443bd41 100755 --- a/dns_scripts/dns_godaddy +++ b/dns_scripts/dns_godaddy @@ -187,7 +187,7 @@ fi authhdr="Authorization: sso-key $GODADDY_KEY:$GODADDY_SECRET" if [ -n "$TRACE" ]; then - function timestamp { local tm="`date '+%T:%S%N'`" + function timestamp { local tm="`LC_TIME=C date '+%T.%N'`" local class="$1"; shift echo "${tm:0:15} ** ${class}: $*" >>"$TRACE" } From 1c7c0276488990d5464e4a218ce39450adbfe15e Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Sat, 5 Aug 2017 10:02:47 -0400 Subject: [PATCH 12/18] When combining .key files with certs, set umask to 077 to protect key --- getssl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/getssl b/getssl index da7f3860..e869b862 100755 --- a/getssl +++ b/getssl @@ -1736,11 +1736,15 @@ if [[ "${CHECK_REMOTE}" == "true" ]] && [[ $_FORCE_RENEW -eq 0 ]]; then copy_file_to_location "full pem" \ "$TEMP_DIR/${DOMAIN}_chain.pem" \ "$DOMAIN_CHAIN_LOCATION" + umask 077 cat "$DOMAIN_DIR/${DOMAIN}.key" "$CERT_FILE" > "$TEMP_DIR/${DOMAIN}_K_C.pem" + umask "$ORIG_UMASK" copy_file_to_location "private key and domain cert pem" \ "$TEMP_DIR/${DOMAIN}_K_C.pem" \ "$DOMAIN_KEY_CERT_LOCATION" + umask 077 cat "$DOMAIN_DIR/${DOMAIN}.key" "$CERT_FILE" "$CA_CERT" > "$TEMP_DIR/${DOMAIN}.pem" + umask "$ORIG_UMASK" copy_file_to_location "full pem" \ "$TEMP_DIR/${DOMAIN}.pem" \ "$DOMAIN_PEM_LOCATION" @@ -2154,12 +2158,14 @@ if [[ ! -z "$DOMAIN_KEY_CERT_LOCATION" ]]; then else to_location="${DOMAIN_KEY_CERT_LOCATION}" fi + umask 077 cat "$DOMAIN_DIR/${DOMAIN}.key" "$CERT_FILE" > "$TEMP_DIR/${DOMAIN}_K_C.pem" copy_file_to_location "private key and domain cert pem" "$TEMP_DIR/${DOMAIN}_K_C.pem" "$to_location" if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then cat "$DOMAIN_DIR/${DOMAIN}.ec.key" "${CERT_FILE::-4}.ec.crt" > "$TEMP_DIR/${DOMAIN}_K_C.pem.ec" copy_file_to_location "private ec key and domain cert pem" "$TEMP_DIR/${DOMAIN}_K_C.pem.ec" "${to_location}.ec" fi + umask "$ORIG_UMASK" fi # if DOMAIN_PEM_LOCATION is not blank, then create and copy file. if [[ ! -z "$DOMAIN_PEM_LOCATION" ]]; then @@ -2168,12 +2174,14 @@ if [[ ! -z "$DOMAIN_PEM_LOCATION" ]]; then else to_location="${DOMAIN_PEM_LOCATION}" fi + umask 077 cat "$DOMAIN_DIR/${DOMAIN}.key" "$CERT_FILE" "$CA_CERT" > "$TEMP_DIR/${DOMAIN}.pem" copy_file_to_location "full key, cert and chain pem" "$TEMP_DIR/${DOMAIN}.pem" "$to_location" if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then cat "$DOMAIN_DIR/${DOMAIN}.ec.key" "${CERT_FILE::-4}.ec.crt" "${CA_CERT::-4}.ec.crt" > "$TEMP_DIR/${DOMAIN}.pem.ec" copy_file_to_location "full ec key, cert and chain pem" "$TEMP_DIR/${DOMAIN}.pem.ec" "${to_location}.ec" fi + umask "$ORIG_UMASK" fi # end of copying certs. From b57cad33451889edcdba78aa41a4ee31a03b33ea Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Mon, 14 May 2018 06:41:29 -0400 Subject: [PATCH 13/18] GoDaddy API change requires JSON array to add TXT records The GoDaddy API now strictly requires any array when adding a single TXT record. --- dns_scripts/dns_godaddy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dns_scripts/dns_godaddy b/dns_scripts/dns_godaddy index 4443bd41..9ebe6ddc 100755 --- a/dns_scripts/dns_godaddy +++ b/dns_scripts/dns_godaddy @@ -1,8 +1,8 @@ #!/bin/bash -# Copyright (2017) Timothe Litt litt at acm _dot org +# Copyright (C) 2017,2018) Timothe Litt litt at acm _dot org -VERSION="1.0.1" +VERSION="1.0.2" PROG="`basename $0`" # This script is used to update TXT records in GoDaddy DNS server @@ -209,7 +209,7 @@ if [ "$op" = "add" ]; then url="$API/$domain/records/TXT/$name" - request='{"data":"'$data'","ttl":'$ttl'}' + request='[{"data":"'$data'","ttl":'$ttl'}]' [ -n "$DEBUG" ] && cat >&2 < Date: Wed, 16 May 2018 10:44:16 -0400 Subject: [PATCH 14/18] More GoDaddy API changes PUT now requires a relative domain name. GET changed the order of name and data in the JSON. Note: Due to the API changes, you may need to add GODADDY_BASE to getssl.cfg. This is a space-separated list of base domain names (zones) in which the challenge responses are entered. There doesn't seem to be a way around this that works in all cases, as the GoDaddy API requires that the zone name be known. --- dns_scripts/00GoDaddy-README.txt | 5 ++++- dns_scripts/dns_add_godaddy | 3 ++- dns_scripts/dns_del_godaddy | 3 ++- dns_scripts/dns_godaddy | 36 ++++++++++++++++++++++++++------ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/dns_scripts/00GoDaddy-README.txt b/dns_scripts/00GoDaddy-README.txt index d58ba737..9973556e 100644 --- a/dns_scripts/00GoDaddy-README.txt +++ b/dns_scripts/00GoDaddy-README.txt @@ -34,6 +34,9 @@ With those in hand, the installation procedure is: DNS_DEL_COMMAND="/usr/share/getssl/dns_scripts/dns_del_godaddy" # The API key for your account/this domain export GODADDY_KEY="..." GODADDY_SECRET="..." + # The base domain name(s) in which the challege records are stored + # E.g. if www.example.net is in the example.net zone: + export GODADDY_BASE="example.com example.net" 4) Set any other options that you wish (per the standard directions.) Use the test CA to make sure that @@ -47,7 +50,7 @@ GODADDY_TRACE=Y getssl example.net There are additional options, which are documented in the *godaddy" files and dns_godaddy -h. -Copyright (2017) Timothe Litt litt at acm _dot org +Copyright (C) 2017, 2018 Timothe Litt litt at acm _dot org This sofware may be freely used providing this notice is included with all copies. The name of the author may not be used to endorse diff --git a/dns_scripts/dns_add_godaddy b/dns_scripts/dns_add_godaddy index f7a871c6..fc08f097 100755 --- a/dns_scripts/dns_add_godaddy +++ b/dns_scripts/dns_add_godaddy @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (2017) Timothe Litt litt at acm _dot org +# Copyright (C) 2017, 2018 Timothe Litt litt at acm _dot org # Add token to GoDaddy dns using dns_godaddy @@ -36,5 +36,6 @@ fi export GODADDY_KEY export GODADDY_SECRET +export GODADDY_BASE $GODADDY_SCRIPT -q add ${fulldomain} "_acme-challenge.${fulldomain}." "${token}" diff --git a/dns_scripts/dns_del_godaddy b/dns_scripts/dns_del_godaddy index 7ca0da9f..120430fa 100755 --- a/dns_scripts/dns_del_godaddy +++ b/dns_scripts/dns_del_godaddy @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (2017) Timothe Litt litt at acm _dot org +# Copyright (C) 2017,2018 Timothe Litt litt at acm _dot org # Remove token from GoDaddy dns using dns_godaddy @@ -34,5 +34,6 @@ fi export GODADDY_KEY export GODADDY_SECRET +export GODADDY_BASE $GODADDY_SCRIPT -q del ${fulldomain} "_acme-challenge.${fulldomain}." "${token}" diff --git a/dns_scripts/dns_godaddy b/dns_scripts/dns_godaddy index 9ebe6ddc..a89a8555 100755 --- a/dns_scripts/dns_godaddy +++ b/dns_scripts/dns_godaddy @@ -1,8 +1,8 @@ #!/bin/bash -# Copyright (C) 2017,2018) Timothe Litt litt at acm _dot org +# Copyright (C) 2017,2018 Timothe Litt litt at acm _dot org -VERSION="1.0.2" +VERSION="1.0.3" PROG="`basename $0`" # This script is used to update TXT records in GoDaddy DNS server @@ -31,6 +31,7 @@ DEBUG="$GODADDY_DEBUG" while getopts 'dhj:k:s:t:qv' opt; do case $opt in + b) GODADDY_BASE="$OPTARG" ;; d) DEBUG="Y" ;; j) JSON="$OPTARG" ;; k) GODADDY_KEY="$OPTARG" ;; @@ -72,6 +73,9 @@ Arguments: For minimal trace output (to override -q), define GODADDY_TRACE="y". Options + -b Domain name(s) in which challenge records are stored + E.g. often, www.example.net is stored in example.net. + Default from GODADDY_BASE -d Provide debugging output - all requests and responses -h This help. -j: Location of JSON.sh Default `dirname $0`/JSON.sh, or @@ -84,6 +88,7 @@ Options All output, except for this help text, is to stderr. Environment variables + GODADDY_BASE Domain name(s) in which challenge records are stored GODADDY_JSON location of the JSOH.sh script GODADDY_KEY default API key GODADDY_SCRIPT location of this script, default location of JSON.sh @@ -92,7 +97,7 @@ Environment variables GODADDY_TFILE appends protocol trace to file. Overrides -t BUGS - Due to a limitation of the gOdADDY API, deleting the last TXT record + Due to a limitation of the GoDaddy API, deleting the last TXT record would be too risky for my taste. So in that case, I replace it with _dummy.record_.domain. TXT "Ihis record is not used". This record is not automatically deleted by this script, though it's perfectly OK to @@ -207,7 +212,23 @@ if [ "$op" = "add" ]; then while [[ "$domain" =~ [^.]+\.[^.]+ ]]; do - url="$API/$domain/records/TXT/$name" + reqname="$name" + # The API doesn't trim the base domain from the name (it used to) + # If specified, remove any listed base. + if [ -n "$GODADDY_BASE" ]; then + for GDB in $GODADDY_BASE; do + gdb="`echo "$GDB" | sed -e's/\\.$//;s/\\./\\\\./g;'`" + gdb="^(.+)\\.$gdb\\.?$" + if [[ "$name" =~ $gdb ]]; then + reqname="${BASH_REMATCH[1]}" + break; + fi + done + else + eval 'reqname="$''{name%'"'.$domain.'}"'"' + fi + + url="$API/$domain/records/TXT/$reqname" request='[{"data":"'$data'","ttl":'$ttl'}]' [ -n "$DEBUG" ] && cat >&2 <&2 exit 1 # Intent was to change DNS, so this is an error From 6a1f4320005fd90d421664b650956ba9565e8208 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Fri, 27 Sep 2019 11:58:04 -0400 Subject: [PATCH 15/18] work-around for http2 syntax differences Newer curl uses http2 by default, results in getssl: Error registering account ... JWS has no anti-replay nonce Force http1.1 as a work-around. Also add debugging info for "error in EC signing".issue opened --- getssl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/getssl b/getssl index e869b862..14538709 100755 --- a/getssl +++ b/getssl @@ -1139,7 +1139,7 @@ send_signed_request() { # Sends a request to the ACME server, signed with your p CURL_HEADER="$TEMP_DIR/curl.header" dp="$TEMP_DIR/curl.dump" - CURL="curl --silent --dump-header $CURL_HEADER " + CURL="curl --http1.1 --silent --dump-header $CURL_HEADER " if [[ ${_USE_DEBUG} -eq 1 ]]; then CURL="$CURL --trace-ascii $dp " fi @@ -1232,7 +1232,7 @@ sign_string() { # sign a string with a given key and algorithm and return urlbas R=$(echo "$signed" | cut -c 11-142) part2=$(echo "$signed" | cut -c 143-) else - error_exit "error in EC signing couldn't get R from $signed" + error_exit "error in EC signing couldn't get R from $signed ($signalg using $key)" fi debug "R $R" From ff2a55622492bb1b73b015c011235f4132662ab5 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Sat, 8 May 2021 16:48:45 -0400 Subject: [PATCH 16/18] Update README Add --version Update default endpoint to acme-v02. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7ff8b2e3..454a3880 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ certificates to a remote server ( providing you have a ssh with key, sftp or ftp access to the remote server). ```getssl -h -getssl ver. 2.35 +getssl ver. 2.36 Obtain SSL certificates from the letsencrypt.org ACME server Usage: getssl [-h|--help] [-d|--debug] [-c|--create] [-f|--force] [-a|--all] [-q|--quiet] [-Q|--mute] [-u|--upgrade] [-k|--keep #] [-U|--nocheck] [-r|--revoke cert key] [-w working_dir] [--preferred-chain chain] domain @@ -107,6 +107,7 @@ Options: -u, --upgrade Upgrade getssl if a more recent version is available - can be used with or without domain(s) -k, --keep "#" Maximum number of old getssl versions to keep when upgrading -U, --nocheck Do not check if a more recent version is available + -v --version Display current version of getssl -w working_dir "Working directory" --preferred-chain "chain" Use an alternate chain for the certificate ``` @@ -376,7 +377,7 @@ Usage: `getssl -r path/to/cert path/to/key [CA_server]` You need to specify both the certificate you want to revoke, and the account or private domain key which was used to sign / obtain the original certificate. The `CA_server` is an optional parameter and -defaults to Let's Encrypt ("") as +defaults to Let's Encrypt ("") as that is currently the only Certificate Authority using the ACME protocol. From e315d870e4d0ca46e0a0da4ec8c7d8a6a68268b1 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Sat, 8 May 2021 17:51:11 -0400 Subject: [PATCH 17/18] Fix lint from merge --- dns_scripts/dns_add_godaddy | 2 +- dns_scripts/dns_del_godaddy | 2 +- dns_scripts/dns_godaddy | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dns_scripts/dns_add_godaddy b/dns_scripts/dns_add_godaddy index fc08f097..f9be7453 100755 --- a/dns_scripts/dns_add_godaddy +++ b/dns_scripts/dns_add_godaddy @@ -38,4 +38,4 @@ export GODADDY_KEY export GODADDY_SECRET export GODADDY_BASE -$GODADDY_SCRIPT -q add ${fulldomain} "_acme-challenge.${fulldomain}." "${token}" +$GODADDY_SCRIPT -q add "${fulldomain}" "_acme-challenge.${fulldomain}." "${token}" diff --git a/dns_scripts/dns_del_godaddy b/dns_scripts/dns_del_godaddy index 120430fa..4a3228f7 100755 --- a/dns_scripts/dns_del_godaddy +++ b/dns_scripts/dns_del_godaddy @@ -36,4 +36,4 @@ export GODADDY_KEY export GODADDY_SECRET export GODADDY_BASE -$GODADDY_SCRIPT -q del ${fulldomain} "_acme-challenge.${fulldomain}." "${token}" +$GODADDY_SCRIPT -q del "${fulldomain}" "_acme-challenge.${fulldomain}." "${token}" diff --git a/dns_scripts/dns_godaddy b/dns_scripts/dns_godaddy index a89a8555..0d41e6a1 100755 --- a/dns_scripts/dns_godaddy +++ b/dns_scripts/dns_godaddy @@ -237,6 +237,7 @@ Add request to: $url $request" -------- EOF + result="$(curl -i -s -X PUT -d "$request" --config - "$url" < Date: Sat, 8 May 2021 19:05:50 -0400 Subject: [PATCH 18/18] Fix test errors caused by DNS_CHECK_OPTIONS Use a regexp rather than a partial match to skip any DNS_CHECK_OPTIONS, which in the current tests create whitespace, but could be anything. Catch a missing inclusion of DNS_CHECK_OPTIONS for dig CNAME --- getssl | 4 ++-- test/u1-test-get_auth_dns-dig.bats | 14 +++++++------- test/u2-test-get_auth_dns-drill.bats | 14 +++++++------- test/u5-test-get_auth_dns-no-root-servers.bats | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/getssl b/getssl index 4f5fa34b..6ba65236 100755 --- a/getssl +++ b/getssl @@ -674,7 +674,7 @@ check_config() { # check the config files for all obvious errors # check domain exists using all DNS utilities. DNS_CHECK_OPTIONS may bind IP address or provide TSIG found_ip=false if [[ -n "$HAS_DIG_OR_DRILL" ]]; then - debug "DNS lookup using $HAS_DIG_OR_DRILL ${d}" + debug "DNS lookup using $HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS ${d}" if [[ "$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS -t SOA "${d}" |grep -c -i "^${d}")" -ge 1 ]]; then found_ip=true elif [[ "$($HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS -t A "${d}"|grep -c -i "^${d}")" -ge 1 ]]; then @@ -1389,7 +1389,7 @@ get_auth_dns() { # get the authoritative dns server for a domain (sets primary_n fi # Check if domain is a CNAME, first - test_output "Using $HAS_DIG_OR_DRILL CNAME" + test_output "Using $HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS CNAME" # Two options here; either dig CNAME will return the CNAME and the NS or just the CNAME debug Checking for CNAME using "$HAS_DIG_OR_DRILL $DNS_CHECK_OPTIONS CNAME $gad_d $gad_s" diff --git a/test/u1-test-get_auth_dns-dig.bats b/test/u1-test-get_auth_dns-dig.bats index 6e64e68d..471732fb 100644 --- a/test/u1-test-get_auth_dns-dig.bats +++ b/test/u1-test-get_auth_dns-dig.bats @@ -61,7 +61,7 @@ teardown() { # Assert that we've found the primary_ns server assert_output --regexp 'set primary_ns = ns[1-4]+\.duckdns\.org' # Assert that we had to use dig NS - assert_line --partial 'Using dig NS' + assert_line --regexp 'Using dig.* NS' # Check all Authoritive DNS servers are returned if requested CHECK_ALL_AUTH_DNS=true @@ -89,8 +89,8 @@ teardown() { assert_output --regexp 'set primary_ns = ns[1-4]+\.duckdns\.org' # Assert that we had to use dig NS - assert_line --partial 'Using dig SOA' - refute_line --partial 'Using dig NS' + assert_line --regexp 'Using dig.* SOA' + refute_line --regexp 'Using dig.* NS' # Check all Authoritive DNS servers are returned if requested CHECK_ALL_AUTH_DNS=true @@ -125,8 +125,8 @@ teardown() { assert_output --regexp 'set primary_ns = ns.*\.awsdns.*\.com' # Assert that we found a CNAME and use dig NS - assert_line --partial 'Using dig CNAME' - assert_line --partial 'Using dig NS' + assert_line --regexp 'Using dig.* CNAME' + assert_line --regexp 'Using dig.* NS' # Check all Authoritive DNS servers are returned if requested CHECK_ALL_AUTH_DNS=true @@ -168,8 +168,8 @@ teardown() { assert_output --regexp 'set primary_ns = ns[1-4]+\.duckdns\.org' # Assert that we found a CNAME but didn't use dig NS - assert_line --partial 'Using dig CNAME' - refute_line --partial 'Using dig NS' + assert_line --regexp 'Using dig.* CNAME' + refute_line --regexp 'Using dig.* NS' # Check all Authoritive DNS servers are returned if requested CHECK_ALL_AUTH_DNS=true diff --git a/test/u2-test-get_auth_dns-drill.bats b/test/u2-test-get_auth_dns-drill.bats index 33b22778..434a9b5e 100644 --- a/test/u2-test-get_auth_dns-drill.bats +++ b/test/u2-test-get_auth_dns-drill.bats @@ -67,7 +67,7 @@ teardown() { # Assert that we've found the primary_ns server assert_output --regexp 'set primary_ns = ns[1-4]+\.duckdns\.org' # Assert that we had to use drill NS - assert_line --partial 'Using drill NS' + assert_line --regexp 'Using drill.* NS' # Check all Authoritive DNS servers are returned if requested CHECK_ALL_AUTH_DNS=true @@ -100,8 +100,8 @@ teardown() { assert_output --regexp 'set primary_ns = ns[1-4]+\.duckdns\.org' # Assert that we had to use drill NS - assert_line --partial 'Using drill SOA' - refute_line --partial 'Using drill NS' + assert_line --regexp 'Using drill.* SOA' + refute_line --regexp 'Using drill.* NS' # Check all Authoritive DNS servers are returned if requested CHECK_ALL_AUTH_DNS=true @@ -141,8 +141,8 @@ teardown() { assert_output --regexp 'set primary_ns = ns.*\.awsdns.*\.com' # Assert that we found a CNAME and use drill NS - assert_line --partial 'Using drill CNAME' - assert_line --partial 'Using drill NS' + assert_line --regexp 'Using drill.* CNAME' + assert_line --regexp 'Using drill.* NS' # Check all Authoritive DNS servers are returned if requested CHECK_ALL_AUTH_DNS=true @@ -192,8 +192,8 @@ teardown() { assert_output --regexp 'set primary_ns = ns[1-4]+\.duckdns\.org' # Assert that we found a CNAME but didn't use drill NS - assert_line --partial 'Using drill CNAME' - refute_line --partial 'Using drill NS' + assert_line --regexp 'Using drill.* CNAME' + refute_line --regexp 'Using drill.* NS' # Check all Authoritive DNS servers are returned if requested CHECK_ALL_AUTH_DNS=true diff --git a/test/u5-test-get_auth_dns-no-root-servers.bats b/test/u5-test-get_auth_dns-no-root-servers.bats index b88fd413..d218eb90 100644 --- a/test/u5-test-get_auth_dns-no-root-servers.bats +++ b/test/u5-test-get_auth_dns-no-root-servers.bats @@ -60,7 +60,7 @@ teardown() { # Assert that we've found the primary_ns server assert_output --regexp 'set primary_ns = ' # Assert that we had to use dig NS - assert_line --partial 'Using dig NS' + assert_line --regexp 'Using dig.* NS' # Check we didn't include any root servers refute_line --partial 'root-servers.net' @@ -89,7 +89,7 @@ teardown() { # Assert that we've found the primary_ns server assert_output --regexp 'set primary_ns = ' # Assert that we had to use dig SOA - assert_line --partial 'Using dig SOA' + assert_line --regexp 'Using dig.* SOA' # Check we didn't include any root servers refute_line --partial 'root-servers.net'