Failed to extract signature
1 changed files with 159 additions and 0 deletions
@ -0,0 +1,159 @@ |
|||
#!/usr/bin/env sh |
|||
# shellcheck disable=SC2034 |
|||
dns_link11_info='link11.com |
|||
Site: link11.com/ |
|||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_link11 |
|||
Options: |
|||
LINK11_API_KEY xxxx |
|||
' |
|||
|
|||
LINK11_API="https://api.link11.de" |
|||
LINK11_SERVICE_KEY="l11securedns" |
|||
# Link11 API documentation https://docs.link11.com/using-link11/api/secure-dns |
|||
# How to create an API key: https://docs.link11.com/product-guides/secure-dns/interface/api-access |
|||
|
|||
######## Public functions ##################### |
|||
|
|||
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
dns_link11_add() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
|
|||
LINK11_API_KEY="${LINK11_API_KEY:-$(_readaccountconf_mutable LINK11_API_KEY)}" |
|||
_saveaccountconf_mutable LINK11_API_KEY "$LINK11_API_KEY" |
|||
|
|||
_info "Using Link11 Secure DNS" |
|||
_debug fulldomain "$fulldomain" |
|||
_debug txtvalue "$txtvalue" |
|||
if [ -z "$LINK11_API_KEY" ]; then |
|||
_err "Missing LINK11_API_KEY environment variable." |
|||
fi |
|||
if ! _exists jq; then |
|||
_err "Tool 'jq' is required but not installed." |
|||
return 1 |
|||
fi |
|||
|
|||
_debug "First detect the root zone for $fulldomain" |
|||
if ! _get_root "$fulldomain"; then |
|||
_err "Failed to get root zone for $fulldomain" |
|||
return 1 |
|||
fi |
|||
_debug _zone_id "$_zone_id" |
|||
_debug _domain "$_domain" |
|||
_debug _sub_domain "$_sub_domain" |
|||
|
|||
# get existing entries for the zone |
|||
if ! _link11_rest "list_primary_zone_entries&zone=$_zone_id"; then |
|||
_err "Failed to list primary zone entries for $_zone_id" |
|||
return 1 |
|||
fi |
|||
value="$(printf "%s" "$response" | jq -r --arg sub_domain "$_sub_domain" '.data[] | select(.type=="TXT" and .name==$sub_domain) | .value' | _head_n 1)" |
|||
if [ -n "$value" ]; then |
|||
_debug2 "Entry already exists for $_sub_domain with value $value" |
|||
if [ "$value" = "$txtvalue" ]; then |
|||
_info "TXT record for $fulldomain already exists with the correct value." |
|||
return 0 |
|||
else |
|||
_debug2 "Updating existing TXT record for $_sub_domain with new value $txtvalue" |
|||
entry_id="$(printf "%s" "$response" | jq -r --arg sub_domain "$_sub_domain" '.data[] | select(.type=="TXT" and .name==$sub_domain) | .id' | _head_n 1)" |
|||
_link11_rest "update_primary_zone_entry&zone=$_zone_id&entry=$entry_id&value=$txtvalue" |
|||
fi |
|||
else |
|||
_debug2 "No existing entry found for $_sub_domain, adding new TXT record" |
|||
_link11_rest "add_primary_zone_entry&zone=$_zone_id&name=$_sub_domain&value=$txtvalue&type=TXT&ttl=60" |
|||
fi |
|||
|
|||
# validate the addition |
|||
if ! _link11_rest "list_primary_zone_entries&zone=$_zone_id"; then |
|||
_err "Failed to list primary zone entries for $_zone_id" |
|||
return 1 |
|||
fi |
|||
value="$(printf "%s" "$response" | jq -r --arg sub_domain "$_sub_domain" '.data[] | select(.type=="TXT" and .name==$sub_domain) | .value' | _head_n 1)" |
|||
if [ -z "$value" ] || [ "$value" != "$txtvalue" ]; then |
|||
_debug2 "Expected TXT record value for $_sub_domain is $txtvalue, but got $value" |
|||
_err "Failed to add TXT record for $fulldomain" |
|||
return 1 |
|||
fi |
|||
_info "Added TXT record for $fulldomain with value $txtvalue" |
|||
} |
|||
|
|||
#Usage: fulldomain txtvalue |
|||
#Remove the txt record after validation. |
|||
dns_link11_rm() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
_info "Using Link11 Secure DNS" |
|||
|
|||
_debug "First detect the root zone for $fulldomain" |
|||
if ! _get_root "$fulldomain"; then |
|||
_err "Failed to get root zone for $fulldomain" |
|||
return 1 |
|||
fi |
|||
_debug _zone_id "$_zone_id" |
|||
_debug _domain "$_domain" |
|||
_debug _sub_domain "$_sub_domain" |
|||
|
|||
# get entry id |
|||
if ! _link11_rest "list_primary_zone_entries&zone=$_zone_id"; then |
|||
_err "Failed to list primary zone entries for $_zone_id" |
|||
return 1 |
|||
fi |
|||
entry_id="$(printf "%s" "$response" | jq -r --arg sub_domain "$_sub_domain" '.data[] | select(.type=="TXT" and .name==$sub_domain) | .id' | _head_n 1)" |
|||
if [ -z "$entry_id" ]; then |
|||
_info "Nothing to remove, no entry found for $_sub_domain" |
|||
return 0 |
|||
fi |
|||
# remove entry |
|||
if ! _link11_rest "delete_primary_zone_entry&zone=$_zone_id&entry=$entry_id"; then |
|||
_err "Failed to remove entry for $_sub_domain" |
|||
return 1 |
|||
fi |
|||
_debug2 "Removed entry for $_sub_domain" |
|||
return 0 |
|||
} |
|||
|
|||
#################### Private functions below ################################## |
|||
|
|||
#_acme-challenge.www.domain.com |
|||
#returns |
|||
# _zone_id=l11securednsprimary1234 |
|||
# _domain=domain.com |
|||
# _sub_domain=_acme-challenge.www |
|||
_get_root() { |
|||
domain="$1" |
|||
|
|||
_link11_rest "list_primary_zones" |
|||
while true; do |
|||
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) |
|||
_debug2 h "$h" |
|||
if [ -z "$h" ]; then |
|||
#not valid |
|||
return 1 |
|||
fi |
|||
_zone_id="$(printf "%s" "$response" | jq -r --arg h "$h" '.data[] | select(.domain==$h) | .id')" |
|||
if [ "$_zone_id" ]; 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 |
|||
} |
|||
|
|||
_link11_rest() { |
|||
parameters="$1" |
|||
_debug2 "parameters" "$parameters" |
|||
|
|||
export _H1="Content-Type: application/json" |
|||
export _H2="key: $LINK11_API_KEY" |
|||
response="$(_get "$LINK11_API/?apikey=$LINK11_SERVICE_KEY&$parameters")" |
|||
# shellcheck disable=SC2181 |
|||
if [ "$?" != "0" ] || [ "$(printf "%s" "$response" | jq -r '.status_code')" != "200" ]; then |
|||
_err "$response" |
|||
return 1 |
|||
fi |
|||
_debug2 "response" "$response" |
|||
return 0 |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue