From 2c83224f07ff1a29cbf1ea88cbf09aac1ccd36ac Mon Sep 17 00:00:00 2001 From: Martin Donlon Date: Sun, 11 Feb 2018 07:37:15 -0800 Subject: [PATCH 1/7] Fixup dns_dreamhost travis failures --- README.md | 1 + dnsapi/README.md | 14 +++++- dnsapi/dns_dreamhost.sh | 97 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 dnsapi/dns_dreamhost.sh diff --git a/README.md b/README.md index c66b7f6..e7b62f7 100644 --- a/README.md +++ b/README.md @@ -302,6 +302,7 @@ You don't have to do anything manually! 1. Dynu API (https://www.dynu.com) 1. DNSimple API 1. NS1.com API +1. DreamHost.com API 1. DuckDNS.org API 1. Name.com API 1. Dyn Managed DNS API diff --git a/dnsapi/README.md b/dnsapi/README.md index 32eca13..aef528e 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -512,7 +512,7 @@ acme.sh --issue --dns dns_nsone -d example.com -d www.example.com export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" ``` -Please note that since DuckDNS uses StartSSL as their cert provider, thus +Please note that since DuckDNS uses StartSSL as their cert provider, thus --insecure may need to be used when issuing certs: ``` acme.sh --insecure --issue --dns dns_duckdns -d mydomain.duckdns.org @@ -719,6 +719,18 @@ acme.sh --issue --dns dns_selectel -d example.com -d www.example.com The `SL_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 39. Use DreamHost DNS API + +DNS API keys may be created at https://panel.dreamhost.com/?tree=home.api. +Ensure the created key has add and remove privelages. + +``` +export DH_API_Key="" +acme.sh --issue --dns dns_dreamhost -d example.com -d www.example.com +``` + +The 'DH_API_KEY' will be saved in `~/.acme.sh/account.conf` and will +be reused when needed. # Use custom API diff --git a/dnsapi/dns_dreamhost.sh b/dnsapi/dns_dreamhost.sh new file mode 100644 index 0000000..35b3444 --- /dev/null +++ b/dnsapi/dns_dreamhost.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env sh + +#Author: RhinoLance +#Report Bugs here: https://github.com/RhinoLance/acme.sh +# + +#define the api endpoint +DH_API_ENDPOINT="https://api.dreamhost.com/" +querystring="" + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_dreamhost_add() { + fulldomain=$1 + txtvalue=$2 + + if ! validate "$fulldomain" "$txtvalue"; then + return 1 + fi + + querystring="key=$DH_API_KEY&cmd=dns-add_record&record=$fulldomain&type=TXT&value=$txtvalue" + if ! submit "$querystring"; then + return 1 + fi + + return 0 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_dreamhost_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! validate "$fulldomain" "$txtvalue"; then + return 1 + fi + + querystring="key=$DH_API_KEY&cmd=dns-remove_record&record=$fulldomain&type=TXT&value=$txtvalue" + if ! submit "$querystring"; then + return 1 + fi + + return 0 +} + +#################### Private functions below ################################## + +#send the command to the api endpoint. +submit() { + querystring=$1 + + url="$DH_API_ENDPOINT?$querystring" + + _debug url "$url" + + if ! response="$(_get "$url")"; then + _err "Error <$1>" + return 1 + fi + + if [ -z "$2" ]; then + message="$(printf "%s" "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" + if [ -n "$message" ]; then + _err "$message" + return 1 + fi + fi + + _debug response "$response" + + return 0 +} + +#check that we have a valid API Key +validate() { + fulldomain=$1 + txtvalue=$2 + + _info "Using dreamhost" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + #retrieve the API key from the environment variable if it exists, otherwise look for a saved key. + DH_API_KEY="${DH_API_KEY:-$(_readaccountconf_mutable DH_API_KEY)}" + + if [ -z "$DH_API_KEY" ]; then + DH_API_KEY="" + _err "You didn't specify the DreamHost api key yet (export DH_API_KEY=\"\")" + _err "Please login to your control panel, create a key and try again." + return 1 + fi + + #save the api key to the account conf file. + _saveaccountconf_mutable DH_API_KEY "$DH_API_KEY" +} From 84649e9d20603e402462b09fd1481371cd1b5ebc Mon Sep 17 00:00:00 2001 From: Martin Donlon Date: Tue, 13 Feb 2018 21:02:38 -0800 Subject: [PATCH 2/7] Addressing PR feedback Replace printf with echo Move dreamhost to bottom of DNS API list --- README.md | 2 +- dnsapi/dns_dreamhost.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f6c73ba..5e3709a 100644 --- a/README.md +++ b/README.md @@ -302,7 +302,6 @@ You don't have to do anything manually! 1. Dynu API (https://www.dynu.com) 1. DNSimple API 1. NS1.com API -1. DreamHost.com API 1. DuckDNS.org API 1. Name.com API 1. Dyn Managed DNS API @@ -316,6 +315,7 @@ You don't have to do anything manually! 1. Azure DNS 1. selectel.com(selectel.ru) DNS API 1. zonomi.com DNS API +1. DreamHost.com API And: 1. lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api diff --git a/dnsapi/dns_dreamhost.sh b/dnsapi/dns_dreamhost.sh index 35b3444..a401793 100644 --- a/dnsapi/dns_dreamhost.sh +++ b/dnsapi/dns_dreamhost.sh @@ -61,7 +61,7 @@ submit() { fi if [ -z "$2" ]; then - message="$(printf "%s" "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" + message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" if [ -n "$message" ]; then _err "$message" return 1 From b51ed9bbb74356fa54e83b86204232499ccb5edd Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 15 Feb 2018 10:29:03 +0800 Subject: [PATCH 3/7] https://github.com/Neilpang/acme.sh/issues/1251 --- acme.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/acme.sh b/acme.sh index b9e57a7..8cd9c59 100755 --- a/acme.sh +++ b/acme.sh @@ -3598,6 +3598,10 @@ $_authorizations_map" _debug entry "$entry" if [ -z "$entry" ]; then _err "Error, can not get domain token entry $d" + _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" + if [ "$_supported_vtypes" ]; then + _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" + fi _clearup _on_issue_err "$_post_hook" return 1 From ce6c7d4b594ccc0ecc253c459ffa8020fb1ec447 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 15 Feb 2018 10:51:13 +0800 Subject: [PATCH 4/7] fix dp --- dnsapi/dns_dp.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index bf623e2..3cc720a 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -93,12 +93,7 @@ add_record() { return 1 fi - if _contains "$response" "Action completed successful"; then - - return 0 - fi - - return 1 #error + _contains "$response" "Action completed successful" || _contains "$response" "Domain record already exists" } #################### Private functions below ################################## From 0096ef4ddb5e6b86c512a6a4a57afc62ba725701 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 15 Feb 2018 12:26:35 +0800 Subject: [PATCH 5/7] fix ali --- dnsapi/dns_ali.sh | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index f796f07..543a0a5 100755 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -10,6 +10,8 @@ dns_ali_add() { fulldomain=$1 txtvalue=$2 + Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" + Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then Ali_Key="" Ali_Secret="" @@ -18,8 +20,8 @@ dns_ali_add() { fi #save the api key and secret to the account conf file. - _saveaccountconf Ali_Key "$Ali_Key" - _saveaccountconf Ali_Secret "$Ali_Secret" + _saveaccountconf_mutable Ali_Key "$Ali_Key" + _saveaccountconf_mutable Ali_Secret "$Ali_Secret" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -32,6 +34,15 @@ dns_ali_add() { dns_ali_rm() { fulldomain=$1 + txtvalue=$2 + Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" + Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + return 1 + fi + _clean } @@ -76,16 +87,14 @@ _ali_rest() { return 1 fi + _debug2 response "$response" if [ -z "$2" ]; then - message="$(printf "%s" "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" - if [ -n "$message" ]; then + message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" + if [ "$message" ]; then _err "$message" return 1 fi fi - - _debug2 response "$response" - return 0 } _ali_urlencode() { @@ -112,12 +121,14 @@ _ali_nonce() { } _check_exist_query() { + _qdomain="$1" + _qsubdomain="$2" query='' query=$query'AccessKeyId='$Ali_Key query=$query'&Action=DescribeDomainRecords' - query=$query'&DomainName='$1 + query=$query'&DomainName='$_qdomain query=$query'&Format=json' - query=$query'&RRKeyWord=_acme-challenge' + query=$query'&RRKeyWord='$_qsubdomain query=$query'&SignatureMethod=HMAC-SHA1' query=$query"&SignatureNonce=$(_ali_nonce)" query=$query'&SignatureVersion=1.0' @@ -169,17 +180,21 @@ _describe_records_query() { } _clean() { - _check_exist_query "$_domain" + _check_exist_query "$_domain" "$_sub_domain" if ! _ali_rest "Check exist records" "ignore"; then return 1 fi - records="$(echo "$response" -n | _egrep_o "\"RecordId\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" - printf "%s" "$records" \ - | while read -r record_id; do - _delete_record_query "$record_id" - _ali_rest "Delete record $record_id" "ignore" - done + record_id="$(echo "$response" | tr '{' "\n" | grep "$_sub_domain" | grep "$txtvalue" | tr "," "\n" | grep RecordId | cut -d '"' -f 4)" + _debug2 record_id "$record_id" + + if [ -z "$record_id" ]; then + _debug "record not found, skip" + else + _delete_record_query "$record_id" + _ali_rest "Delete record $record_id" "ignore" + fi + } _timestamp() { From f213215c81c2b3df4ea18cdc0ac86e757099c050 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 15 Feb 2018 12:38:45 +0800 Subject: [PATCH 6/7] fix lua --- dnsapi/dns_lua.sh | 50 +++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 00c5443..be678b9 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -17,6 +17,8 @@ dns_lua_add() { fulldomain=$1 txtvalue=$2 + LUA_Key="${LUA_Key:-$(_readaccountconf_mutable LUA_Key)}" + LUA_Email="${LUA_Email:-$(_readaccountconf_mutable LUA_Email)}" if [ -z "$LUA_Key" ] || [ -z "$LUA_Email" ]; then LUA_Key="" LUA_Email="" @@ -26,8 +28,8 @@ dns_lua_add() { fi #save the api key and email to the account conf file. - _saveaccountconf LUA_Key "$LUA_Key" - _saveaccountconf LUA_Email "$LUA_Email" + _saveaccountconf_mutable LUA_Key "$LUA_Key" + _saveaccountconf_mutable LUA_Email "$LUA_Email" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -38,50 +40,26 @@ dns_lua_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _debug "Getting txt records" - _LUA_rest GET "zones/${_domain_id}/records" - - if ! _contains "$response" "\"id\":"; then - _err "Error" - return 1 - fi - - count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | wc -l | tr -d " ") - _debug count "$count" - if [ "$count" = "0" ]; then - _info "Adding record" - if _LUA_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"ttl\":120}"; then - if _contains "$response" "$fulldomain"; then - _info "Added" - #todo: check if the record takes effect - return 0 - else - _err "Add txt record error." - return 1 - fi - fi - _err "Add txt record error." - else - _info "Updating record" - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | _head_n 1 | cut -d: -f2 | cut -d, -f1) - _debug "record_id" "$record_id" - - _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":$record_id,\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":$_domain_id,\"ttl\":120}" - if [ "$?" = "0" ] && _contains "$response" "updated_at"; then - _info "Updated!" + _info "Adding record" + if _LUA_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"ttl\":120}"; then + if _contains "$response" "$fulldomain"; then + _info "Added" #todo: check if the record takes effect return 0 + else + _err "Add txt record error." + return 1 fi - _err "Update error" - return 1 fi - } #fulldomain dns_lua_rm() { fulldomain=$1 txtvalue=$2 + + LUA_Key="${LUA_Key:-$(_readaccountconf_mutable LUA_Key)}" + LUA_Email="${LUA_Email:-$(_readaccountconf_mutable LUA_Email)}" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" From abd0dad2bf500885f2fdb005b51c43f76380fcf9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 15 Feb 2018 20:35:31 +0800 Subject: [PATCH 7/7] fix https://github.com/Neilpang/acme.sh/issues/1145#issuecomment-365863118 --- dnsapi/dns_ovh.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 296a269..2669cc8 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -90,6 +90,10 @@ _initAuth() { return 1 fi + if [ "$OVH_AK" != "$(_readaccountconf OVH_AK)" ]; then + _info "It seems that your ovh key is changed, let's clear consumer key first." + _clearaccountconf OVH_CK + fi _saveaccountconf_mutable OVH_AK "$OVH_AK" _saveaccountconf_mutable OVH_AS "$OVH_AS"