You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
5.7 KiB
201 lines
5.7 KiB
#!/usr/bin/env sh
|
|
# shellcheck disable=SC2034
|
|
dns_apertodns_info='ApertoDNS
|
|
Site: www.apertodns.com
|
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_apertodns
|
|
Options:
|
|
APERTODNS_API_KEY API Key
|
|
APERTODNS_API_URL API URL (optional, default: https://api.apertodns.com)
|
|
Author: Andrea Ferro <support@apertodns.com>
|
|
'
|
|
|
|
APERTODNS_API_DEFAULT="https://api.apertodns.com"
|
|
|
|
######## Public functions #####################
|
|
|
|
# Usage: dns_apertodns_add _acme-challenge.myhost.apertodns.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
|
dns_apertodns_add() {
|
|
fulldomain=$1
|
|
txtvalue=$2
|
|
|
|
_info "Using ApertoDNS API"
|
|
_debug fulldomain "$fulldomain"
|
|
_debug txtvalue "$txtvalue"
|
|
|
|
APERTODNS_API_KEY="${APERTODNS_API_KEY:-$(_readaccountconf_mutable APERTODNS_API_KEY)}"
|
|
APERTODNS_API_URL="${APERTODNS_API_URL:-$(_readaccountconf_mutable APERTODNS_API_URL)}"
|
|
|
|
if [ -z "$APERTODNS_API_KEY" ]; then
|
|
APERTODNS_API_KEY=""
|
|
_err "You did not specify APERTODNS_API_KEY yet."
|
|
_err "Please create your API key at https://www.apertodns.com/dashboard and try again."
|
|
_err "e.g."
|
|
_err "export APERTODNS_API_KEY=apertodns_live_xxxxxxxx"
|
|
return 1
|
|
fi
|
|
|
|
if [ -z "$APERTODNS_API_URL" ]; then
|
|
APERTODNS_API_URL="$APERTODNS_API_DEFAULT"
|
|
fi
|
|
|
|
# Save the credentials
|
|
_saveaccountconf_mutable APERTODNS_API_KEY "$APERTODNS_API_KEY"
|
|
if [ "$APERTODNS_API_URL" != "$APERTODNS_API_DEFAULT" ]; then
|
|
_saveaccountconf_mutable APERTODNS_API_URL "$APERTODNS_API_URL"
|
|
fi
|
|
|
|
# Extract hostname and TXT name from fulldomain
|
|
# fulldomain: _acme-challenge.myhost.apertodns.com
|
|
# hostname: myhost.apertodns.com
|
|
# txtname: _acme-challenge
|
|
if ! _apertodns_parse_domain "$fulldomain"; then
|
|
return 1
|
|
fi
|
|
|
|
_debug _hostname "$_hostname"
|
|
_debug _txtname "$_txtname"
|
|
|
|
# Build JSON payload
|
|
_info "Adding TXT record for $_hostname"
|
|
_body="{\"hostname\":\"$_hostname\",\"txt\":{\"name\":\"$_txtname\",\"value\":\"$txtvalue\",\"action\":\"set\"}}"
|
|
|
|
if _apertodns_rest POST "/.well-known/apertodns/v1/update" "$_body"; then
|
|
if _contains "$response" "\"success\":true" || _contains "$response" "\"status\":\"good\"" || _contains "$response" "\"status\":\"nochg\""; then
|
|
_info "TXT record added successfully"
|
|
return 0
|
|
else
|
|
_err "Failed to add TXT record: $response"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
_err "Error adding TXT record"
|
|
return 1
|
|
}
|
|
|
|
# Usage: dns_apertodns_rm _acme-challenge.myhost.apertodns.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
|
dns_apertodns_rm() {
|
|
fulldomain=$1
|
|
txtvalue=$2
|
|
|
|
_info "Using ApertoDNS API"
|
|
_debug fulldomain "$fulldomain"
|
|
_debug txtvalue "$txtvalue"
|
|
|
|
APERTODNS_API_KEY="${APERTODNS_API_KEY:-$(_readaccountconf_mutable APERTODNS_API_KEY)}"
|
|
APERTODNS_API_URL="${APERTODNS_API_URL:-$(_readaccountconf_mutable APERTODNS_API_URL)}"
|
|
|
|
if [ -z "$APERTODNS_API_KEY" ]; then
|
|
APERTODNS_API_KEY=""
|
|
_err "You did not specify APERTODNS_API_KEY yet."
|
|
return 1
|
|
fi
|
|
|
|
if [ -z "$APERTODNS_API_URL" ]; then
|
|
APERTODNS_API_URL="$APERTODNS_API_DEFAULT"
|
|
fi
|
|
|
|
# Extract hostname and TXT name from fulldomain
|
|
if ! _apertodns_parse_domain "$fulldomain"; then
|
|
return 1
|
|
fi
|
|
|
|
_debug _hostname "$_hostname"
|
|
_debug _txtname "$_txtname"
|
|
|
|
# Build JSON payload (include value for multi-TXT support)
|
|
_info "Removing TXT record for $_hostname"
|
|
_body="{\"hostname\":\"$_hostname\",\"txt\":{\"name\":\"$_txtname\",\"value\":\"$txtvalue\",\"action\":\"delete\"}}"
|
|
|
|
if _apertodns_rest POST "/.well-known/apertodns/v1/update" "$_body"; then
|
|
if _contains "$response" "\"success\":true" || _contains "$response" "\"status\":\"good\"" || _contains "$response" "\"status\":\"nochg\""; then
|
|
_info "TXT record removed successfully"
|
|
return 0
|
|
else
|
|
_err "Failed to remove TXT record: $response"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
_err "Error removing TXT record"
|
|
return 1
|
|
}
|
|
|
|
#################### Private functions below ##################################
|
|
|
|
# Parse fulldomain to extract hostname and txtname
|
|
# Input: _acme-challenge.myhost.apertodns.com
|
|
# Output: _hostname=myhost.apertodns.com, _txtname=_acme-challenge
|
|
_apertodns_parse_domain() {
|
|
domain="$1"
|
|
|
|
# Check if domain ends with .apertodns.com
|
|
if ! _contains "$domain" ".apertodns.com"; then
|
|
_err "Domain must be under apertodns.com"
|
|
return 1
|
|
fi
|
|
|
|
# Extract the TXT name (first part before the hostname)
|
|
# For _acme-challenge.myhost.apertodns.com:
|
|
# - _txtname = _acme-challenge
|
|
# - _hostname = myhost.apertodns.com
|
|
|
|
# Count dots to determine structure
|
|
# _acme-challenge.myhost.apertodns.com has 4 parts
|
|
# myhost.apertodns.com has 3 parts
|
|
|
|
# Get everything after the first dot
|
|
_rest="$(printf "%s" "$domain" | cut -d . -f 2-)"
|
|
|
|
# Check if _rest is a valid apertodns hostname (X.apertodns.com)
|
|
if _contains "$_rest" ".apertodns.com"; then
|
|
# The first part is the TXT name
|
|
_txtname="$(printf "%s" "$domain" | cut -d . -f 1)"
|
|
_hostname="$_rest"
|
|
else
|
|
# No subdomain prefix, use the full domain
|
|
_txtname="_acme-challenge"
|
|
_hostname="$domain"
|
|
fi
|
|
|
|
# Validate hostname format
|
|
if [ -z "$_hostname" ] || [ -z "$_txtname" ]; then
|
|
_err "Could not parse domain: $domain"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# REST API call
|
|
# Usage: _apertodns_rest METHOD ENDPOINT [DATA]
|
|
_apertodns_rest() {
|
|
method="$1"
|
|
endpoint="$2"
|
|
data="$3"
|
|
|
|
url="$APERTODNS_API_URL$endpoint"
|
|
|
|
export _H1="Authorization: Bearer $APERTODNS_API_KEY"
|
|
export _H2="Content-Type: application/json"
|
|
export _H3="Accept: application/json"
|
|
|
|
_debug url "$url"
|
|
|
|
if [ "$method" = "POST" ]; then
|
|
_secure_debug2 data "$data"
|
|
response="$(_post "$data" "$url" "" "POST")"
|
|
else
|
|
response="$(_get "$url")"
|
|
fi
|
|
|
|
_ret="$?"
|
|
_debug2 response "$response"
|
|
|
|
if [ "$_ret" != "0" ]; then
|
|
_err "API request failed"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|