Merge branch 'acmesh-official:master' into master
commit
72259059ef
|
|
@ -26,7 +26,7 @@ jobs:
|
||||||
Linux:
|
Linux:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3"]
|
os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "gentoo/stage3"]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
TEST_LOCAL: 1
|
TEST_LOCAL: 1
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
repository: ${{ github.repository }}.wiki
|
repository: ${{ github.repository }}.wiki
|
||||||
path: wiki
|
path: wiki
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Generate wiki change message
|
- name: Generate wiki change message
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -58,3 +59,4 @@ jobs:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,9 +98,9 @@ https://github.com/acmesh-official/acmetest
|
||||||
|
|
||||||
- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA)(default)
|
- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA)(default)
|
||||||
- Letsencrypt.org CA
|
- Letsencrypt.org CA
|
||||||
- [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA)
|
|
||||||
- [SSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA)
|
- [SSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA)
|
||||||
- [Google.com Public CA](https://github.com/acmesh-official/acme.sh/wiki/Google-Public-CA)
|
- [Google.com Public CA](https://github.com/acmesh-official/acme.sh/wiki/Google-Public-CA)
|
||||||
|
- [Actalis.com CA](https://github.com/acmesh-official/acme.sh/wiki/Actalis.com-CA)
|
||||||
- [Pebble strict Mode](https://github.com/letsencrypt/pebble)
|
- [Pebble strict Mode](https://github.com/letsencrypt/pebble)
|
||||||
- Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA
|
- Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA
|
||||||
|
|
||||||
|
|
|
||||||
137
acme.sh
137
acme.sh
|
|
@ -23,9 +23,6 @@ _SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY"
|
||||||
CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory"
|
CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory"
|
||||||
CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory"
|
CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
|
|
||||||
CA_BUYPASS="https://api.buypass.com/acme/directory"
|
|
||||||
CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory"
|
|
||||||
|
|
||||||
CA_ZEROSSL="https://acme.zerossl.com/v2/DV90"
|
CA_ZEROSSL="https://acme.zerossl.com/v2/DV90"
|
||||||
_ZERO_EAB_ENDPOINT="https://api.zerossl.com/acme/eab-credentials-email"
|
_ZERO_EAB_ENDPOINT="https://api.zerossl.com/acme/eab-credentials-email"
|
||||||
|
|
||||||
|
|
@ -35,6 +32,8 @@ CA_SSLCOM_ECC="https://acme.ssl.com/sslcom-dv-ecc"
|
||||||
CA_GOOGLE="https://dv.acme-v02.api.pki.goog/directory"
|
CA_GOOGLE="https://dv.acme-v02.api.pki.goog/directory"
|
||||||
CA_GOOGLE_TEST="https://dv.acme-v02.test-api.pki.goog/directory"
|
CA_GOOGLE_TEST="https://dv.acme-v02.test-api.pki.goog/directory"
|
||||||
|
|
||||||
|
CA_ACTALIS="https://acme-api.actalis.com/acme/directory"
|
||||||
|
|
||||||
DEFAULT_CA=$CA_ZEROSSL
|
DEFAULT_CA=$CA_ZEROSSL
|
||||||
DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST
|
DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST
|
||||||
|
|
||||||
|
|
@ -42,14 +41,13 @@ CA_NAMES="
|
||||||
ZeroSSL.com,zerossl
|
ZeroSSL.com,zerossl
|
||||||
LetsEncrypt.org,letsencrypt
|
LetsEncrypt.org,letsencrypt
|
||||||
LetsEncrypt.org_test,letsencrypt_test,letsencrypttest
|
LetsEncrypt.org_test,letsencrypt_test,letsencrypttest
|
||||||
BuyPass.com,buypass
|
|
||||||
BuyPass.com_test,buypass_test,buypasstest
|
|
||||||
SSL.com,sslcom
|
SSL.com,sslcom
|
||||||
Google.com,google
|
Google.com,google
|
||||||
Google.com_test,googletest,google_test
|
Google.com_test,googletest,google_test
|
||||||
|
Actalis.com,actalis.com,actalis
|
||||||
"
|
"
|
||||||
|
|
||||||
CA_SERVERS="$CA_ZEROSSL,$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_SSLCOM_RSA,$CA_GOOGLE,$CA_GOOGLE_TEST"
|
CA_SERVERS="$CA_ZEROSSL,$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_SSLCOM_RSA,$CA_GOOGLE,$CA_GOOGLE_TEST,$CA_ACTALIS"
|
||||||
|
|
||||||
DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)"
|
DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)"
|
||||||
|
|
||||||
|
|
@ -180,6 +178,8 @@ _VALIDITY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Validity"
|
||||||
|
|
||||||
_DNSCHECK_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnscheck"
|
_DNSCHECK_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnscheck"
|
||||||
|
|
||||||
|
_PROFILESELECTION_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Profile-selection"
|
||||||
|
|
||||||
_DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead."
|
_DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead."
|
||||||
|
|
||||||
_DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR"
|
_DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR"
|
||||||
|
|
@ -436,14 +436,28 @@ _secure_debug3() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__USE_TR_TAG=""
|
||||||
|
if [ "$(echo "abc" | LANG=C tr a-z A-Z 2>/dev/null)" != "ABC" ]; then
|
||||||
|
__USE_TR_TAG="1"
|
||||||
|
fi
|
||||||
|
export __USE_TR_TAG
|
||||||
|
|
||||||
_upper_case() {
|
_upper_case() {
|
||||||
# shellcheck disable=SC2018,SC2019
|
if [ "$__USE_TR_TAG" ]; then
|
||||||
tr '[a-z]' '[A-Z]'
|
LANG=C tr '[:lower:]' '[:upper:]'
|
||||||
|
else
|
||||||
|
# shellcheck disable=SC2018,SC2019
|
||||||
|
LANG=C tr '[a-z]' '[A-Z]'
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_lower_case() {
|
_lower_case() {
|
||||||
# shellcheck disable=SC2018,SC2019
|
if [ "$__USE_TR_TAG" ]; then
|
||||||
tr '[A-Z]' '[a-z]'
|
LANG=C tr '[:upper:]' '[:lower:]'
|
||||||
|
else
|
||||||
|
# shellcheck disable=SC2018,SC2019
|
||||||
|
LANG=C tr '[A-Z]' '[a-z]'
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_startswith() {
|
_startswith() {
|
||||||
|
|
@ -1811,6 +1825,10 @@ _time() {
|
||||||
# 2022-04-01 08:10:33 to 1648800633
|
# 2022-04-01 08:10:33 to 1648800633
|
||||||
#or 2022-04-01T08:10:33Z to 1648800633
|
#or 2022-04-01T08:10:33Z to 1648800633
|
||||||
_date2time() {
|
_date2time() {
|
||||||
|
#Mac/BSD
|
||||||
|
if date -u -j -f "%Y-%m-%d %H:%M:%S" "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
#Linux
|
#Linux
|
||||||
if date -u -d "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then
|
if date -u -d "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then
|
||||||
return
|
return
|
||||||
|
|
@ -1820,10 +1838,6 @@ _date2time() {
|
||||||
if gdate -u -d "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then
|
if gdate -u -d "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
#Mac/BSD
|
|
||||||
if date -u -j -f "%Y-%m-%d %H:%M:%S" "$(echo "$1" | tr -d "Z" | tr "T" ' ')" +"%s" 2>/dev/null; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
#Omnios
|
#Omnios
|
||||||
if python3 -c "import datetime; print(int(datetime.datetime.strptime(\"$1\", \"%Y-%m-%d %H:%M:%S\").replace(tzinfo=datetime.timezone.utc).timestamp()))" 2>/dev/null; then
|
if python3 -c "import datetime; print(int(datetime.datetime.strptime(\"$1\", \"%Y-%m-%d %H:%M:%S\").replace(tzinfo=datetime.timezone.utc).timestamp()))" 2>/dev/null; then
|
||||||
return
|
return
|
||||||
|
|
@ -2538,15 +2552,19 @@ _startserver() {
|
||||||
_NC="socat"
|
_NC="socat"
|
||||||
if [ "$Le_Listen_V6" ]; then
|
if [ "$Le_Listen_V6" ]; then
|
||||||
_NC="$_NC -6"
|
_NC="$_NC -6"
|
||||||
else
|
SOCAT_OPTIONS=TCP6-LISTEN
|
||||||
|
elif [ "$Le_Listen_V4" ]; then
|
||||||
_NC="$_NC -4"
|
_NC="$_NC -4"
|
||||||
|
SOCAT_OPTIONS=TCP4-LISTEN
|
||||||
|
else
|
||||||
|
SOCAT_OPTIONS=TCP-LISTEN
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$DEBUG" ] && [ "$DEBUG" -gt "1" ]; then
|
if [ "$DEBUG" ] && [ "$DEBUG" -gt "1" ]; then
|
||||||
_NC="$_NC -d -d -v"
|
_NC="$_NC -d -d -v"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SOCAT_OPTIONS=TCP-LISTEN:$Le_HTTPPort,crlf,reuseaddr,fork
|
SOCAT_OPTIONS=$SOCAT_OPTIONS:$Le_HTTPPort,crlf,reuseaddr,fork
|
||||||
|
|
||||||
#Adding bind to local-address
|
#Adding bind to local-address
|
||||||
if [ "$ncaddr" ]; then
|
if [ "$ncaddr" ]; then
|
||||||
|
|
@ -3513,7 +3531,7 @@ _on_before_issue() {
|
||||||
_debug _chk_alt_domains "$_chk_alt_domains"
|
_debug _chk_alt_domains "$_chk_alt_domains"
|
||||||
#run pre hook
|
#run pre hook
|
||||||
if [ "$_chk_pre_hook" ]; then
|
if [ "$_chk_pre_hook" ]; then
|
||||||
_info "Runing pre hook:'$_chk_pre_hook'"
|
_info "Running pre hook:'$_chk_pre_hook'"
|
||||||
if ! (
|
if ! (
|
||||||
export Le_Domain="$_chk_main_domain"
|
export Le_Domain="$_chk_main_domain"
|
||||||
export Le_Alt="$_chk_alt_domains"
|
export Le_Alt="$_chk_alt_domains"
|
||||||
|
|
@ -4416,6 +4434,7 @@ issue() {
|
||||||
_preferred_chain="${15}"
|
_preferred_chain="${15}"
|
||||||
_valid_from="${16}"
|
_valid_from="${16}"
|
||||||
_valid_to="${17}"
|
_valid_to="${17}"
|
||||||
|
_certificate_profile="${18}"
|
||||||
|
|
||||||
if [ -z "$_ACME_IS_RENEW" ]; then
|
if [ -z "$_ACME_IS_RENEW" ]; then
|
||||||
_initpath "$_main_domain" "$_key_length"
|
_initpath "$_main_domain" "$_key_length"
|
||||||
|
|
@ -4491,6 +4510,11 @@ issue() {
|
||||||
else
|
else
|
||||||
_cleardomainconf "Le_Preferred_Chain"
|
_cleardomainconf "Le_Preferred_Chain"
|
||||||
fi
|
fi
|
||||||
|
if [ "$_certificate_profile" ]; then
|
||||||
|
_savedomainconf "Le_Certificate_Profile" "$_certificate_profile"
|
||||||
|
else
|
||||||
|
_cleardomainconf "Le_Certificate_Profile"
|
||||||
|
fi
|
||||||
|
|
||||||
Le_API="$ACME_DIRECTORY"
|
Le_API="$ACME_DIRECTORY"
|
||||||
_savedomainconf "Le_API" "$Le_API"
|
_savedomainconf "Le_API" "$Le_API"
|
||||||
|
|
@ -4502,6 +4526,7 @@ issue() {
|
||||||
|
|
||||||
if ! _on_before_issue "$_web_roots" "$_main_domain" "$_alt_domains" "$_pre_hook" "$_local_addr"; then
|
if ! _on_before_issue "$_web_roots" "$_main_domain" "$_alt_domains" "$_pre_hook" "$_local_addr"; then
|
||||||
_err "_on_before_issue."
|
_err "_on_before_issue."
|
||||||
|
_on_issue_err "$_post_hook"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -4622,6 +4647,9 @@ issue() {
|
||||||
if [ "$_notAfter" ]; then
|
if [ "$_notAfter" ]; then
|
||||||
_newOrderObj="$_newOrderObj,\"notAfter\": \"$_notAfter\""
|
_newOrderObj="$_newOrderObj,\"notAfter\": \"$_notAfter\""
|
||||||
fi
|
fi
|
||||||
|
if [ "$_certificate_profile" ]; then
|
||||||
|
_newOrderObj="$_newOrderObj,\"profile\": \"$_certificate_profile\""
|
||||||
|
fi
|
||||||
_debug "STEP 1, Ordering a Certificate"
|
_debug "STEP 1, Ordering a Certificate"
|
||||||
if ! _send_signed_request "$ACME_NEW_ORDER" "$_newOrderObj}"; then
|
if ! _send_signed_request "$ACME_NEW_ORDER" "$_newOrderObj}"; then
|
||||||
_err "Error creating new order."
|
_err "Error creating new order."
|
||||||
|
|
@ -4761,7 +4789,8 @@ $_authorizations_map"
|
||||||
_debug keyauthorization "$keyauthorization"
|
_debug keyauthorization "$keyauthorization"
|
||||||
fi
|
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"
|
_debug entry "$entry"
|
||||||
|
|
||||||
if [ -z "$keyauthorization" -a -z "$entry" ]; then
|
if [ -z "$keyauthorization" -a -z "$entry" ]; then
|
||||||
|
|
@ -5458,10 +5487,6 @@ renew() {
|
||||||
_info "Switching back to $CA_LETSENCRYPT_V2"
|
_info "Switching back to $CA_LETSENCRYPT_V2"
|
||||||
Le_API="$CA_LETSENCRYPT_V2"
|
Le_API="$CA_LETSENCRYPT_V2"
|
||||||
;;
|
;;
|
||||||
"$CA_BUYPASS_TEST")
|
|
||||||
_info "Switching back to $CA_BUYPASS"
|
|
||||||
Le_API="$CA_BUYPASS"
|
|
||||||
;;
|
|
||||||
"$CA_GOOGLE_TEST")
|
"$CA_GOOGLE_TEST")
|
||||||
_info "Switching back to $CA_GOOGLE"
|
_info "Switching back to $CA_GOOGLE"
|
||||||
Le_API="$CA_GOOGLE"
|
Le_API="$CA_GOOGLE"
|
||||||
|
|
@ -5503,6 +5528,7 @@ renew() {
|
||||||
Le_PostHook="$(_readdomainconf Le_PostHook)"
|
Le_PostHook="$(_readdomainconf Le_PostHook)"
|
||||||
Le_RenewHook="$(_readdomainconf Le_RenewHook)"
|
Le_RenewHook="$(_readdomainconf Le_RenewHook)"
|
||||||
Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)"
|
Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)"
|
||||||
|
Le_Certificate_Profile="$(_readdomainconf Le_Certificate_Profile)"
|
||||||
# When renewing from an old version, the empty Le_Keylength means 2048.
|
# When renewing from an old version, the empty Le_Keylength means 2048.
|
||||||
# Note, do not use DEFAULT_DOMAIN_KEY_LENGTH as that value may change over
|
# Note, do not use DEFAULT_DOMAIN_KEY_LENGTH as that value may change over
|
||||||
# time but an empty value implies 2048 specifically.
|
# time but an empty value implies 2048 specifically.
|
||||||
|
|
@ -5517,7 +5543,7 @@ renew() {
|
||||||
_cleardomainconf Le_OCSP_Staple
|
_cleardomainconf Le_OCSP_Staple
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain" "$Le_Valid_From" "$Le_Valid_To"
|
issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain" "$Le_Valid_From" "$Le_Valid_To" "$Le_Certificate_Profile"
|
||||||
res="$?"
|
res="$?"
|
||||||
if [ "$res" != "0" ]; then
|
if [ "$res" != "0" ]; then
|
||||||
return "$res"
|
return "$res"
|
||||||
|
|
@ -5778,7 +5804,7 @@ list() {
|
||||||
_sep="|"
|
_sep="|"
|
||||||
if [ "$_raw" ]; then
|
if [ "$_raw" ]; then
|
||||||
if [ -z "$_domain" ]; then
|
if [ -z "$_domain" ]; then
|
||||||
printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}CA${_sep}Created${_sep}Renew"
|
printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}Profile${_sep}CA${_sep}Created${_sep}Renew"
|
||||||
fi
|
fi
|
||||||
for di in "${CERT_HOME}"/*.*/; do
|
for di in "${CERT_HOME}"/*.*/; do
|
||||||
d=$(basename "$di")
|
d=$(basename "$di")
|
||||||
|
|
@ -5793,7 +5819,7 @@ list() {
|
||||||
. "$DOMAIN_CONF"
|
. "$DOMAIN_CONF"
|
||||||
_ca="$(_getCAShortName "$Le_API")"
|
_ca="$(_getCAShortName "$Le_API")"
|
||||||
if [ -z "$_domain" ]; then
|
if [ -z "$_domain" ]; then
|
||||||
printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr"
|
printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$Le_Certificate_Profile${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr"
|
||||||
else
|
else
|
||||||
if [ "$_domain" = "$d" ]; then
|
if [ "$_domain" = "$d" ]; then
|
||||||
cat "$DOMAIN_CONF"
|
cat "$DOMAIN_CONF"
|
||||||
|
|
@ -5812,6 +5838,48 @@ list() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_profiles() {
|
||||||
|
_initpath
|
||||||
|
_initAPI
|
||||||
|
|
||||||
|
_l_server_url="$ACME_DIRECTORY"
|
||||||
|
_l_server_name="$(_getCAShortName "$_l_server_url")"
|
||||||
|
_info "Fetching profiles from $_l_server_name ($_l_server_url)..."
|
||||||
|
|
||||||
|
response=$(_get "$_l_server_url" "" 10)
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "Failed to connect to CA directory: $_l_server_url"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
normalized_response=$(echo "$response" | _normalizeJson)
|
||||||
|
profiles_json=$(echo "$normalized_response" | _egrep_o '"profiles" *: *\{[^\}]*\}')
|
||||||
|
|
||||||
|
if [ -z "$profiles_json" ]; then
|
||||||
|
_info "The CA '$_l_server_name' does not publish certificate profiles via its directory endpoint."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Strip the outer layer to get the key-value pairs
|
||||||
|
profiles_kv=$(echo "$profiles_json" | sed 's/"profiles" *: *{//' | sed 's/}$//' | tr ',' '\n')
|
||||||
|
|
||||||
|
printf "\n%-15s %s\n" "name" "info"
|
||||||
|
printf -- "--------------------------------------------------------------------\n"
|
||||||
|
|
||||||
|
_old_IFS="$IFS"
|
||||||
|
IFS='
|
||||||
|
'
|
||||||
|
for pair in $profiles_kv; do
|
||||||
|
# Trim quotes and whitespace
|
||||||
|
_name=$(echo "$pair" | cut -d: -f1 | tr -d '" \t')
|
||||||
|
_info_url=$(echo "$pair" | cut -d: -f2- | sed 's/^ *//' | tr -d '"')
|
||||||
|
printf "%-15s %s\n" "$_name" "$_info_url"
|
||||||
|
done
|
||||||
|
IFS="$_old_IFS"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
_deploy() {
|
_deploy() {
|
||||||
_d="$1"
|
_d="$1"
|
||||||
_hooks="$2"
|
_hooks="$2"
|
||||||
|
|
@ -6350,7 +6418,8 @@ _deactivate() {
|
||||||
fi
|
fi
|
||||||
_debug "Trigger validation."
|
_debug "Trigger validation."
|
||||||
vtype="$(_getIdType "$_d_domain")"
|
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"
|
_debug entry "$entry"
|
||||||
if [ -z "$entry" ]; then
|
if [ -z "$entry" ]; then
|
||||||
_err "$d: Cannot get domain token"
|
_err "$d: Cannot get domain token"
|
||||||
|
|
@ -6989,6 +7058,9 @@ Parameters:
|
||||||
If no match, the default offered chain will be used. (default: empty)
|
If no match, the default offered chain will be used. (default: empty)
|
||||||
See: $_PREFERRED_CHAIN_WIKI
|
See: $_PREFERRED_CHAIN_WIKI
|
||||||
|
|
||||||
|
--cert-profile, --certificate-profile <profile> If the CA offers profiles, select the desired profile
|
||||||
|
See: $_PROFILESELECTION_WIKI
|
||||||
|
|
||||||
--valid-to <date-time> Request the NotAfter field of the cert.
|
--valid-to <date-time> Request the NotAfter field of the cert.
|
||||||
See: $_VALIDITY_WIKI
|
See: $_VALIDITY_WIKI
|
||||||
--valid-from <date-time> Request the NotBefore field of the cert.
|
--valid-from <date-time> Request the NotBefore field of the cert.
|
||||||
|
|
@ -7364,6 +7436,7 @@ _process() {
|
||||||
_preferred_chain=""
|
_preferred_chain=""
|
||||||
_valid_from=""
|
_valid_from=""
|
||||||
_valid_to=""
|
_valid_to=""
|
||||||
|
_certificate_profile=""
|
||||||
while [ ${#} -gt 0 ]; do
|
while [ ${#} -gt 0 ]; do
|
||||||
case "${1}" in
|
case "${1}" in
|
||||||
|
|
||||||
|
|
@ -7467,6 +7540,9 @@ _process() {
|
||||||
--set-default-chain)
|
--set-default-chain)
|
||||||
_CMD="setdefaultchain"
|
_CMD="setdefaultchain"
|
||||||
;;
|
;;
|
||||||
|
--list-profiles)
|
||||||
|
_CMD="list_profiles"
|
||||||
|
;;
|
||||||
-d | --domain)
|
-d | --domain)
|
||||||
_dvalue="$2"
|
_dvalue="$2"
|
||||||
|
|
||||||
|
|
@ -7682,6 +7758,10 @@ _process() {
|
||||||
_valid_to="$2"
|
_valid_to="$2"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--certificate-profile | --cert-profile)
|
||||||
|
_certificate_profile="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--httpport)
|
--httpport)
|
||||||
_httpport="$2"
|
_httpport="$2"
|
||||||
Le_HTTPPort="$_httpport"
|
Le_HTTPPort="$_httpport"
|
||||||
|
|
@ -7957,7 +8037,7 @@ _process() {
|
||||||
uninstall) uninstall "$_nocron" ;;
|
uninstall) uninstall "$_nocron" ;;
|
||||||
upgrade) upgrade ;;
|
upgrade) upgrade ;;
|
||||||
issue)
|
issue)
|
||||||
issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" "$_valid_from" "$_valid_to"
|
issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" "$_valid_from" "$_valid_to" "$_certificate_profile"
|
||||||
;;
|
;;
|
||||||
deploy)
|
deploy)
|
||||||
deploy "$_domain" "$_deploy_hook" "$_ecc"
|
deploy "$_domain" "$_deploy_hook" "$_ecc"
|
||||||
|
|
@ -8028,6 +8108,9 @@ _process() {
|
||||||
setdefaultchain)
|
setdefaultchain)
|
||||||
setdefaultchain "$_preferred_chain"
|
setdefaultchain "$_preferred_chain"
|
||||||
;;
|
;;
|
||||||
|
list_profiles)
|
||||||
|
list_profiles
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
if [ "$_CMD" ]; then
|
if [ "$_CMD" ]; then
|
||||||
_err "Invalid command: $_CMD"
|
_err "Invalid command: $_CMD"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
#!/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_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"
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Optional SCHEME
|
||||||
|
_getdeployconf DirectAdmin_SCHEME
|
||||||
|
# set default values for DirectAdmin_SCHEME
|
||||||
|
[ -n "${DirectAdmin_SCHEME}" ] || DirectAdmin_SCHEME="https"
|
||||||
|
|
||||||
|
_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" "$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."
|
||||||
|
_err "$_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "$_response"
|
||||||
|
_info "Domain $_cdomain certificate successfully deployed to DirectAdmin Domain $DirectAdmin_MAIN_DOMAIN."
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
#!/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"
|
||||||
|
|
||||||
|
# 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 #####################
|
||||||
|
|
||||||
|
#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')
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
#!/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
|
||||||
|
|
||||||
|
# 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)"
|
||||||
|
_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 class="message-body ">/,/<\/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')
|
||||||
|
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&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 class="message-body ">/,/<\/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
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
#!/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"
|
||||||
|
|
||||||
|
# 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 #####################
|
||||||
|
|
||||||
|
#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')
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
@ -7,20 +7,26 @@
|
||||||
#
|
#
|
||||||
# Firewall admin with superuser and IP address is required.
|
# Firewall admin with superuser and IP address is required.
|
||||||
#
|
#
|
||||||
# REQURED:
|
# REQUIRED:
|
||||||
# export PANOS_HOST=""
|
# export PANOS_HOST=""
|
||||||
# export PANOS_USER="" #User *MUST* have Commit and Import Permissions in XML API for Admin Role
|
# export PANOS_USER="" #User *MUST* have Commit and Import Permissions in XML API for Admin Role
|
||||||
# export PANOS_PASS=""
|
# export PANOS_PASS=""
|
||||||
#
|
#
|
||||||
# OPTIONAL
|
# OPTIONAL
|
||||||
# export PANOS_TEMPLATE="" #Template Name of panorama managed devices
|
# export PANOS_TEMPLATE="" # Template Name of panorama managed devices
|
||||||
|
# export PANOS_TEMPLATE_STACK="" # set a Template Stack if certificate should also be pushed automatically
|
||||||
|
# export PANOS_VSYS="Shared" # name of the vsys to import the certificate
|
||||||
#
|
#
|
||||||
# The script will automatically generate a new API key if
|
# The script will automatically generate a new API key if
|
||||||
# no key is found, or if a saved key has expired or is invalid.
|
# no key is found, or if a saved key has expired or is invalid.
|
||||||
|
|
||||||
|
_COMMIT_WAIT_INTERVAL=30 # query commit status every 30 seconds
|
||||||
|
_COMMIT_WAIT_ITERATIONS=20 # query commit status 20 times (20*30 = 600 seconds = 10 minutes)
|
||||||
|
|
||||||
# This function is to parse the XML response from the firewall
|
# This function is to parse the XML response from the firewall
|
||||||
parse_response() {
|
parse_response() {
|
||||||
type=$2
|
type=$2
|
||||||
|
_debug "API Response: $1"
|
||||||
if [ "$type" = 'keygen' ]; then
|
if [ "$type" = 'keygen' ]; then
|
||||||
status=$(echo "$1" | sed 's/^.*\(['\'']\)\([a-z]*\)'\''.*/\2/g')
|
status=$(echo "$1" | sed 's/^.*\(['\'']\)\([a-z]*\)'\''.*/\2/g')
|
||||||
if [ "$status" = "success" ]; then
|
if [ "$status" = "success" ]; then
|
||||||
|
|
@ -30,6 +36,13 @@ parse_response() {
|
||||||
message="PAN-OS Key could not be set."
|
message="PAN-OS Key could not be set."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
if [ "$type" = 'commit' ]; then
|
||||||
|
job_id=$(echo "$1" | sed 's/^.*\(<job>\)\(.*\)<\/job>.*/\2/g')
|
||||||
|
_commit_job_id=$job_id
|
||||||
|
elif [ "$type" = 'job_status' ]; then
|
||||||
|
job_status=$(echo "$1" | tr -d '\n' | sed 's/^.*<result>\([^<]*\)<\/result>.*/\1/g')
|
||||||
|
_commit_job_status=$job_status
|
||||||
|
fi
|
||||||
status=$(echo "$1" | tr -d '\n' | sed 's/^.*"\([a-z]*\)".*/\1/g')
|
status=$(echo "$1" | tr -d '\n' | sed 's/^.*"\([a-z]*\)".*/\1/g')
|
||||||
message=$(echo "$1" | tr -d '\n' | sed 's/.*\(<result>\|<msg>\|<line>\)\([^<]*\).*/\2/g')
|
message=$(echo "$1" | tr -d '\n' | sed 's/.*\(<result>\|<msg>\|<line>\)\([^<]*\).*/\2/g')
|
||||||
_debug "Firewall message: $message"
|
_debug "Firewall message: $message"
|
||||||
|
|
@ -44,13 +57,13 @@ parse_response() {
|
||||||
#This function is used to deploy to the firewall
|
#This function is used to deploy to the firewall
|
||||||
deployer() {
|
deployer() {
|
||||||
content=""
|
content=""
|
||||||
type=$1 # Types are keytest, keygen, cert, key, commit
|
type=$1 # Types are keytest, keygen, cert, key, commit, job_status, push
|
||||||
panos_url="https://$_panos_host/api/"
|
panos_url="https://$_panos_host/api/"
|
||||||
|
export _H1="Content-Type: application/x-www-form-urlencoded"
|
||||||
|
|
||||||
#Test API Key by performing a lookup
|
#Test API Key by performing a lookup
|
||||||
if [ "$type" = 'keytest' ]; then
|
if [ "$type" = 'keytest' ]; then
|
||||||
_debug "**** Testing saved API Key ****"
|
_debug "**** Testing saved API Key ****"
|
||||||
_H1="Content-Type: application/x-www-form-urlencoded"
|
|
||||||
# Get Version Info to test key
|
# Get Version Info to test key
|
||||||
content="type=version&key=$_panos_key"
|
content="type=version&key=$_panos_key"
|
||||||
## Exclude all scopes for the empty commit
|
## Exclude all scopes for the empty commit
|
||||||
|
|
@ -61,7 +74,6 @@ deployer() {
|
||||||
# Generate API Key
|
# Generate API Key
|
||||||
if [ "$type" = 'keygen' ]; then
|
if [ "$type" = 'keygen' ]; then
|
||||||
_debug "**** Generating new API Key ****"
|
_debug "**** Generating new API Key ****"
|
||||||
_H1="Content-Type: application/x-www-form-urlencoded"
|
|
||||||
content="type=keygen&user=$_panos_user&password=$_panos_pass"
|
content="type=keygen&user=$_panos_user&password=$_panos_pass"
|
||||||
# content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}"
|
# content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}"
|
||||||
fi
|
fi
|
||||||
|
|
@ -84,6 +96,9 @@ deployer() {
|
||||||
if [ "$_panos_template" ]; then
|
if [ "$_panos_template" ]; then
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
|
||||||
fi
|
fi
|
||||||
|
if [ "$_panos_vsys" ]; then
|
||||||
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl-vsys\"\r\n\r\n$_panos_vsys"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$type" = 'key' ]; then
|
if [ "$type" = 'key' ]; then
|
||||||
panos_url="${panos_url}?type=import"
|
panos_url="${panos_url}?type=import"
|
||||||
|
|
@ -96,6 +111,9 @@ deployer() {
|
||||||
if [ "$_panos_template" ]; then
|
if [ "$_panos_template" ]; then
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n$_panos_template"
|
||||||
fi
|
fi
|
||||||
|
if [ "$_panos_vsys" ]; then
|
||||||
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"target-tpl-vsys\"\r\n\r\n$_panos_vsys"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
#Close multipart
|
#Close multipart
|
||||||
content="$content${nl}--$delim--${nl}${nl}"
|
content="$content${nl}--$delim--${nl}${nl}"
|
||||||
|
|
@ -106,7 +124,6 @@ deployer() {
|
||||||
# Commit changes
|
# Commit changes
|
||||||
if [ "$type" = 'commit' ]; then
|
if [ "$type" = 'commit' ]; then
|
||||||
_debug "**** Committing changes ****"
|
_debug "**** Committing changes ****"
|
||||||
export _H1="Content-Type: application/x-www-form-urlencoded"
|
|
||||||
#Check for force commit - will commit ALL uncommited changes to the firewall. Use with caution!
|
#Check for force commit - will commit ALL uncommited changes to the firewall. Use with caution!
|
||||||
if [ "$FORCE" ]; then
|
if [ "$FORCE" ]; then
|
||||||
_debug "Force switch detected. Committing ALL changes to the firewall."
|
_debug "Force switch detected. Committing ALL changes to the firewall."
|
||||||
|
|
@ -118,6 +135,20 @@ deployer() {
|
||||||
content="type=commit&action=partial&key=$_panos_key&cmd=$cmd"
|
content="type=commit&action=partial&key=$_panos_key&cmd=$cmd"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Query job status
|
||||||
|
if [ "$type" = 'job_status' ]; then
|
||||||
|
echo "**** Querying job $_commit_job_id status ****"
|
||||||
|
cmd=$(printf "%s" "<show><jobs><id>$_commit_job_id</id></jobs></show>" | _url_encode)
|
||||||
|
content="type=op&key=$_panos_key&cmd=$cmd"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Push changes
|
||||||
|
if [ "$type" = 'push' ]; then
|
||||||
|
echo "**** Pushing changes ****"
|
||||||
|
cmd=$(printf "%s" "<commit-all><template-stack><name>$_panos_template_stack</name><admin><member>$_panos_user</member></admin></template-stack></commit-all>" | _url_encode)
|
||||||
|
content="type=commit&action=all&key=$_panos_key&cmd=$cmd"
|
||||||
|
fi
|
||||||
|
|
||||||
response=$(_post "$content" "$panos_url" "" "POST")
|
response=$(_post "$content" "$panos_url" "" "POST")
|
||||||
parse_response "$response" "$type"
|
parse_response "$response" "$type"
|
||||||
# Saving response to variables
|
# Saving response to variables
|
||||||
|
|
@ -126,6 +157,8 @@ deployer() {
|
||||||
if [ "$response_status" = "success" ]; then
|
if [ "$response_status" = "success" ]; then
|
||||||
_debug "Successfully deployed $type"
|
_debug "Successfully deployed $type"
|
||||||
return 0
|
return 0
|
||||||
|
elif [ "$_commit_job_status" ]; then
|
||||||
|
_debug "Commit Job Status = $_commit_job_status"
|
||||||
else
|
else
|
||||||
_err "Deploy of type $type failed. Try deploying with --debug to troubleshoot."
|
_err "Deploy of type $type failed. Try deploying with --debug to troubleshoot."
|
||||||
_debug "$message"
|
_debug "$message"
|
||||||
|
|
@ -191,11 +224,31 @@ panos_deploy() {
|
||||||
_getdeployconf PANOS_TEMPLATE
|
_getdeployconf PANOS_TEMPLATE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# PANOS_TEMPLATE_STACK
|
||||||
|
if [ "$PANOS_TEMPLATE_STACK" ]; then
|
||||||
|
_debug "Detected ENV variable PANOS_TEMPLATE_STACK. Saving to file."
|
||||||
|
_savedeployconf PANOS_TEMPLATE_STACK "$PANOS_TEMPLATE_STACK" 1
|
||||||
|
else
|
||||||
|
_debug "Attempting to load variable PANOS_TEMPLATE_STACK from file."
|
||||||
|
_getdeployconf PANOS_TEMPLATE_STACK
|
||||||
|
fi
|
||||||
|
|
||||||
|
# PANOS_TEMPLATE_STACK
|
||||||
|
if [ "$PANOS_VSYS" ]; then
|
||||||
|
_debug "Detected ENV variable PANOS_VSYS. Saving to file."
|
||||||
|
_savedeployconf PANOS_VSYS "$PANOS_VSYS" 1
|
||||||
|
else
|
||||||
|
_debug "Attempting to load variable PANOS_VSYS from file."
|
||||||
|
_getdeployconf PANOS_VSYS
|
||||||
|
fi
|
||||||
|
|
||||||
#Store variables
|
#Store variables
|
||||||
_panos_host=$PANOS_HOST
|
_panos_host=$PANOS_HOST
|
||||||
_panos_user=$PANOS_USER
|
_panos_user=$PANOS_USER
|
||||||
_panos_pass=$PANOS_PASS
|
_panos_pass=$PANOS_PASS
|
||||||
_panos_template=$PANOS_TEMPLATE
|
_panos_template=$PANOS_TEMPLATE
|
||||||
|
_panos_template_stack=$PANOS_TEMPLATE_STACK
|
||||||
|
_panos_vsys=$PANOS_VSYS
|
||||||
|
|
||||||
#Test API Key if found. If the key is invalid, the variable _panos_key will be unset.
|
#Test API Key if found. If the key is invalid, the variable _panos_key will be unset.
|
||||||
if [ "$_panos_host" ] && [ "$_panos_key" ]; then
|
if [ "$_panos_host" ] && [ "$_panos_key" ]; then
|
||||||
|
|
@ -229,6 +282,20 @@ panos_deploy() {
|
||||||
deployer cert
|
deployer cert
|
||||||
deployer key
|
deployer key
|
||||||
deployer commit
|
deployer commit
|
||||||
|
if [ "$_panos_template_stack" ]; then
|
||||||
|
# try to get job status for 20 times in 30 sec interval
|
||||||
|
i=0
|
||||||
|
while [ "$i" -lt $_COMMIT_WAIT_ITERATIONS ]; do
|
||||||
|
deployer job_status
|
||||||
|
if [ "$_commit_job_status" = "OK" ]; then
|
||||||
|
echo "Commit finished!"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep $_COMMIT_WAIT_INTERVAL
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
deployer push
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,16 @@ HEREDOC
|
||||||
_info "Push certificates to server"
|
_info "Push certificates to server"
|
||||||
export HTTPS_INSECURE=1
|
export HTTPS_INSECURE=1
|
||||||
export _H1="Authorization: PBSAPIToken=${_proxmoxbs_header_api_token}"
|
export _H1="Authorization: PBSAPIToken=${_proxmoxbs_header_api_token}"
|
||||||
_post "$_json_payload" "$_target_url" "" POST "application/json"
|
response=$(_post "$_json_payload" "$_target_url" "" POST "application/json")
|
||||||
|
_retval=$?
|
||||||
|
if [ "${_retval}" -eq 0 ]; then
|
||||||
|
_debug3 response "$response"
|
||||||
|
_info "Certificate successfully deployed"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Certificate deployment failed"
|
||||||
|
_debug "Response" "$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,16 @@ HEREDOC
|
||||||
_info "Push certificates to server"
|
_info "Push certificates to server"
|
||||||
export HTTPS_INSECURE=1
|
export HTTPS_INSECURE=1
|
||||||
export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}"
|
export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}"
|
||||||
_post "$_json_payload" "$_target_url" "" POST "application/json"
|
response=$(_post "$_json_payload" "$_target_url" "" POST "application/json")
|
||||||
|
_retval=$?
|
||||||
|
if [ "${_retval}" -eq 0 ]; then
|
||||||
|
_debug3 response "$response"
|
||||||
|
_info "Certificate successfully deployed"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Certificate deployment failed"
|
||||||
|
_debug "Response" "$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,13 +39,13 @@ _ws_call() {
|
||||||
_debug "_ws_call arg2" "$2"
|
_debug "_ws_call arg2" "$2"
|
||||||
_debug "_ws_call arg3" "$3"
|
_debug "_ws_call arg3" "$3"
|
||||||
if [ $# -eq 3 ]; then
|
if [ $# -eq 3 ]; then
|
||||||
_ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2" "$3")
|
_ws_response=$(midclt --uri "$_ws_uri" -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2" "$3")
|
||||||
fi
|
fi
|
||||||
if [ $# -eq 2 ]; then
|
if [ $# -eq 2 ]; then
|
||||||
_ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2")
|
_ws_response=$(midclt --uri "$_ws_uri" -K "$DEPLOY_TRUENAS_APIKEY" call "$1" "$2")
|
||||||
fi
|
fi
|
||||||
if [ $# -eq 1 ]; then
|
if [ $# -eq 1 ]; then
|
||||||
_ws_response=$(midclt -K "$DEPLOY_TRUENAS_APIKEY" call "$1")
|
_ws_response=$(midclt --uri "$_ws_uri" -K "$DEPLOY_TRUENAS_APIKEY" call "$1")
|
||||||
fi
|
fi
|
||||||
_debug "_ws_response" "$_ws_response"
|
_debug "_ws_response" "$_ws_response"
|
||||||
printf "%s" "$_ws_response"
|
printf "%s" "$_ws_response"
|
||||||
|
|
@ -60,7 +60,7 @@ _ws_upload_cert() {
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from truenas_api_client import Client
|
from truenas_api_client import Client
|
||||||
with Client() as c:
|
with Client(uri="$_ws_uri") as c:
|
||||||
|
|
||||||
### Login with API key
|
### Login with API key
|
||||||
print("I:Trying to upload new certificate...")
|
print("I:Trying to upload new certificate...")
|
||||||
|
|
@ -121,7 +121,7 @@ _ws_check_jobid() {
|
||||||
# n/a
|
# n/a
|
||||||
_ws_get_job_result() {
|
_ws_get_job_result() {
|
||||||
while true; do
|
while true; do
|
||||||
sleep 2
|
_sleep 2
|
||||||
_ws_response=$(_ws_call "core.get_jobs" "[[\"id\", \"=\", $1]]")
|
_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"')"
|
_ws_result="$(printf "%s" "$_ws_response" | jq '.[]."result"')"
|
||||||
|
|
@ -179,11 +179,27 @@ truenas_ws_deploy() {
|
||||||
|
|
||||||
_info "Checking environment variables..."
|
_info "Checking environment variables..."
|
||||||
_getdeployconf DEPLOY_TRUENAS_APIKEY
|
_getdeployconf DEPLOY_TRUENAS_APIKEY
|
||||||
|
_getdeployconf DEPLOY_TRUENAS_HOSTNAME
|
||||||
|
_getdeployconf DEPLOY_TRUENAS_PROTOCOL
|
||||||
# Check API Key
|
# 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."
|
_err "TrueNAS API key not found, please set the DEPLOY_TRUENAS_APIKEY environment variable."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
# Check Hostname, default to localhost if not set
|
||||||
|
if [ -z "$DEPLOY_TRUENAS_HOSTNAME" ]; then
|
||||||
|
_info "TrueNAS hostname not set. Using 'localhost'."
|
||||||
|
DEPLOY_TRUENAS_HOSTNAME="localhost"
|
||||||
|
fi
|
||||||
|
# Check protocol, default to ws if not set
|
||||||
|
if [ -z "$DEPLOY_TRUENAS_PROTOCOL" ]; then
|
||||||
|
_info "TrueNAS protocol not set. Using 'ws'."
|
||||||
|
DEPLOY_TRUENAS_PROTOCOL="ws"
|
||||||
|
fi
|
||||||
|
_ws_uri="$DEPLOY_TRUENAS_PROTOCOL://$DEPLOY_TRUENAS_HOSTNAME/websocket"
|
||||||
|
_debug2 DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME"
|
||||||
|
_debug2 DEPLOY_TRUENAS_PROTOCOL "$DEPLOY_TRUENAS_PROTOCOL"
|
||||||
|
_debug _ws_uri "$_ws_uri"
|
||||||
_secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY"
|
_secure_debug2 DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY"
|
||||||
_info "Environment variables: OK"
|
_info "Environment variables: OK"
|
||||||
|
|
||||||
|
|
@ -205,6 +221,8 @@ truenas_ws_deploy() {
|
||||||
return 2
|
return 2
|
||||||
fi
|
fi
|
||||||
_savedeployconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY"
|
_savedeployconf DEPLOY_TRUENAS_APIKEY "$DEPLOY_TRUENAS_APIKEY"
|
||||||
|
_savedeployconf DEPLOY_TRUENAS_HOSTNAME "$DEPLOY_TRUENAS_HOSTNAME"
|
||||||
|
_savedeployconf DEPLOY_TRUENAS_PROTOCOL "$DEPLOY_TRUENAS_PROTOCOL"
|
||||||
_info "TrueNAS health: OK"
|
_info "TrueNAS health: OK"
|
||||||
|
|
||||||
########## System info
|
########## System info
|
||||||
|
|
@ -304,7 +322,7 @@ truenas_ws_deploy() {
|
||||||
_info "Restarting WebUI..."
|
_info "Restarting WebUI..."
|
||||||
_ws_response=$(_ws_call "system.general.ui_restart")
|
_ws_response=$(_ws_call "system.general.ui_restart")
|
||||||
_info "Waiting for UI restart..."
|
_info "Waiting for UI restart..."
|
||||||
sleep 6
|
_sleep 15
|
||||||
|
|
||||||
########## Certificates
|
########## Certificates
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
BEGET_User API user
|
BEGET_User API user
|
||||||
BEGET_Password API password
|
BEGET_Password API password
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/6200
|
Issues: github.com/acmesh-official/acme.sh/issues/6200
|
||||||
Author: ARNik arnik@arnik.ru
|
Author: ARNik <arnik@arnik.ru>
|
||||||
'
|
'
|
||||||
|
|
||||||
Beget_Api="https://api.beget.com/api"
|
Beget_Api="https://api.beget.com/api"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
BOOKMYNAME_USERNAME Username
|
BOOKMYNAME_USERNAME Username
|
||||||
BOOKMYNAME_PASSWORD Password
|
BOOKMYNAME_PASSWORD Password
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/3209
|
Issues: github.com/acmesh-official/acme.sh/issues/3209
|
||||||
Author: Neilpang
|
Author: @Neilpang
|
||||||
'
|
'
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ dns_constellix_rm() {
|
||||||
#################### Private functions below ##################################
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
_get_root() {
|
_get_root() {
|
||||||
domain=$1
|
domain=$(echo "$1" | _lower_case)
|
||||||
i=2
|
i=2
|
||||||
p=1
|
p=1
|
||||||
_debug "Detecting root zone"
|
_debug "Detecting root zone"
|
||||||
|
|
@ -156,6 +156,9 @@ _constellix_rest() {
|
||||||
data="$3"
|
data="$3"
|
||||||
_debug "$ep"
|
_debug "$ep"
|
||||||
|
|
||||||
|
# Prevent rate limit
|
||||||
|
_sleep 2
|
||||||
|
|
||||||
rdate=$(date +"%s")"000"
|
rdate=$(date +"%s")"000"
|
||||||
hmac=$(printf "%s" "$rdate" | _hmac sha1 "$(printf "%s" "$CONSTELLIX_Secret" | _hex_dump | tr -d ' ')" | _base64)
|
hmac=$(printf "%s" "$rdate" | _hmac sha1 "$(printf "%s" "$CONSTELLIX_Secret" | _hex_dump | tr -d ' ')" | _base64)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_ddnss
|
||||||
Options:
|
Options:
|
||||||
DDNSS_Token API Token
|
DDNSS_Token API Token
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/2230
|
Issues: github.com/acmesh-official/acme.sh/issues/2230
|
||||||
Author: RaidenII, helbgd, mod242
|
Author: @helbgd, @mod242
|
||||||
'
|
'
|
||||||
|
|
||||||
DDNSS_DNS_API="https://ddnss.de/upd.php"
|
DDNSS_DNS_API="https://ddnss.de/upd.php"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
DNSHOME_Subdomain Subdomain
|
DNSHOME_Subdomain Subdomain
|
||||||
DNSHOME_SubdomainPassword Subdomain Password
|
DNSHOME_SubdomainPassword Subdomain Password
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/3819
|
Issues: github.com/acmesh-official/acme.sh/issues/3819
|
||||||
Author: dnsHome.de https://github.com/dnsHome-de
|
Author: @dnsHome-de
|
||||||
'
|
'
|
||||||
|
|
||||||
# Usage: add subdomain.ddnsdomain.tld "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
# Usage: add subdomain.ddnsdomain.tld "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Site: www.DuckDNS.org
|
||||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_duckdns
|
||||||
Options:
|
Options:
|
||||||
DuckDNS_Token API Token
|
DuckDNS_Token API Token
|
||||||
Author: RaidenII
|
Author: @RaidenII
|
||||||
'
|
'
|
||||||
|
|
||||||
DuckDNS_API="https://www.duckdns.org/update"
|
DuckDNS_API="https://www.duckdns.org/update"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ Options:
|
||||||
DYN_Customer Customer
|
DYN_Customer Customer
|
||||||
DYN_Username API Username
|
DYN_Username API Username
|
||||||
DYN_Password Secret
|
DYN_Password Secret
|
||||||
Author: Gerd Naschenweng <https://github.com/magicdude4eva>
|
Author: Gerd Naschenweng <@magicdude4eva>
|
||||||
'
|
'
|
||||||
|
|
||||||
# Dyn Managed DNS API
|
# Dyn Managed DNS API
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ Options:
|
||||||
OptionsAlt:
|
OptionsAlt:
|
||||||
KEY Path to SSH private key file. E.g. "/root/.ssh/dynv6"
|
KEY Path to SSH private key file. E.g. "/root/.ssh/dynv6"
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/2702
|
Issues: github.com/acmesh-official/acme.sh/issues/2702
|
||||||
Author: StefanAbl
|
Author: @StefanAbl
|
||||||
'
|
'
|
||||||
|
|
||||||
dynv6_api="https://dynv6.com/api/v2"
|
dynv6_api="https://dynv6.com/api/v2"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
EASYDNS_Token API Token
|
EASYDNS_Token API Token
|
||||||
EASYDNS_Key API Key
|
EASYDNS_Key API Key
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/2647
|
Issues: github.com/acmesh-official/acme.sh/issues/2647
|
||||||
Author: Neilpang, wurzelpanzer <wurzelpanzer@maximolider.net>
|
Author: @Neilpang, wurzelpanzer <wurzelpanzer@maximolider.net>
|
||||||
'
|
'
|
||||||
|
|
||||||
# API Documentation: https://sandbox.rest.easydns.net:3001/
|
# API Documentation: https://sandbox.rest.easydns.net:3001/
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ _get_root() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _rest GET "dns/domain/"; then
|
if ! _rest GET "dns/domain/?q=$h"; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
FREEDNS_User Username
|
FREEDNS_User Username
|
||||||
FREEDNS_Password Password
|
FREEDNS_Password Password
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/2305
|
Issues: github.com/acmesh-official/acme.sh/issues/2305
|
||||||
Author: David Kerr <https://github.com/dkerr64>
|
Author: David Kerr <@dkerr64>
|
||||||
'
|
'
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ Site: dns.he.net
|
||||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_he_ddns
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_he_ddns
|
||||||
Options:
|
Options:
|
||||||
HE_DDNS_KEY The DDNS key
|
HE_DDNS_KEY The DDNS key
|
||||||
|
Issues: https://github.com/acmesh-official/acme.sh/issues/5238
|
||||||
Author: Markku Leiniö
|
Author: Markku Leiniö
|
||||||
'
|
'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
JOKER_USERNAME Username
|
JOKER_USERNAME Username
|
||||||
JOKER_PASSWORD Password
|
JOKER_PASSWORD Password
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/2840
|
Issues: github.com/acmesh-official/acme.sh/issues/2840
|
||||||
Author: <https://github.com/aattww/>
|
Author: @aattww
|
||||||
'
|
'
|
||||||
|
|
||||||
JOKER_API="https://svc.joker.com/nic/replace"
|
JOKER_API="https://svc.joker.com/nic/replace"
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# LA_Id="123"
|
||||||
|
# LA_Sk="456"
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
dns_la_info='dns.la
|
dns_la_info='dns.la
|
||||||
Site: dns.la
|
Site: dns.la
|
||||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_la
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_la
|
||||||
Options:
|
Options:
|
||||||
LA_Id API ID
|
LA_Id APIID
|
||||||
LA_Key API key
|
LA_Sk APISecret
|
||||||
|
LA_Token 用冒号连接 APIID APISecret 再base64生成
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/4257
|
Issues: github.com/acmesh-official/acme.sh/issues/4257
|
||||||
'
|
'
|
||||||
|
|
||||||
LA_Api="https://api.dns.la/api"
|
LA_Api="https://api.dns.la/api"
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
@ -19,18 +22,23 @@ dns_la_add() {
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
|
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
|
||||||
LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}"
|
LA_Sk="${LA_Sk:-$(_readaccountconf_mutable LA_Sk)}"
|
||||||
|
_log "LA_Id=$LA_Id"
|
||||||
|
_log "LA_Sk=$LA_Sk"
|
||||||
|
|
||||||
if [ -z "$LA_Id" ] || [ -z "$LA_Key" ]; then
|
if [ -z "$LA_Id" ] || [ -z "$LA_Sk" ]; then
|
||||||
LA_Id=""
|
LA_Id=""
|
||||||
LA_Key=""
|
LA_Sk=""
|
||||||
_err "You didn't specify a dnsla api id and key yet."
|
_err "You didn't specify a dnsla api id and key yet."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#save the api key and email to the account conf file.
|
#save the api key and email to the account conf file.
|
||||||
_saveaccountconf_mutable LA_Id "$LA_Id"
|
_saveaccountconf_mutable LA_Id "$LA_Id"
|
||||||
_saveaccountconf_mutable LA_Key "$LA_Key"
|
_saveaccountconf_mutable LA_Sk "$LA_Sk"
|
||||||
|
|
||||||
|
# generate dnsla token
|
||||||
|
_la_token
|
||||||
|
|
||||||
_debug "First detect the root zone"
|
_debug "First detect the root zone"
|
||||||
if ! _get_root "$fulldomain"; then
|
if ! _get_root "$fulldomain"; then
|
||||||
|
|
@ -42,11 +50,13 @@ dns_la_add() {
|
||||||
_debug _domain "$_domain"
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
_info "Adding record"
|
_info "Adding record"
|
||||||
if _la_rest "record.ashx?cmd=create&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue&recordline="; then
|
|
||||||
if _contains "$response" '"resultid":'; then
|
# record type is enum in new api, 16 for TXT
|
||||||
|
if _la_post "{\"domainId\":\"$_domain_id\",\"type\":16,\"host\":\"$_sub_domain\",\"data\":\"$txtvalue\",\"ttl\":600}" "record"; then
|
||||||
|
if _contains "$response" '"id":'; then
|
||||||
_info "Added, OK"
|
_info "Added, OK"
|
||||||
return 0
|
return 0
|
||||||
elif _contains "$response" '"code":532'; then
|
elif _contains "$response" '"msg":"与已有记录冲突"'; then
|
||||||
_info "Already exists, OK"
|
_info "Already exists, OK"
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
|
|
@ -54,7 +64,7 @@ dns_la_add() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
_err "Add txt record error."
|
_err "Add txt record failed."
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +75,9 @@ dns_la_rm() {
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
|
LA_Id="${LA_Id:-$(_readaccountconf_mutable LA_Id)}"
|
||||||
LA_Key="${LA_Key:-$(_readaccountconf_mutable LA_Key)}"
|
LA_Sk="${LA_Sk:-$(_readaccountconf_mutable LA_Sk)}"
|
||||||
|
|
||||||
|
_la_token
|
||||||
|
|
||||||
_debug "First detect the root zone"
|
_debug "First detect the root zone"
|
||||||
if ! _get_root "$fulldomain"; then
|
if ! _get_root "$fulldomain"; then
|
||||||
|
|
@ -77,27 +89,29 @@ dns_la_rm() {
|
||||||
_debug _domain "$_domain"
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
_debug "Getting txt records"
|
_debug "Getting txt records"
|
||||||
if ! _la_rest "record.ashx?cmd=listn&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&host=$_sub_domain&recordtype=TXT&recorddata=$txtvalue"; then
|
# record type is enum in new api, 16 for TXT
|
||||||
|
if ! _la_get "recordList?pageIndex=1&pageSize=10&domainId=$_domain_id&host=$_sub_domain&type=16&data=$txtvalue"; then
|
||||||
_err "Error"
|
_err "Error"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _contains "$response" '"recordid":'; then
|
if ! _contains "$response" '"id":'; then
|
||||||
_info "Don't need to remove."
|
_info "Don't need to remove."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
record_id=$(printf "%s" "$response" | grep '"recordid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n')
|
record_id=$(printf "%s" "$response" | grep '"id":' | _head_n 1 | sed 's/.*"id": *"\([^"]*\)".*/\1/')
|
||||||
_debug "record_id" "$record_id"
|
_debug "record_id" "$record_id"
|
||||||
if [ -z "$record_id" ]; then
|
if [ -z "$record_id" ]; then
|
||||||
_err "Can not get record id to remove."
|
_err "Can not get record id to remove."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
if ! _la_rest "record.ashx?cmd=remove&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domainid=$_domain_id&domain=$_domain&recordid=$record_id"; then
|
# remove record in new api is RESTful
|
||||||
|
if ! _la_post "" "record?id=$record_id" "DELETE"; then
|
||||||
_err "Delete record error."
|
_err "Delete record error."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_contains "$response" '"code":300'
|
_contains "$response" '"code":200'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,12 +133,13 @@ _get_root() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _la_rest "domain.ashx?cmd=get&apiid=$LA_Id&apipass=$LA_Key&rtype=json&domain=$h"; then
|
if ! _la_get "domain?domain=$h"; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$response" '"domainid":'; then
|
if _contains "$response" '"domain":'; then
|
||||||
_domain_id=$(printf "%s" "$response" | grep '"domainid":' | cut -d : -f 2 | cut -d , -f 1 | tr -d '\r' | tr -d '\n')
|
_domain_id=$(echo "$response" | sed -n 's/.*"id":"\([^"]*\)".*/\1/p')
|
||||||
|
_log "_domain_id" "$_domain_id"
|
||||||
if [ "$_domain_id" ]; then
|
if [ "$_domain_id" ]; then
|
||||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
|
||||||
_domain="$h"
|
_domain="$h"
|
||||||
|
|
@ -143,6 +158,21 @@ _la_rest() {
|
||||||
url="$LA_Api/$1"
|
url="$LA_Api/$1"
|
||||||
_debug "$url"
|
_debug "$url"
|
||||||
|
|
||||||
|
if ! response="$(_get "$url" "Authorization: Basic $LA_Token" | tr -d ' ' | tr "}" ",")"; then
|
||||||
|
_err "Error: $url"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug2 response "$response"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_la_get() {
|
||||||
|
url="$LA_Api/$1"
|
||||||
|
_debug "$url"
|
||||||
|
|
||||||
|
export _H1="Authorization: Basic $LA_Token"
|
||||||
|
|
||||||
if ! response="$(_get "$url" | tr -d ' ' | tr "}" ",")"; then
|
if ! response="$(_get "$url" | tr -d ' ' | tr "}" ",")"; then
|
||||||
_err "Error: $url"
|
_err "Error: $url"
|
||||||
return 1
|
return 1
|
||||||
|
|
@ -151,3 +181,29 @@ _la_rest() {
|
||||||
_debug2 response "$response"
|
_debug2 response "$response"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Usage: _la_post body url [POST|PUT|DELETE]
|
||||||
|
_la_post() {
|
||||||
|
body=$1
|
||||||
|
url="$LA_Api/$2"
|
||||||
|
http_method=$3
|
||||||
|
_debug "$body"
|
||||||
|
_debug "$url"
|
||||||
|
|
||||||
|
export _H1="Authorization: Basic $LA_Token"
|
||||||
|
|
||||||
|
if ! response="$(_post "$body" "$url" "" "$http_method")"; then
|
||||||
|
_err "Error: $url"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug2 response "$response"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_la_token() {
|
||||||
|
LA_Token=$(printf "%s:%s" "$LA_Id" "$LA_Sk" | _base64)
|
||||||
|
_debug "$LA_Token"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
dns_mijnhost_info='mijn.host
|
dns_mijnhost_info='mijn.host
|
||||||
Domains: mijn.host
|
|
||||||
Site: mijn.host
|
Site: mijn.host
|
||||||
Docs: https://mijn.host/api/doc/
|
Docs: https://github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_mijnhost
|
||||||
Issues: https://github.com/acmesh-official/acme.sh/issues/6177
|
|
||||||
Author: peterv99
|
|
||||||
Options:
|
Options:
|
||||||
MIJNHOST_API_KEY API Key
|
MIJNHOST_API_KEY API Key
|
||||||
|
Issues: github.com/acmesh-official/acme.sh/issues/6177
|
||||||
|
Author: @peterv99
|
||||||
'
|
'
|
||||||
|
|
||||||
######## Public functions ###################### Constants for your mijn-host API
|
######## Public functions ######################
|
||||||
MIJNHOST_API="https://mijn.host/api/v2"
|
MIJNHOST_API="https://mijn.host/api/v2"
|
||||||
|
|
||||||
# Add TXT record for domain verification
|
# Add TXT record for domain verification
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_mydnsjp
|
||||||
Options:
|
Options:
|
||||||
MYDNSJP_MasterID Master ID
|
MYDNSJP_MasterID Master ID
|
||||||
MYDNSJP_Password Password
|
MYDNSJP_Password Password
|
||||||
Author: epgdatacapbon
|
Author: @tkmsst
|
||||||
'
|
'
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_namecom
|
||||||
Options:
|
Options:
|
||||||
Namecom_Username Username
|
Namecom_Username Username
|
||||||
Namecom_Token API Token
|
Namecom_Token API Token
|
||||||
Author: RaidenII
|
Author: @RaidenII
|
||||||
'
|
'
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Site: NameSilo.com
|
||||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_namesilo
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_namesilo
|
||||||
Options:
|
Options:
|
||||||
Namesilo_Key API Key
|
Namesilo_Key API Key
|
||||||
Author: meowthink
|
Author: @meowthink
|
||||||
'
|
'
|
||||||
|
|
||||||
#Utilize API to finish dns-01 verifications.
|
#Utilize API to finish dns-01 verifications.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,186 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
dns_openprovider_rest_info='OpenProvider (REST)
|
||||||
|
Domains: OpenProvider.com
|
||||||
|
Site: OpenProvider.eu
|
||||||
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_openprovider_rest
|
||||||
|
Options:
|
||||||
|
OPENPROVIDER_REST_USERNAME Openprovider Account Username
|
||||||
|
OPENPROVIDER_REST_PASSWORD Openprovider Account Password
|
||||||
|
Issues: github.com/acmesh-official/acme.sh/issues/6122
|
||||||
|
Author: Lambiek12
|
||||||
|
'
|
||||||
|
|
||||||
|
OPENPROVIDER_API_URL="https://api.openprovider.eu/v1beta"
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
# Used to add txt record
|
||||||
|
dns_openprovider_rest_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
_openprovider_prepare_credentials || return 1
|
||||||
|
|
||||||
|
_debug "Try fetch OpenProvider DNS zone details"
|
||||||
|
if ! _get_dns_zone "$fulldomain"; then
|
||||||
|
_err "DNS zone not found within configured OpenProvider account."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$_domain_id" ]; then
|
||||||
|
addzonerecordrequestparameters="dns/zones/$_domain_name"
|
||||||
|
addzonerecordrequestbody="{\"id\":$_domain_id,\"name\":\"$_domain_name\",\"records\":{\"add\":[{\"name\":\"$_sub_domain\",\"ttl\":900,\"type\":\"TXT\",\"value\":\"$txtvalue\"}]}}"
|
||||||
|
|
||||||
|
if _openprovider_rest PUT "$addzonerecordrequestparameters" "$addzonerecordrequestbody"; then
|
||||||
|
if _contains "$response" "\"success\":true"; then
|
||||||
|
return 0
|
||||||
|
elif _contains "$response" "\"Duplicate record\""; then
|
||||||
|
_debug "Record already existed"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Adding TXT record failed due to errors."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
_err "Adding TXT record failed due to errors."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Usage: rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
# Used to remove the txt record after validation
|
||||||
|
dns_openprovider_rest_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
_openprovider_prepare_credentials || return 1
|
||||||
|
|
||||||
|
_debug "Try fetch OpenProvider DNS zone details"
|
||||||
|
if ! _get_dns_zone "$fulldomain"; then
|
||||||
|
_err "DNS zone not found within configured OpenProvider account."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$_domain_id" ]; then
|
||||||
|
removezonerecordrequestparameters="dns/zones/$_domain_name"
|
||||||
|
removezonerecordrequestbody="{\"id\":$_domain_id,\"name\":\"$_domain_name\",\"records\":{\"remove\":[{\"name\":\"$_sub_domain\",\"ttl\":900,\"type\":\"TXT\",\"value\":\"\\\"$txtvalue\\\"\"}]}}"
|
||||||
|
|
||||||
|
if _openprovider_rest PUT "$removezonerecordrequestparameters" "$removezonerecordrequestbody"; then
|
||||||
|
if _contains "$response" "\"success\":true"; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Removing TXT record failed due to errors."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
_err "Removing TXT record failed due to errors."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### OpenProvider API common functions ####################
|
||||||
|
_openprovider_prepare_credentials() {
|
||||||
|
OPENPROVIDER_REST_USERNAME="${OPENPROVIDER_REST_USERNAME:-$(_readaccountconf_mutable OPENPROVIDER_REST_USERNAME)}"
|
||||||
|
OPENPROVIDER_REST_PASSWORD="${OPENPROVIDER_REST_PASSWORD:-$(_readaccountconf_mutable OPENPROVIDER_REST_PASSWORD)}"
|
||||||
|
|
||||||
|
if [ -z "$OPENPROVIDER_REST_USERNAME" ] || [ -z "$OPENPROVIDER_REST_PASSWORD" ]; then
|
||||||
|
OPENPROVIDER_REST_USERNAME=""
|
||||||
|
OPENPROVIDER_REST_PASSWORD=""
|
||||||
|
_err "You didn't specify the Openprovider username or password yet."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#save the credentials to the account conf file.
|
||||||
|
_saveaccountconf_mutable OPENPROVIDER_REST_USERNAME "$OPENPROVIDER_REST_USERNAME"
|
||||||
|
_saveaccountconf_mutable OPENPROVIDER_REST_PASSWORD "$OPENPROVIDER_REST_PASSWORD"
|
||||||
|
}
|
||||||
|
|
||||||
|
_openprovider_rest() {
|
||||||
|
httpmethod=$1
|
||||||
|
queryparameters=$2
|
||||||
|
requestbody=$3
|
||||||
|
|
||||||
|
_openprovider_rest_login
|
||||||
|
if [ -z "$openproviderauthtoken" ]; then
|
||||||
|
_err "Unable to fetch authentication token from Openprovider API."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export _H1="Content-Type: application/json"
|
||||||
|
export _H2="Accept: application/json"
|
||||||
|
export _H3="Authorization: Bearer $openproviderauthtoken"
|
||||||
|
|
||||||
|
if [ "$httpmethod" != "GET" ]; then
|
||||||
|
response="$(_post "$requestbody" "$OPENPROVIDER_API_URL/$queryparameters" "" "$httpmethod")"
|
||||||
|
else
|
||||||
|
response="$(_get "$OPENPROVIDER_API_URL/$queryparameters")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "No valid parameters supplied for Openprovider API: Error $queryparameters"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug2 response "$response"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_openprovider_rest_login() {
|
||||||
|
export _H1="Content-Type: application/json"
|
||||||
|
export _H2="Accept: application/json"
|
||||||
|
|
||||||
|
loginrequesturl="$OPENPROVIDER_API_URL/auth/login"
|
||||||
|
loginrequestbody="{\"ip\":\"0.0.0.0\",\"password\":\"$OPENPROVIDER_REST_PASSWORD\",\"username\":\"$OPENPROVIDER_REST_USERNAME\"}"
|
||||||
|
loginresponse="$(_post "$loginrequestbody" "$loginrequesturl" "" "POST")"
|
||||||
|
|
||||||
|
openproviderauthtoken="$(printf "%s\n" "$loginresponse" | _egrep_o '"token" *: *"[^"]*' | _head_n 1 | sed 's#^"token" *: *"##')"
|
||||||
|
|
||||||
|
export openproviderauthtoken
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions ##################################
|
||||||
|
|
||||||
|
# Usage: _get_dns_zone _acme-challenge.www.domain.com
|
||||||
|
# Returns:
|
||||||
|
# _domain_id=123456789
|
||||||
|
# _domain_name=domain.com
|
||||||
|
# _sub_domain=_acme-challenge.www
|
||||||
|
_get_dns_zone() {
|
||||||
|
domain=$1
|
||||||
|
i=1
|
||||||
|
p=1
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
# Empty value not allowed
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _openprovider_rest GET "dns/zones/$h" ""; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _contains "$response" "\"name\":\"$h\""; then
|
||||||
|
_domain_id="$(printf "%s\n" "$response" | _egrep_o '"id" *: *[^,]*' | _head_n 1 | sed 's#^"id" *: *##')"
|
||||||
|
_debug _domain_id "$_domain_id"
|
||||||
|
|
||||||
|
_domain_name="$h"
|
||||||
|
_debug _domain_name "$_domain_name"
|
||||||
|
|
||||||
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
p=$i
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
@ -110,15 +110,16 @@ rm_record() {
|
||||||
if _existingchallenge "$_domain" "$_host" "$new_challenge"; then
|
if _existingchallenge "$_domain" "$_host" "$new_challenge"; then
|
||||||
# Delete
|
# Delete
|
||||||
if _opns_rest "POST" "/record/delRecord/${_uuid}" "\{\}"; then
|
if _opns_rest "POST" "/record/delRecord/${_uuid}" "\{\}"; then
|
||||||
if echo "$_return_str" | _egrep_o "\"result\":\"deleted\"" >/dev/null; then
|
if echo "$response" | _egrep_o "\"result\":\"deleted\"" >/dev/null; then
|
||||||
_opns_rest "POST" "/service/reconfigure" "{}"
|
|
||||||
_debug "Record deleted"
|
_debug "Record deleted"
|
||||||
|
_opns_rest "POST" "/service/reconfigure" "{}"
|
||||||
|
_debug "Service reconfigured"
|
||||||
else
|
else
|
||||||
_err "Error deleting record $_host from domain $fulldomain"
|
_err "Error deleting record $_host from domain $fulldomain"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
_err "Error deleting record $_host from domain $fulldomain"
|
_err "Error requesting deletion of record $_host from domain $fulldomain"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
|
@ -150,14 +151,17 @@ _get_root() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_debug h "$h"
|
_debug h "$h"
|
||||||
id=$(echo "$_domain_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"primary\",\"domainname\":\"${h}\"" | cut -d ':' -f 2 | cut -d '"' -f 2)
|
lines=$(echo "$_domain_response" | sed 's/{/\n/g')
|
||||||
if [ -n "$id" ]; then
|
for line in $lines; do
|
||||||
_debug id "$id"
|
id=$(echo "$line" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"1\",\"type\":\"primary\",.*\"domainname\":\"${h}\"" | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||||
_host=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
|
if [ -n "$id" ]; then
|
||||||
_domain="${h}"
|
_debug id "$id"
|
||||||
_domainid="${id}"
|
_host=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
|
||||||
return 0
|
_domain="${h}"
|
||||||
fi
|
_domainid="${id}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
p=$i
|
p=$i
|
||||||
i=$(_math "$i" + 1)
|
i=$(_math "$i" + 1)
|
||||||
done
|
done
|
||||||
|
|
@ -206,13 +210,13 @@ _existingchallenge() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_uuid=""
|
_uuid=""
|
||||||
_uuid=$(echo "$_record_response" | _egrep_o "\"uuid\":\"[^\"]*\",\"enabled\":\"[01]\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"" | cut -d ':' -f 2 | cut -d '"' -f 2)
|
_uuid=$(echo "$_record_response" | _egrep_o "\"uuid\":\"[a-z0-9\-]*\",\"enabled\":\"[01]\",\"domain\":\"[a-z0-9\-]*\",\"%domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"" | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||||
|
|
||||||
if [ -n "$_uuid" ]; then
|
if [ -n "$_uuid" ]; then
|
||||||
_debug uuid "$_uuid"
|
_debug uuid "$_uuid"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
_debug "${2}.$1{1} record not found"
|
_debug "${2}.${1} record not found"
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ dns_ovh_rm() {
|
||||||
if ! _ovh_rest GET "domain/zone/$_domain/record/$rid"; then
|
if ! _ovh_rest GET "domain/zone/$_domain/record/$rid"; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
if _contains "$response" "\"target\":\"$txtvalue\""; then
|
if _contains "$response" "$txtvalue"; then
|
||||||
_debug "Found txt id:$rid"
|
_debug "Found txt id:$rid"
|
||||||
if ! _ovh_rest DELETE "domain/zone/$_domain/record/$rid"; then
|
if ! _ovh_rest DELETE "domain/zone/$_domain/record/$rid"; then
|
||||||
return 1
|
return 1
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ Options:
|
||||||
pleskxml_user Username
|
pleskxml_user Username
|
||||||
pleskxml_pass Password
|
pleskxml_pass Password
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/2577
|
Issues: github.com/acmesh-official/acme.sh/issues/2577
|
||||||
Author: Stilez, <https://github.com/romanlum>
|
Author: @Stilez, @romanlum
|
||||||
'
|
'
|
||||||
|
|
||||||
## Plesk XML API described at:
|
## Plesk XML API described at:
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,14 @@ dns_rage4_add() {
|
||||||
_debug _domain_id "$_domain_id"
|
_debug _domain_id "$_domain_id"
|
||||||
|
|
||||||
_rage4_rest "createrecord/?id=$_domain_id&name=$fulldomain&content=$unquotedtxtvalue&type=TXT&active=true&ttl=1"
|
_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
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,7 +71,12 @@ dns_rage4_rm() {
|
||||||
_debug "Getting txt records"
|
_debug "Getting txt records"
|
||||||
_rage4_rest "getrecords/?id=${_domain_id}"
|
_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}"
|
_rage4_rest "deleterecord/?id=${_record_id}"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
@ -105,8 +118,7 @@ _rage4_rest() {
|
||||||
token_trimmed=$(echo "$RAGE4_TOKEN" | tr -d '"')
|
token_trimmed=$(echo "$RAGE4_TOKEN" | tr -d '"')
|
||||||
auth=$(printf '%s:%s' "$username_trimmed" "$token_trimmed" | _base64)
|
auth=$(printf '%s:%s' "$username_trimmed" "$token_trimmed" | _base64)
|
||||||
|
|
||||||
export _H1="Content-Type: application/json"
|
export _H1="Authorization: Basic $auth"
|
||||||
export _H2="Authorization: Basic $auth"
|
|
||||||
|
|
||||||
response="$(_get "$RAGE4_Api$ep")"
|
response="$(_get "$RAGE4_Api$ep")"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
SCHLUNDTECH_USER Username
|
SCHLUNDTECH_USER Username
|
||||||
SCHLUNDTECH_PASSWORD Password
|
SCHLUNDTECH_PASSWORD Password
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/2246
|
Issues: github.com/acmesh-official/acme.sh/issues/2246
|
||||||
Author: <https://github.com/mod242>
|
Author: @mod242
|
||||||
'
|
'
|
||||||
|
|
||||||
SCHLUNDTECH_API="https://gateway.schlundtech.de"
|
SCHLUNDTECH_API="https://gateway.schlundtech.de"
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,21 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
|
dns_selectel_info='Selectel.com
|
||||||
# dns_selectel_info='Selectel.com
|
Domains: Selectel.ru
|
||||||
# Domains: Selectel.ru
|
Site: Selectel.com
|
||||||
# Site: Selectel.com
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel
|
||||||
# Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel
|
Options: For old API version v1 (deprecated)
|
||||||
# Options:
|
SL_Ver API version. Use "v1".
|
||||||
# Variables that must be defined before running
|
SL_Key API Key
|
||||||
# SL_Ver can take one of the values 'v1' or 'v2', default is 'v1'
|
OptionsAlt: For the current API version v2
|
||||||
# SL_Ver='v1', when using version API legacy (v1)
|
SL_Ver API version. Use "v2".
|
||||||
# SL_Ver='v2', when using version API actual (v2)
|
SL_Login_ID Account ID
|
||||||
# when using API version v1, i.e. SL_Ver is 'v1' or not defined:
|
SL_Project_Name Project name
|
||||||
# SL_Key - API Key, required
|
SL_Login_Name Service user name
|
||||||
# when using API version v2:
|
SL_Pswd Service user password
|
||||||
# SL_Ver - required as 'v2'
|
SL_Expire Token lifetime. In minutes (0-1440). Default "1400"
|
||||||
# SL_Login_ID - account ID, required
|
Issues: github.com/acmesh-official/acme.sh/issues/5126
|
||||||
# SL_Project_Name - name project, required
|
'
|
||||||
# SL_Login_Name - service user name, required
|
|
||||||
# SL_Pswd - service user password, required
|
|
||||||
# SL_Expire - token lifetime in minutes (0-1440), default 1400 minutes
|
|
||||||
#
|
|
||||||
# Issues: github.com/acmesh-official/acme.sh/issues/5126
|
|
||||||
#
|
|
||||||
|
|
||||||
SL_Api="https://api.selectel.ru/domains"
|
SL_Api="https://api.selectel.ru/domains"
|
||||||
auth_uri="https://cloud.api.selcloud.ru/identity/v3/auth/tokens"
|
auth_uri="https://cloud.api.selcloud.ru/identity/v3/auth/tokens"
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ dns_spaceship_info='Spaceship.com
|
||||||
Site: Spaceship.com
|
Site: Spaceship.com
|
||||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_spaceship
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_spaceship
|
||||||
Options:
|
Options:
|
||||||
SPACESHIP_API_KEY Spaceship API Key
|
SPACESHIP_API_KEY API Key
|
||||||
SPACESHIP_API_SECRET Spaceship API Secret
|
SPACESHIP_API_SECRET API Secret
|
||||||
SPACESHIP_ROOT_DOMAIN (Optional) Manually specify the root domain if auto-detection fails
|
SPACESHIP_ROOT_DOMAIN Root domain. Manually specify the root domain if auto-detection fails. Optional.
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/6304
|
Issues: github.com/acmesh-official/acme.sh/issues/6304
|
||||||
Author: Meow <https://github.com/Meo597>
|
Author: Meow <@Meo597>
|
||||||
'
|
'
|
||||||
|
|
||||||
# Spaceship API
|
# Spaceship API
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#tele3
|
||||||
Options:
|
Options:
|
||||||
TELE3_Key API Key
|
TELE3_Key API Key
|
||||||
TELE3_Secret API Secret
|
TELE3_Secret API Secret
|
||||||
Author: Roman Blizik <https://github.com/par-pa>
|
Author: Roman Blizik <@par-pa>
|
||||||
'
|
'
|
||||||
|
|
||||||
TELE3_API="https://www.tele3.cz/acme/"
|
TELE3_API="https://www.tele3.cz/acme/"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_timeweb
|
||||||
Options:
|
Options:
|
||||||
TW_Token API JWT token. Get it from the control panel at https://timeweb.cloud/my/api-keys
|
TW_Token API JWT token. Get it from the control panel at https://timeweb.cloud/my/api-keys
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/5140
|
Issues: github.com/acmesh-official/acme.sh/issues/5140
|
||||||
Author: Nikolay Pronchev <https://github.com/nikolaypronchev>
|
Author: Nikolay Pronchev <@nikolaypronchev>
|
||||||
'
|
'
|
||||||
|
|
||||||
TW_Api="https://api.timeweb.cloud/api/v1"
|
TW_Api="https://api.timeweb.cloud/api/v1"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
UDR_USER Username
|
UDR_USER Username
|
||||||
UDR_PASS Password
|
UDR_PASS Password
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/3923
|
Issues: github.com/acmesh-official/acme.sh/issues/3923
|
||||||
Author: Andreas Scherer <https://github.com/andischerer>
|
Author: Andreas Scherer <@andischerer>
|
||||||
'
|
'
|
||||||
|
|
||||||
UDR_API="https://api.domainreselling.de/api/call.cgi"
|
UDR_API="https://api.domainreselling.de/api/call.cgi"
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ dns_variomedia_rm() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_record_id="$(echo "$response" | sed -E 's/,"tags":\[[^]]*\]//g' | cut -d '[' -f2 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep "$_sub_domain" | grep -- "$txtvalue" | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')"
|
_record_id="$(echo "$response" | sed -E 's/,"tags":\[[^]]*\]//g' | cut -d '[' -f3 | cut -d']' -f1 | sed 's/},[ \t]*{/\},§\{/g' | tr § '\n' | grep -i "$_sub_domain" | grep -- "$txtvalue" | sed 's/^{//;s/}[,]?$//' | tr , '\n' | tr -d '\"' | grep ^id | cut -d : -f2 | tr -d ' ')"
|
||||||
_debug _record_id "$_record_id"
|
_debug _record_id "$_record_id"
|
||||||
if [ "$_record_id" ]; then
|
if [ "$_record_id" ]; then
|
||||||
_info "Successfully retrieved the record id for ACME challenge."
|
_info "Successfully retrieved the record id for ACME challenge."
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Site: vscale.io
|
||||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_vscale
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_vscale
|
||||||
Options:
|
Options:
|
||||||
VSCALE_API_KEY API Key
|
VSCALE_API_KEY API Key
|
||||||
Author: Alex Loban <https://github.com/LAV45>
|
Author: Alex Loban <@LAV45>
|
||||||
'
|
'
|
||||||
|
|
||||||
VSCALE_API_URL="https://api.vscale.io/v1"
|
VSCALE_API_URL="https://api.vscale.io/v1"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_vultr
|
||||||
Options:
|
Options:
|
||||||
VULTR_API_KEY API Key
|
VULTR_API_KEY API Key
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/2374
|
Issues: github.com/acmesh-official/acme.sh/issues/2374
|
||||||
Author:
|
|
||||||
'
|
'
|
||||||
|
|
||||||
VULTR_Api="https://api.vultr.com/v2"
|
VULTR_Api="https://api.vultr.com/v2"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
WS_ApiKey API Key. Called "Identifier" in the WS Admin
|
WS_ApiKey API Key. Called "Identifier" in the WS Admin
|
||||||
WS_ApiSecret API Secret. Called "Secret key" in the WS Admin
|
WS_ApiSecret API Secret. Called "Secret key" in the WS Admin
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/3486
|
Issues: github.com/acmesh-official/acme.sh/issues/3486
|
||||||
Author: trgo.sk <https://github.com/trgosk>, akulumbeg <https://github.com/akulumbeg>
|
Author: trgo.sk <@trgosk>, @akulumbeg
|
||||||
'
|
'
|
||||||
|
|
||||||
# Requirements: API Key and Secret from https://admin.websupport.sk/en/auth/apiKey
|
# Requirements: API Key and Secret from https://admin.websupport.sk/en/auth/apiKey
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Options:
|
||||||
WORLD4YOU_USERNAME Username
|
WORLD4YOU_USERNAME Username
|
||||||
WORLD4YOU_PASSWORD Password
|
WORLD4YOU_PASSWORD Password
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues/3269
|
Issues: github.com/acmesh-official/acme.sh/issues/3269
|
||||||
Author: Lorenz Stechauner <https://www.github.com/NerLOR>
|
Author: Lorenz Stechauner <@NerLOR>
|
||||||
'
|
'
|
||||||
|
|
||||||
WORLD4YOU_API="https://my.world4you.com/en"
|
WORLD4YOU_API="https://my.world4you.com/en"
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ telegram_send() {
|
||||||
fi
|
fi
|
||||||
_saveaccountconf_mutable TELEGRAM_BOT_URLBASE "$TELEGRAM_BOT_URLBASE"
|
_saveaccountconf_mutable TELEGRAM_BOT_URLBASE "$TELEGRAM_BOT_URLBASE"
|
||||||
|
|
||||||
_subject="$(printf "%s" "$_subject" | sed 's/\\/\\\\\\\\/g' | sed 's/\]/\\\\\]/g' | sed 's/\([_*[()~`>#+--=|{}.!]\)/\\\\\1/g')"
|
_subject="$(printf "%s" "$_subject" | sed -E 's/([][()~`>#+=|{}.!*_\\-])/\\\\\1/g')"
|
||||||
_content="$(printf "%s" "$_content" | sed 's/\\/\\\\\\\\/g' | sed 's/\]/\\\\\]/g' | sed 's/\([_*[()~`>#+--=|{}.!]\)/\\\\\1/g')"
|
_content="$(printf "%s" "$_content" | sed -E 's/([][()~`>#+=|{}.!*_\\-])/\\\\\1/g')"
|
||||||
_content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)"
|
_content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)"
|
||||||
_data="{\"text\": \"$_content\", "
|
_data="{\"text\": \"$_content\", "
|
||||||
_data="$_data\"chat_id\": \"$TELEGRAM_BOT_CHATID\", "
|
_data="$_data\"chat_id\": \"$TELEGRAM_BOT_CHATID\", "
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue