From 778ee02803098904be7dc5ec608665ad56060215 Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Mon, 7 Nov 2022 23:43:37 +0100 Subject: [PATCH 001/810] update documentation for --cert-home Although the main use-case may be the --install command, this command also proves to be useful for the --signcsr and --issue commands. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d6d8e48c..9d6dfecc 100755 --- a/acme.sh +++ b/acme.sh @@ -6897,7 +6897,7 @@ Parameters: --accountconf Specifies a customized account config file. --home Specifies the home dir for $PROJECT_NAME. - --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. + --cert-home Specifies the home dir to save all the certs. --config-home Specifies the home dir to save all the configurations. --useragent Specifies the user agent string. it will be saved for future use too. -m, --email Specifies the account email, only valid for the '--install' and '--update-account' command. From ed72b090af3fce68195b7ab3d605d70831fca45d Mon Sep 17 00:00:00 2001 From: Keith Chiem Date: Wed, 18 Oct 2023 20:32:39 -0700 Subject: [PATCH 002/810] deploy hook for Ruckus ZoneDirector / Unleashed --- deploy/ruckus.sh | 110 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100755 deploy/ruckus.sh diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh new file mode 100755 index 00000000..d16f40e4 --- /dev/null +++ b/deploy/ruckus.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +# Here is a script to deploy cert to Ruckus Zone Director/Unleashed. +# +# Adapted from: +# https://ms264556.net/pages/PfSenseLetsEncryptToRuckus +# +# ```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=ruckus.example.com +# export RUCKUS_USER=myruckususername +# export RUCKUS_PASS=myruckuspassword +# +# acme.sh --deploy -d ruckus.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" + _debug RUCKUS_PASS "$RUCKUS_PASS" + + COOKIE_JAR=$(mktemp) + cleanup() { + rm $COOKIE_JAR + } + trap cleanup EXIT + + LOGIN_URL=$(curl https://$RUCKUS_HOST -ksSLo /dev/null -w '%{url_effective}') + _debug LOGIN_URL "$LOGIN_URL" + + XSS=$(curl -ksSic $COOKIE_JAR $LOGIN_URL -d username=$RUCKUS_USER -d password="$RUCKUS_PASS" -d ok='Log In' | awk '/^HTTP_X_CSRF_TOKEN:/ { print $2 }' | tr -d '\040\011\012\015') + _debug XSS "$XSS" + + if [ -n "$XSS" ]; then + _info "Authentication successful" + else + _err "Authentication failed" + return 1 + fi + + BASE_URL=$(dirname $LOGIN_URL) + CONF_ARGS="-ksSo /dev/null -b $COOKIE_JAR -c $COOKIE_JAR" + UPLOAD="$CONF_ARGS $BASE_URL/_upload.jsp?request_type=xhr" + CMD="$CONF_ARGS $BASE_URL/_cmdstat.jsp" + + REPLACE_CERT_AJAX='' + CERT_REBOOT_AJAX='' + + _info "Uploading certificate" + curl $UPLOAD -H "X-CSRF-Token: $XSS" -F "u=@$_ccert" -F action=uploadcert -F callback=uploader_uploadcert || return 1 + + _info "Uploading private key" + curl $UPLOAD -H "X-CSRF-Token: $XSS" -F "u=@$_ckey" -F action=uploadprivatekey -F callback=uploader_uploadprivatekey || return 1 + + _info "Replacing certificate" + curl $CMD -H "X-CSRF-Token: $XSS" --data-raw "$REPLACE_CERT_AJAX" || return 1 + + _info "Rebooting" + curl $CMD -H "X-CSRF-Token: $XSS" --data-raw "$CERT_REBOOT_AJAX" || return 1 + + return 0 +} + From b0ca4435fdbee019ac72f8df0cb304e1de5deffc Mon Sep 17 00:00:00 2001 From: Ciaran Walsh Date: Wed, 21 Feb 2024 00:21:09 +0000 Subject: [PATCH 003/810] Fix for empty error objects in response breaking extraction of domain validation types Fix for empty error objects in the response which mess up the extraction of domain validation types due to the closing brace in the error object prematurely matching the end of the search pattern. This seems to be a recent change with ZeroSSL in particular where "error":{} is being included in responses. There could potentially be a related issue if there is a complex error object ever returned in the validation check response where an embedded sub-object could lead to an incomplete extraction of the error message, roughly around line 5040. Adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018 --- acme.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 38ccaade..34ac49e8 100755 --- a/acme.sh +++ b/acme.sh @@ -4722,7 +4722,8 @@ $_authorizations_map" _debug keyauthorization "$keyauthorization" fi - entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" + # Fix for empty error objects in response which mess up the original code, adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018 + entry="$(echo "$response" | sed s/'"error":{}'/'"error":null'/ | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" if [ -z "$keyauthorization" -a -z "$entry" ]; then @@ -6283,7 +6284,8 @@ _deactivate() { fi _debug "Trigger validation." vtype="$(_getIdType "$_d_domain")" - entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" + # Fix for empty error objects in response which mess up the original code, adapted from fix suggested here: https://github.com/acmesh-official/acme.sh/issues/4933#issuecomment-1870499018 + entry="$(echo "$response" | sed s/'"error":{}'/'"error":null'/ | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" _debug entry "$entry" if [ -z "$entry" ]; then _err "Error, can not get domain token $d" From 54eba51b35b7ec48f5e4eecfad3139e6a6ed34f4 Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Wed, 20 Mar 2024 19:14:00 +0800 Subject: [PATCH 004/810] Add deployhook for Netlify --- deploy/netlify.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 deploy/netlify.sh diff --git a/deploy/netlify.sh b/deploy/netlify.sh new file mode 100644 index 00000000..3b854018 --- /dev/null +++ b/deploy/netlify.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env sh + +# Script to deploy certificate to Netlify +# https://docs.netlify.com/api/get-started/#authentication +# https://open-api.netlify.com/#tag/sniCertificate + +# This deployment required following variables +# export Netlify_ACCESS_TOKEN="Your Netlify Access Token" +# export Netlify_SITE_ID="Your Netlify Site ID" + +# returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +netlify_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if [ -z "$Netlify_ACCESS_TOKEN" ]; then + _err "Netlify_ACCESS_TOKEN is not defined." + return 1 + else + _savedomainconf Netlify_ACCESS_TOKEN "$Netlify_ACCESS_TOKEN" + fi + if [ -z "$Netlify_SITE_ID" ]; then + _err "Netlify_SITE_ID is not defined." + return 1 + else + _savedomainconf Netlify_SITE_ID "$Netlify_SITE_ID" + fi + + _info "Deploying certificate to Netlify..." + + ## upload certificate + string_ccert=$(sed 's/$/\\n/' "$_ccert" | tr -d '\n') + string_cca=$(sed 's/$/\\n/' "$_cca" | tr -d '\n') + string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') + _request_body="{\"certificate\":\"$string_ccert\",\"key\":\"$string_key\",\"ca_certificates\":\"$string_cca\"}" + _debug _request_body "$_request_body" + _debug Netlify_ACCESS_TOKEN "$Netlify_ACCESS_TOKEN" + export _H1="Authorization: Bearer $Netlify_ACCESS_TOKEN" + _response=$(_post "$_request_body" "https://api.netlify.com/api/v1/sites/$Netlify_SITE_ID/ssl" "" "POST" "application/json") + + if _contains "$_response" "\"error\""; then + _err "Error in deploying $_cdomain certificate to Netlify." + _err "$_response" + return 1 + fi + _debug response "$_response" + _info "Domain $_cdomain certificate successfully deployed to Netlify." + return 0 +} \ No newline at end of file From c508984f564fc99235e5d99142f0af6972430d0c Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:16:53 +0800 Subject: [PATCH 005/810] Add deployhook for Edgio --- deploy/edgio.sh | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 deploy/edgio.sh diff --git a/deploy/edgio.sh b/deploy/edgio.sh new file mode 100644 index 00000000..604b00e8 --- /dev/null +++ b/deploy/edgio.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env sh + +# Here is a script to deploy cert to edgio using its API +# https://docs.edg.io/guides/v7/develop/rest_api/authentication +# https://docs.edg.io/rest_api/#tag/tls-certs/operation/postConfigV01TlsCerts + +# This deployment required following variables +# export EDGIO_CLIENT_ID="Your Edgio Client ID" +# export EDGIO_CLIENT_SECRET="Your Edgio Client Secret" +# export EDGIO_ENVIRONMENT_ID="Your Edgio Environment ID" + +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +edgio_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if [ -z "$EDGIO_CLIENT_ID" ]; then + _err "EDGIO_CLIENT_ID is not defined." + return 1 + else + _savedomainconf EDGIO_CLIENT_ID "$EDGIO_CLIENT_ID" + fi + + if [ -z "$EDGIO_CLIENT_SECRET" ]; then + _err "EDGIO_CLIENT_SECRET is not defined." + return 1 + else + _savedomainconf EDGIO_CLIENT_SECRET "$EDGIO_CLIENT_SECRET" + fi + + if [ -z "$EDGIO_ENVIRONMENT_ID" ]; then + _err "EDGIO_ENVIRONMENT_ID is not defined." + return 1 + else + _savedomainconf EDGIO_ENVIRONMENT_ID "$EDGIO_ENVIRONMENT_ID" + fi + + _info "Getting access token" + _data="client_id=$EDGIO_CLIENT_ID&client_secret=$EDGIO_CLIENT_SECRET&grant_type=client_credentials&scope=app.config" + _debug Get_access_token_data "$_data" + _response=$(_post "$_data" "https://id.edgio.app/connect/token" "" "POST" "application/x-www-form-urlencoded" ) + _debug Get_access_token_response "$_response" + _access_token=$(echo "$_response" | _json_decode | _egrep_o '"access_token":"[^"]*' | cut -d : -f 2 | tr -d '"') + _debug _access_token "$_access_token" + if [ -z "$_access_token" ]; then + _err "Error in getting access token" + return 1 + fi + + _info "Uploading certificate" + string_ccert=$(sed 's/$/\\n/' "$_ccert" | tr -d '\n') + string_cca=$(sed 's/$/\\n/' "$_cca" | tr -d '\n') + string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') + _data="{\"environment_id\":\"$EDGIO_ENVIRONMENT_ID\",\"primary_cert\":\"$string_ccert\",\"intermediate_cert\":\"$string_cca\",\"private_key\":\"$string_key\"}" + _debug Upload_certificate_data "$_data" + _H1="Authorization: Bearer $_access_token" + _response=$(_post "$_data" "https://edgioapis.com/config/v0.1/tls-certs" "" "POST" "application/json") + + if _contains "$_response" "message"; then + _err "Error in deploying $_cdomain certificate to Edgio." + _err "$_response" + return 1 + fi + _debug Upload_certificate_response "$_response" + _info "Domain $_cdomain certificate successfully deployed to Edgio." + return 0 +} \ No newline at end of file From d1a1d1da8f550bf80a8339a7c15735619e581a2b Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:16:44 +0800 Subject: [PATCH 006/810] Add deployhook for CacheFly --- deploy/cachefly.sh | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 deploy/cachefly.sh diff --git a/deploy/cachefly.sh b/deploy/cachefly.sh new file mode 100644 index 00000000..0e436d26 --- /dev/null +++ b/deploy/cachefly.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env sh + +# Script to deploy certificate to CacheFly +# https://api.cachefly.com/api/2.5/docs#tag/Certificates/paths/~1certificates/post + +# This deployment required following variables +# export CACHEFLY_TOKEN="Your CacheFly API Token" + +# returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +CACHEFLY_API_BASE="https://api.cachefly.com/api/2.5" + +cachefly_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if [ -z "$CACHEFLY_TOKEN" ]; then + _err "CACHEFLY_TOKEN is not defined." + return 1 + else + _savedomainconf CACHEFLY_TOKEN "$CACHEFLY_TOKEN" + fi + + _info "Deploying certificate to CacheFly..." + + ## upload certificate + string_fullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n') + string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') + + _request_body="{\"certificate\":\"$string_fullchain\",\"certificateKey\":\"$string_key\"}" + _debug _request_body "$_request_body" + _debug CACHEFLY_TOKEN "$CACHEFLY_TOKEN" + export _H1="Authorization: Bearer $CACHEFLY_TOKEN" + _response=$(_post "$_request_body" "$CACHEFLY_API_BASE/certificates" "" "POST" "application/json") + + if _contains "$_response" "message"; then + _err "Error in deploying $_cdomain certificate to CacheFly." + _err "$_response" + return 1 + fi + _debug response "$_response" + _info "Domain $_cdomain certificate successfully deployed to CacheFly." + return 0 +} \ No newline at end of file From 696182cfa4ceff50cd7c5b05a15cc591c55173bd Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Wed, 20 Mar 2024 23:05:43 +0800 Subject: [PATCH 007/810] deployhook Edgio: Support multiple Environment ID --- deploy/edgio.sh | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/deploy/edgio.sh b/deploy/edgio.sh index 604b00e8..aadaa98a 100644 --- a/deploy/edgio.sh +++ b/deploy/edgio.sh @@ -9,7 +9,10 @@ # export EDGIO_CLIENT_SECRET="Your Edgio Client Secret" # export EDGIO_ENVIRONMENT_ID="Your Edgio Environment ID" -#returns 0 means success, otherwise error. +# If have more than one Environment ID +# export EDGIO_ENVIRONMENT_ID="ENVIRONMENT_ID_1 ENVIRONMENT_ID_2" + +# returns 0 means success, otherwise error. ######## Public functions ##################### @@ -64,17 +67,20 @@ edgio_deploy() { string_ccert=$(sed 's/$/\\n/' "$_ccert" | tr -d '\n') string_cca=$(sed 's/$/\\n/' "$_cca" | tr -d '\n') string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') - _data="{\"environment_id\":\"$EDGIO_ENVIRONMENT_ID\",\"primary_cert\":\"$string_ccert\",\"intermediate_cert\":\"$string_cca\",\"private_key\":\"$string_key\"}" - _debug Upload_certificate_data "$_data" - _H1="Authorization: Bearer $_access_token" - _response=$(_post "$_data" "https://edgioapis.com/config/v0.1/tls-certs" "" "POST" "application/json") - if _contains "$_response" "message"; then - _err "Error in deploying $_cdomain certificate to Edgio." - _err "$_response" - return 1 - fi - _debug Upload_certificate_response "$_response" - _info "Domain $_cdomain certificate successfully deployed to Edgio." + for ENVIRONMENT_ID in $EDGIO_ENVIRONMENT_ID; do + _data="{\"environment_id\":\"$ENVIRONMENT_ID\",\"primary_cert\":\"$string_ccert\",\"intermediate_cert\":\"$string_cca\",\"private_key\":\"$string_key\"}" + _debug Upload_certificate_data "$_data" + _H1="Authorization: Bearer $_access_token" + _response=$(_post "$_data" "https://edgioapis.com/config/v0.1/tls-certs" "" "POST" "application/json") + if _contains "$_response" "message"; then + _err "Error in deploying $_cdomain certificate to Edgio ENVIRONMENT_ID $ENVIRONMENT_ID." + _err "$_response" + return 1 + fi + _debug Upload_certificate_response "$_response" + _info "Domain $_cdomain certificate successfully deployed to Edgio ENVIRONMENT_ID $ENVIRONMENT_ID." + done + return 0 } \ No newline at end of file From 3b46060caa7a94e04926099ba32118efd07cc116 Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Wed, 20 Mar 2024 23:06:09 +0800 Subject: [PATCH 008/810] deployhook Netlify: Support multiple Site ID --- deploy/netlify.sh | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/deploy/netlify.sh b/deploy/netlify.sh index 3b854018..2ff9bcb6 100644 --- a/deploy/netlify.sh +++ b/deploy/netlify.sh @@ -8,6 +8,9 @@ # export Netlify_ACCESS_TOKEN="Your Netlify Access Token" # export Netlify_SITE_ID="Your Netlify Site ID" +# If have more than one SITE ID +# export Netlify_SITE_ID="SITE_ID_1 SITE_ID_2" + # returns 0 means success, otherwise error. ######## Public functions ##################### @@ -45,18 +48,22 @@ netlify_deploy() { string_ccert=$(sed 's/$/\\n/' "$_ccert" | tr -d '\n') string_cca=$(sed 's/$/\\n/' "$_cca" | tr -d '\n') string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') - _request_body="{\"certificate\":\"$string_ccert\",\"key\":\"$string_key\",\"ca_certificates\":\"$string_cca\"}" - _debug _request_body "$_request_body" - _debug Netlify_ACCESS_TOKEN "$Netlify_ACCESS_TOKEN" - export _H1="Authorization: Bearer $Netlify_ACCESS_TOKEN" - _response=$(_post "$_request_body" "https://api.netlify.com/api/v1/sites/$Netlify_SITE_ID/ssl" "" "POST" "application/json") - if _contains "$_response" "\"error\""; then - _err "Error in deploying $_cdomain certificate to Netlify." - _err "$_response" - return 1 - fi - _debug response "$_response" - _info "Domain $_cdomain certificate successfully deployed to Netlify." + for SITE_ID in $Netlify_SITE_ID; do + _request_body="{\"certificate\":\"$string_ccert\",\"key\":\"$string_key\",\"ca_certificates\":\"$string_cca\"}" + _debug _request_body "$_request_body" + _debug Netlify_ACCESS_TOKEN "$Netlify_ACCESS_TOKEN" + export _H1="Authorization: Bearer $Netlify_ACCESS_TOKEN" + _response=$(_post "$_request_body" "https://api.netlify.com/api/v1/sites/$SITE_ID/ssl" "" "POST" "application/json") + + if _contains "$_response" "\"error\""; then + _err "Error in deploying $_cdomain certificate to Netlify SITE_ID $SITE_ID." + _err "$_response" + return 1 + fi + _debug response "$_response" + _info "Domain $_cdomain certificate successfully deployed to Netlify SITE_ID $SITE_ID." + done + return 0 } \ No newline at end of file From e7284df1df2eb586ec89bf69e19086779d63ff02 Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Thu, 21 Mar 2024 21:44:33 +0800 Subject: [PATCH 009/810] Add deployhook for DirectAdmin --- deploy/directadmin.sh | 80 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 deploy/directadmin.sh diff --git a/deploy/directadmin.sh b/deploy/directadmin.sh new file mode 100644 index 00000000..23d46df9 --- /dev/null +++ b/deploy/directadmin.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env sh + +# Script to deploy certificate to DirectAdmin +# https://docs.directadmin.com/directadmin/customizing-workflow/api-all-about.html#creating-a-login-key +# https://docs.directadmin.com/changelog/version-1.24.4.html#cmd-api-catch-all-pop-passwords-frontpage-protected-dirs-ssl-certs + +# This deployment required following variables +# export DirectAdmin_ENDPOINT="example.com:2222" +# export DirectAdmin_USERNAME="Your DirectAdmin Username" +# export DirectAdmin_KEY="Your DirectAdmin Login Key or Password" +# export DirectAdmin_MAIN_DOMAIN="Your DirectAdmin Main Domain, NOT Subdomain" + +# returns 0 means success, otherwise error. + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +directadmin_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if [ -z "$DirectAdmin_ENDPOINT" ]; then + _err "DirectAdmin_ENDPOINT is not defined." + return 1 + else + _savedomainconf DirectAdmin_ENDPOINT "$DirectAdmin_ENDPOINT" + fi + if [ -z "$DirectAdmin_USERNAME" ]; then + _err "DirectAdmin_USERNAME is not defined." + return 1 + else + _savedomainconf DirectAdmin_USERNAME "$DirectAdmin_USERNAME" + fi + if [ -z "$DirectAdmin_KEY" ]; then + _err "DirectAdmin_KEY is not defined." + return 1 + else + _savedomainconf DirectAdmin_KEY "$DirectAdmin_KEY" + fi + if [ -z "$DirectAdmin_MAIN_DOMAIN" ]; then + _err "DirectAdmin_MAIN_DOMAIN is not defined." + return 1 + else + _savedomainconf DirectAdmin_MAIN_DOMAIN "$DirectAdmin_MAIN_DOMAIN" + fi + + _info "Deploying certificate to DirectAdmin..." + + # upload certificate + string_cfullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n') + string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') + + _request_body="{\"domain\":\"$DirectAdmin_MAIN_DOMAIN\",\"action\":\"save\",\"type\":\"paste\",\"certificate\":\"$string_key\n$string_cfullchain\n\"}" + _debug _request_body "$_request_body" + _debug DirectAdmin_ENDPOINT "$DirectAdmin_ENDPOINT" + _debug DirectAdmin_USERNAME "$DirectAdmin_USERNAME" + _debug DirectAdmin_KEY "$DirectAdmin_KEY" + _debug DirectAdmin_MAIN_DOMAIN "$DirectAdmin_MAIN_DOMAIN" + _response=$(_post "$_request_body" "https://$DirectAdmin_USERNAME:$DirectAdmin_KEY@$DirectAdmin_ENDPOINT/CMD_API_SSL" "" "POST" "application/json") + + if _contains "$_response" "error=1"; then + _err "Error in deploying $_cdomain certificate to DirectAdmin Domain $DirectAdmin_MAIN_DOMAIN." + _err "$_response" + return 1 + fi + + _info "$_response" + _info "Domain $_cdomain certificate successfully deployed to DirectAdmin Domain $DirectAdmin_MAIN_DOMAIN." + + return 0 +} \ No newline at end of file From 295af0168753caf491a86745f0c8ef6b6bc207be Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Thu, 28 Mar 2024 23:07:14 +0800 Subject: [PATCH 010/810] Add deployhook for KeyHelp --- deploy/keyhelp.sh | 111 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 deploy/keyhelp.sh diff --git a/deploy/keyhelp.sh b/deploy/keyhelp.sh new file mode 100644 index 00000000..b792f021 --- /dev/null +++ b/deploy/keyhelp.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env sh + +# Script to deploy certificate to KeyHelp +# This deployment required following variables +# export DEPLOY_KEYHELP_BASEURL="https://keyhelp.example.com" +# export DEPLOY_KEYHELP_USERNAME="Your KeyHelp Username" +# export DEPLOY_KEYHELP_PASSWORD="Your KeyHelp Password" +# export DEPLOY_KEYHELP_DOMAIN_ID="Depoly certificate to this Domain ID" + +# Open the 'Edit domain' page, and you will see id=xxx at the end of the URL. This is the Domain ID. +# https://DEPLOY_KEYHELP_BASEURL/index.php?page=domains&action=edit&id=xxx + +# If have more than one domain name +# export DEPLOY_KEYHELP_DOMAIN_ID="111 222 333" + +keyhelp_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + if [ -z "$DEPLOY_KEYHELP_BASEURL" ]; then + _err "DEPLOY_KEYHELP_BASEURL is not defined." + return 1 + else + _savedomainconf DEPLOY_KEYHELP_BASEURL "$DEPLOY_KEYHELP_BASEURL" + fi + + if [ -z "$DEPLOY_KEYHELP_USERNAME" ]; then + _err "DEPLOY_KEYHELP_USERNAME is not defined." + return 1 + else + _savedomainconf DEPLOY_KEYHELP_USERNAME "$DEPLOY_KEYHELP_USERNAME" + fi + + if [ -z "$DEPLOY_KEYHELP_PASSWORD" ]; then + _err "DEPLOY_KEYHELP_PASSWORD is not defined." + return 1 + else + _savedomainconf DEPLOY_KEYHELP_PASSWORD "$DEPLOY_KEYHELP_PASSWORD" + fi + + if [ -z "$DEPLOY_KEYHELP_DOMAIN_ID" ]; then + _err "DEPLOY_KEYHELP_DOMAIN_ID is not defined." + return 1 + else + _savedomainconf DEPLOY_KEYHELP_DOMAIN_ID "$DEPLOY_KEYHELP_DOMAIN_ID" + fi + + _info "Logging in to keyhelp panel" + username_encoded="$(printf "%s" "${DEPLOY_KEYHELP_USERNAME}" | _url_encode)" + password_encoded="$(printf "%s" "${DEPLOY_KEYHELP_PASSWORD}" | _url_encode)" + _H1="Content-Type: application/x-www-form-urlencoded" + _response=$(_get "$DEPLOY_KEYHELP_BASEURL/index.php?submit=1&username=$username_encoded&password=$password_encoded" "TRUE") + _cookie="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)" + + # If cookies is not empty then logon successful + if [ -z "$_cookie" ]; then + _err "Fail to get cookie." + return 1 + fi + _debug "cookie" "$_cookie" + + _info "Uploading certificate" + _date=$(date +"%Y%m%d") + encoded_key="$(_url_encode <"$_ckey")" + encoded_ccert="$(_url_encode <"$_ccert")" + encoded_cca="$(_url_encode <"$_cca")" + certificate_name="$_cdomain-$_date" + + _request_body="submit=1&certificate_name=$certificate_name&add_type=upload&text_private_key=$encoded_key&text_certificate=$encoded_ccert&text_ca_certificate=$encoded_cca" + _H1="Cookie: $_cookie" + _response=$(_post "$_request_body" "$DEPLOY_KEYHELP_BASEURL/index.php?page=ssl_certificates&action=add" "" "POST") + _message=$(echo "$_response" | grep -A 2 'message-body' | sed -n '/
/,/<\/div>/{//!p;}' | sed 's/<[^>]*>//g' | sed 's/^ *//;s/ *$//') + _info "_message" "$_message" + if [ -z "$_message" ]; then + _err "Fail to upload certificate." + return 1 + fi + + for DOMAIN_ID in $DEPLOY_KEYHELP_DOMAIN_ID; do + _info "Apply certificate to domain id $DOMAIN_ID" + _response=$(_get "$DEPLOY_KEYHELP_BASEURL/index.php?page=domains&action=edit&id=$DOMAIN_ID") + cert_value=$(echo "$_response" | grep "$certificate_name" | sed -n 's/.*value="\([^"]*\).*/\1/p') + target_type=$(echo "$_response" | grep 'target_type' | grep 'checked' | sed -n 's/.*value="\([^"]*\).*/\1/p') + _debug "cert_value" "$cert_value" + if [ -z "$cert_value" ]; then + _err "Fail to get certificate id." + return 1 + fi + + _request_body="submit=1&id=$DOMAIN_ID&target_type=$target_type&certificate_type=custom&certificate_id=$cert_value" + _response=$(_post "$_request_body" "$DEPLOY_KEYHELP_BASEURL/index.php?page=domains&action=edit" "" "POST") + _message=$(echo "$_response" | grep -A 2 'message-body' | sed -n '/
/,/<\/div>/{//!p;}' | sed 's/<[^>]*>//g' | sed 's/^ *//;s/ *$//') + _info "_message" "$_message" + if [ -z "$_message" ]; then + _err "Fail to apply certificate." + return 1 + fi + done + + _info "Domain $_cdomain certificate successfully deployed to KeyHelp Domain ID $DEPLOY_KEYHELP_DOMAIN_ID." + return 0 +} \ No newline at end of file From c466f063c82ed23e695612d946ac9dcf98f71a1c Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Mon, 1 Apr 2024 21:59:12 +0800 Subject: [PATCH 011/810] add newline at end of file --- deploy/cachefly.sh | 2 +- deploy/directadmin.sh | 2 +- deploy/edgio.sh | 2 +- deploy/keyhelp.sh | 2 +- deploy/netlify.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/deploy/cachefly.sh b/deploy/cachefly.sh index 0e436d26..325b2230 100644 --- a/deploy/cachefly.sh +++ b/deploy/cachefly.sh @@ -53,4 +53,4 @@ cachefly_deploy() { _debug response "$_response" _info "Domain $_cdomain certificate successfully deployed to CacheFly." return 0 -} \ No newline at end of file +} diff --git a/deploy/directadmin.sh b/deploy/directadmin.sh index 23d46df9..84818f93 100644 --- a/deploy/directadmin.sh +++ b/deploy/directadmin.sh @@ -77,4 +77,4 @@ directadmin_deploy() { _info "Domain $_cdomain certificate successfully deployed to DirectAdmin Domain $DirectAdmin_MAIN_DOMAIN." return 0 -} \ No newline at end of file +} diff --git a/deploy/edgio.sh b/deploy/edgio.sh index aadaa98a..1b0569cb 100644 --- a/deploy/edgio.sh +++ b/deploy/edgio.sh @@ -83,4 +83,4 @@ edgio_deploy() { done return 0 -} \ No newline at end of file +} diff --git a/deploy/keyhelp.sh b/deploy/keyhelp.sh index b792f021..58f13152 100644 --- a/deploy/keyhelp.sh +++ b/deploy/keyhelp.sh @@ -108,4 +108,4 @@ keyhelp_deploy() { _info "Domain $_cdomain certificate successfully deployed to KeyHelp Domain ID $DEPLOY_KEYHELP_DOMAIN_ID." return 0 -} \ No newline at end of file +} diff --git a/deploy/netlify.sh b/deploy/netlify.sh index 2ff9bcb6..fb254a32 100644 --- a/deploy/netlify.sh +++ b/deploy/netlify.sh @@ -66,4 +66,4 @@ netlify_deploy() { done return 0 -} \ No newline at end of file +} From bfba44fbadc142a0f8dd87e107953e17970a4a90 Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Sun, 7 Apr 2024 12:36:19 +0000 Subject: [PATCH 012/810] format adjustment --- deploy/cachefly.sh | 2 +- deploy/edgio.sh | 6 +++--- deploy/keyhelp.sh | 8 ++++---- deploy/netlify.sh | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/deploy/cachefly.sh b/deploy/cachefly.sh index 325b2230..7841b20b 100644 --- a/deploy/cachefly.sh +++ b/deploy/cachefly.sh @@ -44,7 +44,7 @@ cachefly_deploy() { _debug CACHEFLY_TOKEN "$CACHEFLY_TOKEN" export _H1="Authorization: Bearer $CACHEFLY_TOKEN" _response=$(_post "$_request_body" "$CACHEFLY_API_BASE/certificates" "" "POST" "application/json") - + if _contains "$_response" "message"; then _err "Error in deploying $_cdomain certificate to CacheFly." _err "$_response" diff --git a/deploy/edgio.sh b/deploy/edgio.sh index 1b0569cb..1acd0c8f 100644 --- a/deploy/edgio.sh +++ b/deploy/edgio.sh @@ -23,7 +23,7 @@ edgio_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" - + _debug _cdomain "$_cdomain" _debug _ckey "$_ckey" _debug _ccert "$_ccert" @@ -50,11 +50,11 @@ edgio_deploy() { else _savedomainconf EDGIO_ENVIRONMENT_ID "$EDGIO_ENVIRONMENT_ID" fi - + _info "Getting access token" _data="client_id=$EDGIO_CLIENT_ID&client_secret=$EDGIO_CLIENT_SECRET&grant_type=client_credentials&scope=app.config" _debug Get_access_token_data "$_data" - _response=$(_post "$_data" "https://id.edgio.app/connect/token" "" "POST" "application/x-www-form-urlencoded" ) + _response=$(_post "$_data" "https://id.edgio.app/connect/token" "" "POST" "application/x-www-form-urlencoded") _debug Get_access_token_response "$_response" _access_token=$(echo "$_response" | _json_decode | _egrep_o '"access_token":"[^"]*' | cut -d : -f 2 | tr -d '"') _debug _access_token "$_access_token" diff --git a/deploy/keyhelp.sh b/deploy/keyhelp.sh index 58f13152..839b874c 100644 --- a/deploy/keyhelp.sh +++ b/deploy/keyhelp.sh @@ -92,8 +92,8 @@ keyhelp_deploy() { target_type=$(echo "$_response" | grep 'target_type' | grep 'checked' | sed -n 's/.*value="\([^"]*\).*/\1/p') _debug "cert_value" "$cert_value" if [ -z "$cert_value" ]; then - _err "Fail to get certificate id." - return 1 + _err "Fail to get certificate id." + return 1 fi _request_body="submit=1&id=$DOMAIN_ID&target_type=$target_type&certificate_type=custom&certificate_id=$cert_value" @@ -101,8 +101,8 @@ keyhelp_deploy() { _message=$(echo "$_response" | grep -A 2 'message-body' | sed -n '/
/,/<\/div>/{//!p;}' | sed 's/<[^>]*>//g' | sed 's/^ *//;s/ *$//') _info "_message" "$_message" if [ -z "$_message" ]; then - _err "Fail to apply certificate." - return 1 + _err "Fail to apply certificate." + return 1 fi done diff --git a/deploy/netlify.sh b/deploy/netlify.sh index fb254a32..8d25f74c 100644 --- a/deploy/netlify.sh +++ b/deploy/netlify.sh @@ -48,14 +48,14 @@ netlify_deploy() { string_ccert=$(sed 's/$/\\n/' "$_ccert" | tr -d '\n') string_cca=$(sed 's/$/\\n/' "$_cca" | tr -d '\n') string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n') - + for SITE_ID in $Netlify_SITE_ID; do _request_body="{\"certificate\":\"$string_ccert\",\"key\":\"$string_key\",\"ca_certificates\":\"$string_cca\"}" _debug _request_body "$_request_body" _debug Netlify_ACCESS_TOKEN "$Netlify_ACCESS_TOKEN" export _H1="Authorization: Bearer $Netlify_ACCESS_TOKEN" _response=$(_post "$_request_body" "https://api.netlify.com/api/v1/sites/$SITE_ID/ssl" "" "POST" "application/json") - + if _contains "$_response" "\"error\""; then _err "Error in deploying $_cdomain certificate to Netlify SITE_ID $SITE_ID." _err "$_response" From 517baa3235cb5f94ffa866884cd65fa1147c3d10 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Mon, 29 Apr 2024 22:54:31 +1000 Subject: [PATCH 013/810] test DNS for v2 (actual) --- dnsapi/dns_selectel.sh | 483 +++++++++++++++++++++++++++++++++++------ 1 file changed, 420 insertions(+), 63 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 1b09882d..f5b6b1b9 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,10 +1,29 @@ #!/usr/bin/env sh +# переменные, которые должны быть определены перед запуском +# export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). +# По-умолчанию: v2 +# Если SL_Ver="v1" +# export SL_Key="API_KEY" - Токен Selectel (API key) +# Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. +# https://my.selectel.ru/profile/apikeys +# Если SL_Ver="v2" +# export SL_Expire=60 - время жизни token в минутах (0-1440). +# По-умолчанию: 1400 минут +# export SL_Login_ID= - номер аккаунта в панели управления; +# export SL_Project_Name= - имя проекта. +# export SL_Login_name= - имя сервисного пользователя. Посмотреть имя можно в панели управления: +# в правом верхнем углу откройте меню → Профиль и настройки → раздел Управление пользователями → вкладка Сервисные пользователи +# export SL_Pswd='pswd' - пароль сервисного пользователя, можно посмотреть при создании пользователя или изменить на новый. +# Все эти переменные будут сохранены ~/.acme.sh/account.conf и будут использоваться повторно при необходимости. # -#SL_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# Авторизация описана в: +# https://developers.selectel.ru/docs/control-panel/authorization/ +# https://developers.selectel.com/docs/control-panel/authorization/ -SL_Api="https://api.selectel.ru/domains/v1" +SL_Api="https://api.selectel.ru/domains" +auth_uri="https://cloud.api.selcloud.ru/identity/v3/auth/tokens" +_sl_sep='#' ######## Public functions ##################### @@ -13,17 +32,16 @@ dns_selectel_add() { fulldomain=$1 txtvalue=$2 - SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" - - if [ -z "$SL_Key" ]; then - SL_Key="" - _err "You don't specify selectel.ru api key yet." - _err "Please create you key and try again." + #if ! _sl_init_vars; then + if ! _sl_init_vars; then return 1 fi - - #save the api key to the account conf file. - _saveaccountconf_mutable SL_Key "$SL_Key" + _debug2 SL_Ver "$SL_Ver" + _secure_debug3 SL_Key "$SL_Key" + _debug2 SL_Expire "$SL_Expire" + _debug2 SL_Login_Name "$SL_Login_Name" + _debug2 SL_Login_ID "$SL_Login_ID" + _debug2 SL_Project_Name "$SL_Project_Name" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -35,11 +53,68 @@ dns_selectel_add() { _debug _domain "$_domain" _info "Adding record" - if _sl_rest POST "/$_domain_id/records/" "{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"$fulldomain\", \"content\": \"$txtvalue\"}"; then - if _contains "$response" "$txtvalue" || _contains "$response" "record_already_exists"; then + if [ "$SL_Ver" = "v2" ]; then + _ext_srv1="/zones/" + _ext_srv2="/rrset/" + _text_tmp=$(echo "$txtvalue" | sed -En "s/[\"]*([^\"]*)/\1/p") + _debug txtvalue "$txtvalue" + _text_tmp='\"'$_text_tmp'\"' + _debug _text_tmp "$_text_tmp" + _data="{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"${fulldomain}.\", \"records\": [{\"content\":\"$_text_tmp\"}]}" + elif [ "$SL_Ver" = "v1" ]; then + _ext_srv1="/" + _ext_srv2="/records/" + _data="{\"type\":\"TXT\",\"ttl\":60,\"name\":\"$fulldomain\",\"content\":\"$txtvalue\"}" + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi + _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" + _debug3 _ext_uri "$_ext_uri" + _debug3 _data "$_data" + + if _sl_rest POST "$_ext_uri" "$_data"; then + if _contains "$response" "$txtvalue"; then _info "Added, OK" return 0 fi + if _contains "$response" "already_exists"; then + # запись TXT с $fulldomain уже существует + if [ "$SL_Ver" = "v2" ]; then + # надо добавить к существующей записи еще один content + # + # считать записи rrset + _debug "Getting txt records" + _sl_rest GET "${_ext_uri}" + # Если в данной записи, есть текстовое значение $txtvalue, + # то все хорошо, добавлять ничего не надо и результат успешный + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + _info "Txt record ${fulldomain} со значением ${txtvalue} already exists" + return 0 + fi + # группа \1 - полная запись rrset; группа \2 - значение records:[{"content":"\"v1\""},{"content":"\"v2\""}",...], а именно {"content":"\"v1\""},{"content":"\"v2\""}",... + _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\1/p")" + _record_array="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\2/p")" + # record id + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" + _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" + _debug3 _record_seg "$_record_seg" + _debug3 _record_array "$_record_array" + _debug3 _record_array "$_record_id" + _debug3 _data "$_data" + # вызов REST API PATCH + if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then + _info "Added, OK" + return 0 + fi + elif [ "$SL_Ver" = "v1" ]; then + _info "Added, OK" + return 0 + fi + fi fi _err "Add txt record error." return 1 @@ -49,16 +124,17 @@ dns_selectel_add() { dns_selectel_rm() { fulldomain=$1 txtvalue=$2 - - SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" - - if [ -z "$SL_Key" ]; then - SL_Key="" - _err "You don't specify slectel api key yet." - _err "Please create you key and try again." + #SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" + if ! _sl_init_vars "nosave"; then return 1 fi - + _debug2 SL_Ver "$SL_Ver" + _secure_debug3 SL_Key "$SL_Key" + _debug2 SL_Expire "$SL_Expire" + _debug2 SL_Login_Name "$SL_Login_Name" + _debug2 SL_Login_ID "$SL_Login_ID" + _debug2 SL_Project_Name "$SL_Project_Name" + # _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -67,32 +143,90 @@ dns_selectel_rm() { _debug _domain_id "$_domain_id" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - + # + if [ "$SL_Ver" = "v2" ]; then + _ext_srv1="/zones/" + _ext_srv2="/rrset/" + elif [ "$SL_Ver" = "v1" ]; then + _ext_srv1="/" + _ext_srv2="/records/" + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi + # _debug "Getting txt records" - _sl_rest GET "/${_domain_id}/records/" - + _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" + _debug3 _ext_uri "$_ext_uri" + _sl_rest GET "${_ext_uri}" + # if ! _contains "$response" "$txtvalue"; then _err "Txt record not found" return 1 fi - - _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" - _debug2 "_record_seg" "$_record_seg" + # + if [ "$SL_Ver" = "v2" ]; then + _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\1/gp")" + _record_arr="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/p")" + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" + elif [ "$SL_Ver" = "v1" ]; then + _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" + # record id + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi + _debug3 "_record_seg" "$_record_seg" if [ -z "$_record_seg" ]; then _err "can not find _record_seg" return 1 fi - - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" - _debug2 "_record_id" "$_record_id" + # record id + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 fi - - if ! _sl_rest DELETE "/$_domain_id/records/$_record_id"; then - _err "Delete record error." - return 1 + _debug3 "_record_id" "$_record_id" + # delete all record type TXT with text $txtvalue + if [ "$SL_Ver" = "v2" ]; then + # actual + #del_txt='it47Qq60vJuzQJXb9WEaapciTwtt1gb_14gm1ubwzrA'; + _new_arr="$(echo "$_record_seg" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/gp" | sed -En "s/(\},\{)/}\n{/gp" | sed "/${txtvalue}/d" | sed ":a;N;s/\n/,/;ta")" + # uri record for DEL or PATCH + _del_uri="${_ext_uri}${_record_id}" + if [ -z "$_new_arr" ]; then + # удалить запись + if ! _sl_rest DELETE "${_del_uri}"; then + _err "Delete record error: ${_del_uri}." + else + info "Delete record success: ${_del_uri}." + fi + else + # обновить запись, удалив content + _data="{\"ttl\": 60, \"records\": [${_new_arr}]}" + _debug3 _data "$_data" + # вызов REST API PATCH + if _sl_rest PATCH "${_del_uri}" "$_data"; then + _info "Patched, OK: ${_del_uri}" + else + _err "Patched record error: ${_del_uri}." + fi + fi + else + # legacy + for _one_id in $_record_id; do + _del_uri="${_ext_uri}${_one_id}" + _debug2 _ext_uri "$_del_uri" + if ! _sl_rest DELETE "${_del_uri}"; then + _err "Delete record error: ${_del_uri}." + else + info "Delete record success: ${_del_uri}." + fi + done fi return 0 } @@ -105,51 +239,114 @@ dns_selectel_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 - - if ! _sl_rest GET "/"; then - return 1 - fi - - i=2 - p=1 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug h "$h" - if [ -z "$h" ]; then - #not valid + # + if [ "$SL_Ver" = 'v1' ]; then + # version API 1 + if ! _sl_rest GET "/"; then return 1 fi - - if _contains "$response" "\"name\" *: *\"$h\","; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _domain=$h - _debug "Getting domain id for $h" - if ! _sl_rest GET "/$h"; then + i=2 + p=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 return 1 fi - _domain_id="$(echo "$response" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2)" - return 0 + + if _contains "$response" "\"name\" *: *\"$h\","; then + #_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + _domain=$h + _debug "Getting domain id for $h" + if ! _sl_rest GET "/$h"; then + _err "Error read records of all domains $SL_Ver" + return 1 + fi + _domain_id="$(echo "$response" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2)" + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + _err "Error read records of all domains $SL_Ver" + return 1 + elif [ "$SL_Ver" = "v2" ]; then + # version API 2 + _ext_uri='/zones/' + domain="${domain}." + _debug "domain:: " "$domain" + # read records of all domains + if ! _sl_rest GET "$_ext_uri"; then + #not valid + _err "Error read records of all domains $SL_Ver" + return 1 fi - p=$i - i=$(_math "$i" + 1) - done - return 1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + _err "The domain was not found among the registered ones" + return 1 + fi + + _domain_record=$(echo "$response" | sed -En "s/.*(\{[^}]*id[^}]*\"name\" *: *\"$h\"[^}]*}).*/\1/p") + _debug "_domain_record:: " "$_domain_record" + if [ -n "$_domain_record" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + _domain=$h + _debug "Getting domain id for $h" + #_domain_id="$(echo "$_domain_record" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2 | sed -En "s/\"([^\"]*)\"/\1\p")" + _domain_id=$(echo "$_domain_record" | sed -En "s/\{[^}]*\"id\" *: *\"([^\"]*)\"[^}]*\}/\1/p") + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + #not valid + _err "Error read records of all domains $SL_Ver" + return 1 + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi } +################################################################# +# use: method add_url body _sl_rest() { m=$1 ep="$2" data="$3" - _debug "$ep" - export _H1="X-Token: $SL_Key" + _token=$(_get_auth_token) + #_debug "$_token" + if [ -z "$_token" ]; then + _err "BAD key or token $ep" + return 1 + fi + if [ "$SL_Ver" = v2 ]; then + _h1_name="X-Auth-Token" + else + _h1_name='X-Token' + fi + export _H1="${_h1_name}: ${_token}" export _H2="Content-Type: application/json" + _debug3 "Full URI: " "$SL_Api/${SL_Ver}${ep}" + _debug3 "_H1:" "$_H1" + _debug3 "_H2:" "$_H2" if [ "$m" != "GET" ]; then _debug data "$data" - response="$(_post "$data" "$SL_Api/$ep" "" "$m")" + response="$(_post "$data" "$SL_Api/${SL_Ver}${ep}" "" "$m")" else - response="$(_get "$SL_Api/$ep")" + response="$(_get "$SL_Api/${SL_Ver}${ep}")" fi if [ "$?" != "0" ]; then @@ -159,3 +356,163 @@ _sl_rest() { _debug2 response "$response" return 0 } + +#################################################################3 +# use: +_get_auth_token() { + if [ "$SL_Ver" = 'v1' ]; then + # token for v1 + _debug "Token v1" + _token_keystone=$SL_Key + elif [ "$SL_Ver" = 'v2' ]; then + # token for v2. Get a token for calling the API + _debug "Keystone Token v2" + token_v2=$(_readaccountconf_mutable SL_Token_V2) + if [ -n "$token_v2" ]; then + # The structure with the token was considered. Let's check its validity + # field 1 - SL_Login_Name + # field 2 - token keystone + # field 3 - SL_Login_ID + # field 4 - SL_Project_Name + # field 5 - Receipt time + # separator - ';' + _login_name=$(_getfield "$token_v2" 1 "$_sl_sep") + _token_keystone=$(_getfield "$token_v2" 2 "$_sl_sep") + _project_name=$(_getfield "$token_v2" 4 "$_sl_sep") + _receipt_time=$(_getfield "$token_v2" 5 "$_sl_sep") + _login_id=$(_getfield "$token_v2" 3 "$_sl_sep") + _debug3 _login_name "$_login_name" + _debug3 _login_id "$_login_id" + _debug3 _project_name "$_project_name" + _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" + # check the validity of the token for the user and the project and its lifetime + #_dt_diff_minute=$(( ( $(EPOCHSECONDS)-$_receipt_time )/60 )) + _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) + _debug3 _dt_diff_minute "$_dt_diff_minute" + [ "$_dt_diff_minute" -gt "$SL_Expire" ] && unset _token_keystone + if [ "$_project_name" != "$SL_Project_Name" ] || [ "$_login_name" != "$SL_Login_Name" ] || [ "$_login_id" != "$SL_Login_ID" ]; then + unset _token_keystone + fi + _debug "Get exists token" + fi + if [ -z "$_token_keystone" ]; then + # the previous token is incorrect or was not received, get a new one + _debug "Update (get new) token" + _data_auth="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"name\":\"${SL_Login_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"},\"password\":\"${SL_Pswd}\"}}},\"scope\":{\"project\":{\"name\":\"${SL_Project_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"}}}}}" + #_secure_debug2 "_data_auth" "$_data_auth" + export _H1="Content-Type: application/json" + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + _result=$(_post "$_data_auth" "$auth_uri") + _token_keystone=$(grep 'x-subject-token' "$HTTP_HEADER" | sed -nE "s/[[:space:]]*x-subject-token:[[:space:]]*([[:print:]]*)(\r*)/\1/p") + #echo $_token_keystone > /root/123456.qwe + #_dt_curr=$EPOCHSECONDS + _dt_curr=$(date +%s) + SL_Token_V2="${SL_Login_Name}${_sl_sep}${_token_keystone}${_sl_sep}${SL_Login_ID}${_sl_sep}${SL_Project_Name}${_sl_sep}${_dt_curr}" + _saveaccountconf_mutable SL_Token_V2 "$SL_Token_V2" + fi + else + # token set empty for unsupported version API + _token_keystone="" + fi + printf -- "%s" "$_token_keystone" +} + +################################################################# +# use: [non_save] +_sl_init_vars() { + _non_save="${1}" + _debug2 _non_save "$_non_save" + + _debug "First init variables" + # version API + SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" + if [ -z "$SL_Ver" ]; then + SL_Ver="v2" + fi + if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then + _err "You don't specify selectel.ru API version." + _err "Please define specify API version." + fi + _debug2 SL_Ver "$SL_Ver" + + if [ "$SL_Ver" = "v1" ]; then + # token + SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" + + if [ -z "$SL_Key" ]; then + SL_Key="" + _err "You don't specify selectel.ru api key yet." + _err "Please create you key and try again." + return 1 + fi + #save the api key to the account conf file. + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Key "$SL_Key" + fi + elif [ "$SL_Ver" = "v2" ]; then + # time expire token + SL_Expire="${SL_Expire:-$(_readaccountconf_mutable SL_Expire)}" + if [ -z "$SL_Expire" ]; then + SL_Expire=1400 # 23h 20 min + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Expire "$SL_Expire" + fi + # login service user + SL_Login_Name="${SL_Login_Name:-$(_readaccountconf_mutable SL_Login_Name)}" + if [ -z "$SL_Login_Name" ]; then + SL_Login_Name='' + _err "You did not specify the selectel.ru API service user name." + _err "Please provide a service user name and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Login_Name "$SL_Login_Name" + fi + # user ID + SL_Login_ID="${SL_Login_ID:-$(_readaccountconf_mutable SL_Login_ID)}" + if [ -z "$SL_Login_ID" ]; then + SL_Login_ID='' + _err "You did not specify the selectel.ru API user ID." + _err "Please provide a user ID and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Login_ID "$SL_Login_ID" + fi + # project name + SL_Project_Name="${SL_Project_Name:-$(_readaccountconf_mutable SL_Project_Name)}" + if [ -z "$SL_Project_Name" ]; then + SL_Project_Name='' + _err "You did not specify the project name." + _err "Please provide a project name and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Project_Name "$SL_Project_Name" + fi + # service user password + SL_Pswd="${SL_Pswd:-$(_readaccountconf_mutable SL_Pswd)}" + #_secure_debug3 SL_Pswd "$SL_Pswd" + if [ -z "$SL_Pswd" ]; then + SL_Pswd='' + _err "You did not specify the service user password." + _err "Please provide a service user password and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Pswd "$SL_Pswd" "12345678" + fi + else + SL_Ver="" + _err "You also specified the wrong version of the selectel.ru API." + _err "Please provide the correct API version and try again." + return 1 + fi + + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Ver "$SL_Ver" + fi + + return 0 +} From 577920de863d7ee142cc86f925eca1d1526bf441 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 08:36:36 +1000 Subject: [PATCH 014/810] test DNS for v2 (actual) 001 --- dnsapi/dns_selectel.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index f5b6b1b9..99f031dd 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -513,6 +513,5 @@ _sl_init_vars() { if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi - return 0 } From 73fe47ba798d269f3082aa4ec5ca06c1f4f6fb1f Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 09:57:49 +1000 Subject: [PATCH 015/810] test DNS for v1 (legacy) 001 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 99f031dd..73210164 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -427,7 +427,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v2" + SL_Ver="v1" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." From b8949ba3dd82f1846eef195e75700c148a91f214 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 10:01:50 +1000 Subject: [PATCH 016/810] test DNS for v1 (legacy) 002 --- dnsapi/dns_selectel.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 73210164..04c9a388 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -513,5 +513,6 @@ _sl_init_vars() { if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi + return 0 } From ada7e12b5a85297c42f6169e65612ac0cd2eb709 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 11:03:53 +1000 Subject: [PATCH 017/810] test DNS for v1 (legacy) 003 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 04c9a388..f5b6b1b9 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -427,7 +427,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v1" + SL_Ver="v2" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." From 2e3c1ef4ac7f0d971f2afe4e18a9b07c5e0427ca Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 13:49:53 +1000 Subject: [PATCH 018/810] test DNS for v1 (legacy) 003 --- dnsapi/dns_selectel.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index f5b6b1b9..99f031dd 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -513,6 +513,5 @@ _sl_init_vars() { if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi - return 0 } From 8bb29f53d131f4761752a979d03270d650a260f1 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 16:15:45 +1000 Subject: [PATCH 019/810] test DNS for v1 (legacy) 003 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 99f031dd..73210164 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -427,7 +427,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v2" + SL_Ver="v1" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." From 7a1305c1bb3448ba6573101a0cd9854455b2084d Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sat, 4 May 2024 19:12:42 +1000 Subject: [PATCH 020/810] fix del record for v1, delete one entry at a time --- dnsapi/dns_selectel.sh | 58 +++++++++--------------------------------- 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 73210164..4806773d 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -2,7 +2,7 @@ # переменные, которые должны быть определены перед запуском # export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). -# По-умолчанию: v2 +# По-умолчанию: v1 # Если SL_Ver="v1" # export SL_Key="API_KEY" - Токен Selectel (API key) # Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. @@ -32,7 +32,6 @@ dns_selectel_add() { fulldomain=$1 txtvalue=$2 - #if ! _sl_init_vars; then if ! _sl_init_vars; then return 1 fi @@ -66,7 +65,6 @@ dns_selectel_add() { _ext_srv2="/records/" _data="{\"type\":\"TXT\",\"ttl\":60,\"name\":\"$fulldomain\",\"content\":\"$txtvalue\"}" else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -83,29 +81,27 @@ dns_selectel_add() { # запись TXT с $fulldomain уже существует if [ "$SL_Ver" = "v2" ]; then # надо добавить к существующей записи еще один content - # # считать записи rrset _debug "Getting txt records" _sl_rest GET "${_ext_uri}" - # Если в данной записи, есть текстовое значение $txtvalue, - # то все хорошо, добавлять ничего не надо и результат успешный + # Уже есть значение $txtvalue, добавлять не надо if _contains "$response" "$txtvalue"; then _info "Added, OK" _info "Txt record ${fulldomain} со значением ${txtvalue} already exists" return 0 fi - # группа \1 - полная запись rrset; группа \2 - значение records:[{"content":"\"v1\""},{"content":"\"v2\""}",...], а именно {"content":"\"v1\""},{"content":"\"v2\""}",... + # группа \1 - полная запись rrset; группа \2 - значение атрибута records, а именно {"content":"\"value1\""},{"content":"\"value2\""}",... _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\1/p")" _record_array="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\2/p")" # record id _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + # готовим _data _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" _debug3 _record_seg "$_record_seg" _debug3 _record_array "$_record_array" _debug3 _record_array "$_record_id" - _debug3 _data "$_data" - # вызов REST API PATCH + _debug2 "New data for record" "$_data" if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then _info "Added, OK" return 0 @@ -124,7 +120,7 @@ dns_selectel_add() { dns_selectel_rm() { fulldomain=$1 txtvalue=$2 - #SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" + if ! _sl_init_vars "nosave"; then return 1 fi @@ -151,7 +147,6 @@ dns_selectel_rm() { _ext_srv1="/" _ext_srv2="/records/" else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -169,13 +164,9 @@ dns_selectel_rm() { if [ "$SL_Ver" = "v2" ]; then _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\1/gp")" _record_arr="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/p")" - #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" elif [ "$SL_Ver" = "v1" ]; then _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" - # record id - #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -185,7 +176,7 @@ dns_selectel_rm() { return 1 fi # record id - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 @@ -194,7 +185,6 @@ dns_selectel_rm() { # delete all record type TXT with text $txtvalue if [ "$SL_Ver" = "v2" ]; then # actual - #del_txt='it47Qq60vJuzQJXb9WEaapciTwtt1gb_14gm1ubwzrA'; _new_arr="$(echo "$_record_seg" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/gp" | sed -En "s/(\},\{)/}\n{/gp" | sed "/${txtvalue}/d" | sed ":a;N;s/\n/,/;ta")" # uri record for DEL or PATCH _del_uri="${_ext_uri}${_record_id}" @@ -232,14 +222,10 @@ dns_selectel_rm() { } #################### Private functions below ################################## -#_acme-challenge.www.domain.com -#returns -# _sub_domain=_acme-challenge.www -# _domain=domain.com -# _domain_id=sdjkglgdfewsdfg + _get_root() { domain=$1 - # + if [ "$SL_Ver" = 'v1' ]; then # version API 1 if ! _sl_rest GET "/"; then @@ -248,16 +234,12 @@ _get_root() { i=2 p=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 return 1 fi - if _contains "$response" "\"name\" *: *\"$h\","; then - #_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _debug "Getting domain id for $h" @@ -280,7 +262,6 @@ _get_root() { _debug "domain:: " "$domain" # read records of all domains if ! _sl_rest GET "$_ext_uri"; then - #not valid _err "Error read records of all domains $SL_Ver" return 1 fi @@ -290,29 +271,24 @@ _get_root() { h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then - #not valid _err "The domain was not found among the registered ones" return 1 fi - _domain_record=$(echo "$response" | sed -En "s/.*(\{[^}]*id[^}]*\"name\" *: *\"$h\"[^}]*}).*/\1/p") _debug "_domain_record:: " "$_domain_record" if [ -n "$_domain_record" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _debug "Getting domain id for $h" - #_domain_id="$(echo "$_domain_record" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2 | sed -En "s/\"([^\"]*)\"/\1\p")" _domain_id=$(echo "$_domain_record" | sed -En "s/\{[^}]*\"id\" *: *\"([^\"]*)\"[^}]*\}/\1/p") return 0 fi p=$i i=$(_math "$i" + 1) done - #not valid _err "Error read records of all domains $SL_Ver" return 1 else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -341,14 +317,12 @@ _sl_rest() { _debug3 "Full URI: " "$SL_Api/${SL_Ver}${ep}" _debug3 "_H1:" "$_H1" _debug3 "_H2:" "$_H2" - if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$SL_Api/${SL_Ver}${ep}" "" "$m")" else response="$(_get "$SL_Api/${SL_Ver}${ep}")" fi - if [ "$?" != "0" ]; then _err "error $ep" return 1 @@ -357,8 +331,6 @@ _sl_rest() { return 0 } -#################################################################3 -# use: _get_auth_token() { if [ "$SL_Ver" = 'v1' ]; then # token for v1 @@ -375,7 +347,7 @@ _get_auth_token() { # field 3 - SL_Login_ID # field 4 - SL_Project_Name # field 5 - Receipt time - # separator - ';' + # separator - '$_sl_sep' _login_name=$(_getfield "$token_v2" 1 "$_sl_sep") _token_keystone=$(_getfield "$token_v2" 2 "$_sl_sep") _project_name=$(_getfield "$token_v2" 4 "$_sl_sep") @@ -386,7 +358,6 @@ _get_auth_token() { _debug3 _project_name "$_project_name" _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" # check the validity of the token for the user and the project and its lifetime - #_dt_diff_minute=$(( ( $(EPOCHSECONDS)-$_receipt_time )/60 )) _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) _debug3 _dt_diff_minute "$_dt_diff_minute" [ "$_dt_diff_minute" -gt "$SL_Expire" ] && unset _token_keystone @@ -399,13 +370,9 @@ _get_auth_token() { # the previous token is incorrect or was not received, get a new one _debug "Update (get new) token" _data_auth="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"name\":\"${SL_Login_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"},\"password\":\"${SL_Pswd}\"}}},\"scope\":{\"project\":{\"name\":\"${SL_Project_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"}}}}}" - #_secure_debug2 "_data_auth" "$_data_auth" export _H1="Content-Type: application/json" - # body url [needbase64] [POST|PUT|DELETE] [ContentType] _result=$(_post "$_data_auth" "$auth_uri") _token_keystone=$(grep 'x-subject-token' "$HTTP_HEADER" | sed -nE "s/[[:space:]]*x-subject-token:[[:space:]]*([[:print:]]*)(\r*)/\1/p") - #echo $_token_keystone > /root/123456.qwe - #_dt_curr=$EPOCHSECONDS _dt_curr=$(date +%s) SL_Token_V2="${SL_Login_Name}${_sl_sep}${_token_keystone}${_sl_sep}${SL_Login_ID}${_sl_sep}${SL_Project_Name}${_sl_sep}${_dt_curr}" _saveaccountconf_mutable SL_Token_V2 "$SL_Token_V2" @@ -427,14 +394,13 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v1" + SL_Ver="v2" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." _err "Please define specify API version." fi _debug2 SL_Ver "$SL_Ver" - if [ "$SL_Ver" = "v1" ]; then # token SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" @@ -509,9 +475,9 @@ _sl_init_vars() { _err "Please provide the correct API version and try again." return 1 fi - if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi + return 0 } From 177d9b7cb0fce9baabbc5fa90aa86f8765e33c3b Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sat, 4 May 2024 20:38:42 +1000 Subject: [PATCH 021/810] set default SL_Ver to v1 --- dnsapi/dns_selectel.sh | 47 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 4806773d..65729804 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -4,7 +4,7 @@ # export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). # По-умолчанию: v1 # Если SL_Ver="v1" -# export SL_Key="API_KEY" - Токен Selectel (API key) +# export SL_Key="API_Key" - Токен Selectel (API key) # Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. # https://my.selectel.ru/profile/apikeys # Если SL_Ver="v2" @@ -35,12 +35,11 @@ dns_selectel_add() { if ! _sl_init_vars; then return 1 fi - _debug2 SL_Ver "$SL_Ver" - _secure_debug3 SL_Key "$SL_Key" - _debug2 SL_Expire "$SL_Expire" - _debug2 SL_Login_Name "$SL_Login_Name" - _debug2 SL_Login_ID "$SL_Login_ID" - _debug2 SL_Project_Name "$SL_Project_Name" + _debug3 SL_Ver "$SL_Ver" + _debug3 SL_Expire "$SL_Expire" + _debug3 SL_Login_Name "$SL_Login_Name" + _debug3 SL_Login_ID "$SL_Login_ID" + _debug3 SL_Project_Name "$SL_Project_Name" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -56,9 +55,7 @@ dns_selectel_add() { _ext_srv1="/zones/" _ext_srv2="/rrset/" _text_tmp=$(echo "$txtvalue" | sed -En "s/[\"]*([^\"]*)/\1/p") - _debug txtvalue "$txtvalue" _text_tmp='\"'$_text_tmp'\"' - _debug _text_tmp "$_text_tmp" _data="{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"${fulldomain}.\", \"records\": [{\"content\":\"$_text_tmp\"}]}" elif [ "$SL_Ver" = "v1" ]; then _ext_srv1="/" @@ -69,8 +66,8 @@ dns_selectel_add() { return 1 fi _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" - _debug3 _ext_uri "$_ext_uri" - _debug3 _data "$_data" + _debug _ext_uri "$_ext_uri" + _debug _data "$_data" if _sl_rest POST "$_ext_uri" "$_data"; then if _contains "$response" "$txtvalue"; then @@ -101,7 +98,7 @@ dns_selectel_add() { _debug3 _record_seg "$_record_seg" _debug3 _record_array "$_record_array" _debug3 _record_array "$_record_id" - _debug2 "New data for record" "$_data" + _debug "New data for record" "$_data" if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then _info "Added, OK" return 0 @@ -124,12 +121,11 @@ dns_selectel_rm() { if ! _sl_init_vars "nosave"; then return 1 fi - _debug2 SL_Ver "$SL_Ver" - _secure_debug3 SL_Key "$SL_Key" - _debug2 SL_Expire "$SL_Expire" - _debug2 SL_Login_Name "$SL_Login_Name" - _debug2 SL_Login_ID "$SL_Login_ID" - _debug2 SL_Project_Name "$SL_Project_Name" + _debug3 SL_Ver "$SL_Ver" + _debug3 SL_Expire "$SL_Expire" + _debug3 SL_Login_Name "$SL_Login_Name" + _debug3 SL_Login_ID "$SL_Login_ID" + _debug3 SL_Project_Name "$SL_Project_Name" # _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -153,7 +149,7 @@ dns_selectel_rm() { # _debug "Getting txt records" _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" - _debug3 _ext_uri "$_ext_uri" + _debug _ext_uri "$_ext_uri" _sl_rest GET "${_ext_uri}" # if ! _contains "$response" "$txtvalue"; then @@ -176,7 +172,11 @@ dns_selectel_rm() { return 1 fi # record id - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" + # следующие строки меняют алгоритм удаления записей со значением $txtvalue + # если использовать 1-ю строку, то за раз удаляются все такие записи + # если использовать 2-ю строку, то удаляется только первая запись из них + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" # удалять все записи со значением $txtvalue + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" # удалять только первую запись со значением $txtvalue if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 @@ -188,6 +188,7 @@ dns_selectel_rm() { _new_arr="$(echo "$_record_seg" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/gp" | sed -En "s/(\},\{)/}\n{/gp" | sed "/${txtvalue}/d" | sed ":a;N;s/\n/,/;ta")" # uri record for DEL or PATCH _del_uri="${_ext_uri}${_record_id}" + _debug _del_uri "$_del_uri" if [ -z "$_new_arr" ]; then # удалить запись if ! _sl_rest DELETE "${_del_uri}"; then @@ -210,7 +211,7 @@ dns_selectel_rm() { # legacy for _one_id in $_record_id; do _del_uri="${_ext_uri}${_one_id}" - _debug2 _ext_uri "$_del_uri" + _debug _del_uri "$_del_uri" if ! _sl_rest DELETE "${_del_uri}"; then _err "Delete record error: ${_del_uri}." else @@ -302,7 +303,6 @@ _sl_rest() { data="$3" _token=$(_get_auth_token) - #_debug "$_token" if [ -z "$_token" ]; then _err "BAD key or token $ep" return 1 @@ -394,7 +394,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v2" + SL_Ver="v1" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." @@ -459,7 +459,6 @@ _sl_init_vars() { fi # service user password SL_Pswd="${SL_Pswd:-$(_readaccountconf_mutable SL_Pswd)}" - #_secure_debug3 SL_Pswd "$SL_Pswd" if [ -z "$SL_Pswd" ]; then SL_Pswd='' _err "You did not specify the service user password." From d989617825ccc0b9a60b4f9f657148243d14b15b Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sat, 4 May 2024 20:42:38 +1000 Subject: [PATCH 022/810] set default SL_Ver to v1 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 65729804..9868cb12 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -173,7 +173,7 @@ dns_selectel_rm() { fi # record id # следующие строки меняют алгоритм удаления записей со значением $txtvalue - # если использовать 1-ю строку, то за раз удаляются все такие записи + # если использовать 1-ю строку, то за раз удаляются все такие записи # если использовать 2-ю строку, то удаляется только первая запись из них #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" # удалять все записи со значением $txtvalue _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" # удалять только первую запись со значением $txtvalue From a375e924b491e8245ee763305f59627eac996f80 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sun, 5 May 2024 07:42:22 +1000 Subject: [PATCH 023/810] translation of comments into English --- dnsapi/dns_selectel.sh | 62 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 9868cb12..d4ca13b2 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,23 +1,23 @@ #!/usr/bin/env sh -# переменные, которые должны быть определены перед запуском -# export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). -# По-умолчанию: v1 -# Если SL_Ver="v1" -# export SL_Key="API_Key" - Токен Selectel (API key) -# Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. +# Variables that must be defined before running +# export SL_Ver="v1" - version API: 'v2' (actual) or 'v1' (legacy). +# Default: v1 +# If SL_Ver="v1" +# export SL_Key="API_Key" - Token Selectel (API key) +# You can view or create in the control panel in the upper right corner, open the menu: "Profile and setting -> Keys API". # https://my.selectel.ru/profile/apikeys -# Если SL_Ver="v2" -# export SL_Expire=60 - время жизни token в минутах (0-1440). -# По-умолчанию: 1400 минут -# export SL_Login_ID= - номер аккаунта в панели управления; -# export SL_Project_Name= - имя проекта. -# export SL_Login_name= - имя сервисного пользователя. Посмотреть имя можно в панели управления: -# в правом верхнем углу откройте меню → Профиль и настройки → раздел Управление пользователями → вкладка Сервисные пользователи -# export SL_Pswd='pswd' - пароль сервисного пользователя, можно посмотреть при создании пользователя или изменить на новый. -# Все эти переменные будут сохранены ~/.acme.sh/account.conf и будут использоваться повторно при необходимости. +# If SL_Ver="v2" +# export SL_Expire=60 - token lifetime in minutes (0-1440). +# Default: 1400 minutes +# export SL_Login_ID= - account number in the control panel; +# export SL_Project_Name= - name project. +# export SL_Login_name= - service user name. You can view the name in the control panel: +# in the upper right corner open menu: "Profile and setting → User management → Service users +# export SL_Pswd='pswd' - service user password, can be viewed when creating a user or changed to a new one. +# All these variables will be saved in ~/.acme.sh/account.conf and will be reused as needed. # -# Авторизация описана в: +# Authorization is described in: # https://developers.selectel.ru/docs/control-panel/authorization/ # https://developers.selectel.com/docs/control-panel/authorization/ @@ -75,24 +75,24 @@ dns_selectel_add() { return 0 fi if _contains "$response" "already_exists"; then - # запись TXT с $fulldomain уже существует + # record TXT with $fulldomain already exists if [ "$SL_Ver" = "v2" ]; then - # надо добавить к существующей записи еще один content - # считать записи rrset + # It is necessary to add one more content to the comments + # read all records rrset _debug "Getting txt records" _sl_rest GET "${_ext_uri}" - # Уже есть значение $txtvalue, добавлять не надо + # There is already a $txtvalue value, no need to add it if _contains "$response" "$txtvalue"; then _info "Added, OK" - _info "Txt record ${fulldomain} со значением ${txtvalue} already exists" + _info "Txt record ${fulldomain} with value ${txtvalue} already exists" return 0 fi - # группа \1 - полная запись rrset; группа \2 - значение атрибута records, а именно {"content":"\"value1\""},{"content":"\"value2\""}",... + # group \1 - full record rrset; group \2 - records attribute value, exactly {"content":"\"value1\""},{"content":"\"value2\""}",... _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\1/p")" _record_array="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\2/p")" # record id _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" - # готовим _data + # preparing _data _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" _debug3 _record_seg "$_record_seg" @@ -172,11 +172,11 @@ dns_selectel_rm() { return 1 fi # record id - # следующие строки меняют алгоритм удаления записей со значением $txtvalue - # если использовать 1-ю строку, то за раз удаляются все такие записи - # если использовать 2-ю строку, то удаляется только первая запись из них - #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" # удалять все записи со значением $txtvalue - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" # удалять только первую запись со значением $txtvalue + # the following lines change the algorithm for deleting records with the value $txtvalue + # if you use the 1st line, then all such records are deleted at once + # if you use the 2nd line, then only the first entry from them is deleted + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 @@ -190,17 +190,17 @@ dns_selectel_rm() { _del_uri="${_ext_uri}${_record_id}" _debug _del_uri "$_del_uri" if [ -z "$_new_arr" ]; then - # удалить запись + # remove record if ! _sl_rest DELETE "${_del_uri}"; then _err "Delete record error: ${_del_uri}." else info "Delete record success: ${_del_uri}." fi else - # обновить запись, удалив content + # update a record by removing one element in content _data="{\"ttl\": 60, \"records\": [${_new_arr}]}" _debug3 _data "$_data" - # вызов REST API PATCH + # REST API PATCH call if _sl_rest PATCH "${_del_uri}" "$_data"; then _info "Patched, OK: ${_del_uri}" else From 1116b73a08aae1b58c8edb6fbb016d82ac3364c1 Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:47:43 +0800 Subject: [PATCH 024/810] deployhook KeyHelp: Support enabling the Enforce HTTPS option --- deploy/keyhelp.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/deploy/keyhelp.sh b/deploy/keyhelp.sh index 839b874c..0750e415 100644 --- a/deploy/keyhelp.sh +++ b/deploy/keyhelp.sh @@ -5,6 +5,7 @@ # export DEPLOY_KEYHELP_BASEURL="https://keyhelp.example.com" # export DEPLOY_KEYHELP_USERNAME="Your KeyHelp Username" # export DEPLOY_KEYHELP_PASSWORD="Your KeyHelp Password" +# export DEPLOY_KEYHELP_ENFORCE_HTTPS="1" # 0 or 1, input 1 to enable Enforce HTTP to HTTPS redirection. # export DEPLOY_KEYHELP_DOMAIN_ID="Depoly certificate to this Domain ID" # Open the 'Edit domain' page, and you will see id=xxx at the end of the URL. This is the Domain ID. @@ -54,6 +55,11 @@ keyhelp_deploy() { _savedomainconf DEPLOY_KEYHELP_DOMAIN_ID "$DEPLOY_KEYHELP_DOMAIN_ID" fi + # Optional DEPLOY_KEYHELP_ENFORCE_HTTPS + _getdeployconf DEPLOY_KEYHELP_ENFORCE_HTTPS + # set default values for DEPLOY_KEYHELP_ENFORCE_HTTPS + [ -n "${DEPLOY_KEYHELP_ENFORCE_HTTPS}" ] || DEPLOY_KEYHELP_ENFORCE_HTTPS="1" + _info "Logging in to keyhelp panel" username_encoded="$(printf "%s" "${DEPLOY_KEYHELP_USERNAME}" | _url_encode)" password_encoded="$(printf "%s" "${DEPLOY_KEYHELP_PASSWORD}" | _url_encode)" @@ -96,7 +102,7 @@ keyhelp_deploy() { return 1 fi - _request_body="submit=1&id=$DOMAIN_ID&target_type=$target_type&certificate_type=custom&certificate_id=$cert_value" + _request_body="submit=1&id=$DOMAIN_ID&target_type=$target_type&certificate_type=custom&certificate_id=$cert_value&enforce_https=$DEPLOY_KEYHELP_ENFORCE_HTTPS" _response=$(_post "$_request_body" "$DEPLOY_KEYHELP_BASEURL/index.php?page=domains&action=edit" "" "POST") _message=$(echo "$_response" | grep -A 2 'message-body' | sed -n '/
/,/<\/div>/{//!p;}' | sed 's/<[^>]*>//g' | sed 's/^ *//;s/ *$//') _info "_message" "$_message" From 3f40380c69d75bbf09bdb9e4cdb1c007fe437655 Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:57:51 +0800 Subject: [PATCH 025/810] deployhook Directadmin: Support for selecting the scheme of DirectAdmin , HTTP or HTTPS --- deploy/directadmin.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/deploy/directadmin.sh b/deploy/directadmin.sh index 84818f93..3f60a088 100644 --- a/deploy/directadmin.sh +++ b/deploy/directadmin.sh @@ -5,6 +5,7 @@ # https://docs.directadmin.com/changelog/version-1.24.4.html#cmd-api-catch-all-pop-passwords-frontpage-protected-dirs-ssl-certs # This deployment required following variables +# export DirectAdmin_SCHEME="https" # Optional, https or http, defaults to https # export DirectAdmin_ENDPOINT="example.com:2222" # export DirectAdmin_USERNAME="Your DirectAdmin Username" # export DirectAdmin_KEY="Your DirectAdmin Login Key or Password" @@ -53,6 +54,11 @@ directadmin_deploy() { _savedomainconf DirectAdmin_MAIN_DOMAIN "$DirectAdmin_MAIN_DOMAIN" fi + # Optional SCHEME + _getdeployconf DirectAdmin_SCHEME + # set default values for DirectAdmin_SCHEME + [ -n "${DirectAdmin_SCHEME}" ] || DirectAdmin_SCHEME="https" + _info "Deploying certificate to DirectAdmin..." # upload certificate @@ -65,7 +71,7 @@ directadmin_deploy() { _debug DirectAdmin_USERNAME "$DirectAdmin_USERNAME" _debug DirectAdmin_KEY "$DirectAdmin_KEY" _debug DirectAdmin_MAIN_DOMAIN "$DirectAdmin_MAIN_DOMAIN" - _response=$(_post "$_request_body" "https://$DirectAdmin_USERNAME:$DirectAdmin_KEY@$DirectAdmin_ENDPOINT/CMD_API_SSL" "" "POST" "application/json") + _response=$(_post "$_request_body" "$DirectAdmin_SCHEME://$DirectAdmin_USERNAME:$DirectAdmin_KEY@$DirectAdmin_ENDPOINT/CMD_API_SSL" "" "POST" "application/json") if _contains "$_response" "error=1"; then _err "Error in deploying $_cdomain certificate to DirectAdmin Domain $DirectAdmin_MAIN_DOMAIN." From 2beb2f5659e968423f91c8db2d634d85177fff2a Mon Sep 17 00:00:00 2001 From: Manuel Sanchez Pinar Date: Thu, 4 Jul 2024 14:03:20 +0200 Subject: [PATCH 026/810] fix: rage4 - add error 400 and TXT cleanup The following error happens if the header is set to 'Content-Type: application/json': {"statusCode":400,"message":"One or more errors occurred!", "errors":{"serializerErrors":["The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. LineNumber: 0 | BytePositionInLine: 0."]}} Fix TXT removal --- dnsapi/dns_rage4.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_rage4.sh b/dnsapi/dns_rage4.sh index ad312759..c27fbc5f 100755 --- a/dnsapi/dns_rage4.sh +++ b/dnsapi/dns_rage4.sh @@ -42,6 +42,14 @@ dns_rage4_add() { _debug _domain_id "$_domain_id" _rage4_rest "createrecord/?id=$_domain_id&name=$fulldomain&content=$unquotedtxtvalue&type=TXT&active=true&ttl=1" + + # Response after adding a TXT record should be something like this: + # {"status":true,"id":28160443,"error":null} + if ! _contains "$response" '"error":null' >/dev/null; then + _err "Error while adding TXT record: '$response'" + return 1 + fi + return 0 } @@ -63,7 +71,12 @@ dns_rage4_rm() { _debug "Getting txt records" _rage4_rest "getrecords/?id=${_domain_id}" - _record_id=$(echo "$response" | sed -rn 's/.*"id":([[:digit:]]+)[^\}]*'"$txtvalue"'.*/\1/p') + _record_id=$(echo "$response" | tr '{' '\n' | grep '"TXT"' | grep "\"$txtvalue" | sed -rn 's/.*"id":([[:digit:]]+),.*/\1/p') + if [ -z "$_record_id" ]; then + _err "error retrieving the record_id of the new TXT record in order to delete it, got: '$_record_id'." + return 1 + fi + _rage4_rest "deleterecord/?id=${_record_id}" return 0 } @@ -105,8 +118,7 @@ _rage4_rest() { token_trimmed=$(echo "$RAGE4_TOKEN" | tr -d '"') auth=$(printf '%s:%s' "$username_trimmed" "$token_trimmed" | _base64) - export _H1="Content-Type: application/json" - export _H2="Authorization: Basic $auth" + export _H1="Authorization: Basic $auth" response="$(_get "$RAGE4_Api$ep")" From 51151293d7556dde713c197d0fdc83b97cbbe642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D0=BC=D0=B8=D1=80=20=D0=90?= =?UTF-8?q?=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B5=D0=B2?= <73811032+vlad-kms@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:01:25 +1000 Subject: [PATCH 027/810] Remove `date -d` on macOS --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index c8aa2db7..511ab7f5 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -356,7 +356,7 @@ _get_auth_token() { _debug3 _login_name "$_login_name" _debug3 _login_id "$_login_id" _debug3 _project_name "$_project_name" - _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" + # _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" # check the validity of the token for the user and the project and its lifetime _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) _debug3 _dt_diff_minute "$_dt_diff_minute" From 2f5ea120cb18d56d9d21da07034cb679457b3c94 Mon Sep 17 00:00:00 2001 From: b1n23 <97284148+b1n23@users.noreply.github.com> Date: Tue, 16 Jul 2024 00:25:53 +0800 Subject: [PATCH 028/810] deployhook KeyHelp: fix bug --- deploy/keyhelp.sh | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/deploy/keyhelp.sh b/deploy/keyhelp.sh index 0750e415..97f9c21c 100644 --- a/deploy/keyhelp.sh +++ b/deploy/keyhelp.sh @@ -5,7 +5,6 @@ # export DEPLOY_KEYHELP_BASEURL="https://keyhelp.example.com" # export DEPLOY_KEYHELP_USERNAME="Your KeyHelp Username" # export DEPLOY_KEYHELP_PASSWORD="Your KeyHelp Password" -# export DEPLOY_KEYHELP_ENFORCE_HTTPS="1" # 0 or 1, input 1 to enable Enforce HTTP to HTTPS redirection. # export DEPLOY_KEYHELP_DOMAIN_ID="Depoly certificate to this Domain ID" # Open the 'Edit domain' page, and you will see id=xxx at the end of the URL. This is the Domain ID. @@ -96,13 +95,28 @@ keyhelp_deploy() { _response=$(_get "$DEPLOY_KEYHELP_BASEURL/index.php?page=domains&action=edit&id=$DOMAIN_ID") cert_value=$(echo "$_response" | grep "$certificate_name" | sed -n 's/.*value="\([^"]*\).*/\1/p') target_type=$(echo "$_response" | grep 'target_type' | grep 'checked' | sed -n 's/.*value="\([^"]*\).*/\1/p') + if [ "$target_type" = "directory" ]; then + path=$(echo "$_response" | awk '/name="path"/{getline; print}' | sed -n 's/.*value="\([^"]*\).*/\1/p') + fi + echo "$_response" | grep "is_prefer_https" | grep "checked" >/dev/null + if [ $? -eq 0 ]; then + is_prefer_https=1 + else + is_prefer_https=0 + fi + echo "$_response" | grep "hsts_enabled" | grep "checked" >/dev/null + if [ $? -eq 0 ]; then + hsts_enabled=1 + else + hsts_enabled=0 + fi _debug "cert_value" "$cert_value" if [ -z "$cert_value" ]; then _err "Fail to get certificate id." return 1 fi - _request_body="submit=1&id=$DOMAIN_ID&target_type=$target_type&certificate_type=custom&certificate_id=$cert_value&enforce_https=$DEPLOY_KEYHELP_ENFORCE_HTTPS" + _request_body="submit=1&id=$DOMAIN_ID&target_type=$target_type&path=$path&is_prefer_https=$is_prefer_https&hsts_enabled=$hsts_enabled&certificate_type=custom&certificate_id=$cert_value&enforce_https=$DEPLOY_KEYHELP_ENFORCE_HTTPS" _response=$(_post "$_request_body" "$DEPLOY_KEYHELP_BASEURL/index.php?page=domains&action=edit" "" "POST") _message=$(echo "$_response" | grep -A 2 'message-body' | sed -n '/
/,/<\/div>/{//!p;}' | sed 's/<[^>]*>//g' | sed 's/^ *//;s/ *$//') _info "_message" "$_message" From 5214a7c3ec32cdffc3ff3497c163bf235bd7eaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= <25136274+markkuleinio@users.noreply.github.com> Date: Sun, 4 Aug 2024 18:19:21 +0300 Subject: [PATCH 029/810] Add dnsapi script for HE DDNS --- dnsapi/dns_he_ddns.sh | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 dnsapi/dns_he_ddns.sh diff --git a/dnsapi/dns_he_ddns.sh b/dnsapi/dns_he_ddns.sh new file mode 100644 index 00000000..7338ab18 --- /dev/null +++ b/dnsapi/dns_he_ddns.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env sh +dns_he_ddns_info='Hurricane Electric HE.net DDNS +Site: dns.he.net +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_he_ddns +Options: + HE_DDNS_KEY The DDNS key for updating the TXT record +Author: Markku Leiniö +' + +HE_DDNS_URL="https://dyn.dns.he.net/nic/update" + +######## Public functions ##################### + +#Usage: dns_he_ddns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_he_ddns_add() { + fulldomain=$1 + txtvalue=$2 + HE_DDNS_KEY="${HE_DDNS_KEY:-$(_readaccountconf_mutable HE_DDNS_KEY)}" + if [ -z "$HE_DDNS_KEY" ]; then + HE_DDNS_KEY="" + _err "You didn't specify a DDNS key for accessing the TXT record in HE API." + return 1 + fi + #Save the DDNS key to the account conf file. + _saveaccountconf_mutable HE_DDNS_KEY "$HE_DDNS_KEY" + + _info "Using Hurricane Electric DDNS API" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + response="$(_post "hostname=$fulldomain&password=$HE_DDNS_KEY&txt=$txtvalue" "$HE_DDNS_URL")" + _info "Response: $response" + _contains "$response" "good" && return 0 || return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_he_ddns_rm() { + fulldomain=$1 + txtvalue=$2 + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" +} From c96fcf319a8667115baaad335f8820b1fba93735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= <25136274+markkuleinio@users.noreply.github.com> Date: Sun, 4 Aug 2024 18:25:20 +0300 Subject: [PATCH 030/810] Remove dns_he_ddns_rm(), not used --- dnsapi/dns_he_ddns.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_he_ddns.sh b/dnsapi/dns_he_ddns.sh index 7338ab18..44e6783e 100644 --- a/dnsapi/dns_he_ddns.sh +++ b/dnsapi/dns_he_ddns.sh @@ -33,11 +33,5 @@ dns_he_ddns_add() { _contains "$response" "good" && return 0 || return 1 } -#Usage: fulldomain txtvalue -#Remove the txt record after validation. -dns_he_ddns_rm() { - fulldomain=$1 - txtvalue=$2 - _debug fulldomain "$fulldomain" - _debug txtvalue "$txtvalue" -} +# dns_he_ddns_rm() is not implemented because the API call always updates the +# contents of the existing record (that the API key gives access to). From abc76299c0c74faa265933f532c8d1ec59a27b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= <25136274+markkuleinio@users.noreply.github.com> Date: Sun, 4 Aug 2024 18:58:59 +0300 Subject: [PATCH 031/810] Fix documentation link --- dnsapi/dns_he_ddns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_he_ddns.sh b/dnsapi/dns_he_ddns.sh index 44e6783e..95ec290b 100644 --- a/dnsapi/dns_he_ddns.sh +++ b/dnsapi/dns_he_ddns.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh dns_he_ddns_info='Hurricane Electric HE.net DDNS Site: dns.he.net -Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_he_ddns +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_he_ddns Options: HE_DDNS_KEY The DDNS key for updating the TXT record Author: Markku Leiniö From 833632eee3d8aa9b562297cf6a8c13fee9d81b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= <25136274+markkuleinio@users.noreply.github.com> Date: Sun, 4 Aug 2024 19:15:11 +0300 Subject: [PATCH 032/810] Add shellcheck disable=SC2034 for the info variable --- dnsapi/dns_he_ddns.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_he_ddns.sh b/dnsapi/dns_he_ddns.sh index 95ec290b..0893f938 100644 --- a/dnsapi/dns_he_ddns.sh +++ b/dnsapi/dns_he_ddns.sh @@ -1,4 +1,5 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 dns_he_ddns_info='Hurricane Electric HE.net DDNS Site: dns.he.net Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_he_ddns From b6a77e0231923ab13a31c00c73e2727ec2adb070 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Sun, 10 Nov 2024 22:12:38 +1300 Subject: [PATCH 033/810] Ruckus - use _get() and _post() --- deploy/ruckus.sh | 132 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 98 insertions(+), 34 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index d16f40e4..cbd5e353 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -1,9 +1,8 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh -# Here is a script to deploy cert to Ruckus Zone Director/Unleashed. -# -# Adapted from: -# https://ms264556.net/pages/PfSenseLetsEncryptToRuckus +# Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed. +# +# Public domain, 2024, Tony Rielly # # ```sh # acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus @@ -13,11 +12,11 @@ # deploy script to work. # # ```sh -# export RUCKUS_HOST=ruckus.example.com +# export RUCKUS_HOST=myruckus.example.com # export RUCKUS_USER=myruckususername # export RUCKUS_PASS=myruckuspassword # -# acme.sh --deploy -d ruckus.example.com --deploy-hook ruckus +# acme.sh --deploy -d myruckus.example.com --deploy-hook ruckus # ``` # # returns 0 means success, otherwise error. @@ -66,45 +65,110 @@ ruckus_deploy() { _debug RUCKUS_USER "$RUCKUS_USER" _debug RUCKUS_PASS "$RUCKUS_PASS" - COOKIE_JAR=$(mktemp) - cleanup() { - rm $COOKIE_JAR - } - trap cleanup EXIT + export HTTPS_INSECURE=1 + export ACME_HTTP_NO_REDIRECTS=1 - LOGIN_URL=$(curl https://$RUCKUS_HOST -ksSLo /dev/null -w '%{url_effective}') - _debug LOGIN_URL "$LOGIN_URL" + _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 + _get "$_login_url" >/dev/null + _login_url="$(_response_header 'Location')" + fi + fi - XSS=$(curl -ksSic $COOKIE_JAR $LOGIN_URL -d username=$RUCKUS_USER -d password="$RUCKUS_PASS" -d ok='Log In' | awk '/^HTTP_X_CSRF_TOKEN:/ { print $2 }' | tr -d '\040\011\012\015') - _debug XSS "$XSS" + 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 [ -n "$XSS" ]; then - _info "Authentication successful" - else - _err "Authentication failed" + if [ "$_login_page" = "index.html" ]; then + _err "Connection temporarily unavailable: Unleashed Rebuilding." return 1 fi - BASE_URL=$(dirname $LOGIN_URL) - CONF_ARGS="-ksSo /dev/null -b $COOKIE_JAR -c $COOKIE_JAR" - UPLOAD="$CONF_ARGS $BASE_URL/_upload.jsp?request_type=xhr" - CMD="$CONF_ARGS $BASE_URL/_cmdstat.jsp" + 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 - REPLACE_CERT_AJAX='' - CERT_REBOOT_AJAX='' + _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" - curl $UPLOAD -H "X-CSRF-Token: $XSS" -F "u=@$_ccert" -F action=uploadcert -F callback=uploader_uploadcert || return 1 - + _post_upload "uploadcert" "$_cfullchain" + _info "Uploading private key" - curl $UPLOAD -H "X-CSRF-Token: $XSS" -F "u=@$_ckey" -F action=uploadprivatekey -F callback=uploader_uploadprivatekey || return 1 + _post_upload "uploadprivatekey" "$_ckey" _info "Replacing certificate" - curl $CMD -H "X-CSRF-Token: $XSS" --data-raw "$REPLACE_CERT_AJAX" || return 1 - - _info "Rebooting" - curl $CMD -H "X-CSRF-Token: $XSS" --data-raw "$CERT_REBOOT_AJAX" || return 1 - + _replace_cert_ajax='' + _post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null + + info "Rebooting" + _cert_reboot_ajax='' + _post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null + return 0 } +_response_code() { + < "$HTTP_HEADER" _egrep_o "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*" +} + +_response_header() { + < "$HTTP_HEADER" grep -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t " +} + +_response_cookie() { + _response_header 'Set-Cookie' | awk -F';' '{for(i=1;i<=NF;i++) if (tolower($i) !~ /(path|domain|expires|max-age|secure|httponly|samesite)/) printf "%s; ", $i}' | sed 's/; $//' +} + +_post_upload() { + _post_action="$1" + _post_file="$2" + _post_url="$3" + + _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 +} From 717802611afb4d3e36c2aa2796b013355a0643f7 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Sun, 10 Nov 2024 22:43:57 +1300 Subject: [PATCH 034/810] remove dead code --- deploy/ruckus.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index cbd5e353..def8197d 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -149,8 +149,7 @@ _response_cookie() { _post_upload() { _post_action="$1" _post_file="$2" - _post_url="$3" - + _post_boundary="----FormBoundary$(date "+%s%N")" _post_data="$({ From 0cc74b7cfe910d6961cd225e70dfaba884a418b4 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:50:51 +1300 Subject: [PATCH 035/810] fix insecure password debug and _info typo --- deploy/ruckus.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index def8197d..d83675bb 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -63,7 +63,7 @@ ruckus_deploy() { _debug RUCKUS_HOST "$RUCKUS_HOST" _debug RUCKUS_USER "$RUCKUS_USER" - _debug RUCKUS_PASS "$RUCKUS_PASS" + _secure_debug RUCKUS_PASS "$RUCKUS_PASS" export HTTPS_INSECURE=1 export ACME_HTTP_NO_REDIRECTS=1 @@ -127,7 +127,7 @@ ruckus_deploy() { _replace_cert_ajax='' _post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null - info "Rebooting" + _info "Rebooting" _cert_reboot_ajax='' _post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null From e98e7a232ffa70d37bc4af6260e754a5a5060b98 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:27:36 +1300 Subject: [PATCH 036/810] Fix info logging --- deploy/ruckus.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index d83675bb..3b147c25 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -68,7 +68,7 @@ ruckus_deploy() { export HTTPS_INSECURE=1 export ACME_HTTP_NO_REDIRECTS=1 - _info Discovering the login URL + _info "Discovering the login URL" _get "https://$RUCKUS_HOST" >/dev/null _login_url="$(_response_header 'Location')" if [ -n "$_login_url" ]; then @@ -98,7 +98,7 @@ ruckus_deploy() { return 1 fi - _info Login + _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")" @@ -110,10 +110,10 @@ ruckus_deploy() { return 1 fi - _info Collect Session Cookie + _info "Collect Session Cookie" _H1="Cookie: $(_response_cookie)" export _H1 - _info Collect CSRF Token + _info "Collect CSRF Token" _H2="X-CSRF-Token: $(_response_header 'HTTP_X_CSRF_TOKEN')" export _H2 From 38c41b72d6acc0edfe6d7a1fa072fe16a1505ff5 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Thu, 14 Nov 2024 07:16:38 +1300 Subject: [PATCH 037/810] fix acme.sh PR shfmt failure --- deploy/ruckus.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index 3b147c25..b4249472 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh # Here is a script to deploy cert to Ruckus ZoneDirector / Unleashed. -# +# # Public domain, 2024, Tony Rielly # # ```sh @@ -84,20 +84,20 @@ ruckus_deploy() { _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 + if [ "$_login_page" = "index.html" ]; then _err "Connection temporarily unavailable: Unleashed Rebuilding." return 1 fi - if [ "$_login_page" = "wizard.jsp" ]; then + 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)" @@ -109,7 +109,7 @@ ruckus_deploy() { _err "Login failed: incorrect credentials." return 1 fi - + _info "Collect Session Cookie" _H1="Cookie: $(_response_cookie)" export _H1 @@ -119,27 +119,27 @@ ruckus_deploy() { _info "Uploading certificate" _post_upload "uploadcert" "$_cfullchain" - + _info "Uploading private key" _post_upload "uploadprivatekey" "$_ckey" _info "Replacing certificate" _replace_cert_ajax='' _post "$_replace_cert_ajax" "$_base_url/_cmdstat.jsp" >/dev/null - + _info "Rebooting" _cert_reboot_ajax='' _post "$_cert_reboot_ajax" "$_base_url/_cmdstat.jsp" >/dev/null - + return 0 } _response_code() { - < "$HTTP_HEADER" _egrep_o "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*" + _egrep_o <"$HTTP_HEADER" "^HTTP[^ ]* .*$" | cut -d " " -f 2-100 | tr -d "\f\n" | _egrep_o "^[0-9]*" } _response_header() { - < "$HTTP_HEADER" grep -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t " + grep <"$HTTP_HEADER" -i "^$1:" | cut -d ':' -f 2- | tr -d "\r\n\t " } _response_cookie() { @@ -149,9 +149,9 @@ _response_cookie() { _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" From 2bb5fbdee549f6f1baacd2e7cc3cd8f1a4c4fc48 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Thu, 14 Nov 2024 07:21:19 +1300 Subject: [PATCH 038/810] Remove HTTPS_INSECURE --- deploy/ruckus.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index b4249472..1bfa6bd6 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -65,7 +65,6 @@ ruckus_deploy() { _debug RUCKUS_USER "$RUCKUS_USER" _secure_debug RUCKUS_PASS "$RUCKUS_PASS" - export HTTPS_INSECURE=1 export ACME_HTTP_NO_REDIRECTS=1 _info "Discovering the login URL" From 4232923641479da186a21009cd1aae9617801da4 Mon Sep 17 00:00:00 2001 From: ms264556 <29752086+ms264556@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:39:41 +1300 Subject: [PATCH 039/810] Remove awk usage and refuse redirect to new host --- deploy/ruckus.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/ruckus.sh b/deploy/ruckus.sh index 1bfa6bd6..f62e2fc0 100755 --- a/deploy/ruckus.sh +++ b/deploy/ruckus.sh @@ -74,8 +74,8 @@ ruckus_deploy() { _login_path=$(echo "$_login_url" | sed 's|https\?://[^/]\+||') if [ -z "$_login_path" ]; then # redirect was to a different host - _get "$_login_url" >/dev/null - _login_url="$(_response_header 'Location')" + _err "Connection failed: redirected to a different host. Configure Unleashed with a Preferred Master or Management Interface." + return 1 fi fi @@ -142,7 +142,7 @@ _response_header() { } _response_cookie() { - _response_header 'Set-Cookie' | awk -F';' '{for(i=1;i<=NF;i++) if (tolower($i) !~ /(path|domain|expires|max-age|secure|httponly|samesite)/) printf "%s; ", $i}' | sed 's/; $//' + _response_header 'Set-Cookie' | sed 's/;.*//' } _post_upload() { From 413a91646c03b0cd4ab6dace1bdabe78d702a710 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Sat, 16 Nov 2024 19:15:39 +0100 Subject: [PATCH 040/810] Create truenas_ws.sh --- deploy/truenas_ws.sh | 317 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 deploy/truenas_ws.sh diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh new file mode 100644 index 00000000..b5ba51ab --- /dev/null +++ b/deploy/truenas_ws.sh @@ -0,0 +1,317 @@ +#!/usr/bin/env bash + +# TrueNAS deploy script for SCALE/CORE using websocket +# It is recommend to use a wildcard certificate +# +# Websocket Documentation: https://www.truenas.com/docs/api/scale_websocket_api.html +# +# Tested with TrueNAS Scale - Electric Eel 24.10 +# Changes certificate in the following services: +# - Web UI +# - FTP +# - iX Apps +# +# The following environment variables must be set: +# ------------------------------------------------ +# +# # API KEY +# # Use the folowing URL to create a new API token: /ui/apikeys +# export DEPLOY_TRUENAS_APIKEY=" Date: Sun, 17 Nov 2024 20:58:06 +0100 Subject: [PATCH 041/810] Fix syntax for OpenBSD sh --- dnsapi/dns_netcup.sh | 6 +++--- notify/aws_ses.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 687b99bc..8609adf6 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -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" diff --git a/notify/aws_ses.sh b/notify/aws_ses.sh index 30db45ad..07e0c48c 100644 --- a/notify/aws_ses.sh +++ b/notify/aws_ses.sh @@ -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" From d7855e8fe58d7fcbd01cbd195e23f315bb5086e4 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Sun, 24 Nov 2024 14:59:51 +0100 Subject: [PATCH 042/810] Update truenas_ws.sh (shfmt and shellcheck) --- deploy/truenas_ws.sh | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index b5ba51ab..4b3a5c72 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -51,7 +51,7 @@ _ws_call() { _ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1") fi _debug "_ws_response" "$_ws_response" - printf "%s" $_ws_response + printf "%s" "$_ws_response" return 0 } @@ -99,7 +99,7 @@ _ws_get_job_result() { then _ws_result="$(printf "%s" "$_ws_response" | jq '.[]."result"')" _debug "_ws_result" "$_ws_result" - printf "%s" $_ws_result + printf "%s" "$_ws_result" _ws_error="$(printf "%s" "$_ws_response" | jq '.[]."error"')" if [ "$_ws_error" != "null" ] then @@ -175,7 +175,7 @@ truenas_ws_deploy() { then _err "Error calling system.ready:" _err "$_ws_response" - exit $_ws_re + exit $_ws_ret fi if [ "$_ws_response" != "TRUE" ] @@ -196,7 +196,7 @@ truenas_ws_deploy() { _truenas_version=$(printf "%s" "$_ws_response" | jq -r '."version"' | cut -d '-' -f 3) _info "TrueNAS system: $_truenas_system" _info "TrueNAS version: $_truenas_version" - if [ "$_truenas_system" != "SCALE" ] && ["$_truenas_system" != "CORE" ] + if [ "$_truenas_system" != "SCALE" ] && [ "$_truenas_system" != "CORE" ] then _err "Cannot gather TrueNAS system. Nor CORE oder SCALE detected." exit 10 @@ -210,7 +210,6 @@ truenas_ws_deploy() { _ui_certificate_name=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."name"') _info "Current WebUI certificate ID: $_ui_certificate_id" _info "Current WebUI certificate name: $_ui_certificate_name" - _info "WebUI redirect to https: $_ui_http_redirect" ########## Upload new certificate @@ -225,9 +224,10 @@ truenas_ws_deploy() { exit 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") - if [ $? -gt 0 ] + _ws_ret=$? + if [ $_ws_ret -gt 0 ] then - exit $? + exit $_ws_ret fi _debug "_ws_result" "$_ws_result" _new_certid=$(printf "%s" "$_ws_result" | jq -r '."id"') @@ -251,11 +251,11 @@ truenas_ws_deploy() { then _info "Replace app certificates..." _ws_response=$(_ws_call "app.query") - for _app_name in $(printf "%s" $_ws_response | jq -r '.[]."name"') + for _app_name in $(printf "%s" "$_ws_response" | jq -r '.[]."name"') do _info "Checking app $_app_name..." _ws_response=$(_ws_call "app.config" "$_app_name") - if [ "$(printf "%s" $_ws_response | jq -r '."network" | has("certificate_id")')" = "true" ] + if [ "$(printf "%s" "$_ws_response" | jq -r '."network" | has("certificate_id")')" = "true" ] then _info "App has certificate option, setup new certificate..." _info "App will be redeployed after updating the certificate." @@ -267,9 +267,10 @@ truenas_ws_deploy() { exit 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") - if [ $? -gt 0 ] + _ws_ret=$? + if [ $_ws_ret -gt 0 ] then - exit $? + exit $_ws_ret fi _debug "_ws_result" "$_ws_result" _info "App certificate replaced." @@ -305,10 +306,11 @@ truenas_ws_deploy() { _err "No JobID returned from websocket method." exit 3 fi - _ws_result=$(_ws_get_job_result $_ws_jobid) - if [ $? -gt 0 ] + _ws_result=$(_ws_get_job_result "$_ws_jobid") + _ws_ret=$? + if [ $_ws_ret -gt 0 ] then - exit $? + exit $_ws_ret fi From f2a311bb8194cff518978545da619c439b2f1621 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:44:52 +0100 Subject: [PATCH 043/810] Update truenas_ws.sh (added return instead exit) --- deploy/truenas_ws.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index 4b3a5c72..952cfc42 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -161,7 +161,7 @@ truenas_ws_deploy() { if [ -z "$DEPLOY_TRUENAS_APIKEY" ] then _err "TrueNAS API key not found, please set the DEPLOY_TRUENAS_APIKEY environment variable." - exit 1 + return 1 fi _secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" _info "Environment variables: OK" @@ -175,7 +175,7 @@ truenas_ws_deploy() { then _err "Error calling system.ready:" _err "$_ws_response" - exit $_ws_ret + return $_ws_ret fi if [ "$_ws_response" != "TRUE" ] @@ -183,7 +183,7 @@ truenas_ws_deploy() { _err "TrueNAS is not ready." _err "Please check environment variables DEPLOY_TRUENAS_APIKEY, DEPLOY_TRUENAS_HOSTNAME and DEPLOY_TRUENAS_PROTOCOL." _err "Verify API key." - exit 2 + return 2 fi _savedeployconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" _info "TrueNAS health: OK" @@ -199,7 +199,7 @@ truenas_ws_deploy() { if [ "$_truenas_system" != "SCALE" ] && [ "$_truenas_system" != "CORE" ] then _err "Cannot gather TrueNAS system. Nor CORE oder SCALE detected." - exit 10 + return 10 fi ########## Gather current certificate @@ -221,13 +221,13 @@ truenas_ws_deploy() { if ! _ws_check_jobid "$_ws_jobid" then _err "No JobID returned from websocket method." - exit 3 + return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? if [ $_ws_ret -gt 0 ] then - exit $_ws_ret + return $_ws_ret fi _debug "_ws_result" "$_ws_result" _new_certid=$(printf "%s" "$_ws_result" | jq -r '."id"') @@ -242,7 +242,7 @@ truenas_ws_deploy() { then _err "Cannot set FTP certificate." _debug "_ws_response" "$_ws_response" - exit 4 + return 4 fi ########## ix Apps (SCALE only) @@ -264,13 +264,13 @@ truenas_ws_deploy() { if ! _ws_check_jobid "$_ws_jobid" then _err "No JobID returned from websocket method." - exit 3 + return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? if [ $_ws_ret -gt 0 ] then - exit $_ws_ret + return $_ws_ret fi _debug "_ws_result" "$_ws_result" _info "App certificate replaced." @@ -288,7 +288,7 @@ truenas_ws_deploy() { if [ "$_changed_certid" != "$_new_certid" ] then _err "WebUI certificate change error.." - exit 5 + return 5 else _info "WebUI certificate replaced." fi @@ -304,13 +304,13 @@ truenas_ws_deploy() { if ! _ws_check_jobid "$_ws_jobid" then _err "No JobID returned from websocket method." - exit 3 + return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? if [ $_ws_ret -gt 0 ] then - exit $_ws_ret + return $_ws_ret fi From cd924099e43a1eb4ac1895b8004557945499a450 Mon Sep 17 00:00:00 2001 From: Henning Reich Date: Mon, 25 Nov 2024 17:46:59 +0000 Subject: [PATCH 044/810] add template --- dnsapi/dns_technitum.sh | 44 +++++++++++++++++++++++++++++++++++++++++ test.technitum.sh | 3 +++ 2 files changed, 47 insertions(+) create mode 100755 dnsapi/dns_technitum.sh create mode 100755 test.technitum.sh diff --git a/dnsapi/dns_technitum.sh b/dnsapi/dns_technitum.sh new file mode 100755 index 00000000..c9f5eb9f --- /dev/null +++ b/dnsapi/dns_technitum.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_myapi_info='Custom API Example + A sample custom DNS API script. +Domains: example.com +Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide +Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns +Options: + MYAPI_Token API Token. Get API Token from https://example.com/api/. Optional. +Issues: github.com/acmesh-official/acme.sh +Author: Neil Pang +' + +#This file name is "dns_myapi.sh" +#So, here must be a method dns_myapi_add() +#Which will be called by acme.sh to add the txt record to your api system. +#returns 0 means success, otherwise error. + +######## Public functions ##################### + +# Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_myapi_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using myapi" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + _err "Not implemented!" + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_myapi_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using myapi" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" +} + +#################### Private functions below ################################## diff --git a/test.technitum.sh b/test.technitum.sh new file mode 100755 index 00000000..438d2f4d --- /dev/null +++ b/test.technitum.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +./acme.sh --issue --staging --debug 2 -d test.07q.de --dns dns_technitum From c3557bbe3f07052ac29b5ca95ff2405a557af817 Mon Sep 17 00:00:00 2001 From: qupfer Date: Mon, 25 Nov 2024 20:26:23 +0100 Subject: [PATCH 045/810] 1 --- dnsapi/dns_technitum.sh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_technitum.sh b/dnsapi/dns_technitum.sh index c9f5eb9f..8eb2e4b8 100755 --- a/dnsapi/dns_technitum.sh +++ b/dnsapi/dns_technitum.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh # shellcheck disable=SC2034 -dns_myapi_info='Custom API Example - A sample custom DNS API script. +dns_technitum_info='Technitum DNS Server + Domains: example.com Site: github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns @@ -21,10 +21,10 @@ Author: Neil Pang # Please Read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_myapi_add() { +dns_technitum_add() { fulldomain=$1 txtvalue=$2 - _info "Using myapi" + _info "Using technitum" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" _err "Not implemented!" @@ -33,12 +33,17 @@ dns_myapi_add() { #Usage: fulldomain txtvalue #Remove the txt record after validation. -dns_myapi_rm() { +dns_technitum_rm() { fulldomain=$1 txtvalue=$2 - _info "Using myapi" + _info "Using technitum" _debug fulldomain "$fulldomain" _debug txtvalue "$txtvalue" + _err "Not implemented!" + return 1 } #################### Private functions below ################################## + + +dns_technitum_add "_acme-challenge.test.07q.de" "abcd" \ No newline at end of file From 91103751736161e43e1806bc485e591661f4591a Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:50:40 +0100 Subject: [PATCH 046/810] Update truenas_ws.sh (fixed shfmt) --- deploy/truenas_ws.sh | 98 ++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 62 deletions(-) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index 952cfc42..3ee983a3 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -38,16 +38,13 @@ _ws_call() { _debug "_ws_call arg1" "$1" _debug "_ws_call arg2" "$2" _debug "_ws_call arg3" "$3" - if [ $# -eq 3 ] - then + if [ $# -eq 3 ]; then _ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2" "$3") fi - if [ $# -eq 2 ] - then + if [ $# -eq 2 ]; then _ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2") fi - if [ $# -eq 1 ] - then + if [ $# -eq 1 ]; then _ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1") fi _debug "_ws_response" "$_ws_response" @@ -69,14 +66,13 @@ _ws_call() { # 1: false _ws_check_jobid() { case "$1" in - [0-9]*) - return 0 - ;; + [0-9]*) + return 0 + ;; esac return 1 } - # Wait for job to finish and return result as JSON # Usage: # _ws_result=$(_ws_get_job_result "$_ws_jobid") @@ -91,18 +87,15 @@ _ws_check_jobid() { # Returns: # n/a _ws_get_job_result() { - while true - do + while true; do sleep 2 _ws_response=$(_ws_call "core.get_jobs" "[[\"id\", \"=\", $1]]") - if [ "$(printf "%s" "$_ws_response" | jq -r '.[]."state"')" != "RUNNING" ] - then + if [ "$(printf "%s" "$_ws_response" | jq -r '.[]."state"')" != "RUNNING" ]; then _ws_result="$(printf "%s" "$_ws_response" | jq '.[]."result"')" _debug "_ws_result" "$_ws_result" printf "%s" "$_ws_result" _ws_error="$(printf "%s" "$_ws_response" | jq '.[]."error"')" - if [ "$_ws_error" != "null" ] - then + if [ "$_ws_error" != "null" ]; then _err "Job $1 failed:" _err "$_ws_error" return 7 @@ -113,9 +106,6 @@ _ws_get_job_result() { return 0 } - - - ######################## ### Public functions ### ######################## @@ -153,33 +143,30 @@ truenas_ws_deploy() { _debug _file_ca "$_file_ca" _debug _file_fullchain "$_file_fullchain" -########## Environment check + ########## Environment check _info "Checking environment variables..." _getdeployconf DEPLOY_TRUENAS_APIKEY # Check API Key - if [ -z "$DEPLOY_TRUENAS_APIKEY" ] - then + if [ -z "$DEPLOY_TRUENAS_APIKEY" ]; then _err "TrueNAS API key not found, please set the DEPLOY_TRUENAS_APIKEY environment variable." return 1 fi _secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" _info "Environment variables: OK" -########## Health check + ########## Health check _info "Checking TrueNAS health..." _ws_response=$(_ws_call "system.ready" | tr '[:lower:]' '[:upper:]') _ws_ret=$? - if [ $_ws_ret -gt 0 ] - then + if [ $_ws_ret -gt 0 ]; then _err "Error calling system.ready:" _err "$_ws_response" return $_ws_ret fi - if [ "$_ws_response" != "TRUE" ] - then + if [ "$_ws_response" != "TRUE" ]; then _err "TrueNAS is not ready." _err "Please check environment variables DEPLOY_TRUENAS_APIKEY, DEPLOY_TRUENAS_HOSTNAME and DEPLOY_TRUENAS_PROTOCOL." _err "Verify API key." @@ -188,7 +175,7 @@ truenas_ws_deploy() { _savedeployconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY" _info "TrueNAS health: OK" -########## System info + ########## System info _info "Gather system info..." _ws_response=$(_ws_call "system.info") @@ -196,82 +183,73 @@ truenas_ws_deploy() { _truenas_version=$(printf "%s" "$_ws_response" | jq -r '."version"' | cut -d '-' -f 3) _info "TrueNAS system: $_truenas_system" _info "TrueNAS version: $_truenas_version" - if [ "$_truenas_system" != "SCALE" ] && [ "$_truenas_system" != "CORE" ] - then + if [ "$_truenas_system" != "SCALE" ] && [ "$_truenas_system" != "CORE" ]; then _err "Cannot gather TrueNAS system. Nor CORE oder SCALE detected." return 10 fi -########## Gather current certificate + ########## Gather current certificate _info "Gather current WebUI certificate..." _ws_response="$(_ws_call "system.general.config")" _ui_certificate_id=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."id"') - _ui_certificate_name=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."name"') + _ui_certificate_name=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."name"') _info "Current WebUI certificate ID: $_ui_certificate_id" _info "Current WebUI certificate name: $_ui_certificate_name" -########## Upload new certificate + ########## Upload new certificate _info "Upload new certificate..." _certname="acme_$(_utc_date | tr -d '\-\:' | tr ' ' '_')" _debug _certname "$_certname" _ws_jobid=$(_ws_call "certificate.create" "{\"name\": \"${_certname}\", \"create_type\": \"CERTIFICATE_CREATE_IMPORTED\", \"certificate\": \"$(_json_encode <"$_file_fullchain")\", \"privatekey\": \"$(_json_encode <"$_file_key")\", \"passphrase\": \"\"}") _debug "_ws_jobid" "$_ws_jobid" - if ! _ws_check_jobid "$_ws_jobid" - then + if ! _ws_check_jobid "$_ws_jobid"; then _err "No JobID returned from websocket method." return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? - if [ $_ws_ret -gt 0 ] - then + if [ $_ws_ret -gt 0 ]; then return $_ws_ret fi _debug "_ws_result" "$_ws_result" _new_certid=$(printf "%s" "$_ws_result" | jq -r '."id"') _info "New certificate ID: $_new_certid" -########## FTP + ########## FTP _info "Replace FTP certificate..." _ws_response=$(_ws_call "ftp.update" "{\"ssltls_certificate\": $_new_certid}") _ftp_certid=$(printf "%s" "$_ws_response" | jq -r '."ssltls_certificate"') - if [ "$_ftp_certid" != "$_new_certid" ] - then + if [ "$_ftp_certid" != "$_new_certid" ]; then _err "Cannot set FTP certificate." _debug "_ws_response" "$_ws_response" return 4 fi -########## ix Apps (SCALE only) + ########## ix Apps (SCALE only) - if [ "$_truenas_system" = "SCALE" ] - then + if [ "$_truenas_system" = "SCALE" ]; then _info "Replace app certificates..." _ws_response=$(_ws_call "app.query") - for _app_name in $(printf "%s" "$_ws_response" | jq -r '.[]."name"') - do + for _app_name in $(printf "%s" "$_ws_response" | jq -r '.[]."name"'); do _info "Checking app $_app_name..." _ws_response=$(_ws_call "app.config" "$_app_name") - if [ "$(printf "%s" "$_ws_response" | jq -r '."network" | has("certificate_id")')" = "true" ] - then + if [ "$(printf "%s" "$_ws_response" | jq -r '."network" | has("certificate_id")')" = "true" ]; then _info "App has certificate option, setup new certificate..." _info "App will be redeployed after updating the certificate." _ws_jobid=$(_ws_call "app.update" "$_app_name" "{\"values\": {\"network\": {\"certificate_id\": $_new_certid}}}") _debug "_ws_jobid" "$_ws_jobid" - if ! _ws_check_jobid "$_ws_jobid" - then + if ! _ws_check_jobid "$_ws_jobid"; then _err "No JobID returned from websocket method." return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? - if [ $_ws_ret -gt 0 ] - then - return $_ws_ret - fi + if [ $_ws_ret -gt 0 ]; then + return $_ws_ret + fi _debug "_ws_result" "$_ws_result" _info "App certificate replaced." else @@ -280,13 +258,12 @@ truenas_ws_deploy() { done fi -########## WebUI + ########## WebUI _info "Replace WebUI certificate..." _ws_response=$(_ws_call "system.general.update" "{\"ui_certificate\": $_new_certid}") _changed_certid=$(printf "%s" "$_ws_response" | jq -r '."ui_certificate"."id"') - if [ "$_changed_certid" != "$_new_certid" ] - then + if [ "$_changed_certid" != "$_new_certid" ]; then _err "WebUI certificate change error.." return 5 else @@ -297,23 +274,20 @@ truenas_ws_deploy() { _info "Waiting for UI restart..." sleep 6 -########## Certificates + ########## Certificates _info "Deleting old certificate..." _ws_jobid=$(_ws_call "certificate.delete" "$_ui_certificate_id") - if ! _ws_check_jobid "$_ws_jobid" - then + if ! _ws_check_jobid "$_ws_jobid"; then _err "No JobID returned from websocket method." return 3 fi _ws_result=$(_ws_get_job_result "$_ws_jobid") _ws_ret=$? - if [ $_ws_ret -gt 0 ] - then + if [ $_ws_ret -gt 0 ]; then return $_ws_ret fi - _info "Have a nice day...bye!" } From 44240339d9856568d418d41f89556495cb651be2 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Mon, 25 Nov 2024 21:13:43 +0100 Subject: [PATCH 047/810] Update truenas_ws.sh (Interpreter changed from bash to sh) --- deploy/truenas_ws.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index 3ee983a3..7292987b 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # TrueNAS deploy script for SCALE/CORE using websocket # It is recommend to use a wildcard certificate From ebaf4c9c01bd590003bc91dec4ca05e88c091cb7 Mon Sep 17 00:00:00 2001 From: Attackwave <51136146+Attackwave@users.noreply.github.com> Date: Mon, 25 Nov 2024 21:23:59 +0100 Subject: [PATCH 048/810] Update truenas_ws.sh (Output new certificate name) --- deploy/truenas_ws.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/truenas_ws.sh b/deploy/truenas_ws.sh index 7292987b..940cde2e 100644 --- a/deploy/truenas_ws.sh +++ b/deploy/truenas_ws.sh @@ -201,6 +201,7 @@ truenas_ws_deploy() { _info "Upload new certificate..." _certname="acme_$(_utc_date | tr -d '\-\:' | tr ' ' '_')" + _info "New WebUI certificate name: $_certname" _debug _certname "$_certname" _ws_jobid=$(_ws_call "certificate.create" "{\"name\": \"${_certname}\", \"create_type\": \"CERTIFICATE_CREATE_IMPORTED\", \"certificate\": \"$(_json_encode <"$_file_fullchain")\", \"privatekey\": \"$(_json_encode <"$_file_key")\", \"passphrase\": \"\"}") _debug "_ws_jobid" "$_ws_jobid" From 9cd1d1a9dcbabcc2a316f1d655e2f5f2db8682cb Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Tue, 26 Nov 2024 09:20:18 +0100 Subject: [PATCH 049/810] dns_world4you: Adapt to change in world4you.com DeleteDnsRecordForm --- dnsapi/dns_world4you.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_world4you.sh b/dnsapi/dns_world4you.sh index be6ef5c8..2e8efe82 100644 --- a/dnsapi/dns_world4you.sh +++ b/dnsapi/dns_world4you.sh @@ -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 '