mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2025-07-12 11:01:03 +00:00
Merge branch 'dev' into all-inkl-kasserver-dns-script
This commit is contained in:
@ -99,6 +99,7 @@ dns_azure_add() {
|
||||
_azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
|
||||
if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
|
||||
_info "validation value added"
|
||||
return 0
|
||||
else
|
||||
_err "error adding validation value ($_code)"
|
||||
return 1
|
||||
@ -194,6 +195,7 @@ dns_azure_rm() {
|
||||
_azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
|
||||
if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
|
||||
_info "validation value removed"
|
||||
return 0
|
||||
else
|
||||
_err "error removing validation value ($_code)"
|
||||
return 1
|
||||
@ -226,6 +228,7 @@ _azure_rest() {
|
||||
else
|
||||
response="$(_get "$ep")"
|
||||
fi
|
||||
_ret="$?"
|
||||
_secure_debug2 "response $response"
|
||||
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
|
||||
_debug "http response code $_code"
|
||||
@ -236,7 +239,7 @@ _azure_rest() {
|
||||
return 1
|
||||
fi
|
||||
# See https://docs.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#general-rest-and-retry-guidelines for retryable HTTP codes
|
||||
if [ "$?" != "0" ] || [ -z "$_code" ] || [ "$_code" = "408" ] || [ "$_code" = "500" ] || [ "$_code" = "503" ] || [ "$_code" = "504" ]; then
|
||||
if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "408" ] || [ "$_code" = "500" ] || [ "$_code" = "503" ] || [ "$_code" = "504" ]; then
|
||||
_request_retry_times="$(_math "$_request_retry_times" + 1)"
|
||||
_info "REST call error $_code retrying $ep in $_request_retry_times s"
|
||||
_sleep "$_request_retry_times"
|
||||
@ -281,6 +284,7 @@ _azure_getaccess_token() {
|
||||
body="resource=$(printf "%s" 'https://management.core.windows.net/' | _url_encode)&client_id=$(printf "%s" "$clientID" | _url_encode)&client_secret=$(printf "%s" "$clientSecret" | _url_encode)&grant_type=client_credentials"
|
||||
_secure_debug2 "data $body"
|
||||
response="$(_post "$body" "https://login.microsoftonline.com/$tenantID/oauth2/token" "" "POST")"
|
||||
_ret="$?"
|
||||
_secure_debug2 "response $response"
|
||||
response="$(echo "$response" | _normalizeJson)"
|
||||
accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
|
||||
@ -290,7 +294,7 @@ _azure_getaccess_token() {
|
||||
_err "no acccess token received. Check your Azure settings see $WIKI"
|
||||
return 1
|
||||
fi
|
||||
if [ "$?" != "0" ]; then
|
||||
if [ "$_ret" != "0" ]; then
|
||||
_err "error $response"
|
||||
return 1
|
||||
fi
|
||||
|
@ -19,8 +19,8 @@ dns_cf_add() {
|
||||
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
|
||||
CF_Key=""
|
||||
CF_Email=""
|
||||
_err "You don't specify cloudflare api key and email yet."
|
||||
_err "Please create you key and try again."
|
||||
_err "You didn't specify a cloudflare api key and email yet."
|
||||
_err "Please create the key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
@ -94,8 +94,8 @@ dns_cf_rm() {
|
||||
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
|
||||
CF_Key=""
|
||||
CF_Email=""
|
||||
_err "You don't specify cloudflare api key and email yet."
|
||||
_err "Please create you key and try again."
|
||||
_err "You didn't specify a cloudflare api key and email yet."
|
||||
_err "Please create the key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
@ -20,12 +20,22 @@
|
||||
dns_dgon_add() {
|
||||
fulldomain="$(echo "$1" | _lower_case)"
|
||||
txtvalue=$2
|
||||
|
||||
DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}"
|
||||
# Check if API Key Exist
|
||||
if [ -z "$DO_API_KEY" ]; then
|
||||
DO_API_KEY=""
|
||||
_err "You did not specify DigitalOcean API key."
|
||||
_err "Please export DO_API_KEY and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Using digitalocean dns validation - add record"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
## save the env vars (key and domain split location) for later automated use
|
||||
_saveaccountconf DO_API_KEY "$DO_API_KEY"
|
||||
_saveaccountconf_mutable DO_API_KEY "$DO_API_KEY"
|
||||
|
||||
## split the domain for DO API
|
||||
if ! _get_base_domain "$fulldomain"; then
|
||||
@ -39,7 +49,7 @@ dns_dgon_add() {
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="Authorization: Bearer $DO_API_KEY"
|
||||
PURL='https://api.digitalocean.com/v2/domains/'$_domain'/records'
|
||||
PBODY='{"type":"TXT","name":"'$_sub_domain'","data":"'$txtvalue'"}'
|
||||
PBODY='{"type":"TXT","name":"'$_sub_domain'","data":"'$txtvalue'","ttl":120}'
|
||||
|
||||
_debug PURL "$PURL"
|
||||
_debug PBODY "$PBODY"
|
||||
@ -65,6 +75,16 @@ dns_dgon_add() {
|
||||
dns_dgon_rm() {
|
||||
fulldomain="$(echo "$1" | _lower_case)"
|
||||
txtvalue=$2
|
||||
|
||||
DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}"
|
||||
# Check if API Key Exist
|
||||
if [ -z "$DO_API_KEY" ]; then
|
||||
DO_API_KEY=""
|
||||
_err "You did not specify DigitalOcean API key."
|
||||
_err "Please export DO_API_KEY and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Using digitalocean dns validation - remove record"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
@ -92,11 +112,11 @@ dns_dgon_rm() {
|
||||
domain_list="$(_get "$GURL")"
|
||||
## 2) find record
|
||||
## check for what we are looing for: "type":"A","name":"$_sub_domain"
|
||||
record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*\d+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
|
||||
record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
|
||||
## 3) check record and get next page
|
||||
if [ -z "$record" ]; then
|
||||
## find the next page if we dont have a match
|
||||
nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=\d+")"
|
||||
nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")"
|
||||
if [ -z "$nextpage" ]; then
|
||||
_err "no record and no nextpage in digital ocean DNS removal"
|
||||
return 1
|
||||
@ -108,7 +128,7 @@ dns_dgon_rm() {
|
||||
done
|
||||
|
||||
## we found the record
|
||||
rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*\d+" | _egrep_o "\d+")"
|
||||
rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
|
||||
_debug rec_id "$rec_id"
|
||||
|
||||
## delete the record
|
||||
|
@ -53,8 +53,9 @@ dns_freedns_add() {
|
||||
i="$(_math "$i" - 1)"
|
||||
sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")"
|
||||
|
||||
_debug top_domain "$top_domain"
|
||||
_debug sub_domain "$sub_domain"
|
||||
_debug "top_domain: $top_domain"
|
||||
_debug "sub_domain: $sub_domain"
|
||||
|
||||
# Sometimes FreeDNS does not return the subdomain page but rather
|
||||
# returns a page regarding becoming a premium member. This usually
|
||||
# happens after a period of inactivity. Immediately trying again
|
||||
@ -63,6 +64,7 @@ dns_freedns_add() {
|
||||
attempts=2
|
||||
while [ "$attempts" -gt "0" ]; do
|
||||
attempts="$(_math "$attempts" - 1)"
|
||||
|
||||
htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
|
||||
if [ "$?" != "0" ]; then
|
||||
if [ "$using_cached_cookies" = "true" ]; then
|
||||
@ -71,10 +73,9 @@ dns_freedns_add() {
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
_debug2 htmlpage "$htmlpage"
|
||||
|
||||
subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$top_domain")"
|
||||
_debug2 subdomain_csv "$subdomain_csv"
|
||||
_debug3 "subdomain_csv: $subdomain_csv"
|
||||
|
||||
# The above beauty ends with striping out rows that do not have an
|
||||
# href to edit.php and do not have the top domain we are looking for.
|
||||
@ -85,55 +86,25 @@ dns_freedns_add() {
|
||||
lines="$(echo "$subdomain_csv" | wc -l)"
|
||||
i=0
|
||||
found=0
|
||||
DNSdomainid=""
|
||||
while [ "$i" -lt "$lines" ]; do
|
||||
i="$(_math "$i" + 1)"
|
||||
line="$(echo "$subdomain_csv" | sed -n "${i}p")"
|
||||
_debug2 line "$line"
|
||||
_debug2 "line: $line"
|
||||
if [ $found = 0 ] && _contains "$line" "<td>$top_domain</td>"; then
|
||||
# this line will contain DNSdomainid for the top_domain
|
||||
DNSdomainid="$(echo "$line" | _egrep_o "edit_domain_id *= *.*>" | cut -d = -f 2 | cut -d '>' -f 1)"
|
||||
_debug2 DNSdomainid "$DNSdomainid"
|
||||
_debug2 "DNSdomainid: $DNSdomainid"
|
||||
found=1
|
||||
else
|
||||
# lines contain DNS records for all subdomains
|
||||
DNSname="$(echo "$line" | _egrep_o 'edit.php.*</a>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug2 DNSname "$DNSname"
|
||||
DNStype="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '4p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug2 DNStype "$DNStype"
|
||||
if [ "$DNSname" = "$fulldomain" ] && [ "$DNStype" = "TXT" ]; then
|
||||
DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)"
|
||||
# Now get current value for the TXT record. This method may
|
||||
# not produce accurate results as the value field is truncated
|
||||
# on this webpage. To get full value we would need to load
|
||||
# another page. However we don't really need this so long as
|
||||
# there is only one TXT record for the acme challenge subdomain.
|
||||
DNSvalue="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '5p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug2 DNSvalue "$DNSvalue"
|
||||
if [ $found != 0 ]; then
|
||||
break
|
||||
# we are breaking out of the loop at the first match of DNS name
|
||||
# and DNS type (if we are past finding the domainid). This assumes
|
||||
# that there is only ever one TXT record for the LetsEncrypt/acme
|
||||
# challenge subdomain. This seems to be a reasonable assumption
|
||||
# as the acme client deletes the TXT record on successful validation.
|
||||
fi
|
||||
else
|
||||
DNSname=""
|
||||
DNStype=""
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
_debug "DNSname: $DNSname DNStype: $DNStype DNSdomainid: $DNSdomainid DNSdataid: $DNSdataid"
|
||||
_debug "DNSvalue: $DNSvalue"
|
||||
|
||||
if [ -z "$DNSdomainid" ]; then
|
||||
# If domain ID is empty then something went wrong (top level
|
||||
# domain not found at FreeDNS).
|
||||
if [ "$attempts" = "0" ]; then
|
||||
# exhausted maximum retry attempts
|
||||
_debug "$htmlpage"
|
||||
_debug "$subdomain_csv"
|
||||
_err "Domain $top_domain not found at FreeDNS"
|
||||
return 1
|
||||
fi
|
||||
@ -145,33 +116,10 @@ dns_freedns_add() {
|
||||
_info "Retry loading subdomain page ($attempts attempts remaining)"
|
||||
done
|
||||
|
||||
if [ -z "$DNSdataid" ]; then
|
||||
# If data ID is empty then specific subdomain does not exist yet, need
|
||||
# to create it this should always be the case as the acme client
|
||||
# deletes the entry after domain is validated.
|
||||
_freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
|
||||
return $?
|
||||
else
|
||||
if [ "$txtvalue" = "$DNSvalue" ]; then
|
||||
# if value in TXT record matches value requested then DNS record
|
||||
# does not need to be updated. But...
|
||||
# Testing value match fails. Website is truncating the value field.
|
||||
# So for now we will always go down the else path. Though in theory
|
||||
# should never come here anyway as the acme client deletes
|
||||
# the TXT record on successful validation, so we should not even
|
||||
# have found a TXT record !!
|
||||
_info "No update necessary for $fulldomain at FreeDNS"
|
||||
return 0
|
||||
else
|
||||
# Delete the old TXT record (with the wrong value)
|
||||
if _freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"; then
|
||||
# And add in new TXT record with the value provided
|
||||
_freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
|
||||
fi
|
||||
return $?
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
# Add in new TXT record with the value provided
|
||||
_debug "Adding TXT record for $fulldomain, $txtvalue"
|
||||
_freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
|
||||
return $?
|
||||
}
|
||||
|
||||
#Usage: fulldomain txtvalue
|
||||
@ -205,7 +153,7 @@ dns_freedns_rm() {
|
||||
fi
|
||||
|
||||
subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$fulldomain")"
|
||||
_debug2 subdomain_csv "$subdomain_csv"
|
||||
_debug3 "subdomain_csv: $subdomain_csv"
|
||||
|
||||
# The above beauty ends with striping out rows that do not have an
|
||||
# href to edit.php and do not have the domain name we are looking for.
|
||||
@ -216,35 +164,51 @@ dns_freedns_rm() {
|
||||
lines="$(echo "$subdomain_csv" | wc -l)"
|
||||
i=0
|
||||
found=0
|
||||
DNSdataid=""
|
||||
while [ "$i" -lt "$lines" ]; do
|
||||
i="$(_math "$i" + 1)"
|
||||
line="$(echo "$subdomain_csv" | sed -n "${i}p")"
|
||||
_debug2 line "$line"
|
||||
_debug3 "line: $line"
|
||||
DNSname="$(echo "$line" | _egrep_o 'edit.php.*</a>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug2 DNSname "$DNSname"
|
||||
DNStype="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '4p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug2 DNStype "$DNStype"
|
||||
if [ "$DNSname" = "$fulldomain" ] && [ "$DNStype" = "TXT" ]; then
|
||||
DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)"
|
||||
_debug2 DNSdataid "$DNSdataid"
|
||||
DNSvalue="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '5p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug2 DNSvalue "$DNSvalue"
|
||||
# if [ "$DNSvalue" = "$txtvalue" ]; then
|
||||
# Testing value match fails. Website is truncating the value
|
||||
# field. So for now we will assume that there is only one TXT
|
||||
# field for the sub domain and just delete it. Currently this
|
||||
# is a safe assumption.
|
||||
_freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"
|
||||
return $?
|
||||
# fi
|
||||
_debug2 "DNSname: $DNSname"
|
||||
if [ "$DNSname" = "$fulldomain" ]; then
|
||||
DNStype="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '4p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug2 "DNStype: $DNStype"
|
||||
if [ "$DNStype" = "TXT" ]; then
|
||||
DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)"
|
||||
_debug2 "DNSdataid: $DNSdataid"
|
||||
DNSvalue="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '5p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
if _startswith "$DNSvalue" """; then
|
||||
# remove the quotation from the start
|
||||
DNSvalue="$(echo "$DNSvalue" | cut -c 7-)"
|
||||
fi
|
||||
if _endswith "$DNSvalue" "..."; then
|
||||
# value was truncated, remove the dot dot dot from the end
|
||||
DNSvalue="$(echo "$DNSvalue" | sed 's/...$//')"
|
||||
elif _endswith "$DNSvalue" """; then
|
||||
# else remove the closing quotation from the end
|
||||
DNSvalue="$(echo "$DNSvalue" | sed 's/......$//')"
|
||||
fi
|
||||
_debug2 "DNSvalue: $DNSvalue"
|
||||
|
||||
if [ -n "$DNSdataid" ] && _startswith "$txtvalue" "$DNSvalue"; then
|
||||
# Found a match. But note... Website is truncating the
|
||||
# value field so we are only testing that part that is not
|
||||
# truncated. This should be accurate enough.
|
||||
_debug "Deleting TXT record for $fulldomain, $txtvalue"
|
||||
_freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"
|
||||
return $?
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# If we get this far we did not find a match (after two attempts)
|
||||
# Not necessarily an error, but log anyway.
|
||||
_debug2 "$subdomain_csv"
|
||||
_info "Cannot delete TXT record for $fulldomain/$txtvalue. Does not exist at FreeDNS"
|
||||
_debug3 "$subdomain_csv"
|
||||
_info "Cannot delete TXT record for $fulldomain, $txtvalue. Does not exist at FreeDNS"
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -272,7 +236,7 @@ _freedns_login() {
|
||||
|
||||
# if cookies is not empty then logon successful
|
||||
if [ -z "$cookies" ]; then
|
||||
_debug "$htmlpage"
|
||||
_debug3 "htmlpage: $htmlpage"
|
||||
_err "FreeDNS login failed for user $username. Check $HTTP_HEADER file"
|
||||
return 1
|
||||
fi
|
||||
@ -301,7 +265,7 @@ _freedns_retrieve_subdomain_page() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 "$htmlpage"
|
||||
_debug3 "htmlpage: $htmlpage"
|
||||
|
||||
printf "%s" "$htmlpage"
|
||||
return 0
|
||||
@ -323,17 +287,17 @@ _freedns_add_txt_record() {
|
||||
_err "FreeDNS failed to add TXT record for $subdomain bad RC from _post"
|
||||
return 1
|
||||
elif ! grep "200 OK" "$HTTP_HEADER" >/dev/null; then
|
||||
_debug "$htmlpage"
|
||||
_debug3 "htmlpage: $htmlpage"
|
||||
_err "FreeDNS failed to add TXT record for $subdomain. Check $HTTP_HEADER file"
|
||||
return 1
|
||||
elif _contains "$htmlpage" "security code was incorrect"; then
|
||||
_debug "$htmlpage"
|
||||
_debug3 "htmlpage: $htmlpage"
|
||||
_err "FreeDNS failed to add TXT record for $subdomain as FreeDNS requested security code"
|
||||
_err "Note that you cannot use automatic DNS validation for FreeDNS public domains"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 "$htmlpage"
|
||||
_debug3 "htmlpage: $htmlpage"
|
||||
_info "Added acme challenge TXT record for $fulldomain at FreeDNS"
|
||||
return 0
|
||||
}
|
||||
@ -352,7 +316,7 @@ _freedns_delete_txt_record() {
|
||||
_err "FreeDNS failed to delete TXT record for $data_id bad RC from _get"
|
||||
return 1
|
||||
elif ! _contains "$htmlheader" "200 OK"; then
|
||||
_debug "$htmlheader"
|
||||
_debug2 "htmlheader: $htmlheader"
|
||||
_err "FreeDNS failed to delete TXT record $data_id"
|
||||
return 1
|
||||
fi
|
||||
|
Reference in New Issue
Block a user