From bd9af86de152697f3dbc8532ee813dad01566c10 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 13 Jul 2019 17:33:04 +0800 Subject: [PATCH 01/24] support jdcloud.com --- dnsapi/dns_jd.sh | 305 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 dnsapi/dns_jd.sh diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh new file mode 100644 index 00000000..28ac7dcf --- /dev/null +++ b/dnsapi/dns_jd.sh @@ -0,0 +1,305 @@ +#!/usr/bin/env sh + +# +#JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" +#JD_ACCESS_KEY_SECRET="xxxxxxx" +#JD_REGION="cn-north-1" +#JD_PACK_ID=0 + + +_JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey" + +_JD_PROD="clouddnsservice" +_JD_API="jdcloud-api.com" + +_JD_API_VERSION="v1" +_JD_DEFAULT_REGION="cn-north-1" + +_JD_HOST="$_JD_PROD.$_JD_API" + +_JD_PACK_FREE=0 +_JD_PACK_ENTERPRISE=1 +_JD_PACK_PREMIUM=2 + + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_jd_add() { + fulldomain=$1 + txtvalue=$2 + + JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" + JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" + JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" + JD_PACK_ID="${JD_PACK_ID:-$(_readaccountconf_mutable JD_PACK_ID)}" + + if [ -z "$JD_ACCESS_KEY_ID" ] || [ -z "$JD_ACCESS_KEY_SECRET" ]; then + JD_ACCESS_KEY_ID="" + JD_ACCESS_KEY_SECRET="" + _err "You haven't specifed the jdcloud api key id or api key secret yet." + _err "Please create your key and try again. see $(__green $_JD_ACCOUNT)" + return 1 + fi + + _saveaccountconf_mutable JD_ACCESS_KEY_ID "$JD_ACCESS_KEY_ID" + _saveaccountconf_mutable JD_ACCESS_KEY_SECRET "$JD_ACCESS_KEY_SECRET" + if [ -z "$JD_REGION" ]; then + _debug "Using default region: $_JD_DEFAULT_REGION" + JD_REGION="$_JD_DEFAULT_REGION" + else + _saveaccountconf_mutable JD_REGION "$JD_REGION" + fi + _JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION" + + if [ -z "$JD_PACK_ID" ]; then + _debug "Using default free pack: $_JD_PACK_FREE" + JD_PACK_ID=$_JD_PACK_FREE + else + _saveaccountconf_mutable JD_PACK_ID "$JD_PACK_ID" + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + #_debug "Getting getViewTree" + + _debug "Adding records" + + _addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":120,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" + #_addrr='{"req":{"hostRecord":"xx","hostValue":"\"value4\"","jcloudRes":false,"mxPriority":null,"port":null,"ttl":300,"type":"TXT","weight":null,"viewValue":-1},"regionId":"cn-north-1","domainId":"8824"}' + if jd_rest POST "domain/$_domain_id/RRAdd" "" "$_addrr"; then + _rid="$(echo "$response" | tr '{},' '\n' | grep '"id":' | cut -d : -f 2)" + if [ -z "$_rid" ]; then + _err "Can not find record id from the result." + return 1 + fi + _info "TXT record added successfully." + _srid="$(_readdomainconf "JD_CLOUD_RIDS")" + if [ "$_srid" ]; then + _rid="$_srid,$_rid" + fi + _savedomainconf "JD_CLOUD_RIDS" "$_rid" + return 0 + fi + + return 1 +} + + +dns_jd_rm() { + fulldomain=$1 + txtvalue=$2 + + JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" + JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" + JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" + JD_PACK_ID="${JD_PACK_ID:-$(_readaccountconf_mutable JD_PACK_ID)}" + if [ -z "$JD_REGION" ]; then + _debug "Using default region: $_JD_DEFAULT_REGION" + JD_REGION="$_JD_DEFAULT_REGION" + fi + + _JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION" + + _info "Getting existing records for $fulldomain" + _srid="$(_readdomainconf "JD_CLOUD_RIDS")" + _debug _srid "$_srid" + + if [ -z "$_srid" ]; then + _err "Not rid skip" + return 0 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _cleardomainconf JD_CLOUD_RIDS + + _aws_tmpl_xml="{\"ids\":[$_srid],\"action\":\"del\",\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" + + if jd_rest POST "domain/$_domain_id/RROperate" "" "$_aws_tmpl_xml" && _contains "$response" "\"code\":\"OK\""; then + _info "TXT record deleted successfully." + return 0 + fi + return 1 + +} + + +#################### Private functions below ################################## + +_get_root() { + domain=$1 + i=1 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug2 "Checking domain: $h" + if ! jd_rest GET "domain"; then + _err "error get domain list" + return 1 + fi + if [ -z "$h" ]; then + #not valid + _err "Invalid domain" + return 1 + fi + + if _contains "$response" "\"domainName\":\"$h\""; then + hostedzone="$(echo "$response" | tr '{}' '\n' | grep "\"domainName\":\"$h\"")" + _debug hostedzone "$hostedzone" + if [ "$hostedzone" ]; then + _domain_id="$(echo "$hostedzone" | tr ',' '\n' | grep "\"id\":" | cut -d : -f 2)" + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + fi + _err "Can't find domain with id: $h" + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} + + +#method uri qstr data +jd_rest() { + mtd="$1" + ep="$2" + qsr="$3" + data="$4" + + _debug mtd "$mtd" + _debug ep "$ep" + _debug qsr "$qsr" + _debug data "$data" + + CanonicalURI="/$_JD_BASE_URI/$ep" + _debug2 CanonicalURI "$CanonicalURI" + + CanonicalQueryString="$qsr" + _debug2 CanonicalQueryString "$CanonicalQueryString" + + RequestDate="$(date -u +"%Y%m%dT%H%M%SZ")" + #RequestDate="20190713T082155Z" ###################################################### + _debug2 RequestDate "$RequestDate" + export _H1="X-Jdcloud-Date: $RequestDate" + + RequestNonce="2bd0852a-8bae-4087-b2d5-$(_time)" + #RequestNonce="894baff5-72d4-4244-883a-7b2eb51e7fbe" ################################# + _debug2 RequestNonce "$RequestNonce" + export _H2="X-Jdcloud-Nonce: $RequestNonce" + + if [ "$data" ]; then + CanonicalHeaders="content-type:application/json\n" + SignedHeaders="content-type;" + else + CanonicalHeaders="" + SignedHeaders="" + fi + CanonicalHeaders="${CanonicalHeaders}host:$_JD_HOST\nx-jdcloud-date:$RequestDate\nx-jdcloud-nonce:$RequestNonce\n" + SignedHeaders="${SignedHeaders}host;x-jdcloud-date;x-jdcloud-nonce" + + _debug2 CanonicalHeaders "$CanonicalHeaders" + _debug2 SignedHeaders "$SignedHeaders" + + Hash="sha256" + + RequestPayload="$data" + _debug2 RequestPayload "$RequestPayload" + + RequestPayloadHash="$(printf "%s" "$RequestPayload" | _digest "$Hash" hex | _lower_case)" + _debug2 RequestPayloadHash "$RequestPayloadHash" + + CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$RequestPayloadHash" + _debug2 CanonicalRequest "$CanonicalRequest" + + HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)" + _debug2 HashedCanonicalRequest "$HashedCanonicalRequest" + + Algorithm="JDCLOUD2-HMAC-SHA256" + _debug2 Algorithm "$Algorithm" + + RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8)" + _debug2 RequestDateOnly "$RequestDateOnly" + + Region="$JD_REGION" + Service="$_JD_PROD" + + CredentialScope="$RequestDateOnly/$Region/$Service/jdcloud2_request" + _debug2 CredentialScope "$CredentialScope" + + StringToSign="$Algorithm\n$RequestDate\n$CredentialScope\n$HashedCanonicalRequest" + + _debug2 StringToSign "$StringToSign" + + kSecret="JDCLOUD2$JD_ACCESS_KEY_SECRET" + + _secure_debug2 kSecret "$kSecret" + + kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")" + _secure_debug2 kSecretH "$kSecretH" + + kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" + _debug2 kDateH "$kDateH" + + kRegionH="$(printf "$Region%s" | _hmac "$Hash" "$kDateH" hex)" + _debug2 kRegionH "$kRegionH" + + kServiceH="$(printf "$Service%s" | _hmac "$Hash" "$kRegionH" hex)" + _debug2 kServiceH "$kServiceH" + + kSigningH="$(printf "%s" "jdcloud2_request" | _hmac "$Hash" "$kServiceH" hex)" + _debug2 kSigningH "$kSigningH" + + signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)" + _debug2 signature "$signature" + + Authorization="$Algorithm Credential=$JD_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature" + _debug2 Authorization "$Authorization" + + _H3="Authorization: $Authorization" + _debug _H3 "$_H3" + + url="https://$_JD_HOST$CanonicalURI" + if [ "$qsr" ]; then + url="https://$_JD_HOST$CanonicalURI?$qsr" + fi + + if [ "$mtd" = "GET" ]; then + response="$(_get "$url")" + else + response="$(_post "$data" "$url" "" "$mtd" "application/json")" + fi + + _ret="$?" + _debug2 response "$response" + if [ "$_ret" = "0" ]; then + if _contains "$response" "\"error\""; then + _err "Response error:$response" + return 1 + fi + fi + + return "$_ret" +} + From 57b16e3ac2f18401cecceef1ca32d818c3b11bf0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 13 Jul 2019 17:42:01 +0800 Subject: [PATCH 02/24] fix format --- dnsapi/dns_jd.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh index 28ac7dcf..2efc91a3 100644 --- a/dnsapi/dns_jd.sh +++ b/dnsapi/dns_jd.sh @@ -6,7 +6,6 @@ #JD_REGION="cn-north-1" #JD_PACK_ID=0 - _JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey" _JD_PROD="clouddnsservice" @@ -21,7 +20,6 @@ _JD_PACK_FREE=0 _JD_PACK_ENTERPRISE=1 _JD_PACK_PREMIUM=2 - ######## Public functions ##################### #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -92,7 +90,6 @@ dns_jd_add() { return 1 } - dns_jd_rm() { fulldomain=$1 txtvalue=$2 @@ -138,7 +135,6 @@ dns_jd_rm() { } - #################### Private functions below ################################## _get_root() { @@ -180,7 +176,6 @@ _get_root() { return 1 } - #method uri qstr data jd_rest() { mtd="$1" @@ -302,4 +297,3 @@ jd_rest() { return "$_ret" } - From 42497028c458053f9fba1cb9fe43e3c03a3701b4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 13 Jul 2019 19:35:55 +0800 Subject: [PATCH 03/24] ttl 3000 --- dnsapi/dns_jd.sh | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_jd.sh b/dnsapi/dns_jd.sh index 2efc91a3..d0f2a501 100644 --- a/dnsapi/dns_jd.sh +++ b/dnsapi/dns_jd.sh @@ -4,7 +4,6 @@ #JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" #JD_ACCESS_KEY_SECRET="xxxxxxx" #JD_REGION="cn-north-1" -#JD_PACK_ID=0 _JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey" @@ -16,10 +15,6 @@ _JD_DEFAULT_REGION="cn-north-1" _JD_HOST="$_JD_PROD.$_JD_API" -_JD_PACK_FREE=0 -_JD_PACK_ENTERPRISE=1 -_JD_PACK_PREMIUM=2 - ######## Public functions ##################### #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -30,7 +25,6 @@ dns_jd_add() { JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" - JD_PACK_ID="${JD_PACK_ID:-$(_readaccountconf_mutable JD_PACK_ID)}" if [ -z "$JD_ACCESS_KEY_ID" ] || [ -z "$JD_ACCESS_KEY_SECRET" ]; then JD_ACCESS_KEY_ID="" @@ -50,13 +44,6 @@ dns_jd_add() { fi _JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION" - if [ -z "$JD_PACK_ID" ]; then - _debug "Using default free pack: $_JD_PACK_FREE" - JD_PACK_ID=$_JD_PACK_FREE - else - _saveaccountconf_mutable JD_PACK_ID "$JD_PACK_ID" - fi - _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -70,7 +57,7 @@ dns_jd_add() { _debug "Adding records" - _addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":120,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" + _addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":300,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}" #_addrr='{"req":{"hostRecord":"xx","hostValue":"\"value4\"","jcloudRes":false,"mxPriority":null,"port":null,"ttl":300,"type":"TXT","weight":null,"viewValue":-1},"regionId":"cn-north-1","domainId":"8824"}' if jd_rest POST "domain/$_domain_id/RRAdd" "" "$_addrr"; then _rid="$(echo "$response" | tr '{},' '\n' | grep '"id":' | cut -d : -f 2)" @@ -97,7 +84,7 @@ dns_jd_rm() { JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}" JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}" JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}" - JD_PACK_ID="${JD_PACK_ID:-$(_readaccountconf_mutable JD_PACK_ID)}" + if [ -z "$JD_REGION" ]; then _debug "Using default region: $_JD_DEFAULT_REGION" JD_REGION="$_JD_DEFAULT_REGION" From 28a9df669d80e696677ef5ca0248e2801a7bfc0e Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sat, 13 Jul 2019 14:35:09 +0200 Subject: [PATCH 04/24] Escape slashes (#2375) --- dnsapi/dns_namecheap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 6553deb6..a82e12d7 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -164,7 +164,7 @@ _namecheap_set_publicip() { _debug sourceip "$NAMECHEAP_SOURCEIP" ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') - addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*') + addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https):\/\/.*') _debug2 ip "$ip" _debug2 addr "$addr" From 3cdfa4051d98a0bbc1dab64d8028556324b1e0a4 Mon Sep 17 00:00:00 2001 From: Jeff Wang <3102114+wangqiliang@users.noreply.github.com> Date: Sat, 13 Jul 2019 23:05:30 +0800 Subject: [PATCH 05/24] Change 1.1.1.1 to 1.0.0.1 to probe compatibility (#2330) As we can see, 1.1.1.1 is not routed or routed to an Intranet devices due to historical reason. Change 1.1.1.1 to 1.0.0.1 will have a better compatibility. I found this problem on my Tencent Cloud server. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 67fcdcb5..d168b566 100755 --- a/acme.sh +++ b/acme.sh @@ -3621,7 +3621,7 @@ _ns_purge_cf() { _cf_d="$1" _cf_d_type="$2" _debug "Cloudflare purge $_cf_d_type record for domain $_cf_d" - _cf_purl="https://1.1.1.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" + _cf_purl="https://1.0.0.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" response="$(_post "" "$_cf_purl")" _debug2 response "$response" } From 28cadc5e06f9d79ba315636e240514c197656bf6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 18 Jul 2019 21:05:59 +0800 Subject: [PATCH 06/24] check empty id --- dnsapi/dns_namesilo.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index dc1a4fda..15e4f21d 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -59,9 +59,14 @@ dns_namesilo_rm() { if _namesilo_rest GET "dnsListRecords?version=1&type=xml&key=$Namesilo_Key&domain=$_domain"; then retcode=$(printf "%s\n" "$response" | _egrep_o "300") if [ "$retcode" ]; then - _record_id=$(printf "%s\n" "$response" | _egrep_o "([^<]*)TXT$fulldomain" | _egrep_o "([^<]*)" | sed -r "s/([^<]*)<\/record_id>/\1/" | tail -n 1) + _record_id=$(echo "$response" | _egrep_o "([^<]*)TXT$fulldomain" | _egrep_o "([^<]*)" | sed -r "s/([^<]*)<\/record_id>/\1/" | tail -n 1) _debug record_id "$_record_id" - _info "Successfully retrieved the record id for ACME challenge." + if [ "$record_id" ]; then + _info "Successfully retrieved the record id for ACME challenge." + else + _info "Empty record id, it seems no such record." + return 0 + fi else _err "Unable to retrieve the record id." return 1 From 5c09788ec4cacc85a426f3444436b5b374976cff Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 18 Jul 2019 22:20:51 +0800 Subject: [PATCH 07/24] fix error --- dnsapi/dns_namesilo.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh index 15e4f21d..ed6d0e08 100755 --- a/dnsapi/dns_namesilo.sh +++ b/dnsapi/dns_namesilo.sh @@ -60,8 +60,8 @@ dns_namesilo_rm() { retcode=$(printf "%s\n" "$response" | _egrep_o "300") if [ "$retcode" ]; then _record_id=$(echo "$response" | _egrep_o "([^<]*)TXT$fulldomain" | _egrep_o "([^<]*)" | sed -r "s/([^<]*)<\/record_id>/\1/" | tail -n 1) - _debug record_id "$_record_id" - if [ "$record_id" ]; then + _debug _record_id "$_record_id" + if [ "$_record_id" ]; then _info "Successfully retrieved the record id for ACME challenge." else _info "Empty record id, it seems no such record." From 8d393ff13722bf7acfac84879363b8d50a04c7b7 Mon Sep 17 00:00:00 2001 From: Yuri S Date: Sat, 20 Jul 2019 09:26:23 +0500 Subject: [PATCH 08/24] Add dnsapi for Vultr (#2370) * Add Vultr dns api --- dnsapi/dns_vultr.sh | 163 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 dnsapi/dns_vultr.sh diff --git a/dnsapi/dns_vultr.sh b/dnsapi/dns_vultr.sh new file mode 100644 index 00000000..f15e7c49 --- /dev/null +++ b/dnsapi/dns_vultr.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env sh + +# +#VULTR_API_KEY=000011112222333344445555666677778888 + +VULTR_Api="https://api.vultr.com/v1" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_vultr_add() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}" + if test -z "$VULTR_API_KEY"; then + VULTR_API_KEY='' + _err 'VULTR_API_KEY was not exported' + return 1 + fi + + _saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug 'Getting txt records' + _vultr_rest GET "dns/records?domain=$_domain" + + if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then + _err 'Error' + return 1 + fi + + if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + return 0 +} + +#fulldomain txtvalue +dns_vultr_rm() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}" + if test -z "$VULTR_API_KEY"; then + VULTR_API_KEY="" + _err 'VULTR_API_KEY was not exported' + return 1 + fi + + _saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY" + + _debug 'First detect the root zone' + if ! _get_root "$fulldomain"; then + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug 'Getting txt records' + _vultr_rest GET "dns/records?domain=$_domain" + + if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then + _err 'Error' + return 1 + fi + + _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)" + _debug _record_id "$_record_id" + if [ "$_record_id" ]; then + _info "Successfully retrieved the record id for ACME challenge." + else + _info "Empty record id, it seems no such record." + return 0 + fi + + if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then + _err "$response" + return 1 + fi + + _debug2 _response "$response" + return 0 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=sdjkglgdfewsdfg +_get_root() { + domain=$1 + i=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + return 1 + fi + + if ! _vultr_rest GET "dns/list"; then + return 1 + fi + + if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then + if _contains "$response" "\"domain\":\"$_domain\""; then + _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")" + _domain=$_domain + return 0 + else + _err 'Invalid domain' + return 1 + fi + else + _err "$response" + return 1 + fi + i=$(_math "$i" + 1) + done + + return 1 +} + +_vultr_rest() { + m=$1 + ep="$2" + data="$3" + _debug "$ep" + + api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"') + + export _H1="Api-Key: $api_key_trimmed" + export _H2='Content-Type: application/x-www-form-urlencoded' + + if [ "$m" != "GET" ]; then + _debug data "$data" + response="$(_post "$data" "$VULTR_Api/$ep" "" "$m")" + else + response="$(_get "$VULTR_Api/$ep")" + fi + + if [ "$?" != "0" ]; then + _err "Error $ep" + return 1 + fi + + _debug2 response "$response" + return 0 +} From b8e6287774b64ca42de3b301df7d5b57a3e216af Mon Sep 17 00:00:00 2001 From: tdk1069 Date: Sat, 20 Jul 2019 05:30:56 +0100 Subject: [PATCH 09/24] PushOver notifications (#2325) * PushOver notifications, using AppToken, UserKey, and optional sounds --- notify/pushover.sh | 67 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 notify/pushover.sh diff --git a/notify/pushover.sh b/notify/pushover.sh new file mode 100644 index 00000000..70eba733 --- /dev/null +++ b/notify/pushover.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env sh + +#Support for pushover.net's api. Push notification platform for multiple platforms +#PUSHOVER_TOKEN="" Required, pushover application token +#PUSHOVER_USER="" Required, pushover userkey +#PUSHOVER_DEVICE="" Optional, Specific device or devices by hostnames, joining multiples with a comma (such as device=iphone,nexus5) +#PUSHOVER_PRIORITY="" Optional, Lowest Priority (-2), Low Priority (-1), Normal Priority (0), High Priority (1) + +PUSHOVER_URI="https://api.pushover.net/1/messages.json" + +pushover_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_statusCode" "$_statusCode" + + PUSHOVER_TOKEN="${PUSHOVER_TOKEN:-$(_readaccountconf_mutable PUSHOVER_TOKEN)}" + if [ -z "$PUSHOVER_TOKEN" ]; then + PUSHOVER_TOKEN="" + _err "You didn't specify a PushOver application token yet." + return 1 + fi + _saveaccountconf_mutable PUSHOVER_TOKEN "$PUSHOVER_TOKEN" + + PUSHOVER_USER="${PUSHOVER_USER:-$(_readaccountconf_mutable PUSHOVER_USER)}" + if [ -z "$PUSHOVER_USER" ]; then + PUSHOVER_USER="" + _err "You didn't specify a PushOver UserKey yet." + return 1 + fi + _saveaccountconf_mutable PUSHOVER_USER "$PUSHOVER_USER" + + PUSHOVER_DEVICE="${PUSHOVER_DEVICE:-$(_readaccountconf_mutable PUSHOVER_DEVICE)}" + if [ -z "$PUSHOVER_DEVICE" ]; then + PUSHOVER_DEVICE="" + fi + _saveaccountconf_mutable PUSHOVER_DEVICE "$PUSHOVER_DEVICE" + + PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-$(_readaccountconf_mutable PUSHOVER_PRIORITY)}" + if [ -z "$PUSHOVER_PRIORITY" ]; then + PUSHOVER_PRIORITY="0" + fi + _saveaccountconf_mutable PUSHOVER_PRIORITY "$PUSHOVER_PRIORITY" + + + PUSHOVER_SOUND="${PUSHOVER_SOUND:-$(_readaccountconf_mutable PUSHOVER_SOUND)}" + if [ -z "$PUSHOVER_SOUND" ]; then + PUSHOVER_SOUND="" # Play default if not specified. + fi + _saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND" + + export _H1="Content-Type: application/json" + _content="$(printf "*%s*\n" "$_content" | _json_encode)" + _subject="$(printf "*%s*\n" "$_subject" | _json_encode)" + _data="{\"token\": \"$PUSHOVER_TOKEN\",\"user\": \"$PUSHOVER_USER\",\"title\": \"$_subject\",\"message\": \"$_content\",\"sound\": \"$PUSHOVER_SOUND\", \"device\": \"$PUSHOVER_DEVICE\", \"priority\": \"$PUSHOVER_PRIORITY\"}" + + response="" #just make shellcheck happy + if _post "$_data" "$PUSHOVER_URI"; then + if _contains "$response" "{\"status\":1"; then + _info "PUSHOVER send sccess." + return 0 + fi + fi + _err "PUSHOVER send error." + _err "$response" + return 1 +} From 28c153a0a2dd667f2eb2e810d4f2a3cea4471506 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 20 Jul 2019 12:36:28 +0800 Subject: [PATCH 10/24] fix errors --- notify/pushover.sh | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/notify/pushover.sh b/notify/pushover.sh index 70eba733..309b3907 100644 --- a/notify/pushover.sh +++ b/notify/pushover.sh @@ -31,23 +31,20 @@ pushover_send() { _saveaccountconf_mutable PUSHOVER_USER "$PUSHOVER_USER" PUSHOVER_DEVICE="${PUSHOVER_DEVICE:-$(_readaccountconf_mutable PUSHOVER_DEVICE)}" - if [ -z "$PUSHOVER_DEVICE" ]; then - PUSHOVER_DEVICE="" + if [ "$PUSHOVER_DEVICE" ]; then + _saveaccountconf_mutable PUSHOVER_DEVICE "$PUSHOVER_DEVICE" fi - _saveaccountconf_mutable PUSHOVER_DEVICE "$PUSHOVER_DEVICE" PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-$(_readaccountconf_mutable PUSHOVER_PRIORITY)}" - if [ -z "$PUSHOVER_PRIORITY" ]; then - PUSHOVER_PRIORITY="0" + if [ "$PUSHOVER_PRIORITY" ]; then + _saveaccountconf_mutable PUSHOVER_PRIORITY "$PUSHOVER_PRIORITY" fi - _saveaccountconf_mutable PUSHOVER_PRIORITY "$PUSHOVER_PRIORITY" - PUSHOVER_SOUND="${PUSHOVER_SOUND:-$(_readaccountconf_mutable PUSHOVER_SOUND)}" - if [ -z "$PUSHOVER_SOUND" ]; then + if [ "$PUSHOVER_SOUND" ]; then PUSHOVER_SOUND="" # Play default if not specified. + _saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND" fi - _saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND" export _H1="Content-Type: application/json" _content="$(printf "*%s*\n" "$_content" | _json_encode)" From ccc2142b452a5b86e483fc5d80ff658f91d14146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szil=C3=A1rd=20Pfeiffer?= Date: Sat, 20 Jul 2019 10:00:38 +0200 Subject: [PATCH 11/24] added dns api support for hexonet (#1776) --- dnsapi/dns_hexonet.sh | 156 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100755 dnsapi/dns_hexonet.sh diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh new file mode 100755 index 00000000..ccd201eb --- /dev/null +++ b/dnsapi/dns_hexonet.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env sh + +# +# Hexonet_Username="username" +# +# Hexonet_Password="password" + +Hexonet_Api="https://coreapi.1api.net/api/call.cgi" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_hexonet_add() { + fulldomain=$1 + txtvalue=$2 + + Hexonet_Username="${Hexonet_Username:-$(_readaccountconf_mutable Hexonet_Username)}" + Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" + if [ -z "$Hexonet_Username" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Username="" + Hexonet_Password="" + _err "You must export variables: Hexonet_Username and Hexonet_Password" + return 1 + fi + + if ! _contains "$Hexonet_Username" "!"; then + _err "It seems that the Hexonet_Username=$Hexonet_Username is not a restrivteed user." + _err "Please check and retry." + return 1 + fi + + #save the username and password to the account conf file. + _saveaccountconf_mutable Hexonet_Username "$Hexonet_Username" + _saveaccountconf_mutable Hexonet_Password "$Hexonet_Password" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT" + + if ! _contains "$response" "CODE=200"; then + _err "Error" + return 1 + fi + + _info "Adding record" + if _hexonet_rest "command=UpdateDNSZone&dnszone=${_domain}.&addrr0=${_sub_domain}%20IN%20TXT%20${txtvalue}"; then + if _contains "$response" "CODE=200"; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + _err "Add txt record error." + return 1 + +} + +#fulldomain txtvalue +dns_hexonet_rm() { + fulldomain=$1 + txtvalue=$2 + + Hexonet_Username="${Hexonet_Username:-$(_readaccountconf_mutable Hexonet_Username)}" + Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" + if [ -z "$Hexonet_Username" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Username="" + Hexonet_Password="" + _err "You must export variables: Hexonet_Username and Hexonet_Password" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT&RR=${txtvalue}" + + if ! _contains "$response" "CODE=200"; then + _err "Error" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "PROPERTY[TOTAL][0]=" | cut -d = -f 2) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + if ! _hexonet_rest "&command=UpdateDNSZone&dnszone=${_domain}.&delrr0='${_sub_domain}%20IN%20TXT%20\"${txtvalue}\""; then + _err "Delete record error." + return 1 + fi + _contains "$response" "CODE=200" + fi + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}."; then + return 1 + fi + + if _contains "$response" "CODE=200"; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_hexonet_rest() { + query_params="$1" + _debug "$query_params" + + response="$(_get "${Hexonet_Api}?s_login=${Hexonet_Username}&s_pw=${Hexonet_Password}&${query_params}")" + + if [ "$?" != "0" ]; then + _err "error $query_params" + return 1 + fi + _debug2 response "$response" + return 0 +} From 93d29a9733169437cbc5df4a65a8636edbde2c8e Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 20 Jul 2019 17:09:36 +0800 Subject: [PATCH 12/24] update --- dnsapi/dns_hexonet.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dnsapi/dns_hexonet.sh b/dnsapi/dns_hexonet.sh index ccd201eb..f1503118 100755 --- a/dnsapi/dns_hexonet.sh +++ b/dnsapi/dns_hexonet.sh @@ -1,9 +1,9 @@ #!/usr/bin/env sh # -# Hexonet_Username="username" +# Hexonet_Login="username!roleId" # -# Hexonet_Password="password" +# Hexonet_Password="rolePassword" Hexonet_Api="https://coreapi.1api.net/api/call.cgi" @@ -14,23 +14,23 @@ dns_hexonet_add() { fulldomain=$1 txtvalue=$2 - Hexonet_Username="${Hexonet_Username:-$(_readaccountconf_mutable Hexonet_Username)}" + Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}" Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" - if [ -z "$Hexonet_Username" ] || [ -z "$Hexonet_Password" ]; then - Hexonet_Username="" + if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Login="" Hexonet_Password="" - _err "You must export variables: Hexonet_Username and Hexonet_Password" + _err "You must export variables: Hexonet_Login and Hexonet_Password" return 1 fi - if ! _contains "$Hexonet_Username" "!"; then - _err "It seems that the Hexonet_Username=$Hexonet_Username is not a restrivteed user." + if ! _contains "$Hexonet_Login" "!"; then + _err "It seems that the Hexonet_Login=$Hexonet_Login is not a restrivteed user." _err "Please check and retry." return 1 fi #save the username and password to the account conf file. - _saveaccountconf_mutable Hexonet_Username "$Hexonet_Username" + _saveaccountconf_mutable Hexonet_Login "$Hexonet_Login" _saveaccountconf_mutable Hexonet_Password "$Hexonet_Password" _debug "First detect the root zone" @@ -69,12 +69,12 @@ dns_hexonet_rm() { fulldomain=$1 txtvalue=$2 - Hexonet_Username="${Hexonet_Username:-$(_readaccountconf_mutable Hexonet_Username)}" + Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}" Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}" - if [ -z "$Hexonet_Username" ] || [ -z "$Hexonet_Password" ]; then - Hexonet_Username="" + if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then + Hexonet_Login="" Hexonet_Password="" - _err "You must export variables: Hexonet_Username and Hexonet_Password" + _err "You must export variables: Hexonet_Login and Hexonet_Password" return 1 fi @@ -145,7 +145,7 @@ _hexonet_rest() { query_params="$1" _debug "$query_params" - response="$(_get "${Hexonet_Api}?s_login=${Hexonet_Username}&s_pw=${Hexonet_Password}&${query_params}")" + response="$(_get "${Hexonet_Api}?s_login=${Hexonet_Login}&s_pw=${Hexonet_Password}&${query_params}")" if [ "$?" != "0" ]; then _err "error $query_params" From 80af3d6ada23098bb68e3be63e72e0cfd4406ce1 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 22 Jul 2019 21:26:47 +0800 Subject: [PATCH 13/24] minor --- notify/pushover.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/notify/pushover.sh b/notify/pushover.sh index 309b3907..a07cbd3d 100644 --- a/notify/pushover.sh +++ b/notify/pushover.sh @@ -42,7 +42,6 @@ pushover_send() { PUSHOVER_SOUND="${PUSHOVER_SOUND:-$(_readaccountconf_mutable PUSHOVER_SOUND)}" if [ "$PUSHOVER_SOUND" ]; then - PUSHOVER_SOUND="" # Play default if not specified. _saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND" fi @@ -54,7 +53,7 @@ pushover_send() { response="" #just make shellcheck happy if _post "$_data" "$PUSHOVER_URI"; then if _contains "$response" "{\"status\":1"; then - _info "PUSHOVER send sccess." + _info "PUSHOVER send success." return 0 fi fi From c25947d5447ac03ac0fae56b338e8821d49d61ac Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 22 Jul 2019 22:25:50 +0800 Subject: [PATCH 14/24] support new Cloudflare Token format fix https://github.com/Neilpang/acme.sh/issues/2398 --- dnsapi/dns_cf.sh | 83 +++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index cd93189f..d4266d18 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -5,6 +5,9 @@ # #CF_Email="xxxx@sss.com" +#CF_Token="xxxx" +#CF_Account_ID="xxxx" + CF_Api="https://api.cloudflare.com/client/v4" ######## Public functions ##################### @@ -14,26 +17,33 @@ dns_cf_add() { fulldomain=$1 txtvalue=$2 + CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" + CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then - CF_Key="" - CF_Email="" - _err "You didn't specify a Cloudflare api key and email yet." - _err "You can get yours from here https://dash.cloudflare.com/profile." - return 1 - fi + + if [ "$CF_Token" ]; then + _saveaccountconf_mutable CF_Token "$CF_Token" + _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" + else + if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then + CF_Key="" + CF_Email="" + _err "You didn't specify a Cloudflare api key and email yet." + _err "You can get yours from here https://dash.cloudflare.com/profile." + return 1 + fi - if ! _contains "$CF_Email" "@"; then - _err "It seems that the CF_Email=$CF_Email is not a valid email address." - _err "Please check and retry." - return 1 + if ! _contains "$CF_Email" "@"; then + _err "It seems that the CF_Email=$CF_Email is not a valid email address." + _err "Please check and retry." + return 1 + fi + #save the api key and email to the account conf file. + _saveaccountconf_mutable CF_Key "$CF_Key" + _saveaccountconf_mutable CF_Email "$CF_Email" fi - #save the api key and email to the account conf file. - _saveaccountconf_mutable CF_Key "$CF_Key" - _saveaccountconf_mutable CF_Email "$CF_Email" - _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -71,19 +81,6 @@ dns_cf_add() { fi _err "Add txt record error." return 1 - # else - # _info "Updating record" - # record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) - # _debug "record_id" "$record_id" - # - # _cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}" - # if [ "$?" = "0" ]; then - # _info "Updated, OK" - # return 0 - # fi - # _err "Update error" - # return 1 - # fi } @@ -92,15 +89,10 @@ dns_cf_rm() { fulldomain=$1 txtvalue=$2 + CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" + CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then - CF_Key="" - CF_Email="" - _err "You didn't specify a Cloudflare api key and email yet." - _err "You can get yours from here https://dash.cloudflare.com/profile." - return 1 - fi _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -157,8 +149,14 @@ _get_root() { return 1 fi - if ! _cf_rest GET "zones?name=$h"; then - return 1 + if [ "$CF_Account_ID" ]; then + if ! _cf_rest GET "zones?name=$h&account.id=$CF_Account_ID"; then + return 1 + fi + else + if ! _cf_rest GET "zones?name=$h"; then + return 1 + fi fi if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then @@ -184,10 +182,15 @@ _cf_rest() { email_trimmed=$(echo $CF_Email | tr -d '"') key_trimmed=$(echo $CF_Key | tr -d '"') + token_trimmed=$(echo $CF_Token | tr -d '"') - export _H1="X-Auth-Email: $email_trimmed" - export _H2="X-Auth-Key: $key_trimmed" - export _H3="Content-Type: application/json" + export _H1="Content-Type: application/json" + if [ "$token_trimmed" ]; then + export _H2="Authorization: Bearer $token_trimmed" + else + export _H2="X-Auth-Email: $email_trimmed" + export _H3="X-Auth-Key: $key_trimmed" + fi if [ "$m" != "GET" ]; then _debug data "$data" From 54e189616c0e96288a42e5fb24ae7fa2846e16d0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 23 Jul 2019 21:36:42 +0800 Subject: [PATCH 15/24] fix wildcard domain name --- deploy/docker.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deploy/docker.sh b/deploy/docker.sh index 4e550991..44bb044b 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -223,7 +223,8 @@ _docker_cp() { _debug2 "_frompath" "$_frompath" _toname="$(basename "$_to")" _debug2 "_toname" "$_toname" - if ! tar --transform="s,$_frompath,$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then + _debug2 "_from" "$_from" + if ! tar --transform="s,$(printf "%s" "$_frompath" | tr '*' .),$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then _err "copy error" return 1 fi From 45e8bb03e438892d974153b5326b06aece628a56 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 23 Jul 2019 21:43:00 +0800 Subject: [PATCH 16/24] add more info --- deploy/docker.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/docker.sh b/deploy/docker.sh index 44bb044b..05333b3f 100755 --- a/deploy/docker.sh +++ b/deploy/docker.sh @@ -126,6 +126,7 @@ docker_deploy() { fi if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then + _info "Reloading: $DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then return 1 fi From 9a733a57e73fbb09f300f8eac5004aafef6e61d6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 24 Jul 2019 21:49:26 +0800 Subject: [PATCH 17/24] fix https://github.com/Neilpang/acme.sh/issues/2377 --- acme.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d168b566..891d2e1e 100755 --- a/acme.sh +++ b/acme.sh @@ -3035,11 +3035,13 @@ _clearupdns() { d=$(_getfield "$entry" 1) txtdomain=$(_getfield "$entry" 2) aliasDomain=$(_getfield "$entry" 3) + _currentRoot=$(_getfield "$entry" 4) txt=$(_getfield "$entry" 5) d_api=$(_getfield "$entry" 6) _debug "d" "$d" _debug "txtdomain" "$txtdomain" _debug "aliasDomain" "$aliasDomain" + _debug "_currentRoot" "$_currentRoot" _debug "txt" "$txt" _debug "d_api" "$d_api" if [ "$d_api" = "$txt" ]; then @@ -6787,7 +6789,7 @@ _process() { _debug "Using server: $_server" fi fi - + _debug "Running cmd: ${_CMD}" case "${_CMD}" in install) install "$_nocron" "$_confighome" "$_noprofile" ;; uninstall) uninstall "$_nocron" ;; From 72e7eb6777d14097961422959eaa0e9ecb3becfc Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 27 Jul 2019 10:49:11 +0800 Subject: [PATCH 18/24] fix format --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index d4266d18..f1725bd7 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -21,7 +21,7 @@ dns_cf_add() { CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" - + if [ "$CF_Token" ]; then _saveaccountconf_mutable CF_Token "$CF_Token" _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" From 41c951811e38002df1d7efad8b1197368aed4697 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 27 Jul 2019 11:09:13 +0800 Subject: [PATCH 19/24] fix format --- dnsapi/dns_cf.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index f1725bd7..62e40caf 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -180,9 +180,9 @@ _cf_rest() { data="$3" _debug "$ep" - email_trimmed=$(echo $CF_Email | tr -d '"') - key_trimmed=$(echo $CF_Key | tr -d '"') - token_trimmed=$(echo $CF_Token | tr -d '"') + email_trimmed=$(echo "$CF_Email" | tr -d '"') + key_trimmed=$(echo "$CF_Key" | tr -d '"') + token_trimmed=$(echo "$CF_Token" | tr -d '"') export _H1="Content-Type: application/json" if [ "$token_trimmed" ]; then From b9b2cd278b098b7e43143e58809878f1e8fbcf2b Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 29 Jul 2019 21:12:19 +0800 Subject: [PATCH 20/24] fix https://github.com/Neilpang/acme.sh/pull/2275 --- acme.sh | 4 ++-- dnsapi/dns_dp.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 891d2e1e..66d9b7a8 100755 --- a/acme.sh +++ b/acme.sh @@ -3623,7 +3623,7 @@ _ns_purge_cf() { _cf_d="$1" _cf_d_type="$2" _debug "Cloudflare purge $_cf_d_type record for domain $_cf_d" - _cf_purl="https://1.0.0.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" + _cf_purl="https://cloudflare-dns.com/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" response="$(_post "" "$_cf_purl")" _debug2 response "$response" } @@ -3682,11 +3682,11 @@ _check_dns_entries() { fi _left=1 _info "Not valid yet, let's wait 10 seconds and check next one." - _sleep 10 __purge_txt "$txtdomain" if [ "$txtdomain" != "$aliasDomain" ]; then __purge_txt "$aliasDomain" fi + _sleep 10 done if [ "$_left" ]; then _info "Let's wait 10 seconds and check again". diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 6bbf149e..480c1f9a 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -63,7 +63,7 @@ dns_dp_rm() { return 0 fi - record_id=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2) + record_id=$(echo "$response" | tr "{" "\n" | grep -- "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2) _debug record_id "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id." From 75191e71870abdb35365d057ffd746e8cd8d5b4f Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 31 Jul 2019 23:22:07 +0800 Subject: [PATCH 21/24] fix https://github.com/Neilpang/acme.sh/issues/2417 --- acme.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 66d9b7a8..8bff2e84 100755 --- a/acme.sh +++ b/acme.sh @@ -5932,8 +5932,11 @@ _send_notify() { _send_err=0 for _n_hook in $(echo "$_nhooks" | tr ',' " "); do _n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")" - _info "Found $_n_hook_file" - + _info "Found $_n_hook_file for $_n_hook" + if [ -z "$_n_hook_file" ]; then + _err "Can not find the hook file for $_n_hook" + continue + fi if ! ( if ! . "$_n_hook_file"; then _err "Load file $_n_hook_file error. Please check your api file and try again." From d42cf6daebfd134dca7af41b47aac34866b6a771 Mon Sep 17 00:00:00 2001 From: James Qian Date: Mon, 5 Aug 2019 21:35:03 +0800 Subject: [PATCH 22/24] dnsapi: fix typo in dns_desec.sh (#2427) Signed-off-by: James Qian --- dnsapi/dns_desec.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_desec.sh b/dnsapi/dns_desec.sh index 6488b7fb..61d080bd 100644 --- a/dnsapi/dns_desec.sh +++ b/dnsapi/dns_desec.sh @@ -25,8 +25,8 @@ dns_desec_add() { if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then DEDYN_TOKEN="" DEDYN_NAME="" - _err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet." - _err "Please create you key and try again." + _err "You did not specify DEDYN_TOKEN and DEDYN_NAME yet." + _err "Please create your key and try again." _err "e.g." _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" _err "export DEDYN_NAME=foobar.dedyn.io" @@ -92,8 +92,8 @@ dns_desec_rm() { if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then DEDYN_TOKEN="" DEDYN_NAME="" - _err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet." - _err "Please create you key and try again." + _err "You did not specify DEDYN_TOKEN and DEDYN_NAME yet." + _err "Please create your key and try again." _err "e.g." _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" _err "export DEDYN_NAME=foobar.dedyn.io" From d74dfb1f5c333c911d150f7a7485ff99b8c984b4 Mon Sep 17 00:00:00 2001 From: lcdtyph Date: Mon, 5 Aug 2019 21:38:32 +0800 Subject: [PATCH 23/24] IFTTT Webhooks Notification (#2416) * IFTTT webhooks Notification * use sh instead of bash * don't save value that is not set --- notify/ifttt.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 notify/ifttt.sh diff --git a/notify/ifttt.sh b/notify/ifttt.sh new file mode 100644 index 00000000..8a14f5f5 --- /dev/null +++ b/notify/ifttt.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env sh + +#Support ifttt.com webhooks api + +#IFTTT_API_KEY="xxxx" +#IFTTT_EVENT_NAME="yyyy" + +#IFTTT_SUBJECT_KEY="value1|value2|value3" #optional, use "value1" as default +#IFTTT_CONTENT_KEY="value1|value2|value3" #optional, use "value2" as default + +_IFTTT_AVAIL_MSG_KEYS="value1,value2,value3" + +# subject content statusCode +ifttt_send() { + _subject="$1" + _content="$2" + _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped + _debug "_subject" "$_subject" + _debug "_content" "$_content" + _debug "_statusCode" "$_statusCode" + + IFTTT_API_KEY="${IFTTT_API_KEY:-$(_readaccountconf_mutable IFTTT_API_KEY)}" + if [ -z "$IFTTT_API_KEY" ]; then + IFTTT_API_KEY="" + _err "You didn't specify a ifttt webhooks api key IFTTT_API_KEY yet." + _err "You can get yours from https://ifttt.com" + return 1 + fi + _saveaccountconf_mutable IFTTT_API_KEY "$IFTTT_API_KEY" + + IFTTT_EVENT_NAME="${IFTTT_EVENT_NAME:-$(_readaccountconf_mutable IFTTT_EVENT_NAME)}" + if [ -z "$IFTTT_EVENT_NAME" ]; then + IFTTT_EVENT_NAME="" + _err "You didn't specify a ifttt webhooks event name IFTTT_EVENT_NAME yet." + return 1 + fi + _saveaccountconf_mutable IFTTT_EVENT_NAME "$IFTTT_EVENT_NAME" + + IFTTT_SUBJECT_KEY="${IFTTT_SUBJECT_KEY:-$(_readaccountconf_mutable IFTTT_SUBJECT_KEY)}" + if [ -z "$IFTTT_SUBJECT_KEY" ]; then + IFTTT_SUBJECT_KEY="value1" + _info "The IFTTT_SUBJECT_KEY is not set, so use the default value1 as key." + elif ! _hasfield "$_IFTTT_AVAIL_MSG_KEYS" "$IFTTT_SUBJECT_KEY"; then + _err "The IFTTT_SUBJECT_KEY \"$IFTTT_SUBJECT_KEY\" is not available, should be one of $_IFTTT_AVAIL_MSG_KEYS" + IFTTT_SUBJECT_KEY="" + return 1 + else + _saveaccountconf_mutable IFTTT_SUBJECT_KEY "$IFTTT_SUBJECT_KEY" + fi + + IFTTT_CONTENT_KEY="${IFTTT_CONTENT_KEY:-$(_readaccountconf_mutable IFTTT_CONTENT_KEY)}" + if [ -z "$IFTTT_CONTENT_KEY" ]; then + IFTTT_CONTENT_KEY="value2" + _info "The IFTTT_CONTENT_KEY is not set, so use the default value2 as key." + elif ! _hasfield "$_IFTTT_AVAIL_MSG_KEYS" "$IFTTT_CONTENT_KEY"; then + _err "The IFTTT_CONTENT_KEY \"$IFTTT_CONTENT_KEY\" is not available, should be one of $_IFTTT_AVAIL_MSG_KEYS" + IFTTT_CONTENT_KEY="" + return 1 + else + _saveaccountconf_mutable IFTTT_CONTENT_KEY "$IFTTT_CONTENT_KEY" + fi + + if [ "$IFTTT_SUBJECT_KEY" = "$IFTTT_CONTENT_KEY" ]; then + IFTTT_SUBJECT_KEY="" + IFTTT_CONTENT_KEY="" + _err "The IFTTT_SUBJECT_KEY must not be same as IFTTT_CONTENT_KEY." + return 1 + fi + + IFTTT_API_URL="https://maker.ifttt.com/trigger/$IFTTT_EVENT_NAME/with/key/$IFTTT_API_KEY" + + _content=$(echo "$_content" | _json_encode) + _subject=$(echo "$_subject" | _json_encode) + _data="{\"$IFTTT_SUBJECT_KEY\": \"$_subject\", \"$IFTTT_CONTENT_KEY\": \"$_content\"}" + + response="" #just make shellcheck happy + if _post "$_data" "$IFTTT_API_URL" "" "POST" "application/json"; then + if _contains "$response" "Congratulations"; then + _info "IFTTT webhooks event fired success." + return 0 + fi + fi + _err "IFTTT webhooks event fired error." + _err "$response" + return 1 +} From 143eac092ce8b8fe7c068809449ce7a5b71f3ea2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 5 Aug 2019 22:03:56 +0800 Subject: [PATCH 24/24] fix notify message --- acme.sh | 5 +++-- notify/ifttt.sh | 12 ++++++------ notify/pushover.sh | 12 ++++++------ notify/sendgrid.sh | 12 ++++++------ 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/acme.sh b/acme.sh index 8bff2e84..8452d588 100755 --- a/acme.sh +++ b/acme.sh @@ -5932,7 +5932,8 @@ _send_notify() { _send_err=0 for _n_hook in $(echo "$_nhooks" | tr ',' " "); do _n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")" - _info "Found $_n_hook_file for $_n_hook" + _info "Sending via: $_n_hook" + _debug "Found $_n_hook_file for $_n_hook" if [ -z "$_n_hook_file" ]; then _err "Can not find the hook file for $_n_hook" continue @@ -5971,7 +5972,7 @@ _set_notify_hook() { _nhooks="$1" _test_subject="Hello, this is notification from $PROJECT_NAME" - _test_content="If you receive this email, your notification works." + _test_content="If you receive this message, your notification works." _send_notify "$_test_subject" "$_test_content" "$_nhooks" 0 diff --git a/notify/ifttt.sh b/notify/ifttt.sh index 8a14f5f5..7b829639 100644 --- a/notify/ifttt.sh +++ b/notify/ifttt.sh @@ -73,13 +73,13 @@ ifttt_send() { _subject=$(echo "$_subject" | _json_encode) _data="{\"$IFTTT_SUBJECT_KEY\": \"$_subject\", \"$IFTTT_CONTENT_KEY\": \"$_content\"}" - response="" #just make shellcheck happy - if _post "$_data" "$IFTTT_API_URL" "" "POST" "application/json"; then - if _contains "$response" "Congratulations"; then - _info "IFTTT webhooks event fired success." - return 0 - fi + response="$(_post "$_data" "$IFTTT_API_URL" "" "POST" "application/json")" + + if [ "$?" = "0" ] && _contains "$response" "Congratulations"; then + _info "IFTTT webhooks event fired success." + return 0 fi + _err "IFTTT webhooks event fired error." _err "$response" return 1 diff --git a/notify/pushover.sh b/notify/pushover.sh index a07cbd3d..0f99739a 100644 --- a/notify/pushover.sh +++ b/notify/pushover.sh @@ -50,13 +50,13 @@ pushover_send() { _subject="$(printf "*%s*\n" "$_subject" | _json_encode)" _data="{\"token\": \"$PUSHOVER_TOKEN\",\"user\": \"$PUSHOVER_USER\",\"title\": \"$_subject\",\"message\": \"$_content\",\"sound\": \"$PUSHOVER_SOUND\", \"device\": \"$PUSHOVER_DEVICE\", \"priority\": \"$PUSHOVER_PRIORITY\"}" - response="" #just make shellcheck happy - if _post "$_data" "$PUSHOVER_URI"; then - if _contains "$response" "{\"status\":1"; then - _info "PUSHOVER send success." - return 0 - fi + response="$(_post "$_data" "$PUSHOVER_URI")" + + if [ "$?" = "0" ] && _contains "$response" "{\"status\":1"; then + _info "PUSHOVER send success." + return 0 fi + _err "PUSHOVER send error." _err "$response" return 1 diff --git a/notify/sendgrid.sh b/notify/sendgrid.sh index 5c5bfdba..0d5ea3b3 100644 --- a/notify/sendgrid.sh +++ b/notify/sendgrid.sh @@ -42,13 +42,13 @@ sendgrid_send() { _content="$(echo "$_content" | _json_encode)" _data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}" - response="" #just make shellcheck happy - if _post "$_data" "https://api.sendgrid.com/v3/mail/send"; then - if [ -z "$response" ]; then - _info "sendgrid send sccess." - return 0 - fi + response="$(_post "$_data" "https://api.sendgrid.com/v3/mail/send")" + + if [ "$?" = "0" ] && [ -z "$response" ]; then + _info "sendgrid send sccess." + return 0 fi + _err "sendgrid send error." _err "$response" return 1