mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2026-10-21 21:31:51 +00:00
Compare commits
13
Commits
0d1d0092b8
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37d064f7b5 | ||
|
|
3688b094ad | ||
|
|
807da64983 | ||
|
|
c37315c194 | ||
|
|
d5fc938d80 | ||
|
|
2f8e8ed085 | ||
|
|
181425b3c8 | ||
|
|
19980c86e8 | ||
|
|
9656842a30 | ||
|
|
a7e6ceaab0 | ||
|
|
261653ebf4 | ||
|
|
2feb392bd0 | ||
|
|
3661fd86b6 |
No files matched your search
@@ -1,154 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034
|
||||
dns_primedns_info='PrimeDNS
|
||||
Site: primedns.net
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_primedns
|
||||
Options:
|
||||
PRIMEDNS_API_KEY API Key. Scope acme:name:_acme-challenge.<hostname> for each name you issue (or dns:write)
|
||||
OptionsAlt:
|
||||
PRIMEDNS_API_URL API base URL. Optional, default https://api.primedns.net/v1
|
||||
Issues: github.com/acmesh-official/acme.sh/issues/7330
|
||||
Author: PrimeDNS <acme@primedns.net>
|
||||
'
|
||||
|
||||
PRIMEDNS_Api_Default="https://api.primedns.net/v1"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: dns_primedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_primedns_add() {
|
||||
fulldomain=$(_idn "$1")
|
||||
txtvalue=$2
|
||||
|
||||
PRIMEDNS_API_KEY="${PRIMEDNS_API_KEY:-$(_readaccountconf_mutable PRIMEDNS_API_KEY)}"
|
||||
if [ -z "$PRIMEDNS_API_KEY" ]; then
|
||||
PRIMEDNS_API_KEY=""
|
||||
_err "You didn't specify a PrimeDNS API key (PRIMEDNS_API_KEY) yet."
|
||||
_err "Create one in the PrimeDNS panel (Account -> API Keys) with the scope acme:name:_acme-challenge.<hostname> for each name you issue."
|
||||
return 1
|
||||
fi
|
||||
|
||||
PRIMEDNS_API_URL="${PRIMEDNS_API_URL:-$(_readaccountconf_mutable PRIMEDNS_API_URL)}"
|
||||
|
||||
#save the credentials to the account conf file.
|
||||
_saveaccountconf_mutable PRIMEDNS_API_KEY "$PRIMEDNS_API_KEY"
|
||||
if [ "$PRIMEDNS_API_URL" ]; then
|
||||
_saveaccountconf_mutable PRIMEDNS_API_URL "$PRIMEDNS_API_URL"
|
||||
fi
|
||||
|
||||
_info "Using PrimeDNS"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
if ! _primedns_rest POST "$fulldomain" "$txtvalue"; then
|
||||
return 1
|
||||
fi
|
||||
_info "Added, OK"
|
||||
return 0
|
||||
}
|
||||
|
||||
#Usage: dns_primedns_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_primedns_rm() {
|
||||
fulldomain=$(_idn "$1")
|
||||
txtvalue=$2
|
||||
|
||||
PRIMEDNS_API_KEY="${PRIMEDNS_API_KEY:-$(_readaccountconf_mutable PRIMEDNS_API_KEY)}"
|
||||
if [ -z "$PRIMEDNS_API_KEY" ]; then
|
||||
PRIMEDNS_API_KEY=""
|
||||
_err "You didn't specify a PrimeDNS API key (PRIMEDNS_API_KEY) yet."
|
||||
return 1
|
||||
fi
|
||||
PRIMEDNS_API_URL="${PRIMEDNS_API_URL:-$(_readaccountconf_mutable PRIMEDNS_API_URL)}"
|
||||
|
||||
_info "Using PrimeDNS"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
if ! _primedns_rest DELETE "$fulldomain" "$txtvalue"; then
|
||||
return 1
|
||||
fi
|
||||
_info "Removed, OK"
|
||||
return 0
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
#Usage: _primedns_rest POST|DELETE _acme-challenge.www.domain.com txtvalue
|
||||
#The API creates/removes the TXT record with exactly the name given, so the full
|
||||
#name acme.sh passes (_acme-challenge.<domain>, or the name of a DNS alias) is
|
||||
#sent as it is.
|
||||
_primedns_rest() {
|
||||
_method=$1
|
||||
_name=$2
|
||||
_value=$3
|
||||
_url="${PRIMEDNS_API_URL:-$PRIMEDNS_Api_Default}/dns/acme-challenge"
|
||||
|
||||
#The body is built by hand, so refuse anything that would need JSON escaping.
|
||||
case "$_name$_value" in
|
||||
*\"* | *\\*)
|
||||
_err "Refusing to send '$_name': it contains a quote or a backslash."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
if [ -z "$_name" ] || _is_idn "$_name"; then
|
||||
_err "Cannot send '$_name': it is not a plain ASCII host name. For an IDN name install idn (acme.sh converts it to punycode) or pass the punycode name."
|
||||
return 1
|
||||
fi
|
||||
_body="{\"name\":\"$_name\",\"value\":\"$_value\"}"
|
||||
_debug _body "$_body"
|
||||
|
||||
_primedns_retried=""
|
||||
while true; do
|
||||
#acme.sh sends _H1.._H5 with every later request of this process, so the API key
|
||||
#header must not stay set once this call is done (it would reach other hosts).
|
||||
_primedns_old_h1="$_H1"
|
||||
export _H1="X-API-Key: $PRIMEDNS_API_KEY"
|
||||
: >"$HTTP_HEADER"
|
||||
response="$(_post "$_body" "$_url" "" "$_method" "application/json")"
|
||||
_ret=$?
|
||||
export _H1="$_primedns_old_h1"
|
||||
_status=$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d '\r\n')
|
||||
if [ "$_ret" != "0" ]; then
|
||||
_err "Error calling the PrimeDNS API ($_method /dns/acme-challenge)."
|
||||
return 1
|
||||
fi
|
||||
response="$(echo "$response" | _normalizeJson)"
|
||||
_debug response "$response"
|
||||
_debug _status "$_status"
|
||||
|
||||
#Rate limited or temporary server error: wait and try once more.
|
||||
if [ -z "$_primedns_retried" ] && { [ "$_status" = "429" ] || [ "$_status" = "502" ] || [ "$_status" = "503" ] || [ "$_status" = "504" ]; }; then
|
||||
_wait="$(_retryafter_seconds <"$HTTP_HEADER")"
|
||||
case "$_wait" in
|
||||
'' | *[!0-9]*) _wait=5 ;;
|
||||
esac
|
||||
[ "$_wait" -gt 60 ] && _wait=60
|
||||
_info "PrimeDNS API answered HTTP $_status, retrying in $_wait seconds."
|
||||
_sleep "$_wait"
|
||||
_primedns_retried=1
|
||||
continue
|
||||
fi
|
||||
break
|
||||
done
|
||||
|
||||
if _contains "$response" '"success":true'; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$_status" = "401" ]; then
|
||||
_err "The PrimeDNS API refused the key (HTTP 401): it is wrong, revoked or expired. Check PRIMEDNS_API_KEY."
|
||||
elif _contains "$response" 'IP_NOT_ALLOWED'; then
|
||||
_err "This PrimeDNS API key may not be used from this address (allowed_ips). Add the address to the key or run acme.sh from an allowed host."
|
||||
elif _contains "$response" 'NAME_NOT_ALLOWED'; then
|
||||
_err "This PrimeDNS API key may not write $_name: add the scope acme:name:$_name to the key, or the zone to its allowed zones."
|
||||
elif _contains "$response" 'INSUFFICIENT_SCOPE'; then
|
||||
_err "This PrimeDNS API key needs the scope acme:name:$_name (or dns:write)."
|
||||
elif _contains "$response" 'DOMAIN_NOT_FOUND'; then
|
||||
_err "$_name is not in a zone of the PrimeDNS account that owns this API key."
|
||||
elif [ "$_status" = "429" ]; then
|
||||
_err "PrimeDNS API rate limit still hit after a retry. Try again in a minute."
|
||||
else
|
||||
_err "PrimeDNS API error (HTTP $_status): $response"
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
+3
-6
@@ -106,16 +106,13 @@ dns_yc_add() {
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting txt records"
|
||||
if ! _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$fulldomain"; then
|
||||
if ! _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$_sub_domain"; then
|
||||
_err "Error: $response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Adding record"
|
||||
# The absolute name (trailing dot) also covers a record at the zone apex,
|
||||
# e.g. with --domain-alias, which has no relative form: an empty name is
|
||||
# rejected by the API.
|
||||
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"merges\": [ { \"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
|
||||
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"merges\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
|
||||
if _contains "$response" "\"done\": *true"; then
|
||||
_info "Added, OK"
|
||||
return 0
|
||||
@@ -170,7 +167,7 @@ dns_yc_rm() {
|
||||
# upsertRecordSets.deletions removes only the given value from the rrset,
|
||||
# leaving any other values at the same name (e.g. base + wildcard domain)
|
||||
# intact -- no need to read the current data set and recompute it.
|
||||
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"deletions\": [ { \"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
|
||||
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"deletions\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
|
||||
if _contains "$response" "\"done\": *true"; then
|
||||
_info "Delete, OK"
|
||||
return 0
|
||||
|
||||