From e4e6173efff2aa880eecb37509602c12eeac367e Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Fri, 28 Aug 2020 11:21:20 +0200 Subject: [PATCH 01/20] CleverReach Deploy API --- deploy/cleverreach.sh | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 deploy/cleverreach.sh diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh new file mode 100644 index 00000000..bf16ed34 --- /dev/null +++ b/deploy/cleverreach.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env sh +# Here is the script to deploy the cert to your CleverReach Account using the CleverReach REST API. +# Your OAuth needs the right scope, please contact CleverReach support for that. +# +# It requires that jq are in the $PATH. +# +# Written by Jan-Philipp Benecke +# Public domain, 2020 +# +# Following environment variables must be set: +# +#export DEPLOY_CLEVERREACH_CLIENT_ID=myid +#export DEPLOY_CLEVERREACH_CLIENT_SECRET=mysecret + +cleverreach_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + _cleverreach_client_id="${DEPLOY_CLEVERREACH_CLIENT_ID}" + _cleverreach_client_secret="${DEPLOY_CLEVERREACH_CLIENT_SECRET}" + + if [ -z "$_cleverreach_client_id" ]; then + _err "CleverReach Client ID is not found, please define DEPLOY_CLEVERREACH_CLIENT_ID." + return 1 + fi + if [ -z "$_cleverreach_client_secret" ]; then + _err "CleverReach client secret is not found, please define DEPLOY_CLEVERREACH_CLIENT_SECRET." + return 1 + fi + + _saveaccountconf DEPLOY_CLEVERREACH_CLIENT_ID "${_cleverreach_client_id}" + _saveaccountconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${_cleverreach_client_secret}" + + _info "Obtaining a CleverReach access token" + + _data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${_cleverreach_client_id}\", \"client_secret\": \"${_cleverreach_client_secret}\"}" + _auth_result="$(_post "$_data" "https://rest.cleverreach.com/oauth/token.php" "" "POST" "application/json")" + + _debug _data "$_data" + _debug _auth_result "$_auth_result" + + _access_token=$(echo "$_auth_result" | _json_decode | jq -r .access_token) + + _info "Uploading certificate and key to CleverReach" + + _certData="{\"cert\":\"$(cat $_cfullchain | _json_encode)\", \"key\":\"$(cat $_ckey | _json_encode)\"}" + export _H1="Authorization: Bearer ${_access_token}" + _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl/${_cdomain}" "" "POST" "application/json")" + + _debug "Destroying token at CleverReach" + _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" + + if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then + _info "Uploaded certificate successfully" + return 0 + else + _debug _add_cert_result "$_add_cert_result" + _err "Unable to update certificate" + return 1 + fi +} From 39a56884646f0a4038547037050cc8e14d560360 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Fri, 28 Aug 2020 11:28:06 +0200 Subject: [PATCH 02/20] Make CI happy --- deploy/cleverreach.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index bf16ed34..c22e69e1 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -52,12 +52,12 @@ cleverreach_deploy() { _info "Uploading certificate and key to CleverReach" - _certData="{\"cert\":\"$(cat $_cfullchain | _json_encode)\", \"key\":\"$(cat $_ckey | _json_encode)\"}" + _certData="{\"cert\":\"$(_json_encode < "$_cfullchain")\", \"key\":\"$(_json_encode < "$_ckey")\"}" export _H1="Authorization: Bearer ${_access_token}" _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl/${_cdomain}" "" "POST" "application/json")" _debug "Destroying token at CleverReach" - _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" + _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then _info "Uploaded certificate successfully" From 2a9c56d9e328716dd90503760a5834488a76c3a6 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Fri, 28 Aug 2020 11:30:23 +0200 Subject: [PATCH 03/20] Formatting for CI --- deploy/cleverreach.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index c22e69e1..d212846b 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -52,7 +52,7 @@ cleverreach_deploy() { _info "Uploading certificate and key to CleverReach" - _certData="{\"cert\":\"$(_json_encode < "$_cfullchain")\", \"key\":\"$(_json_encode < "$_ckey")\"}" + _certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}" export _H1="Authorization: Bearer ${_access_token}" _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl/${_cdomain}" "" "POST" "application/json")" From f7e12b629f7bdf3b5f637189fafef0af37994f98 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Thu, 1 Oct 2020 11:26:29 +0200 Subject: [PATCH 04/20] Update CleverReach REST Endpoint --- deploy/cleverreach.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index d212846b..0fa07f4a 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -54,7 +54,7 @@ cleverreach_deploy() { _certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}" export _H1="Authorization: Bearer ${_access_token}" - _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl/${_cdomain}" "" "POST" "application/json")" + _add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl" "" "POST" "application/json")" _debug "Destroying token at CleverReach" _post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" From 1db963361c4b832c048b8d85fe302d37b5d41cec Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Wed, 28 Oct 2020 13:50:40 +0100 Subject: [PATCH 05/20] Rework based on review from Neilpang --- deploy/cleverreach.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/deploy/cleverreach.sh b/deploy/cleverreach.sh index 0fa07f4a..552d8149 100644 --- a/deploy/cleverreach.sh +++ b/deploy/cleverreach.sh @@ -2,8 +2,6 @@ # Here is the script to deploy the cert to your CleverReach Account using the CleverReach REST API. # Your OAuth needs the right scope, please contact CleverReach support for that. # -# It requires that jq are in the $PATH. -# # Written by Jan-Philipp Benecke # Public domain, 2020 # @@ -25,30 +23,32 @@ cleverreach_deploy() { _debug _cca "$_cca" _debug _cfullchain "$_cfullchain" - _cleverreach_client_id="${DEPLOY_CLEVERREACH_CLIENT_ID}" - _cleverreach_client_secret="${DEPLOY_CLEVERREACH_CLIENT_SECRET}" + _getdeployconf DEPLOY_CLEVERREACH_CLIENT_ID + _getdeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET - if [ -z "$_cleverreach_client_id" ]; then + if [ -z "${DEPLOY_CLEVERREACH_CLIENT_ID}" ]; then _err "CleverReach Client ID is not found, please define DEPLOY_CLEVERREACH_CLIENT_ID." return 1 fi - if [ -z "$_cleverreach_client_secret" ]; then + if [ -z "${DEPLOY_CLEVERREACH_CLIENT_SECRET}" ]; then _err "CleverReach client secret is not found, please define DEPLOY_CLEVERREACH_CLIENT_SECRET." return 1 fi - _saveaccountconf DEPLOY_CLEVERREACH_CLIENT_ID "${_cleverreach_client_id}" - _saveaccountconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${_cleverreach_client_secret}" + _savedeployconf DEPLOY_CLEVERREACH_CLIENT_ID "${DEPLOY_CLEVERREACH_CLIENT_ID}" + _savedeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${DEPLOY_CLEVERREACH_CLIENT_SECRET}" _info "Obtaining a CleverReach access token" - _data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${_cleverreach_client_id}\", \"client_secret\": \"${_cleverreach_client_secret}\"}" + _data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${DEPLOY_CLEVERREACH_CLIENT_ID}\", \"client_secret\": \"${DEPLOY_CLEVERREACH_CLIENT_SECRET}\"}" _auth_result="$(_post "$_data" "https://rest.cleverreach.com/oauth/token.php" "" "POST" "application/json")" _debug _data "$_data" _debug _auth_result "$_auth_result" - _access_token=$(echo "$_auth_result" | _json_decode | jq -r .access_token) + _regex=".*\"access_token\":\"\([-._0-9A-Za-z]*\)\".*$" + _debug _regex "$_regex" + _access_token=$(echo "$_auth_result" | _json_decode | sed -n "s/$_regex/\1/p") _info "Uploading certificate and key to CleverReach" From a077132d825e6176add7b87f3abf66f81fe48b7f Mon Sep 17 00:00:00 2001 From: tsoybe <51762970+tsoybe@users.noreply.github.com> Date: Thu, 12 Nov 2020 22:04:05 +0100 Subject: [PATCH 06/20] Update dns_desec.sh ttl must be greater than or equal 3600, see https://desec.readthedocs.io/en/latest/dns/domains.html#domain-object --- dnsapi/dns_desec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index 61d080bd..a2e4d887 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -61,7 +61,7 @@ dns_desec_add() { fi _debug txtvalues "$txtvalues" _info "Adding record" - body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]" + body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":3600}]" if _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body"; then if _contains "$response" "$txtvalue"; then From 7dfc5a78bae3f4da640c3cb53b3eedd588c04837 Mon Sep 17 00:00:00 2001 From: tsoybe <51762970+tsoybe@users.noreply.github.com> Date: Thu, 12 Nov 2020 22:09:31 +0100 Subject: [PATCH 07/20] Update dns_desec.sh Deletion to --- dnsapi/dns_desec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index a2e4d887..f64660a8 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -130,7 +130,7 @@ dns_desec_rm() { _debug txtvalues "$txtvalues" _info "Deleting record" - body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]" + body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":3600}]" _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body" if [ "$_code" = "200" ]; then _info "Deleted, OK" From b8e5c0d8988522acbad8e0346d8a69fe024fcdd1 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sun, 22 Nov 2020 22:34:21 +0800 Subject: [PATCH 08/20] feat: Add huaweicloud intl dnsapi --- dnsapi/dns_huaweicloud.sh | 199 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 dnsapi/dns_huaweicloud.sh diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh new file mode 100644 index 00000000..69ab14be --- /dev/null +++ b/dnsapi/dns_huaweicloud.sh @@ -0,0 +1,199 @@ +#!/usr/bin/env sh + +# HUAWEICLOUD_Username +# HUAWEICLOUD_Password +# HUAWEICLOUD_ProjectID + +iam_api="https://iam.myhuaweicloud.com" +dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" + +######## Public functions ##################### + +# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Used to add txt record +# +# Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/zh-cn_topic_0132421999.html +# + +dns_huaweicloud_add() { + fulldomain=$1 + txtvalue=$2 + + HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" + HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" + HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" + _debug2 "${token}" + zoneid="$(_get_zoneid "${token}" "${fulldomain}")" + _debug "${zoneid}" + + _debug "Adding Record" + _add_record "${token}" "${fulldomain}" "${txtvalue}" + ret="$?" + if [ "${ret}" != "0" ]; then + _err "dns_huaweicloud: Error adding record." + return 1 + fi + + # Do saving work if all succeeded + _saveaccountconf_mutable HUAWEICLOUD_Username "${HUAWEICLOUD_Username}" + _saveaccountconf_mutable HUAWEICLOUD_Password "${HUAWEICLOUD_Password}" + _saveaccountconf_mutable HUAWEICLOUD_ProjectID "${HUAWEICLOUD_ProjectID}" + return 0 +} + +# Usage: fulldomain txtvalue +# Used to remove the txt record after validation +# +# Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/dns_api_64005.html +# + +dns_huaweicloud_rm() { + fulldomain=$1 + txtvalue=$2 + + HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}" + HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" + HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" + _debug2 "${token}" + zoneid="$(_get_zoneid "${token}" "${fulldomain}")" + _debug "${zoneid}" + record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" + _debug "Record Set ID is: ${record_id}" + while [ "${record_id}" != "0" ]; do + _debug "Adding Record" + _rm_record "${token}" "${zoneid}" "${record_id}" + record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" + done + return 0 +} + +################### Private functions below ################################## + +# _get_zoneid +# +# _token=$1 +# _domain_string=$2 +# +# printf "%s" "${_zoneid}" +_get_zoneid() { + _token=$1 + _domain_string=$2 + export _H1="X-Auth-Token: ${_token}" + + i=1 + while true; do + h=$(printf "%s" "${_domain_string}" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + _debug "$h" + response=$(_get "${dns_api}/v2/zones?name=${h}") + + if _contains "${response}" "id"; then + _debug "Get Zone ID Success." + _zoneid=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ") + printf "%s" "${_zoneid}" + return 0 + fi + + i=$(_math "$i" + 1) + done + return 1 +} + +_get_recordset_id() { + _token=$1 + _domain=$2 + _zoneid=$3 + export _H1="X-Auth-Token: ${_token}" + + response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}") + if _contains "${response}" "id"; then + _id="$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")" + printf "%s" "${_id}" + return 0 + fi + printf "%s" "0" + return 1 +} + +_add_record() { + _token=$1 + _domain=$2 + _txtvalue=$3 + body="{ + \"name\": \"${_domain}.\", + \"description\": \"ACME Challenge\", + \"type\": \"TXT\", + \"ttl\": 1, + \"records\": [ + \"\\\"${_txtvalue}\\\"\" + ] + }" + _debug2 "${body}" + export _H2="Content-Type: application/json" + export _H1="X-Auth-Token: ${_token}" + + _post "${body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + if [ "$_code" != "202" ]; then + _err "dns_huaweicloud: http code ${_code}" + return 1 + fi + return 0 +} + +_rm_record() { + _token=$1 + _zone_id=$2 + _record_id=$3 + + export _H2="Content-Type: application/json" + export _H1="X-Auth-Token: ${_token}" + + _post "${body}" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" + return 0 +} + +_get_token() { + _username=$1 + _password=$2 + _project=$3 + + _debug "Getting Token" + body="{ + \"auth\": { + \"identity\": { + \"methods\": [ + \"password\" + ], + \"password\": { + \"user\": { + \"name\": \"${_username}\", + \"password\": \"${_password}\", + \"domain\": { + \"name\": \"${_username}\" + } + } + } + }, + \"scope\": { + \"project\": { + \"id\": \"${_project}\" + } + } + } + }" + export _H1="Content-Type: application/json;charset=utf8" + _post "${body}" "${iam_api}/v3/auth/tokens" >/dev/null + _code=$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n") + _token=$(grep "^X-Subject-Token" "$HTTP_HEADER" | cut -d " " -f 2-) + _debug2 "${_code}" + printf "%s" "${_token}" + return 0 +} From 7db592d27a7be071033d221cb57cf33bb5ae206a Mon Sep 17 00:00:00 2001 From: Easton Man Date: Sun, 22 Nov 2020 22:56:47 +0800 Subject: [PATCH 09/20] fix: fix failing ci test --- dnsapi/dns_huaweicloud.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 69ab14be..4aee6410 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -63,6 +63,8 @@ dns_huaweicloud_rm() { _debug "${zoneid}" record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" _debug "Record Set ID is: ${record_id}" + + # Remove all records while [ "${record_id}" != "0" ]; do _debug "Adding Record" _rm_record "${token}" "${zoneid}" "${record_id}" From 28ce1c1249bc2297d3588adfa49c2974d0353c3d Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 00:20:38 +0800 Subject: [PATCH 10/20] fix: fix wrong debug output --- dnsapi/dns_huaweicloud.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 4aee6410..56ba19ef 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -66,7 +66,7 @@ dns_huaweicloud_rm() { # Remove all records while [ "${record_id}" != "0" ]; do - _debug "Adding Record" + _debug "Removing Record" _rm_record "${token}" "${zoneid}" "${record_id}" record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")" done @@ -158,7 +158,7 @@ _rm_record() { export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" - _post "${body}" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" + _post "${body}" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" >/dev/null return 0 } From e01fb503592f4c9fd4a58edfc8aa1b445396cf2e Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 00:32:50 +0800 Subject: [PATCH 11/20] feat: add env var check --- dnsapi/dns_huaweicloud.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 56ba19ef..0f08bcdf 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -57,6 +57,11 @@ dns_huaweicloud_rm() { HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ]; then + _err "Please provide enough information" + return 1 + fi + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" _debug2 "${token}" zoneid="$(_get_zoneid "${token}" "${fulldomain}")" From f6f6550bfbf19c0b3554d531787a33b20b9ddd83 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 14:25:48 +0800 Subject: [PATCH 12/20] feat: add very tricky method to adapt to non-intuitive huaweicloud api --- dnsapi/dns_huaweicloud.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 0f08bcdf..2b891b38 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -23,6 +23,11 @@ dns_huaweicloud_add() { HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ]; then + _err "Not enough info provided to dns_huaweicloud!" + return 1 + fi + token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")" _debug2 "${token}" zoneid="$(_get_zoneid "${token}" "${fulldomain}")" @@ -133,15 +138,36 @@ _add_record() { _token=$1 _domain=$2 _txtvalue=$3 + + # Get Existing Records + export _H1="X-Auth-Token: ${_token}" + response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}") + _exist_record=$(echo "${response}" | sed ':a;N;$!ba;s/\n/ /g' | grep -o '"records":[^]]*' | sed 's/\"records\"\: \[//g') + _debug "${_exist_record}" + + # Check if record exist + # Generate body data body="{ \"name\": \"${_domain}.\", \"description\": \"ACME Challenge\", \"type\": \"TXT\", \"ttl\": 1, \"records\": [ + ${_exist_record}, \"\\\"${_txtvalue}\\\"\" ] }" + if [ -z "${_exist_record}" ]; then + body="{ + \"name\": \"${_domain}.\", + \"description\": \"ACME Challenge\", + \"type\": \"TXT\", + \"ttl\": 1, + \"records\": [ + \"\\\"${_txtvalue}\\\"\" + ] + }" + fi _debug2 "${body}" export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" From 5d0657c49a0d2ac6f50981f91c6a95cfe490ae15 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 14:57:33 +0800 Subject: [PATCH 13/20] fix: fix adding record before removing --- dnsapi/dns_huaweicloud.sh | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 2b891b38..625588d1 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -141,13 +141,15 @@ _add_record() { # Get Existing Records export _H1="X-Auth-Token: ${_token}" - response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}") - _exist_record=$(echo "${response}" | sed ':a;N;$!ba;s/\n/ /g' | grep -o '"records":[^]]*' | sed 's/\"records\"\: \[//g') + response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") + + _debug "${response}" + _exist_record=$(echo "${response}" | sed ':a;N;$!ba;s/\n/ /g' | grep -o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist # Generate body data - body="{ + _post_body="{ \"name\": \"${_domain}.\", \"description\": \"ACME Challenge\", \"type\": \"TXT\", @@ -158,7 +160,7 @@ _add_record() { ] }" if [ -z "${_exist_record}" ]; then - body="{ + _post_body="{ \"name\": \"${_domain}.\", \"description\": \"ACME Challenge\", \"type\": \"TXT\", @@ -168,19 +170,38 @@ _add_record() { ] }" fi - _debug2 "${body}" + + _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" + _debug "Record Set ID is: ${_record_id}" + + # Remove all records + while [ "${_record_id}" != "0" ]; do + _debug "Removing Record" + _rm_record "${_token}" "${zoneid}" "${_record_id}" + _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" + _debug "${_record_id}" + done + + # Add brand new records with all old and new records export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" - _post "${body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null + _debug "${_post_body}" + sleep 2 + _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" if [ "$_code" != "202" ]; then _err "dns_huaweicloud: http code ${_code}" + sleep 60 return 1 fi return 0 } +# _rm_record $token $zoneid $recordid +# assume ${dns_api} exist +# no output +# return 0 _rm_record() { _token=$1 _zone_id=$2 @@ -189,8 +210,8 @@ _rm_record() { export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" - _post "${body}" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" >/dev/null - return 0 + _post "" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" >/dev/null + return $? } _get_token() { From e35ef7594993665e8f472a99e0a6d392cc80e44d Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 22:18:57 +0800 Subject: [PATCH 14/20] fix: fix solaris sed and grep issue --- dnsapi/dns_huaweicloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 625588d1..11f231bc 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -144,7 +144,7 @@ _add_record() { response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") _debug "${response}" - _exist_record=$(echo "${response}" | sed ':a;N;$!ba;s/\n/ /g' | grep -o '"records":[^]]*' | sed 's/\"records\"\:\[//g') + _exist_record=$(echo "${response}" | sed -e ':a' -e 'N;$!ba;' -e 's/\n/ /g' | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist From 83a4db3b31f7fb91c4a6c9a3fed447c92d486092 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Mon, 23 Nov 2020 23:46:06 +0800 Subject: [PATCH 15/20] fix: remove sed before grep, but lead to less robusty --- dnsapi/dns_huaweicloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 11f231bc..36be21a3 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -144,7 +144,7 @@ _add_record() { response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") _debug "${response}" - _exist_record=$(echo "${response}" | sed -e ':a' -e 'N;$!ba;' -e 's/\n/ /g' | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') + _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist From c4ddddd4344e728e3273634cb58583fe62e4022f Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 24 Nov 2020 10:05:34 +0800 Subject: [PATCH 16/20] refactor: remove dirty debug code - add tr to replace sed for robusty - add comments --- dnsapi/dns_huaweicloud.sh | 42 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index 36be21a3..a7ca619f 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -23,8 +23,9 @@ dns_huaweicloud_add() { HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" - if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ]; then - _err "Not enough info provided to dns_huaweicloud!" + # Check information + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then + _err "Not enough information provided to dns_huaweicloud!" return 1 fi @@ -62,8 +63,9 @@ dns_huaweicloud_rm() { HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}" HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}" - if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Username}" ]; then - _err "Please provide enough information" + # Check information + if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then + _err "Not enough information provided to dns_huaweicloud!" return 1 fi @@ -75,6 +77,8 @@ dns_huaweicloud_rm() { _debug "Record Set ID is: ${record_id}" # Remove all records + # Therotically HuaweiCloud does not allow more than one record set + # But remove them recurringly to increase robusty while [ "${record_id}" != "0" ]; do _debug "Removing Record" _rm_record "${token}" "${zoneid}" "${record_id}" @@ -143,22 +147,12 @@ _add_record() { export _H1="X-Auth-Token: ${_token}" response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") - _debug "${response}" - _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') + _debug2 "${response}" + _exist_record=$(echo "${response}" | tr -d "\\r\\n" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist # Generate body data - _post_body="{ - \"name\": \"${_domain}.\", - \"description\": \"ACME Challenge\", - \"type\": \"TXT\", - \"ttl\": 1, - \"records\": [ - ${_exist_record}, - \"\\\"${_txtvalue}\\\"\" - ] - }" if [ -z "${_exist_record}" ]; then _post_body="{ \"name\": \"${_domain}.\", @@ -169,6 +163,17 @@ _add_record() { \"\\\"${_txtvalue}\\\"\" ] }" + else + _post_body="{ + \"name\": \"${_domain}.\", + \"description\": \"ACME Challenge\", + \"type\": \"TXT\", + \"ttl\": 1, + \"records\": [ + ${_exist_record}, + \"\\\"${_txtvalue}\\\"\" + ] + }" fi _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" @@ -179,20 +184,17 @@ _add_record() { _debug "Removing Record" _rm_record "${_token}" "${zoneid}" "${_record_id}" _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" - _debug "${_record_id}" done # Add brand new records with all old and new records export _H2="Content-Type: application/json" export _H1="X-Auth-Token: ${_token}" - _debug "${_post_body}" - sleep 2 + _debug2 "${_post_body}" _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" if [ "$_code" != "202" ]; then _err "dns_huaweicloud: http code ${_code}" - sleep 60 return 1 fi return 0 From fd511966a75e416a1c8cd00783305228e960bc37 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Tue, 24 Nov 2020 12:58:16 +0800 Subject: [PATCH 17/20] fix: revert adding tr to replace sed --- dnsapi/dns_huaweicloud.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_huaweicloud.sh b/dnsapi/dns_huaweicloud.sh index a7ca619f..74fec2a9 100644 --- a/dnsapi/dns_huaweicloud.sh +++ b/dnsapi/dns_huaweicloud.sh @@ -148,7 +148,7 @@ _add_record() { response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") _debug2 "${response}" - _exist_record=$(echo "${response}" | tr -d "\\r\\n" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') + _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') _debug "${_exist_record}" # Check if record exist From 996f53373e490fc37e9373b1ff575f42cae5b7f0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 13 Nov 2020 19:58:21 +0800 Subject: [PATCH 18/20] fix https://github.com/acmesh-official/acme.sh/issues/3250 --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index e549f7c8..b234fb26 100755 --- a/acme.sh +++ b/acme.sh @@ -6649,8 +6649,8 @@ _checkSudo() { return 0 fi if [ -n "$SUDO_COMMAND" ]; then - #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s` - _endswith "$SUDO_COMMAND" /bin/su || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1 + #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s`, or `sudo su acmeuser1` + _endswith "$SUDO_COMMAND" /bin/su || _contains "$SUDO_COMMAND" "/bin/su " || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1 return $? fi #otherwise From ed01fd4edfd76fe96a1d38af3731f6efb46c904c Mon Sep 17 00:00:00 2001 From: Moritz H Date: Sat, 28 Nov 2020 15:22:14 +0100 Subject: [PATCH 19/20] uconv as fallback for iconv --- deploy/fritzbox.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/deploy/fritzbox.sh b/deploy/fritzbox.sh index 89b19806..2ca7ab7d 100644 --- a/deploy/fritzbox.sh +++ b/deploy/fritzbox.sh @@ -28,9 +28,11 @@ fritzbox_deploy() { _debug _cfullchain "$_cfullchain" if ! _exists iconv; then - if ! _exists perl; then - _err "iconv or perl not found" - return 1 + if ! _exists uconv; then + if ! _exists perl; then + _err "iconv or uconv or perl not found" + return 1 + fi fi fi @@ -65,6 +67,8 @@ fritzbox_deploy() { _fritzbox_challenge="$(_get "${_fritzbox_url}/login_sid.lua" | sed -e 's/^.*//' -e 's/<\/Challenge>.*$//')" if _exists iconv; then _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | _digest md5 hex)" + elif _exists uconv; then + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | uconv -f ASCII -t UTF16LE | _digest md5 hex)" else _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | _digest md5 hex)" fi From effa7fd57d2a36233f8c3f3d29bac0789a9a12b4 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 29 Nov 2020 18:39:11 +0800 Subject: [PATCH 20/20] add ACME_HTTP_NO_REDIRECTS and _resethttp to make http requests not follow redirects --- acme.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index b234fb26..dcbe3c9d 100755 --- a/acme.sh +++ b/acme.sh @@ -1722,6 +1722,14 @@ _mktemp() { _err "Can not create temp file." } +#clear all the https envs to cause _inithttp() to run next time. +_resethttp() { + __HTTP_INITIALIZED="" + _ACME_CURL="" + _ACME_WGET="" + ACME_HTTP_NO_REDIRECTS="" +} + _inithttp() { if [ -z "$HTTP_HEADER" ] || ! touch "$HTTP_HEADER"; then @@ -1737,7 +1745,10 @@ _inithttp() { fi if [ -z "$_ACME_CURL" ] && _exists "curl"; then - _ACME_CURL="curl -L --silent --dump-header $HTTP_HEADER " + _ACME_CURL="curl --silent --dump-header $HTTP_HEADER " + if [ -z "$ACME_HTTP_NO_REDIRECTS" ]; then + _ACME_CURL="$_ACME_CURL -L " + fi if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _CURL_DUMP="$(_mktemp)" _ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP " @@ -1756,6 +1767,9 @@ _inithttp() { if [ -z "$_ACME_WGET" ] && _exists "wget"; then _ACME_WGET="wget -q" + if [ "$ACME_HTTP_NO_REDIRECTS" ]; then + _ACME_WGET="$_ACME_WGET --max-redirect 0 " + fi if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then _ACME_WGET="$_ACME_WGET -d " fi