|13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl)
|16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux
|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux
|19|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux
|11|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
|22|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
|23|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
|14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl)
|17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux
|18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux
|10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux
|22|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
|23|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
|24|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
_err "No host, user and pass found.. If this is the first time deploying please set PANOS_HOST, PANOS_USER and PANOS_PASS in environment variables. Delete them after you have succesfully deployed certs."
# VALID FILE CHECK
if[ ! -f "$_ckey"]||[ ! -f "$_cfullchain"];then
_err "Unable to find a valid key and/or cert. If this is an ECDSA/ECC cert, use the --ecc flag when deploying."
return1
return1
else
_debug "Using saved env variables."
fi
fi
# PANOS_HOST
if["$PANOS_HOST"];then
_debug "Detected ENV variable PANOS_HOST. Saving to file."
_savedeployconf PANOS_HOST "$PANOS_HOST"1
else
else
_debug "Detected ENV variables to be saved to the deploy conf."
# Encrypt and save user
_debug "Attempting to load variable PANOS_HOST from file."
_getdeployconf PANOS_HOST
fi
# PANOS USER
if["$PANOS_USER"];then
_debug "Detected ENV variable PANOS_USER. Saving to file."
_savedeployconf PANOS_USER "$PANOS_USER"1
_savedeployconf PANOS_USER "$PANOS_USER"1
else
_debug "Attempting to load variable PANOS_USER from file."
_getdeployconf PANOS_USER
fi
# PANOS_PASS
if["$PANOS_PASS"];then
_debug "Detected ENV variable PANOS_PASS. Saving to file."
_savedeployconf PANOS_PASS "$PANOS_PASS"1
_savedeployconf PANOS_PASS "$PANOS_PASS"1
_savedeployconf PANOS_HOST "$PANOS_HOST"1
_panos_user="$PANOS_USER"
_panos_pass="$PANOS_PASS"
_panos_host="$PANOS_HOST"
else
_debug "Attempting to load variable PANOS_PASS from file."
_getdeployconf PANOS_PASS
fi
# PANOS_KEY
_getdeployconf PANOS_KEY
if["$PANOS_KEY"];then
_debug "Detected saved key."
_panos_key=$PANOS_KEY
else
_debug "No key detected"
unset _panos_key
fi
#Store variables
_panos_host=$PANOS_HOST
_panos_user=$PANOS_USER
_panos_pass=$PANOS_PASS
#Test API Key if found. If the key is invalid, the variable _panos_key will be unset.
if["$_panos_host"]&&["$_panos_key"];then
_debug "**** Testing API KEY ****"
deployer keytest
fi
fi
_debug "Let's use username and pass to generate token."
_err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST"
# Check for valid variables
if[ -z "$_panos_host"];then
_err "No host found. If this is your first time deploying, please set PANOS_HOST in ENV variables. You can delete it after you have successfully deployed the certs."
return1
elif[ -z "$_panos_user"];then
_err "No user found. If this is your first time deploying, please set PANOS_USER in ENV variables. You can delete it after you have successfully deployed the certs."
return1
elif[ -z "$_panos_pass"];then
_err "No password found. If this is your first time deploying, please set PANOS_PASS in ENV variables. You can delete it after you have successfully deployed the certs."
return1
return1
else
else
_debug "Getting PANOS KEY"
# Generate a new API key if no valid API key is found
if[ -z "$_panos_key"];then
_debug "**** Generating new PANOS API KEY ****"
deployer keygen
deployer keygen
_savedeployconf PANOS_KEY "$_panos_key"1
fi
# Confirm that a valid key was generated
if[ -z "$_panos_key"];then
if[ -z "$_panos_key"];then
_err "Missing apikey."
_err "Unable to generate an API key. The user and pass may be invalid or not authorized to generate a new key. Please check the PANOS_USER and PANOS_PASS credentials and try again"
# Get device ID if still empty first, otherwise log in right away
# If SYNO_Device_Name is set, we treat that account enabled two-factor authorization, consider SYNO_Device_ID is not set, so it won't be able to login without requiring the OTP code.
if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"add\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":0,\"overwrite\":false}}";then
_err "$response"
return1
fi
_debug2 _response "$response"
return0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_dnsexit_rm(){
fulldomain=$1
txtvalue=$2
_info "Using DNSExit.com"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_debug 'Load account auth'
if ! get_account_info;then
return1
fi
_debug 'First detect the root zone'
if ! _get_root "$fulldomain";then
_err "$response"
return1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"delete\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\"}}";then
_info "Record with mismatch txtvalue, try update it"
payload=$(echo"$response"| tr -d " "| sed 's/"updated_at":[0-9]\+,//g'| sed 's/"meta":{}}]}/"meta":{}},{"content":['\""$txtvalue"\"'],"enabled":true}]}/')
fi
# For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
if ! _gcore_rest DELETE "zones/$_zone_name/$fulldomain/TXT";then
_err "Delete record error. $response"
return1
fi
return0
fi
payload="$(echo"$response"| tr -d " "| sed 's/"updated_at":[0-9]\+,//g'| sed 's/{"id":[0-9]\+,"content":\["'"$txtvalue"'"\],"enabled":true,"meta":{}}//'| sed 's/\[,/\[/'| sed 's/,,/,/'| sed 's/,\]/\]/')"
if ! _gcore_rest PUT "zones/$_zone_name/$fulldomain/TXT""$payload";then
_err "Could not find a Google Domains-managed zone containing the requested domain."
return1
fi
_debug zone "$zone"
_debug txtvalue "$txtvalue"
_info "Adding TXT record for $fulldomain."
if _dns_googledomains_api "$zone"":rotateChallenges""{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToAdd\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}";then
_err "Could not find a Google Domains-managed domain based on request."
return1
fi
_debug zone "$zone"
_debug txtvalue "$txtvalue"
_info "Removing TXT record for $fulldomain."
if _dns_googledomains_api "$zone"":rotateChallenges""{\"accessToken\":\"$GOOGLEDOMAINS_ACCESS_TOKEN\",\"recordsToRemove\":[{\"fqdn\":\"$fulldomain\",\"digest\":\"$txtvalue\"}],\"keepExpiredRecords\":true}";then
_err "No TXT records found for root domain ${root_domain_name} (Plesk domain ID ${root_domain_id}). Exiting."
_err "No TXT records found for root domain $fulldomain (Plesk domain ID ${root_domain_id}). Exiting."
return1
return1
fi
fi
_debug "Got list of DNS TXT records for root domain '$root_domain_name':"
_debug "Got list of DNS TXT records for root Plesk domain ID ${root_domain_id} of root domain $fulldomain:"
_debug "$reclist"
_debug "$reclist"
# Extracting the id of the TXT record for the full domain (NOT case-sensitive) and corresponding value
recid="$(
recid="$(
_value "$reclist"|
_value "$reclist"|
grep "<host>${fulldomain}.</host>"|
grep -i "<host>${fulldomain}.</host>"|
grep "<value>${txtvalue}</value>"|
grep "<value>${txtvalue}</value>"|
sed 's/^.*<id>\([0-9]\{1,\}\)<\/id>.*$/\1/'
sed 's/^.*<id>\([0-9]\{1,\}\)<\/id>.*$/\1/'
)"
)"
_debug "Got id from line: $recid"
if ! _value "$recid"| grep '^[0-9]\{1,\}$' >/dev/null;then
if ! _value "$recid"| grep '^[0-9]\{1,\}$' >/dev/null;then
_err "DNS records for root domain '${root_domain_name}' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'"
_err "DNS records for root domain '${fulldomain}.' (Plesk ID ${root_domain_id}) + host '${sub_domain_name}' do not contain the TXT record '${txtvalue}'"
_err "Cannot delete TXT record. Exiting."
_err "Cannot delete TXT record. Exiting."
return1
return1
fi
fi
@ -251,9 +258,12 @@ _call_api() {
# Detect any <status> that isn't "ok". None of the used calls should fail if the API is working correctly.
# Detect any <status> that isn't "ok". None of the used calls should fail if the API is working correctly.
# Also detect if there simply aren't any status lines (null result?) and report that, as well.
# Also detect if there simply aren't any status lines (null result?) and report that, as well.
# Remove <data></data> structure from result string, since it might contain <status> values that are related to the status of the domain and not to the API request
if ! _rest POST "domain/dns/""act=dnsrec.remove&username=$WEST_Username&apikey=$WEST_Key&domain=$fulldomain&hostname=$fulldomain&record_id=$record_id";then
_err "dnsrec.remove error."
return1
fi
_contains "$response""success"
}
#add the txt record.
#usage: add fulldomain txtvalue
add_record(){
fulldomain=$1
txtvalue=$2
_info "Adding record"
if ! _rest POST "domain/dns/""act=dnsrec.add&username=$WEST_Username&apikey=$WEST_Key&domain=$fulldomain&hostname=$fulldomain&record_type=TXT&record_value=$txtvalue";then