From a4980d800758a81f0235ddd968b04ee3fa7eba3e Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 2 Feb 2019 22:34:07 +0800 Subject: [PATCH 1/8] support dns over https --- acme.sh | 70 +++++++++++++++++++++------------------------------------ 1 file changed, 25 insertions(+), 45 deletions(-) diff --git a/acme.sh b/acme.sh index cfdf5714..a4fe5e81 100755 --- a/acme.sh +++ b/acme.sh @@ -2919,42 +2919,35 @@ _clearup() { _clearupdns() { _debug "_clearupdns" - _debug "dnsadded" "$dnsadded" - _debug "vlist" "$vlist" - #dnsadded is "0" or "1" means dns-01 method was used for at least one domain - if [ -z "$dnsadded" ] || [ -z "$vlist" ]; then + _debug "dns_entries" "$dns_entries" + + if [ -z "$dns_entries" ]; then _debug "skip dns." return fi _info "Removing DNS records." - ventries=$(echo "$vlist" | tr ',' ' ') - _alias_index=1 - for ventry in $ventries; do - d=$(echo "$ventry" | cut -d "$sep" -f 1) - keyauthorization=$(echo "$ventry" | cut -d "$sep" -f 2) - vtype=$(echo "$ventry" | cut -d "$sep" -f 4) - _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5) - txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" - _debug txt "$txt" - if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then - _debug "$d is already verified, skip $vtype." - _alias_index="$(_math "$_alias_index" + 1)" - continue - fi - if [ "$vtype" != "$VTYPE_DNS" ]; then - _debug "Skip $d for $vtype" - continue - fi - - d_api="$(_findHook "$d" dnsapi "$_currentRoot")" - _debug d_api "$d_api" + for entry in $dns_entries; do + d=$(_getfield "$entry" 1) + txtdomain=$(_getfield "$entry" 2) + aliasDomain=$(_getfield "$entry" 3) + txt=$(_getfield "$entry" 5) + d_api=$(_getfield "$entry" 6) + _debug "d" "$d" + _debug "txtdomain" "$txtdomain" + _debug "aliasDomain" "$aliasDomain" + _debug "txt" "$txt" + _debug "d_api" "$d_api" if [ -z "$d_api" ]; then _info "Not Found domain api file: $d_api" continue fi + if [ "$aliasDomain" ]; then + txtdomain="$aliasDomain" + fi + ( if ! . "$d_api"; then _err "Load file $d_api error. Please check your api file and try again." @@ -2967,24 +2960,6 @@ _clearupdns() { return 1 fi - _dns_root_d="$d" - if _startswith "$_dns_root_d" "*."; then - _dns_root_d="$(echo "$_dns_root_d" | sed 's/*.//')" - fi - - _d_alias="$(_getfield "$_challenge_alias" "$_alias_index")" - _alias_index="$(_math "$_alias_index" + 1)" - _debug "_d_alias" "$_d_alias" - if [ "$_d_alias" ]; then - if _startswith "$_d_alias" "$DNS_ALIAS_PREFIX"; then - txtdomain="$(echo "$_d_alias" | sed "s/$DNS_ALIAS_PREFIX//")" - else - txtdomain="_acme-challenge.$_d_alias" - fi - else - txtdomain="_acme-challenge.$_dns_root_d" - fi - if ! $rmcommand "$txtdomain" "$txt"; then _err "Error removing txt for domain:$txtdomain" return 1 @@ -3776,6 +3751,7 @@ $_authorizations_map" done _debug vlist "$vlist" #add entry + dns_entries=""; dnsadded="" ventries=$(echo "$vlist" | tr "$dvsep" ' ') _alias_index=1 @@ -3806,8 +3782,10 @@ $_authorizations_map" else txtdomain="_acme-challenge.$_d_alias" fi + dns_entries="${dns_entries}${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$txtdomain$dvsep$_currentRoot" else txtdomain="_acme-challenge.$_dns_root_d" + dns_entries="${dns_entries}${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$dvsep$_currentRoot" fi _debug txtdomain "$txtdomain" txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" @@ -3816,7 +3794,9 @@ $_authorizations_map" d_api="$(_findHook "$_dns_root_d" dnsapi "$_currentRoot")" _debug d_api "$d_api" - + dns_entries="$dns_entries$dvsep$txt${dvsep}$d_api +" + _debug2 "$dns_entries" if [ "$d_api" ]; then _info "Found domain api file: $d_api" else @@ -3870,7 +3850,7 @@ $_authorizations_map" fi - if [ "$dnsadded" = '1' ]; then + if [ "$dns_entries" ]; then if [ -z "$Le_DNSSleep" ]; then Le_DNSSleep="$DEFAULT_DNS_SLEEP" else From ee47b9ee9f4daee0672bd712c34d8385bc71dfef Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 5 Feb 2019 18:44:36 +0800 Subject: [PATCH 2/8] support doh --- acme.sh | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index a4fe5e81..b8dbd756 100755 --- a/acme.sh +++ b/acme.sh @@ -3428,6 +3428,92 @@ __trigger_validation() { fi } +#endpoint domain type +_ns_lookup() { + _ns_ep="$1" + _ns_domain="$2" + _ns_type="$3" + _debug2 "_ns_ep" "$_ns_ep" + _debug2 "_ns_domain" "$_ns_domain" + _debug2 "_ns_type" "$_ns_type" + + response="$(_H1="accept: application/dns-json" _get "$_ns_ep?name=$_ns_domain&type=$_ns_type")" + _ret=$? + _debug2 "response" "$response" + if [ "$_ret" != "0" ]; then + return $_ret + fi + _answers="$(echo "$response" | tr '{}' '<>' | _egrep_o '"Answer":\[[^]]*]' | tr '<>' '\n\n')" + _debug2 "_answers" "$_answers" + echo "$_answers" +} + +#domain, type +_ns_lookup_cf() { + _cf_ld="$1" + _cf_ld_type="$2" + _cf_ep="https://cloudflare-dns.com/dns-query" + _ns_lookup "$_cf_ep" "$_cf_ld" "$_cf_ld_type" +} + +#txtdomain, alias, txt +__check_txt() { + _c_txtdomain="$1" + _c_aliasdomain="$2" + _c_txt="$3" + _debug "_c_txtdomain" "$_c_txtdomain" + _debug "_c_aliasdomain" "$_c_aliasdomain" + _debug "_c_txt" "$_c_txt" + _answers="$(_ns_lookup_cf "$_c_aliasdomain" TXT)" + _contains "$_answers" "$_c_txt" + +} + +#wait and check each dns entries +_check_dns_entries() { + _success_txt=","; + _end_time="$(_time)" + _end_time="$(_math "$_end_time" + 1200)" #let's check no more than 20 minutes. + + while [ "$(_time)" -le "$_end_time" ]; do + _left=""; + for entry in $dns_entries; do + d=$(_getfield "$entry" 1) + txtdomain=$(_getfield "$entry" 2) + aliasDomain=$(_getfield "$entry" 3) + txt=$(_getfield "$entry" 5) + d_api=$(_getfield "$entry" 6) + _debug "d" "$d" + _debug "txtdomain" "$txtdomain" + _debug "aliasDomain" "$aliasDomain" + _debug "txt" "$txt" + _debug "d_api" "$d_api" + _info "Checking $d for $aliasDomain" + if _contains "$_success_txt" ",$txt,"; then + _info "Already success, continue next one." + continue; + fi + + if __check_txt "$txtdomain" "$aliasDomain" "$txt"; then + _info "Domain $d '$aliasDomain' success." + _success_txt="$_success_txt,$txt," + continue + fi + _left=1 + _info "Not valid yet, let's wait 5 seconds and check next one." + _sleep 5; + done + if [ "$_left" ]; then + _info "Let's wait 10 seconds and check again". + _sleep 10 + else + _info "All success, let's return" + break + fi + done + +} + #webroot, domain domainlist keylength issue() { if [ -z "$2" ]; then @@ -3852,13 +3938,18 @@ $_authorizations_map" if [ "$dns_entries" ]; then if [ -z "$Le_DNSSleep" ]; then - Le_DNSSleep="$DEFAULT_DNS_SLEEP" + _info "Let's check each dns records now." + if ! _check_dns_entries; then + _err "check dns error." + _on_issue_err "$_post_hook" + _clearup + return 1 + fi else _savedomainconf "Le_DNSSleep" "$Le_DNSSleep" + _info "Sleep $(__green $Le_DNSSleep) seconds for the txt records to take effect" + _sleep "$Le_DNSSleep" fi - - _info "Sleep $(__green $Le_DNSSleep) seconds for the txt records to take effect" - _sleep "$Le_DNSSleep" fi NGINX_RESTORE_VLIST="" From 8c20ef030976dd174fbf9e80429459325b542c4d Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 5 Feb 2019 18:48:48 +0800 Subject: [PATCH 3/8] fix format --- acme.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index b8dbd756..f576c725 100755 --- a/acme.sh +++ b/acme.sh @@ -3471,12 +3471,12 @@ __check_txt() { #wait and check each dns entries _check_dns_entries() { - _success_txt=","; + _success_txt="," _end_time="$(_time)" _end_time="$(_math "$_end_time" + 1200)" #let's check no more than 20 minutes. while [ "$(_time)" -le "$_end_time" ]; do - _left=""; + _left="" for entry in $dns_entries; do d=$(_getfield "$entry" 1) txtdomain=$(_getfield "$entry" 2) @@ -3491,7 +3491,7 @@ _check_dns_entries() { _info "Checking $d for $aliasDomain" if _contains "$_success_txt" ",$txt,"; then _info "Already success, continue next one." - continue; + continue fi if __check_txt "$txtdomain" "$aliasDomain" "$txt"; then @@ -3501,7 +3501,7 @@ _check_dns_entries() { fi _left=1 _info "Not valid yet, let's wait 5 seconds and check next one." - _sleep 5; + _sleep 5 done if [ "$_left" ]; then _info "Let's wait 10 seconds and check again". @@ -3837,7 +3837,7 @@ $_authorizations_map" done _debug vlist "$vlist" #add entry - dns_entries=""; + dns_entries="" dnsadded="" ventries=$(echo "$vlist" | tr "$dvsep" ' ') _alias_index=1 From 1bbc62313c819f3dcd53117e2c836af666ca2e55 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 6 Feb 2019 09:47:23 +0800 Subject: [PATCH 4/8] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index f576c725..4bd34b3c 100755 --- a/acme.sh +++ b/acme.sh @@ -3493,7 +3493,7 @@ _check_dns_entries() { _info "Already success, continue next one." continue fi - + if __check_txt "$txtdomain" "$aliasDomain" "$txt"; then _info "Domain $d '$aliasDomain' success." _success_txt="$_success_txt,$txt," From 7345b92c7523ce0b3666b41c6815873c4a7b48b8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 15 Feb 2019 21:59:04 +0800 Subject: [PATCH 5/8] purge the record everytime --- acme.sh | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 4bd34b3c..110907b4 100755 --- a/acme.sh +++ b/acme.sh @@ -3456,6 +3456,15 @@ _ns_lookup_cf() { _ns_lookup "$_cf_ep" "$_cf_ld" "$_cf_ld_type" } +#domain, type +_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" + _post "" "$_cf_purl" +} + #txtdomain, alias, txt __check_txt() { _c_txtdomain="$1" @@ -3469,6 +3478,13 @@ __check_txt() { } +#txtdomain +__purge_txt() { + _p_txtdomain="$1" + _debug _p_txtdomain "$_p_txtdomain" + _ns_purge_cf "$_p_txtdomain" "TXT" +} + #wait and check each dns entries _check_dns_entries() { _success_txt="," @@ -3500,8 +3516,9 @@ _check_dns_entries() { continue fi _left=1 - _info "Not valid yet, let's wait 5 seconds and check next one." - _sleep 5 + _info "Not valid yet, let's wait 10 seconds and check next one." + _sleep 10 + __purge_txt done if [ "$_left" ]; then _info "Let's wait 10 seconds and check again". @@ -3938,7 +3955,8 @@ $_authorizations_map" if [ "$dns_entries" ]; then if [ -z "$Le_DNSSleep" ]; then - _info "Let's check each dns records now." + _info "Let's check each dns records now. Sleep 20 seconds first." + _sleep 20 if ! _check_dns_entries; then _err "check dns error." _on_issue_err "$_post_hook" From 04f7f0ab3d773d709e16f2329c9e1ec7181af69a Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 15 Feb 2019 22:33:03 +0800 Subject: [PATCH 6/8] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 110907b4..25f7fa2e 100755 --- a/acme.sh +++ b/acme.sh @@ -3518,7 +3518,7 @@ _check_dns_entries() { _left=1 _info "Not valid yet, let's wait 10 seconds and check next one." _sleep 10 - __purge_txt + __purge_txt done if [ "$_left" ]; then _info "Let's wait 10 seconds and check again". From 37bb717aa125f7af12bc164195e81abb251eea87 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 15 Feb 2019 23:05:42 +0800 Subject: [PATCH 7/8] minor, fix api not found --- acme.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/acme.sh b/acme.sh index 25f7fa2e..364b7db2 100755 --- a/acme.sh +++ b/acme.sh @@ -2938,6 +2938,9 @@ _clearupdns() { _debug "aliasDomain" "$aliasDomain" _debug "txt" "$txt" _debug "d_api" "$d_api" + if [ "$d_api" = "$txt" ]; then + d_api="" + fi if [ -z "$d_api" ]; then _info "Not Found domain api file: $d_api" From 6aaf0193c8ed55e364a4970e68291ffa079e9ccb Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 16 Feb 2019 10:05:32 +0800 Subject: [PATCH 8/8] fix purge --- acme.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 364b7db2..0f297e18 100755 --- a/acme.sh +++ b/acme.sh @@ -3465,7 +3465,8 @@ _ns_purge_cf() { _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" - _post "" "$_cf_purl" + response="$(_post "" "$_cf_purl")" + _debug2 response "$response" } #txtdomain, alias, txt @@ -3521,7 +3522,10 @@ _check_dns_entries() { _left=1 _info "Not valid yet, let's wait 10 seconds and check next one." _sleep 10 - __purge_txt + __purge_txt "$txtdomain" + if [ "$txtdomain" != "$aliasDomain" ]; then + __purge_txt "$aliasDomain" + fi done if [ "$_left" ]; then _info "Let's wait 10 seconds and check again".