mirror of
https://github.com/plantroon/acme.sh.git
synced 2024-12-22 13:11:41 +00:00
commit
edd46eb3d1
2
.github/workflows/DNS.yml
vendored
2
.github/workflows/DNS.yml
vendored
@ -184,7 +184,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Clone acmetest
|
- name: Clone acmetest
|
||||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
- uses: vmactions/freebsd-vm@v0.1.2
|
- uses: vmactions/freebsd-vm@v0.1.3
|
||||||
with:
|
with:
|
||||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||||
prepare: pkg install -y socat curl
|
prepare: pkg install -y socat curl
|
||||||
|
2
.github/workflows/LetsEncrypt.yml
vendored
2
.github/workflows/LetsEncrypt.yml
vendored
@ -111,7 +111,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Clone acmetest
|
- name: Clone acmetest
|
||||||
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
- uses: vmactions/freebsd-vm@v0.1.2
|
- uses: vmactions/freebsd-vm@v0.1.3
|
||||||
with:
|
with:
|
||||||
envs: 'NGROK_TOKEN TEST_LOCAL'
|
envs: 'NGROK_TOKEN TEST_LOCAL'
|
||||||
prepare: pkg install -y socat curl
|
prepare: pkg install -y socat curl
|
||||||
|
25
acme.sh
25
acme.sh
@ -562,8 +562,16 @@ if _exists xargs && [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
_h2b() {
|
_h2b() {
|
||||||
if _exists xxd && xxd -r -p 2>/dev/null; then
|
if _exists xxd; then
|
||||||
return
|
if _contains "$(xxd --help 2>&1)" "assumes -c30"; then
|
||||||
|
if xxd -r -p -c 9999 2>/dev/null; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if xxd -r -p 2>/dev/null; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
hex=$(cat)
|
hex=$(cat)
|
||||||
@ -1124,7 +1132,7 @@ _createkey() {
|
|||||||
|
|
||||||
if _isEccKey "$length"; then
|
if _isEccKey "$length"; then
|
||||||
_debug "Using ec name: $eccname"
|
_debug "Using ec name: $eccname"
|
||||||
if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then
|
if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -noout -genkey 2>/dev/null)"; then
|
||||||
echo "$_opkey" >"$f"
|
echo "$_opkey" >"$f"
|
||||||
else
|
else
|
||||||
_err "error ecc key name: $eccname"
|
_err "error ecc key name: $eccname"
|
||||||
@ -2125,6 +2133,12 @@ _send_signed_request() {
|
|||||||
_sleep $_sleep_retry_sec
|
_sleep $_sleep_retry_sec
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
if _contains "$_body" "The Replay Nonce is not recognized"; then
|
||||||
|
_info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds."
|
||||||
|
_CACHED_NONCE=""
|
||||||
|
_sleep $_sleep_retry_sec
|
||||||
|
continue
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
done
|
done
|
||||||
@ -5273,6 +5287,7 @@ signcsr() {
|
|||||||
_renew_hook="${10}"
|
_renew_hook="${10}"
|
||||||
_local_addr="${11}"
|
_local_addr="${11}"
|
||||||
_challenge_alias="${12}"
|
_challenge_alias="${12}"
|
||||||
|
_preferred_chain="${13}"
|
||||||
|
|
||||||
_csrsubj=$(_readSubjectFromCSR "$_csrfile")
|
_csrsubj=$(_readSubjectFromCSR "$_csrfile")
|
||||||
if [ "$?" != "0" ]; then
|
if [ "$?" != "0" ]; then
|
||||||
@ -5319,7 +5334,7 @@ signcsr() {
|
|||||||
_info "Copy csr to: $CSR_PATH"
|
_info "Copy csr to: $CSR_PATH"
|
||||||
cp "$_csrfile" "$CSR_PATH"
|
cp "$_csrfile" "$CSR_PATH"
|
||||||
|
|
||||||
issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias"
|
issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7416,7 +7431,7 @@ _process() {
|
|||||||
deploy "$_domain" "$_deploy_hook" "$_ecc"
|
deploy "$_domain" "$_deploy_hook" "$_ecc"
|
||||||
;;
|
;;
|
||||||
signcsr)
|
signcsr)
|
||||||
signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias"
|
signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain"
|
||||||
;;
|
;;
|
||||||
showcsr)
|
showcsr)
|
||||||
showcsr "$_csr" "$_domain"
|
showcsr "$_csr" "$_domain"
|
||||||
|
@ -17,6 +17,8 @@ cleverreach_deploy() {
|
|||||||
_cca="$4"
|
_cca="$4"
|
||||||
_cfullchain="$5"
|
_cfullchain="$5"
|
||||||
|
|
||||||
|
_rest_endpoint="https://rest.cleverreach.com"
|
||||||
|
|
||||||
_debug _cdomain "$_cdomain"
|
_debug _cdomain "$_cdomain"
|
||||||
_debug _ckey "$_ckey"
|
_debug _ckey "$_ckey"
|
||||||
_debug _ccert "$_ccert"
|
_debug _ccert "$_ccert"
|
||||||
@ -25,6 +27,7 @@ cleverreach_deploy() {
|
|||||||
|
|
||||||
_getdeployconf DEPLOY_CLEVERREACH_CLIENT_ID
|
_getdeployconf DEPLOY_CLEVERREACH_CLIENT_ID
|
||||||
_getdeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET
|
_getdeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET
|
||||||
|
_getdeployconf DEPLOY_CLEVERREACH_SUBCLIENT_ID
|
||||||
|
|
||||||
if [ -z "${DEPLOY_CLEVERREACH_CLIENT_ID}" ]; then
|
if [ -z "${DEPLOY_CLEVERREACH_CLIENT_ID}" ]; then
|
||||||
_err "CleverReach Client ID is not found, please define DEPLOY_CLEVERREACH_CLIENT_ID."
|
_err "CleverReach Client ID is not found, please define DEPLOY_CLEVERREACH_CLIENT_ID."
|
||||||
@ -37,11 +40,12 @@ cleverreach_deploy() {
|
|||||||
|
|
||||||
_savedeployconf DEPLOY_CLEVERREACH_CLIENT_ID "${DEPLOY_CLEVERREACH_CLIENT_ID}"
|
_savedeployconf DEPLOY_CLEVERREACH_CLIENT_ID "${DEPLOY_CLEVERREACH_CLIENT_ID}"
|
||||||
_savedeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${DEPLOY_CLEVERREACH_CLIENT_SECRET}"
|
_savedeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${DEPLOY_CLEVERREACH_CLIENT_SECRET}"
|
||||||
|
_savedeployconf DEPLOY_CLEVERREACH_SUBCLIENT_ID "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}"
|
||||||
|
|
||||||
_info "Obtaining a CleverReach access token"
|
_info "Obtaining a CleverReach access token"
|
||||||
|
|
||||||
_data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${DEPLOY_CLEVERREACH_CLIENT_ID}\", \"client_secret\": \"${DEPLOY_CLEVERREACH_CLIENT_SECRET}\"}"
|
_data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${DEPLOY_CLEVERREACH_CLIENT_ID}\", \"client_secret\": \"${DEPLOY_CLEVERREACH_CLIENT_SECRET}\"}"
|
||||||
_auth_result="$(_post "$_data" "https://rest.cleverreach.com/oauth/token.php" "" "POST" "application/json")"
|
_auth_result="$(_post "$_data" "$_rest_endpoint/oauth/token.php" "" "POST" "application/json")"
|
||||||
|
|
||||||
_debug _data "$_data"
|
_debug _data "$_data"
|
||||||
_debug _auth_result "$_auth_result"
|
_debug _auth_result "$_auth_result"
|
||||||
@ -50,14 +54,32 @@ cleverreach_deploy() {
|
|||||||
_debug _regex "$_regex"
|
_debug _regex "$_regex"
|
||||||
_access_token=$(echo "$_auth_result" | _json_decode | sed -n "s/$_regex/\1/p")
|
_access_token=$(echo "$_auth_result" | _json_decode | sed -n "s/$_regex/\1/p")
|
||||||
|
|
||||||
|
_debug _subclient "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}"
|
||||||
|
|
||||||
|
if [ -n "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" ]; then
|
||||||
|
_info "Obtaining token for sub-client ${DEPLOY_CLEVERREACH_SUBCLIENT_ID}"
|
||||||
|
export _H1="Authorization: Bearer ${_access_token}"
|
||||||
|
_subclient_token_result="$(_get "$_rest_endpoint/v3/clients/$DEPLOY_CLEVERREACH_SUBCLIENT_ID/token")"
|
||||||
|
_access_token=$(echo "$_subclient_token_result" | sed -n "s/\"//p")
|
||||||
|
|
||||||
|
_debug _subclient_token_result "$_access_token"
|
||||||
|
|
||||||
|
_info "Destroying parent token at CleverReach, as it not needed anymore"
|
||||||
|
_destroy_result="$(_post "" "$_rest_endpoint/v3/oauth/token.json" "" "DELETE" "application/json")"
|
||||||
|
_debug _destroy_result "$_destroy_result"
|
||||||
|
fi
|
||||||
|
|
||||||
_info "Uploading certificate and key to CleverReach"
|
_info "Uploading certificate and key to CleverReach"
|
||||||
|
|
||||||
_certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}"
|
_certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}"
|
||||||
export _H1="Authorization: Bearer ${_access_token}"
|
export _H1="Authorization: Bearer ${_access_token}"
|
||||||
_add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl" "" "POST" "application/json")"
|
_add_cert_result="$(_post "$_certData" "$_rest_endpoint/v3/ssl" "" "POST" "application/json")"
|
||||||
|
|
||||||
_debug "Destroying token at CleverReach"
|
if [ -z "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" ]; then
|
||||||
_post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json"
|
_info "Destroying token at CleverReach, as it not needed anymore"
|
||||||
|
_destroy_result="$(_post "" "$_rest_endpoint/v3/oauth/token.json" "" "DELETE" "application/json")"
|
||||||
|
_debug _destroy_result "$_destroy_result"
|
||||||
|
fi
|
||||||
|
|
||||||
if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then
|
if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then
|
||||||
_info "Uploaded certificate successfully"
|
_info "Uploaded certificate successfully"
|
||||||
|
@ -50,12 +50,12 @@ vault_cli_deploy() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$FABIO" ]; then
|
if [ -n "$FABIO" ]; then
|
||||||
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}" cert=@"$_cfullchain" key=@"$_ckey" || return 1
|
||||||
else
|
else
|
||||||
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
|
||||||
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
|
||||||
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
|
||||||
$VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
|
$VAULT_CMD kv put "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,16 +30,41 @@ dns_constellix_add() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_info "Adding TXT record"
|
# The TXT record might already exist when working with wildcard certificates. In that case, update the record by adding the new value.
|
||||||
if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"add\":true,\"set\":{\"name\":\"${_sub_domain}\",\"ttl\":120,\"roundRobin\":[{\"value\":\"${txtvalue}\"}]}}]"; then
|
_debug "Search TXT record"
|
||||||
if printf -- "%s" "$response" | grep "{\"success\":\"1 record(s) added, 0 record(s) updated, 0 record(s) deleted\"}" >/dev/null; then
|
if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then
|
||||||
_info "Added"
|
if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then
|
||||||
return 0
|
_info "Adding TXT record"
|
||||||
|
if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"add\":true,\"set\":{\"name\":\"${_sub_domain}\",\"ttl\":60,\"roundRobin\":[{\"value\":\"${txtvalue}\"}]}}]"; then
|
||||||
|
if printf -- "%s" "$response" | grep "{\"success\":\"1 record(s) added, 0 record(s) updated, 0 record(s) deleted\"}" >/dev/null; then
|
||||||
|
_info "Added"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Error adding TXT record"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_err "Error adding TXT record"
|
_record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2)
|
||||||
return 1
|
if _constellix_rest GET "domains/${_domain_id}/records/TXT/${_record_id}"; then
|
||||||
|
_new_rr_values=$(printf "%s\n" "$response" | _egrep_o '"roundRobin":\[[^]]*\]' | sed "s/\]$/,{\"value\":\"${txtvalue}\"}]/")
|
||||||
|
_debug _new_rr_values "$_new_rr_values"
|
||||||
|
_info "Updating TXT record"
|
||||||
|
if _constellix_rest PUT "domains/${_domain_id}/records/TXT/${_record_id}" "{\"name\":\"${_sub_domain}\",\"ttl\":60,${_new_rr_values}}"; then
|
||||||
|
if printf -- "%s" "$response" | grep "{\"success\":\"Record.*updated successfully\"}" >/dev/null; then
|
||||||
|
_info "Updated"
|
||||||
|
return 0
|
||||||
|
elif printf -- "%s" "$response" | grep "{\"errors\":\[\"Contents are identical\"\]}" >/dev/null; then
|
||||||
|
_info "Already exists, no need to update"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Error updating TXT record"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Usage: fulldomain txtvalue
|
# Usage: fulldomain txtvalue
|
||||||
@ -61,16 +86,26 @@ dns_constellix_rm() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_info "Removing TXT record"
|
# The TXT record might have been removed already when working with some wildcard certificates.
|
||||||
if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"delete\":true,\"filter\":{\"field\":\"name\",\"op\":\"eq\",\"value\":\"${_sub_domain}\"}}]"; then
|
_debug "Search TXT record"
|
||||||
if printf -- "%s" "$response" | grep "{\"success\":\"0 record(s) added, 0 record(s) updated, 1 record(s) deleted\"}" >/dev/null; then
|
if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then
|
||||||
|
if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then
|
||||||
_info "Removed"
|
_info "Removed"
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
_err "Error removing TXT record"
|
_info "Removing TXT record"
|
||||||
return 1
|
if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"delete\":true,\"filter\":{\"field\":\"name\",\"op\":\"eq\",\"value\":\"${_sub_domain}\"}}]"; then
|
||||||
|
if printf -- "%s" "$response" | grep "{\"success\":\"0 record(s) added, 0 record(s) updated, 1 record(s) deleted\"}" >/dev/null; then
|
||||||
|
_info "Removed"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Error removing TXT record"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
#################### Private functions below ##################################
|
#################### Private functions below ##################################
|
||||||
@ -91,7 +126,7 @@ _get_root() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$response" "\"name\":\"$h\""; then
|
if _contains "$response" "\"name\":\"$h\""; then
|
||||||
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+" | cut -d ':' -f 2)
|
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2)
|
||||||
if [ "$_domain_id" ]; then
|
if [ "$_domain_id" ]; then
|
||||||
_sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p)
|
_sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p)
|
||||||
_domain="$h"
|
_domain="$h"
|
||||||
|
@ -89,7 +89,7 @@ add_record() {
|
|||||||
|
|
||||||
_info "Adding record"
|
_info "Adding record"
|
||||||
|
|
||||||
if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then
|
if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=%E9%BB%98%E8%AE%A4"; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -24,20 +24,9 @@ dns_ionos_add() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_new_record="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}"
|
_body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]"
|
||||||
|
|
||||||
# As no POST route is supported by the API, check for existing records and include them in the PATCH request in order not delete them.
|
if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ -z "$response" ]; then
|
||||||
# This is required to support ACME v2 wildcard certificate creation, where two TXT records for the same domain name are created.
|
|
||||||
|
|
||||||
_ionos_get_existing_records "$fulldomain" "$_zone_id"
|
|
||||||
|
|
||||||
if [ "$_existing_records" ]; then
|
|
||||||
_body="[$_new_record,$_existing_records]"
|
|
||||||
else
|
|
||||||
_body="[$_new_record]"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then
|
|
||||||
_info "TXT record has been created successfully."
|
_info "TXT record has been created successfully."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@ -125,17 +114,6 @@ _get_root() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
_ionos_get_existing_records() {
|
|
||||||
fulldomain=$1
|
|
||||||
zone_id=$2
|
|
||||||
|
|
||||||
if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then
|
|
||||||
response="$(echo "$response" | tr -d "\n")"
|
|
||||||
|
|
||||||
_existing_records="$(printf "%s\n" "$response" | _egrep_o "\"records\":\[.*\]" | _head_n 1 | cut -d '[' -f 2 | sed 's/]//')"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_ionos_get_record() {
|
_ionos_get_record() {
|
||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
zone_id=$2
|
zone_id=$2
|
||||||
@ -168,7 +146,7 @@ _ionos_rest() {
|
|||||||
export _H2="Accept: application/json"
|
export _H2="Accept: application/json"
|
||||||
export _H3="Content-Type: application/json"
|
export _H3="Content-Type: application/json"
|
||||||
|
|
||||||
response="$(_post "$data" "$IONOS_API$route" "" "$method")"
|
response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")"
|
||||||
else
|
else
|
||||||
export _H2="Accept: */*"
|
export _H2="Accept: */*"
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ _namecheap_parse_host() {
|
|||||||
_hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2)
|
_hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2)
|
||||||
_hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2)
|
_hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2)
|
||||||
_hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2)
|
_hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2)
|
||||||
_hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2)
|
_hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2 | _xml_decode)
|
||||||
_hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2)
|
_hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2)
|
||||||
_hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2)
|
_hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2)
|
||||||
|
|
||||||
@ -405,3 +405,7 @@ _namecheap_set_tld_sld() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_xml_decode() {
|
||||||
|
sed 's/"/"/g'
|
||||||
|
}
|
||||||
|
157
dnsapi/dns_porkbun.sh
Normal file
157
dnsapi/dns_porkbun.sh
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
#PORKBUN_API_KEY="pk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||||
|
#PORKBUN_SECRET_API_KEY="sk1_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||||
|
|
||||||
|
PORKBUN_Api="https://porkbun.com/api/json/v3"
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_porkbun_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}"
|
||||||
|
PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}"
|
||||||
|
|
||||||
|
if [ -z "$PORKBUN_API_KEY" ] || [ -z "$PORKBUN_SECRET_API_KEY" ]; then
|
||||||
|
PORKBUN_API_KEY=''
|
||||||
|
PORKBUN_SECRET_API_KEY=''
|
||||||
|
_err "You didn't specify a Porkbun api key and secret api key yet."
|
||||||
|
_err "You can get yours from here https://porkbun.com/account/api."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#save the credentials to the account conf file.
|
||||||
|
_saveaccountconf_mutable PORKBUN_API_KEY "$PORKBUN_API_KEY"
|
||||||
|
_saveaccountconf_mutable PORKBUN_SECRET_API_KEY "$PORKBUN_SECRET_API_KEY"
|
||||||
|
|
||||||
|
_debug 'First detect the root zone'
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
# For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
|
||||||
|
# we can not use updating anymore.
|
||||||
|
# count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2)
|
||||||
|
# _debug count "$count"
|
||||||
|
# if [ "$count" = "0" ]; then
|
||||||
|
_info "Adding record"
|
||||||
|
if _porkbun_rest POST "dns/create/$_domain" "{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
|
||||||
|
if _contains "$response" '\"status\":"SUCCESS"'; then
|
||||||
|
_info "Added, OK"
|
||||||
|
return 0
|
||||||
|
elif _contains "$response" "The record already exists"; then
|
||||||
|
_info "Already exists, OK"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Add txt record error. ($response)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_err "Add txt record error."
|
||||||
|
return 1
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#fulldomain txtvalue
|
||||||
|
dns_porkbun_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
PORKBUN_API_KEY="${PORKBUN_API_KEY:-$(_readaccountconf_mutable PORKBUN_API_KEY)}"
|
||||||
|
PORKBUN_SECRET_API_KEY="${PORKBUN_SECRET_API_KEY:-$(_readaccountconf_mutable PORKBUN_SECRET_API_KEY)}"
|
||||||
|
|
||||||
|
_debug 'First detect the root zone'
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
count=$(echo "$response" | _egrep_o "\"count\": *[^,]*" | cut -d : -f 2 | tr -d " ")
|
||||||
|
_debug count "$count"
|
||||||
|
if [ "$count" = "0" ]; then
|
||||||
|
_info "Don't need to remove."
|
||||||
|
else
|
||||||
|
record_id=$(echo "$response" | tr '{' '\n' | grep "$txtvalue" | cut -d, -f1 | cut -d: -f2 | tr -d \")
|
||||||
|
_debug "record_id" "$record_id"
|
||||||
|
if [ -z "$record_id" ]; then
|
||||||
|
_err "Can not get record id to remove."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if ! _porkbun_rest POST "dns/delete/$_domain/$record_id"; then
|
||||||
|
_err "Delete record error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "$response" | tr -d " " | grep '\"status\":"SUCCESS"' >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
#_acme-challenge.www.domain.com
|
||||||
|
#returns
|
||||||
|
# _sub_domain=_acme-challenge.www
|
||||||
|
# _domain=domain.com
|
||||||
|
_get_root() {
|
||||||
|
domain=$1
|
||||||
|
i=1
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
_debug h "$h"
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _porkbun_rest POST "dns/retrieve/$h"; then
|
||||||
|
if _contains "$response" "\"status\":\"SUCCESS\""; then
|
||||||
|
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
|
||||||
|
_domain=$h
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_debug "Go to next level of $_domain"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_debug "Go to next level of $_domain"
|
||||||
|
fi
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_porkbun_rest() {
|
||||||
|
m=$1
|
||||||
|
ep="$2"
|
||||||
|
data="$3"
|
||||||
|
_debug "$ep"
|
||||||
|
|
||||||
|
api_key_trimmed=$(echo "$PORKBUN_API_KEY" | tr -d '"')
|
||||||
|
secret_api_key_trimmed=$(echo "$PORKBUN_SECRET_API_KEY" | tr -d '"')
|
||||||
|
|
||||||
|
test -z "$data" && data="{" || data="$(echo $data | cut -d'}' -f1),"
|
||||||
|
data="$data\"apikey\":\"$api_key_trimmed\",\"secretapikey\":\"$secret_api_key_trimmed\"}"
|
||||||
|
|
||||||
|
export _H1="Content-Type: application/json"
|
||||||
|
|
||||||
|
if [ "$m" != "GET" ]; then
|
||||||
|
_debug data "$data"
|
||||||
|
response="$(_post "$data" "$PORKBUN_Api/$ep" "" "$m")"
|
||||||
|
else
|
||||||
|
response="$(_get "$PORKBUN_Api/$ep")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_sleep 3 # prevent rate limit
|
||||||
|
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "error $ep"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug2 response "$response"
|
||||||
|
return 0
|
||||||
|
}
|
@ -49,16 +49,42 @@ dns_servercow_add() {
|
|||||||
_debug _sub_domain "$_sub_domain"
|
_debug _sub_domain "$_sub_domain"
|
||||||
_debug _domain "$_domain"
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then
|
# check whether a txt record already exists for the subdomain
|
||||||
if printf -- "%s" "$response" | grep "ok" >/dev/null; then
|
if printf -- "%s" "$response" | grep "{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\"" >/dev/null; then
|
||||||
_info "Added, OK"
|
_info "A txt record with the same name already exists."
|
||||||
return 0
|
# trim the string on the left
|
||||||
else
|
txtvalue_old=${response#*{\"name\":\"$_sub_domain\",\"ttl\":20,\"type\":\"TXT\",\"content\":\"}
|
||||||
_err "add txt record error."
|
# trim the string on the right
|
||||||
return 1
|
txtvalue_old=${txtvalue_old%%\"*}
|
||||||
|
|
||||||
|
_debug txtvalue_old "$txtvalue_old"
|
||||||
|
|
||||||
|
_info "Add the new txtvalue to the existing txt record."
|
||||||
|
if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":[\"$txtvalue\",\"$txtvalue_old\"],\"ttl\":20}"; then
|
||||||
|
if printf -- "%s" "$response" | grep "ok" >/dev/null; then
|
||||||
|
_info "Added additional txtvalue, OK"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "add txt record error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
_err "add txt record error."
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
_info "There is no txt record with the name yet."
|
||||||
|
if _servercow_api POST "$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then
|
||||||
|
if printf -- "%s" "$response" | grep "ok" >/dev/null; then
|
||||||
|
_info "Added, OK"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "add txt record error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_err "add txt record error."
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
_err "add txt record error."
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,11 @@
|
|||||||
#SIMPLY_ApiKey="apikey"
|
#SIMPLY_ApiKey="apikey"
|
||||||
#
|
#
|
||||||
#SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]"
|
#SIMPLY_Api="https://api.simply.com/1/[ACCOUNTNAME]/[APIKEY]"
|
||||||
|
|
||||||
SIMPLY_Api_Default="https://api.simply.com/1"
|
SIMPLY_Api_Default="https://api.simply.com/1"
|
||||||
|
|
||||||
|
#This is used for determining success of REST call
|
||||||
|
SIMPLY_SUCCESS_CODE='"status": 200'
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
dns_simply_add() {
|
dns_simply_add() {
|
||||||
@ -171,7 +173,7 @@ _get_root() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$response" '"code":"NOT_FOUND"'; then
|
if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then
|
||||||
_debug "$h not found"
|
_debug "$h not found"
|
||||||
else
|
else
|
||||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
@ -196,6 +198,12 @@ _simply_add_record() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then
|
||||||
|
_err "Call to API not sucessfull, see below message for more details"
|
||||||
|
_err "$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,6 +219,12 @@ _simply_delete_record() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! _contains "$response" "$SIMPLY_SUCCESS_CODE"; then
|
||||||
|
_err "Call to API not sucessfull, see below message for more details"
|
||||||
|
_err "$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user