mirror of
https://github.com/anikeen-com/acme.sh.git
synced 2026-03-13 13:46:10 +00:00
Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d0cffc9eed | |||
|
|
65239c7c25 | ||
|
|
1b123054b3 | ||
|
|
b29d17f522 | ||
|
|
04aefbf28d | ||
|
|
0e4fd5269b | ||
|
|
6328496bfb | ||
|
|
524b40b75f | ||
|
|
0241552c0d | ||
|
|
fd3f6687ce | ||
|
|
93d63749e6 | ||
|
|
41bf5450d9 | ||
|
|
d37553e7b8 | ||
|
|
101d7138c2 | ||
|
|
11de3aed51 | ||
|
|
1ae7dd9b11 | ||
|
e6ea3548e2
|
|||
|
|
a3250fac6d | ||
|
0adea055ef
|
|||
|
|
fabe6317ef | ||
|
|
9526dbadad | ||
|
|
6ad469c637 | ||
|
|
b30cdf0873 | ||
|
|
234bc93ddb | ||
|
|
42862852b8 | ||
|
|
7a6101c417 | ||
|
|
588123ed11 | ||
|
|
ac9852f9df | ||
|
|
d093476da5 | ||
|
|
9ad794f2cc | ||
|
|
b0f566a80d | ||
|
|
150c708726 | ||
|
|
7512dbffbb | ||
|
|
3cfa882fe1 | ||
|
|
35f3b7088d | ||
|
|
07220a324d | ||
|
|
c7cecd5b4f | ||
|
|
ab1a2045d9 | ||
|
|
5e9a067e87 | ||
|
|
4cc460be64 | ||
|
|
02da1700e0 | ||
|
|
a9f97e1fe2 | ||
|
|
d75077c6f9 | ||
|
|
b81939f02d | ||
|
|
0e1d90dd0c | ||
|
|
03e9c612b9 | ||
|
|
f981c782bb | ||
|
|
3fbdb7a007 | ||
|
|
2997a15ba8 | ||
|
|
b4c02eca16 | ||
|
|
223dc87cef | ||
|
|
3ccdae0634 | ||
|
|
11af6f49c6 | ||
|
|
157d3f9dc9 | ||
|
|
fca53a0c2c | ||
|
|
6d302889fa | ||
|
|
a94ac63e74 | ||
|
|
19e73f8889 | ||
|
|
aacc26179e | ||
|
|
36f060dcf6 | ||
|
|
cb12c8dfd5 | ||
|
|
9cd1d1a9dc | ||
|
|
c3557bbe3f | ||
|
|
cd924099e4 | ||
|
|
3b8608761b | ||
|
|
4299c6a802 | ||
|
|
4232923641 | ||
|
|
412e14a41c | ||
|
|
2bb5fbdee5 | ||
|
|
38c41b72d6 | ||
|
|
b665014707 | ||
|
|
e98e7a232f | ||
|
|
5f7ad72d45 | ||
|
|
0cc74b7cfe | ||
|
|
d7bafa6dfa | ||
|
|
717802611a | ||
|
|
b6a77e0231 | ||
|
|
ed72b090af |
1
.github/workflows/pr_dns.yml
vendored
1
.github/workflows/pr_dns.yml
vendored
@@ -23,6 +23,7 @@ jobs:
|
||||
First thing: don't send PR to the master branch, please send to the dev branch instead.
|
||||
Please make sure you've read our [DNS API Dev Guide](../wiki/DNS-API-Dev-Guide) and [DNS-API-Test](../wiki/DNS-API-Test).
|
||||
Then reply on this message, otherwise, your code will not be reviewed or merged.
|
||||
Please also make sure to add/update the usage here: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2
|
||||
We look forward to reviewing your Pull request shortly ✨
|
||||
注意: 必须通过了 [DNS-API-Test](../wiki/DNS-API-Test) 才会被 review. 无论是修改, 还是新加的 dns api, 都必须确保通过这个测试.
|
||||
`
|
||||
|
||||
172
deploy/ruckus.sh
Executable file
172
deploy/ruckus.sh
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed.
|
||||
#
|
||||
# Public domain, 2024, Tony Rielly <https://github.com/ms264556>
|
||||
#
|
||||
# ```sh
|
||||
# acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus
|
||||
# ```
|
||||
#
|
||||
# Then you need to set the environment variables for the
|
||||
# deploy script to work.
|
||||
#
|
||||
# ```sh
|
||||
# export RUCKUS_HOST=myruckus.example.com
|
||||
# export RUCKUS_USER=myruckususername
|
||||
# export RUCKUS_PASS=myruckuspassword
|
||||
#
|
||||
# acme.sh --deploy -d myruckus.example.com --deploy-hook ruckus
|
||||
# ```
|
||||
#
|
||||
# returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
ruckus_deploy() {
|
||||
_cdomain="$1"
|
||||
_ckey="$2"
|
||||
_ccert="$3"
|
||||
_cca="$4"
|
||||
_cfullchain="$5"
|
||||
_err_code=0
|
||||
|
||||
_debug _cdomain "$_cdomain"
|
||||
_debug _ckey "$_ckey"
|
||||
_debug _ccert "$_ccert"
|
||||
_debug _cca "$_cca"
|
||||
_debug _cfullchain "$_cfullchain"
|
||||
|
||||
_getdeployconf RUCKUS_HOST
|
||||
_getdeployconf RUCKUS_USER
|
||||
_getdeployconf RUCKUS_PASS
|
||||
|
||||
if [ -z "$RUCKUS_HOST" ]; then
|
||||
_debug "Using _cdomain as RUCKUS_HOST, please set if not correct."
|
||||
RUCKUS_HOST="$_cdomain"
|
||||
fi
|
||||
|
||||
if [ -z "$RUCKUS_USER" ]; then
|
||||
_err "Need to set the env variable RUCKUS_USER"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "$RUCKUS_PASS" ]; then
|
||||
_err "Need to set the env variable RUCKUS_PASS"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_savedeployconf RUCKUS_HOST "$RUCKUS_HOST"
|
||||
_savedeployconf RUCKUS_USER "$RUCKUS_USER"
|
||||
_savedeployconf RUCKUS_PASS "$RUCKUS_PASS"
|
||||
|
||||
_debug RUCKUS_HOST "$RUCKUS_HOST"
|
||||
_debug RUCKUS_USER "$RUCKUS_USER"
|
||||
_secure_debug RUCKUS_PASS "$RUCKUS_PASS"
|
||||
|
||||
export ACME_HTTP_NO_REDIRECTS=1
|
||||
|
||||
_info "Discovering the login URL"
|
||||
_get "https://$RUCKUS_HOST" >/dev/null
|
||||
_login_url="$(_response_header 'Location')"
|
||||
if [ -n "$_login_url" ]; then
|
||||
_login_path=$(echo "$_login_url" | sed 's|https\?://[^/]\+||')
|
||||
if [ -z "$_login_path" ]; then
|
||||
# redirect was to a different host
|
||||
_err "Connection failed: redirected to a different host. Configure Unleashed with a Preferred Master or Management Interface."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${_login_url}" ]; then
|
||||
_err "Connection failed: couldn't find login page."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_base_url=$(dirname "$_login_url")
|
||||
_login_page=$(basename "$_login_url")
|
||||
|
||||
if [ "$_login_page" = "index.html" ]; then
|
||||
_err "Connection temporarily unavailable: Unleashed Rebuilding."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$_login_page" = "wizard.jsp" ]; then
|
||||
_err "Connection failed: Setup Wizard not complete."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Login"
|
||||
_username_encoded="$(printf "%s" "$RUCKUS_USER" | _url_encode)"
|
||||
_password_encoded="$(printf "%s" "$RUCKUS_PASS" | _url_encode)"
|
||||
_login_query="$(printf "%s" "username=${_username_encoded}&password=${_password_encoded}&ok=Log+In")"
|
||||
_post "$_login_query" "$_login_url" >/dev/null
|
||||
|
||||
_login_code="$(_response_code)"
|
||||
if [ "$_login_code" = "200" ]; then
|
||||
_err "Login failed: incorrect credentials."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Collect Session Cookie"
|
||||
_H1="Cookie: $(_response_cookie)"
|
||||
export _H1
|
||||
_info "Collect CSRF Token"
|
||||
_H2="X-CSRF-Token: $(_response_header 'HTTP_X_CSRF_TOKEN')"
|
||||
export _H2
|
||||
|
||||
_info "Uploading certificate"
|
||||
_post_upload "uploadcert" "$_cfullchain"
|
||||
|
||||
_info "Uploading private key"
|
||||
_post_upload "uploadprivatekey" "$_ckey"
|
||||
|
||||
_info "Replacing certificate"
|
||||
_replace_cert_ajax='<ajax-request action="docmd" comp="system" updater="rid.0.5" xcmd="replace-cert" checkAbility="6" timeout="-1"><xcmd cmd="replace-cert" cn="'$RUCKUS_HOST'"/></ajax-request>'
|
||||
_post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null
|
||||
|
||||
_info "Rebooting"
|
||||
_cert_reboot_ajax='<ajax-request action="docmd" comp="worker" updater="rid.0.5" xcmd="cert-reboot" checkAbility="6"><xcmd cmd="cert-reboot" action="undefined"/></ajax-request>'
|
||||
_post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_response_code() {
|
||||
_egrep_o <"$HTTP_HEADER" "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*"
|
||||
}
|
||||
|
||||
_response_header() {
|
||||
grep <"$HTTP_HEADER" -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t "
|
||||
}
|
||||
|
||||
_response_cookie() {
|
||||
_response_header 'Set-Cookie' | sed 's/;.*//'
|
||||
}
|
||||
|
||||
_post_upload() {
|
||||
_post_action="$1"
|
||||
_post_file="$2"
|
||||
|
||||
_post_boundary="----FormBoundary$(date "+%s%N")"
|
||||
|
||||
_post_data="$({
|
||||
printf -- "--%s\r\n" "$_post_boundary"
|
||||
printf -- "Content-Disposition: form-data; name=\"u\"; filename=\"%s\"\r\n" "$_post_action"
|
||||
printf -- "Content-Type: application/octet-stream\r\n\r\n"
|
||||
printf -- "%s\r\n" "$(cat "$_post_file")"
|
||||
|
||||
printf -- "--%s\r\n" "$_post_boundary"
|
||||
printf -- "Content-Disposition: form-data; name=\"action\"\r\n\r\n"
|
||||
printf -- "%s\r\n" "$_post_action"
|
||||
|
||||
printf -- "--%s\r\n" "$_post_boundary"
|
||||
printf -- "Content-Disposition: form-data; name=\"callback\"\r\n\r\n"
|
||||
printf -- "%s\r\n" "uploader_$_post_action"
|
||||
|
||||
printf -- "--%s--\r\n\r\n" "$_post_boundary"
|
||||
})"
|
||||
|
||||
_post "$_post_data" "$_base_url/_upload.jsp?request_type=xhr" "" "" "multipart/form-data; boundary=$_post_boundary" >/dev/null
|
||||
}
|
||||
@@ -217,7 +217,7 @@ truenas_deploy() {
|
||||
_app_id=$(echo "$_app_id_list" | sed -n "${i}p")
|
||||
_app_config="$(_post "\"$_app_id\"" "$_api_url/app/config" "" "POST" "application/json")"
|
||||
# Check if the app use the same certificate TrueNAS web UI
|
||||
_app_active_cert_config=$(echo "$_app_config" | _json_decode | jq -r ".ix_certificates[\"$_active_cert_id\"]")
|
||||
_app_active_cert_config=$(echo "$_app_config" | tr -d '\000-\037' | _json_decode | jq -r ".ix_certificates[\"$_active_cert_id\"]")
|
||||
if [ "$_app_active_cert_config" != "null" ]; then
|
||||
_info "Updating certificate from $_active_cert_id to $_cert_id for app: $_app_id"
|
||||
#Replace the old certificate id with the new one in path
|
||||
|
||||
@@ -135,20 +135,36 @@ unifi_deploy() {
|
||||
cp -f "$_import_pkcs12" "$_unifi_keystore"
|
||||
fi
|
||||
|
||||
# correct file ownership according to the directory, the keystore is placed in
|
||||
_unifi_keystore_dir=$(dirname "${_unifi_keystore}")
|
||||
_unifi_keystore_dir_owner=$(find "${_unifi_keystore_dir}" -maxdepth 0 -printf '%u\n')
|
||||
_unifi_keystore_owner=$(find "${_unifi_keystore}" -maxdepth 0 -printf '%u\n')
|
||||
if ! [ "${_unifi_keystore_owner}" = "${_unifi_keystore_dir_owner}" ]; then
|
||||
_debug "Changing keystore owner to ${_unifi_keystore_dir_owner}"
|
||||
chown "$_unifi_keystore_dir_owner" "${_unifi_keystore}" >/dev/null 2>&1 # fail quietly if we're not running as root
|
||||
fi
|
||||
|
||||
# Update unifi service for certificate cipher compatibility
|
||||
if ${ACME_OPENSSL_BIN:-openssl} pkcs12 \
|
||||
-in "$_import_pkcs12" \
|
||||
-password pass:aircontrolenterprise \
|
||||
-nokeys | ${ACME_OPENSSL_BIN:-openssl} x509 -text \
|
||||
-noout | grep -i "signature" | grep -iq ecdsa >/dev/null 2>&1; then
|
||||
cp -f /usr/lib/unifi/data/system.properties /usr/lib/unifi/data/system.properties_original
|
||||
_info "Updating system configuration for cipher compatibility."
|
||||
_info "Saved original system config to /usr/lib/unifi/data/system.properties_original"
|
||||
sed -i '/unifi\.https\.ciphers/d' /usr/lib/unifi/data/system.properties
|
||||
echo "unifi.https.ciphers=ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256" >>/usr/lib/unifi/data/system.properties
|
||||
sed -i '/unifi\.https\.sslEnabledProtocols/d' /usr/lib/unifi/data/system.properties
|
||||
echo "unifi.https.sslEnabledProtocols=TLSv1.3,TLSv1.2" >>/usr/lib/unifi/data/system.properties
|
||||
_info "System configuration updated."
|
||||
if [ -f "$(dirname "${DEPLOY_UNIFI_KEYSTORE}")/system.properties" ]; then
|
||||
_unifi_system_properties="$(dirname "${DEPLOY_UNIFI_KEYSTORE}")/system.properties"
|
||||
else
|
||||
_unifi_system_properties="/usr/lib/unifi/data/system.properties"
|
||||
fi
|
||||
if [ -f "${_unifi_system_properties}" ]; then
|
||||
cp -f "${_unifi_system_properties}" "${_unifi_system_properties}"_original
|
||||
_info "Updating system configuration for cipher compatibility."
|
||||
_info "Saved original system config to ${_unifi_system_properties}_original"
|
||||
sed -i '/unifi\.https\.ciphers/d' "${_unifi_system_properties}"
|
||||
echo "unifi.https.ciphers=ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256" >>"${_unifi_system_properties}"
|
||||
sed -i '/unifi\.https\.sslEnabledProtocols/d' "${_unifi_system_properties}"
|
||||
echo "unifi.https.sslEnabledProtocols=TLSv1.3,TLSv1.2" >>"${_unifi_system_properties}"
|
||||
_info "System configuration updated."
|
||||
fi
|
||||
fi
|
||||
|
||||
rm "$_import_pkcs12"
|
||||
|
||||
151
dnsapi/dns_anikeen.sh
Executable file
151
dnsapi/dns_anikeen.sh
Executable file
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034
|
||||
|
||||
dns_anikeen_info='Anikeen Cloud
|
||||
Site: Anikeen.cloud
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_anikeen
|
||||
Options:
|
||||
ANIKEEN_API_KEY API Key
|
||||
Issues: github.com/acmesh-official/acme.sh/issues/6175
|
||||
Author: Maurice Preuß <maurice@anikeen.com>
|
||||
'
|
||||
|
||||
### Public functions
|
||||
|
||||
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
# Used to add txt record
|
||||
dns_anikeen_add() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
_info "Using Anikeen Cloud API to add TXT record"
|
||||
|
||||
_check_anikeen_api_key || return 1
|
||||
|
||||
_debug "Finding zone for domain: $fulldomain"
|
||||
_anikeen_find_zone "$fulldomain"
|
||||
if [ -z "$_domain_id" ]; then
|
||||
_err "Domain not found in Anikeen Cloud API"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Adding TXT record"
|
||||
_anikeen_add_record "$_domain_id" "$fulldomain" "TXT" "$txtvalue"
|
||||
}
|
||||
|
||||
# Usage: fulldomain txtvalue
|
||||
# Used to remove the txt record after validation
|
||||
dns_anikeen_rm() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
_info "Using Anikeen Cloud API to remove TXT record"
|
||||
|
||||
_check_anikeen_api_key || return 1
|
||||
|
||||
_debug "Finding zone for domain: $fulldomain"
|
||||
_anikeen_find_zone "$fulldomain"
|
||||
if [ -z "$_domain_id" ]; then
|
||||
_err "Domain not found in Anikeen Cloud API"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Removing TXT record"
|
||||
_anikeen_delete_record "$_domain_id" "$fulldomain" "TXT" "$txtvalue"
|
||||
}
|
||||
|
||||
### Private functions
|
||||
|
||||
_check_anikeen_api_key() {
|
||||
ANIKEEN_API_KEY="${ANIKEEN_API_KEY:-$(_readaccountconf_mutable ANIKEEN_API_KEY)}"
|
||||
if [ -z "$ANIKEEN_API_KEY" ]; then
|
||||
ANIKEEN_API_KEY=""
|
||||
_err "You don't specify the Anikeen Cloud api key yet."
|
||||
_err "Please create your key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# save the credentials to the account conf file
|
||||
_saveaccountconf_mutable ANIKEEN_API_KEY "$ANIKEEN_API_KEY"
|
||||
|
||||
_debug "API Key is set"
|
||||
|
||||
export _H1="Accept: application/json"
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="Authorization: Bearer $ANIKEEN_API_KEY"
|
||||
|
||||
_debug "Headers set"
|
||||
}
|
||||
|
||||
_anikeen_find_zone() {
|
||||
domain="$1"
|
||||
|
||||
while [ -n "$domain" ]; do
|
||||
_debug2 "Finding zone for domain: $domain"
|
||||
|
||||
response=$(_get "https://api.anikeen.cloud/v1/zones?name=$domain")
|
||||
_debug2 response "$response"
|
||||
|
||||
if echo "$response" | grep -q '"data"'; then
|
||||
_domain_id=$(echo "$response" | _egrep_o '"data":\[\{"id":"[a-zA-Z0-9]*"' | _egrep_o '[a-zA-Z0-9]{26}')
|
||||
|
||||
if [ -n "$_domain_id" ]; then
|
||||
_info "Using zone $_domain_id for domain $domain"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
domain="${domain#*.}"
|
||||
done
|
||||
|
||||
_err "No matching zone found for domain $1"
|
||||
return 1
|
||||
}
|
||||
|
||||
_anikeen_add_record() {
|
||||
domain_id="$1"
|
||||
name="$2"
|
||||
type="$3"
|
||||
content="$4"
|
||||
|
||||
data="{\"name\":\"$name\",\"type\":\"$type\",\"content\":\"\\\"$content\\\"\",\"ttl\":300,\"prio\":0}"
|
||||
response=$(_post "$data" "https://api.anikeen.cloud/v1/zones/$domain_id/records" "", "POST")
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "Failed to add record: $response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 response "$response"
|
||||
|
||||
_info "TXT record added successfully"
|
||||
}
|
||||
|
||||
_anikeen_delete_record() {
|
||||
domain_id="$1"
|
||||
name="$2"
|
||||
type="$3"
|
||||
content="$4"
|
||||
|
||||
response=$(_get "https://api.anikeen.cloud/v1/zones/$domain_id/records?name=$name&type=$type&content=\"$content\"")
|
||||
|
||||
_debug2 response "$response"
|
||||
|
||||
record_id=$(echo "$response" | _egrep_o '"data":\[\{"id":[0-9]*' | _egrep_o '[0-9]*')
|
||||
|
||||
if [ -z "$record_id" ]; then
|
||||
_err "Record not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
response=$(_post "", "https://api.anikeen.cloud/v1/zones/$domain_id/records/$record_id", "", "DELETE")
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "Failed to delete record: $response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 response "$response"
|
||||
|
||||
_info "TXT record removed successfully"
|
||||
}
|
||||
@@ -9,7 +9,7 @@ Options:
|
||||
AZUREDNS_APPID App ID. App ID of the service principal
|
||||
AZUREDNS_CLIENTSECRET Client Secret. Secret from creating the service principal
|
||||
AZUREDNS_MANAGEDIDENTITY Use Managed Identity. Use Managed Identity assigned to a resource instead of a service principal. "true"/"false"
|
||||
AZUREDNS_BEARERTOKEN Optional Bearer Token. Used instead of service principal credentials or managed identity
|
||||
AZUREDNS_BEARERTOKEN Bearer Token. Used instead of service principal credentials or managed identity. Optional.
|
||||
'
|
||||
|
||||
wiki=https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Azure-DNS
|
||||
|
||||
@@ -215,10 +215,8 @@ _cyon_change_domain_env() {
|
||||
|
||||
if ! _cyon_check_if_2fa_missed "${domain_env_response}"; then return 1; fi
|
||||
|
||||
domain_env_success="$(printf "%s" "${domain_env_response}" | _egrep_o '"authenticated":\w*' | cut -d : -f 2)"
|
||||
|
||||
# Bail if domain environment change fails.
|
||||
if [ "${domain_env_success}" != "true" ]; then
|
||||
if [ "$(printf "%s" "${domain_env_response}" | _cyon_get_environment_change_status)" != "true" ]; then
|
||||
_err " $(printf "%s" "${domain_env_response}" | _cyon_get_response_message)"
|
||||
_err ""
|
||||
return 1
|
||||
@@ -232,7 +230,7 @@ _cyon_add_txt() {
|
||||
_info " - Adding DNS TXT entry..."
|
||||
|
||||
add_txt_url="https://my.cyon.ch/domain/dnseditor/add-record-async"
|
||||
add_txt_data="zone=${fulldomain_idn}.&ttl=900&type=TXT&value=${txtvalue}"
|
||||
add_txt_data="name=${fulldomain_idn}.&ttl=900&type=TXT&dnscontent=${txtvalue}"
|
||||
|
||||
add_txt_response="$(_post "$add_txt_data" "$add_txt_url")"
|
||||
_debug add_txt_response "${add_txt_response}"
|
||||
@@ -241,9 +239,10 @@ _cyon_add_txt() {
|
||||
|
||||
add_txt_message="$(printf "%s" "${add_txt_response}" | _cyon_get_response_message)"
|
||||
add_txt_status="$(printf "%s" "${add_txt_response}" | _cyon_get_response_status)"
|
||||
add_txt_validation="$(printf "%s" "${add_txt_response}" | _cyon_get_validation_status)"
|
||||
|
||||
# Bail if adding TXT entry fails.
|
||||
if [ "${add_txt_status}" != "true" ]; then
|
||||
if [ "${add_txt_status}" != "true" ] || [ "${add_txt_validation}" != "true" ]; then
|
||||
_err " ${add_txt_message}"
|
||||
_err ""
|
||||
return 1
|
||||
@@ -305,13 +304,21 @@ _cyon_get_response_message() {
|
||||
}
|
||||
|
||||
_cyon_get_response_status() {
|
||||
_egrep_o '"status":\w*' | cut -d : -f 2
|
||||
_egrep_o '"status":[a-zA-z0-9]*' | cut -d : -f 2
|
||||
}
|
||||
|
||||
_cyon_get_validation_status() {
|
||||
_egrep_o '"valid":[a-zA-z0-9]*' | cut -d : -f 2
|
||||
}
|
||||
|
||||
_cyon_get_response_success() {
|
||||
_egrep_o '"onSuccess":"[^"]*"' | cut -d : -f 2 | tr -d '"'
|
||||
}
|
||||
|
||||
_cyon_get_environment_change_status() {
|
||||
_egrep_o '"authenticated":[a-zA-z0-9]*' | cut -d : -f 2
|
||||
}
|
||||
|
||||
_cyon_check_if_2fa_missed() {
|
||||
# Did we miss the 2FA?
|
||||
if test "${1#*multi_factor_form}" != "${1}"; then
|
||||
|
||||
@@ -88,7 +88,7 @@ _get_root() {
|
||||
|
||||
i=1
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
|
||||
_debug h "$h"
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Created by Laraveluser
|
||||
#
|
||||
# Pass credentials before "acme.sh --issue --dns dns_limacity ..."
|
||||
# --
|
||||
# export LIMACITY_APIKEY="<API-KEY>"
|
||||
# --
|
||||
#
|
||||
# Pleas note: APIKEY must have following roles: dns.admin, domains.reader
|
||||
# shellcheck disable=SC2034
|
||||
dns_limacity_info='lima-city.de
|
||||
Site: www.lima-city.de
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_limacity
|
||||
Options:
|
||||
LIMACITY_APIKEY API Key. Note: The API Key must have following roles: dns.admin, domains.reader
|
||||
Issues: github.com/acmesh-official/acme.sh/issues/4758
|
||||
Author: @Laraveluser
|
||||
'
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
|
||||
215
dnsapi/dns_mijnhost.sh
Normal file
215
dnsapi/dns_mijnhost.sh
Normal file
@@ -0,0 +1,215 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034
|
||||
dns_mijnhost_info='mijn.host
|
||||
Domains: mijn.host
|
||||
Site: mijn.host
|
||||
Docs: https://mijn.host/api/doc/
|
||||
Issues: https://github.com/acmesh-official/acme.sh/issues/6177
|
||||
Author: peterv99
|
||||
Options:
|
||||
MIJNHOST_API_KEY API Key
|
||||
'
|
||||
|
||||
######## Public functions ###################### Constants for your mijn-host API
|
||||
MIJNHOST_API="https://mijn.host/api/v2"
|
||||
|
||||
# Add TXT record for domain verification
|
||||
dns_mijnhost_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
MIJNHOST_API_KEY="${MIJNHOST_API_KEY:-$(_readaccountconf_mutable MIJNHOST_API_KEY)}"
|
||||
if [ -z "$MIJNHOST_API_KEY" ]; then
|
||||
MIJNHOST_API_KEY=""
|
||||
_err "You haven't specified your mijn-host API key yet."
|
||||
_err "Please add MIJNHOST_API_KEY to the env."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Save the API key for future use
|
||||
_saveaccountconf_mutable MIJNHOST_API_KEY "$MIJNHOST_API_KEY"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "Invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 _sub_domain "$_sub_domain"
|
||||
_debug2 _domain "$_domain"
|
||||
_debug "Adding DNS record" "${fulldomain}."
|
||||
|
||||
# Construct the API URL
|
||||
api_url="$MIJNHOST_API/domains/$_domain/dns"
|
||||
|
||||
# Getting previous records
|
||||
_mijnhost_rest GET "$api_url" ""
|
||||
|
||||
if [ "$_code" != "200" ]; then
|
||||
_err "Error getting current DNS enties ($_code)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
records=$(echo "$response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://')
|
||||
|
||||
_debug2 "Current records" "$records"
|
||||
|
||||
# Build the payload for the API
|
||||
data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"ttl\":300}"
|
||||
|
||||
_debug2 "Record to add" "$data"
|
||||
|
||||
# Updating the records
|
||||
updated_records=$(echo "$records" | sed -E "s/\]( *$)/,$data\]/")
|
||||
|
||||
_debug2 "Updated records" "$updated_records"
|
||||
|
||||
# data
|
||||
data="{\"records\": $updated_records}"
|
||||
|
||||
_mijnhost_rest PUT "$api_url" "$data"
|
||||
|
||||
if [ "$_code" = "200" ]; then
|
||||
_info "DNS record succesfully added."
|
||||
return 0
|
||||
else
|
||||
_err "Error adding DNS record ($_code)."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Remove TXT record after verification
|
||||
dns_mijnhost_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
MIJNHOST_API_KEY="${MIJNHOST_API_KEY:-$(_readaccountconf_mutable MIJNHOST_API_KEY)}"
|
||||
if [ -z "$MIJNHOST_API_KEY" ]; then
|
||||
MIJNHOST_API_KEY=""
|
||||
_err "You haven't specified your mijn-host API key yet."
|
||||
_err "Please add MIJNHOST_API_KEY to the env."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Detecting root zone for" "${fulldomain}."
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "Invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Removing DNS record for TXT value" "${txtvalue}."
|
||||
|
||||
# Construct the API URL
|
||||
api_url="$MIJNHOST_API/domains/$_domain/dns"
|
||||
|
||||
# Get current records
|
||||
_mijnhost_rest GET "$api_url" ""
|
||||
|
||||
if [ "$_code" != "200" ]; then
|
||||
_err "Error getting current DNS enties ($_code)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 "Get current records response:" "$response"
|
||||
|
||||
records=$(echo "$response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://')
|
||||
|
||||
_debug2 "Current records:" "$records"
|
||||
|
||||
updated_records=$(echo "$records" | sed -E "s/\{[^}]*\"value\":\"$txtvalue\"[^}]*\},?//g" | sed 's/,]/]/g')
|
||||
|
||||
_debug2 "Updated records:" "$updated_records"
|
||||
|
||||
# Build the new payload
|
||||
data="{\"records\": $updated_records}"
|
||||
|
||||
# Use the _put method to update the records
|
||||
_mijnhost_rest PUT "$api_url" "$data"
|
||||
|
||||
if [ "$_code" = "200" ]; then
|
||||
_info "DNS record removed successfully."
|
||||
return 0
|
||||
else
|
||||
_err "Error removing DNS record ($_code)."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Helper function to detect the root zone
|
||||
_get_root() {
|
||||
domain=$1
|
||||
|
||||
# Get current records
|
||||
_debug "Getting current domains"
|
||||
_mijnhost_rest GET "$MIJNHOST_API/domains" ""
|
||||
|
||||
if [ "$_code" != "200" ]; then
|
||||
_err "error getting current domains ($_code)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract root domains from response
|
||||
rootDomains=$(echo "$response" | _egrep_o '"domain":"[^"]*"' | sed -E 's/"domain":"([^"]*)"/\1/')
|
||||
_debug "Root domains:" "$rootDomains"
|
||||
|
||||
for rootDomain in $rootDomains; do
|
||||
if _contains "$domain" "$rootDomain"; then
|
||||
_domain="$rootDomain"
|
||||
_sub_domain=$(echo "$domain" | sed "s/.$rootDomain//g")
|
||||
_debug "Found root domain" "$_domain" "and subdomain" "$_sub_domain" "for" "$domain"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Helper function for rest calls
|
||||
_mijnhost_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
data="$3"
|
||||
|
||||
MAX_REQUEST_RETRY_TIMES=15
|
||||
_request_retry_times=0
|
||||
_retry_sleep=5 #Initial sleep time in seconds.
|
||||
|
||||
while [ "${_request_retry_times}" -lt "$MAX_REQUEST_RETRY_TIMES" ]; do
|
||||
_debug2 _request_retry_times "$_request_retry_times"
|
||||
export _H1="API-Key: $MIJNHOST_API_KEY"
|
||||
export _H2="Content-Type: application/json"
|
||||
# clear headers from previous request to avoid getting wrong http code on timeouts
|
||||
: >"$HTTP_HEADER"
|
||||
_debug "$ep"
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug2 "data $data"
|
||||
response="$(_post "$data" "$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$ep")"
|
||||
fi
|
||||
_ret="$?"
|
||||
_debug2 "response $response"
|
||||
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
|
||||
_debug "http response code $_code"
|
||||
if [ "$_code" = "401" ]; then
|
||||
# we have an invalid API token, maybe it is expired?
|
||||
_err "Access denied. Invalid API token."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "400" ] || _contains "$response" "DNS records not managed by mijn.host"; then #Sometimes API errors out
|
||||
_request_retry_times="$(_math "$_request_retry_times" + 1)"
|
||||
_info "REST call error $_code retrying $ep in ${_retry_sleep}s"
|
||||
_sleep "$_retry_sleep"
|
||||
_retry_sleep="$(_math "$_retry_sleep" \* 2)"
|
||||
continue
|
||||
fi
|
||||
break
|
||||
done
|
||||
if [ "$_request_retry_times" = "$MAX_REQUEST_RETRY_TIMES" ]; then
|
||||
_err "Error mijn.host API call was retried $MAX_REQUEST_RETRY_TIMES times."
|
||||
_err "Calling $ep failed."
|
||||
return 1
|
||||
fi
|
||||
response="$(echo "$response" | _normalizeJson)"
|
||||
return 0
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034
|
||||
dns_myapi_info='Custom API Example
|
||||
A sample custom DNS API script.
|
||||
Domains: example.com
|
||||
A sample custom DNS API script description.
|
||||
Domains: example.com example.net
|
||||
Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_myapi
|
||||
Options:
|
||||
MYAPI_Token API Token. Get API Token from https://example.com/api/. Optional.
|
||||
MYAPI_Token API Token. Get API Token from https://example.com/api/
|
||||
MYAPI_Variable2 Option 2. Default "default value".
|
||||
MYAPI_Variable2 Option 3. Optional.
|
||||
Issues: github.com/acmesh-official/acme.sh
|
||||
Author: Neil Pang <neilgit@neilpang.com>
|
||||
'
|
||||
|
||||
@@ -19,7 +19,7 @@ client=""
|
||||
|
||||
dns_netcup_add() {
|
||||
_debug NC_Apikey "$NC_Apikey"
|
||||
login
|
||||
_login
|
||||
if [ "$NC_Apikey" = "" ] || [ "$NC_Apipw" = "" ] || [ "$NC_CID" = "" ]; then
|
||||
_err "No Credentials given"
|
||||
return 1
|
||||
@@ -61,7 +61,7 @@ dns_netcup_add() {
|
||||
}
|
||||
|
||||
dns_netcup_rm() {
|
||||
login
|
||||
_login
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
@@ -125,7 +125,7 @@ dns_netcup_rm() {
|
||||
logout
|
||||
}
|
||||
|
||||
login() {
|
||||
_login() {
|
||||
tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST")
|
||||
sid=$(echo "$tmp" | tr '{}' '\n' | grep apisessionid | cut -d '"' -f 4)
|
||||
_debug "$tmp"
|
||||
|
||||
@@ -4,8 +4,8 @@ dns_omglol_info='omg.lol
|
||||
Site: omg.lol
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_omglol
|
||||
Options:
|
||||
OMG_ApiKey API Key from omg.lol. This is accessible from the bottom of the account page at https://home.omg.lol/account
|
||||
OMG_Address This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard
|
||||
OMG_ApiKey API Key. This is accessible from the bottom of the account page at https://home.omg.lol/account
|
||||
OMG_Address Address. This is your omg.lol address, without the preceding @ - you can see your list on your dashboard at https://home.omg.lol/dashboard
|
||||
Issues: github.com/acmesh-official/acme.sh/issues/5299
|
||||
Author: @Kholin <kholin+acme.omglolapi@omg.lol>
|
||||
'
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# shellcheck disable=SC2034
|
||||
dns_openprovider_info='OpenProvider.eu
|
||||
Site: OpenProvider.eu
|
||||
Domains: OpenProvider.com
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_openprovider
|
||||
Options:
|
||||
OPENPROVIDER_USER Username
|
||||
|
||||
@@ -7,7 +7,7 @@ Options:
|
||||
PDNS_Url API URL. E.g. "http://ns.example.com:8081"
|
||||
PDNS_ServerId Server ID. E.g. "localhost"
|
||||
PDNS_Token API Token
|
||||
PDNS_Ttl=60 Domain TTL. Default: "60".
|
||||
PDNS_Ttl Domain TTL. Default: "60".
|
||||
'
|
||||
|
||||
DEFAULT_PDNS_TTL=60
|
||||
|
||||
55
dnsapi/dns_technitium.sh
Executable file
55
dnsapi/dns_technitium.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034
|
||||
dns_technitium_info='Technitium DNS Server
|
||||
Site: Technitium.com/dns/
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_technitium
|
||||
Options:
|
||||
Technitium_Server Server Address
|
||||
Technitium_Token API Token
|
||||
Issues: github.com/acmesh-official/acme.sh/issues/6116
|
||||
Author: Henning Reich <acmesh@qupfer.de>
|
||||
'
|
||||
|
||||
dns_technitium_add() {
|
||||
_info "add txt Record using Technitium"
|
||||
_Technitium_account
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
response="$(_get "$Technitium_Server/api/zones/records/add?token=$Technitium_Token&domain=$fulldomain&type=TXT&text=${txtvalue}")"
|
||||
if _contains "$response" '"status":"ok"'; then
|
||||
return 0
|
||||
fi
|
||||
_err "Could not add txt record."
|
||||
return 1
|
||||
}
|
||||
|
||||
dns_technitium_rm() {
|
||||
_info "remove txt record using Technitium"
|
||||
_Technitium_account
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
response="$(_get "$Technitium_Server/api/zones/records/delete?token=$Technitium_Token&domain=$fulldomain&type=TXT&text=${txtvalue}")"
|
||||
if _contains "$response" '"status":"ok"'; then
|
||||
return 0
|
||||
fi
|
||||
_err "Could not remove txt record"
|
||||
return 1
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
_Technitium_account() {
|
||||
Technitium_Server="${Technitium_Server:-$(_readaccountconf_mutable Technitium_Server)}"
|
||||
Technitium_Token="${Technitium_Token:-$(_readaccountconf_mutable Technitium_Token)}"
|
||||
if [ -z "$Technitium_Server" ] || [ -z "$Technitium_Token" ]; then
|
||||
Technitium_Server=""
|
||||
Technitium_Token=""
|
||||
_err "You don't specify Technitium Server and Token yet."
|
||||
_err "Please create your Token and add server address and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the credentials to the account conf file.
|
||||
_saveaccountconf_mutable Technitium_Server "$Technitium_Server"
|
||||
_saveaccountconf_mutable Technitium_Token "$Technitium_Token"
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# West.cn Domain api
|
||||
#WEST_Username="username"
|
||||
#WEST_Key="sADDsdasdgdsf"
|
||||
#Set key at https://www.west.cn/manager/API/APIconfig.asp
|
||||
# shellcheck disable=SC2034
|
||||
dns_west_cn_info='West.cn
|
||||
Site: West.cn
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_west_cn
|
||||
Options:
|
||||
WEST_Username API username
|
||||
WEST_Key API Key. Set at https://www.west.cn/manager/API/APIconfig.asp
|
||||
Issues: github.com/acmesh-official/acme.sh/issues/4894
|
||||
'
|
||||
|
||||
REST_API="https://api.west.cn/API/v2"
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ dns_world4you_rm() {
|
||||
|
||||
_resethttp
|
||||
export ACME_HTTP_NO_REDIRECTS=1
|
||||
body="DeleteDnsRecordForm[recordId]=$recordid&DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[_token]=$form_token"
|
||||
body="DeleteDnsRecordForm[id]=$recordid&DeleteDnsRecordForm[uniqueFormIdDP]=$formiddp&DeleteDnsRecordForm[_token]=$form_token"
|
||||
_info "Removing record..."
|
||||
ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns/record/delete" '' POST 'application/x-www-form-urlencoded')
|
||||
_resethttp
|
||||
@@ -203,6 +203,7 @@ _get_paketnr() {
|
||||
form="$2"
|
||||
|
||||
domains=$(echo "$form" | grep '<ul class="nav header-paket-list">' | sed 's/<li/\n<li/g' | sed 's/<[^>]*>/ /g' | sed 's/^.*>\([^>]*\)$/\1/')
|
||||
_debug domains "$domains"
|
||||
domain=''
|
||||
for domain in $domains; do
|
||||
if _contains "$fqdn" "$domain\$"; then
|
||||
@@ -217,7 +218,7 @@ _get_paketnr() {
|
||||
TLD="$domain"
|
||||
_debug domain "$domain"
|
||||
RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))")
|
||||
PAKETNR=$(echo "$domains" | grep "$domain" | sed 's/^[^,]*, *\([0-9]*\).*$/\1/')
|
||||
PAKETNR=$(echo "$domains" | grep -o " $domain.*" | sed 's/^[^,]*, *\([0-9]*\).*$/\1/')
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034
|
||||
dns_yandex360_info='Yandex 360 for Business DNS API.
|
||||
Yandex 360 for Business is a digital environment for effective collaboration.
|
||||
Yandex 360 for Business is a digital environment for effective collaboration.
|
||||
Site: https://360.yandex.com/
|
||||
Docs: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_yandex360
|
||||
Options:
|
||||
|
||||
149
dnsapi/dns_zoneedit.sh
Normal file
149
dnsapi/dns_zoneedit.sh
Normal file
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034
|
||||
dns_zoneedit_info='ZoneEdit.com
|
||||
Site: ZoneEdit.com
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_zoneedit
|
||||
Options:
|
||||
ZONEEDIT_ID ID
|
||||
ZONEEDIT_Token API Token
|
||||
Issues: github.com/acmesh-official/acme.sh/issues/6135
|
||||
'
|
||||
|
||||
# https://github.com/blueslow/sslcertzoneedit
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
# Usage: dns_zoneedit_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_zoneedit_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
_info "Using ZoneEdit"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
# Load the credentials from the account conf file
|
||||
ZONEEDIT_ID="${ZONEEDIT_ID:-$(_readaccountconf_mutable ZONEEDIT_ID)}"
|
||||
ZONEEDIT_Token="${ZONEEDIT_Token:-$(_readaccountconf_mutable ZONEEDIT_Token)}"
|
||||
if [ -z "$ZONEEDIT_ID" ] || [ -z "$ZONEEDIT_Token" ]; then
|
||||
ZONEEDIT_ID=""
|
||||
ZONEEDIT_Token=""
|
||||
_err "Please specify ZONEEDIT_ID and _Token."
|
||||
_err "Please export as ZONEEDIT_ID and ZONEEDIT_Token then try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Save the credentials to the account conf file
|
||||
_saveaccountconf_mutable ZONEEDIT_ID "$ZONEEDIT_ID"
|
||||
_saveaccountconf_mutable ZONEEDIT_Token "$ZONEEDIT_Token"
|
||||
|
||||
if _zoneedit_api "CREATE" "$fulldomain" "$txtvalue"; then
|
||||
_info "Added, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage: dns_zoneedit_rm fulldomain txtvalue
|
||||
dns_zoneedit_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
_info "Using ZoneEdit"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
# Load the credentials from the account conf file
|
||||
ZONEEDIT_ID="${ZONEEDIT_ID:-$(_readaccountconf_mutable ZONEEDIT_ID)}"
|
||||
ZONEEDIT_Token="${ZONEEDIT_Token:-$(_readaccountconf_mutable ZONEEDIT_Token)}"
|
||||
if [ -z "$ZONEEDIT_ID" ] || [ -z "$ZONEEDIT_Token" ]; then
|
||||
ZONEEDIT_ID=""
|
||||
ZONEEDIT_Token=""
|
||||
_err "Please specify ZONEEDIT_ID and _Token."
|
||||
_err "Please export as ZONEEDIT_ID and ZONEEDIT_Token then try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _zoneedit_api "DELETE" "$fulldomain" "$txtvalue"; then
|
||||
_info "Deleted, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Delete txt record error."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
#Usage: _zoneedit_api <CREATE|DELETE> fulldomain txtvalue
|
||||
_zoneedit_api() {
|
||||
cmd=$1
|
||||
fulldomain=$2
|
||||
txtvalue=$3
|
||||
|
||||
# Construct basic authorization header
|
||||
credentials=$(printf "%s:%s" "$ZONEEDIT_ID" "$ZONEEDIT_Token" | _base64)
|
||||
export _H1="Authorization: Basic ${credentials}"
|
||||
|
||||
# Generate request URL
|
||||
case "$cmd" in
|
||||
"CREATE")
|
||||
# https://dynamic.zoneedit.com/txt-create.php?host=_acme-challenge.example.com&rdata=depE1VF_xshMm1IVY1Y56Kk9Zb_7jA2VFkP65WuNgu8W
|
||||
geturl="https://dynamic.zoneedit.com/txt-create.php?host=${fulldomain}&rdata=${txtvalue}"
|
||||
;;
|
||||
"DELETE")
|
||||
# https://dynamic.zoneedit.com/txt-delete.php?host=_acme-challenge.example.com&rdata=depE1VF_xshMm1IVY1Y56Kk9Zb_7jA2VFkP65WuNgu8W
|
||||
geturl="https://dynamic.zoneedit.com/txt-delete.php?host=${fulldomain}&rdata=${txtvalue}"
|
||||
ze_sleep=2
|
||||
;;
|
||||
*)
|
||||
_err "Unknown parameter : $cmd"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Execute request
|
||||
i=3 # Tries
|
||||
while [ "$i" -gt 0 ]; do
|
||||
i=$(_math "$i" - 1)
|
||||
|
||||
if ! response=$(_get "$geturl"); then
|
||||
_err "_get() failed ($response)"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
if _contains "$response" "SUCCESS.*200"; then
|
||||
# Sleep (when needed) to work around a Zonedit API bug
|
||||
# https://forum.zoneedit.com/threads/automating-changes-of-txt-records-in-dns.7394/page-2#post-23855
|
||||
if [ "$ze_sleep" ]; then _sleep "$ze_sleep"; fi
|
||||
return 0
|
||||
elif _contains "$response" "ERROR.*Minimum.*seconds"; then
|
||||
_info "ZoneEdit responded with a rate limit of..."
|
||||
ze_ratelimit=$(echo "$response" | sed -n 's/.*Minimum \([0-9]\+\) seconds.*/\1/p')
|
||||
if [ "$ze_ratelimit" ] && [ ! "$(echo "$ze_ratelimit" | tr -d '0-9')" ]; then
|
||||
_info "$ze_ratelimit seconds."
|
||||
else
|
||||
_err "$response"
|
||||
_err "not a number, or blank ($ze_ratelimit), API change?"
|
||||
unset ze_ratelimit
|
||||
fi
|
||||
else
|
||||
_err "$response"
|
||||
_err "Unknown response, API change?"
|
||||
fi
|
||||
|
||||
# Retry
|
||||
if [ "$i" -lt 1 ]; then
|
||||
_err "Tries exceeded, giving up."
|
||||
return 1
|
||||
fi
|
||||
if [ "$ze_ratelimit" ]; then
|
||||
_info "Waiting $ze_ratelimit seconds..."
|
||||
_sleep "$ze_ratelimit"
|
||||
else
|
||||
_err "Going to retry after 10 seconds..."
|
||||
_sleep 10
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
@@ -89,7 +89,7 @@ _use_metadata() {
|
||||
_normalizeJson |
|
||||
tr '{,}' '\n' |
|
||||
while read -r _line; do
|
||||
_key="$(echo "${_line%%:*}" | tr -d '"')"
|
||||
_key="$(echo "${_line%%:*}" | tr -d \")"
|
||||
_value="${_line#*:}"
|
||||
_debug3 "_key" "$_key"
|
||||
_secure_debug3 "_value" "$_value"
|
||||
|
||||
Reference in New Issue
Block a user