mirror of
https://github.com/plantroon/acme.sh.git
synced 2024-12-23 05:31:42 +00:00
commit
ba4bd3ed55
34
README.md
34
README.md
@ -45,25 +45,25 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
|
|||||||
|
|
||||||
| NO | Status| Platform|
|
| NO | Status| Platform|
|
||||||
|----|-------|---------|
|
|----|-------|---------|
|
||||||
|1|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu
|
|1|[![](https://neilpang.github.io/acmetest/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu
|
||||||
|2|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/debian-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Debian
|
|2|[![](https://neilpang.github.io/acmetest/status/debian-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Debian
|
||||||
|3|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/centos-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|CentOS
|
|3|[![](https://neilpang.github.io/acmetest/status/centos-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|CentOS
|
||||||
|4|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/windows-cygwin.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included)
|
|4|[![](https://neilpang.github.io/acmetest/status/windows-cygwin.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included)
|
||||||
|5|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/freebsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|FreeBSD
|
|5|[![](https://neilpang.github.io/acmetest/status/freebsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|FreeBSD
|
||||||
|6|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/pfsense.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|pfsense
|
|6|[![](https://neilpang.github.io/acmetest/status/pfsense.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|pfsense
|
||||||
|7|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/opensuse-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|openSUSE
|
|7|[![](https://neilpang.github.io/acmetest/status/opensuse-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|openSUSE
|
||||||
|8|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/alpine-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Alpine Linux (with curl)
|
|8|[![](https://neilpang.github.io/acmetest/status/alpine-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Alpine Linux (with curl)
|
||||||
|9|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/base-archlinux.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Archlinux
|
|9|[![](https://neilpang.github.io/acmetest/status/base-archlinux.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Archlinux
|
||||||
|10|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/fedora-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|fedora
|
|10|[![](https://neilpang.github.io/acmetest/status/fedora-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|fedora
|
||||||
|11|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/kalilinux-kali-linux-docker.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Kali Linux
|
|11|[![](https://neilpang.github.io/acmetest/status/kalilinux-kali-linux-docker.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Kali Linux
|
||||||
|12|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/oraclelinux-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Oracle Linux
|
|12|[![](https://neilpang.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Oracle Linux
|
||||||
|13|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/proxmox.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh
|
|13|[![](https://neilpang.github.io/acmetest/status/proxmox.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Proxmox https://pve.proxmox.com/wiki/HTTPSCertificateConfiguration#Let.27s_Encrypt_using_acme.sh
|
||||||
|14|-----| Cloud Linux https://github.com/Neilpang/le/issues/111
|
|14|-----| Cloud Linux https://github.com/Neilpang/le/issues/111
|
||||||
|15|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/openbsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|OpenBSD
|
|15|[![](https://neilpang.github.io/acmetest/status/openbsd.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|OpenBSD
|
||||||
|16|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia
|
|16|[![](https://neilpang.github.io/acmetest/status/mageia.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Mageia
|
||||||
|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT)
|
|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT)
|
||||||
|18|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris
|
|18|[![](https://neilpang.github.io/acmetest/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris
|
||||||
|19|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux
|
|19|[![](https://neilpang.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux
|
||||||
|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX
|
|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX
|
||||||
|
|
||||||
For all build statuses, check our [weekly build project](https://github.com/Neilpang/acmetest):
|
For all build statuses, check our [weekly build project](https://github.com/Neilpang/acmetest):
|
||||||
|
107
acme.sh
107
acme.sh
@ -1006,10 +1006,20 @@ _createkey() {
|
|||||||
|
|
||||||
if _isEccKey "$length"; then
|
if _isEccKey "$length"; then
|
||||||
_debug "Using ec name: $eccname"
|
_debug "Using ec name: $eccname"
|
||||||
${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null >"$f"
|
if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then
|
||||||
|
echo "$_opkey" >"$f"
|
||||||
|
else
|
||||||
|
_err "error ecc key name: $eccname"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_debug "Using RSA: $length"
|
_debug "Using RSA: $length"
|
||||||
${ACME_OPENSSL_BIN:-openssl} genrsa "$length" 2>/dev/null >"$f"
|
if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa "$length" 2>/dev/null)"; then
|
||||||
|
echo "$_opkey" >"$f"
|
||||||
|
else
|
||||||
|
_err "error rsa key: $length"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$?" != "0" ]; then
|
if [ "$?" != "0" ]; then
|
||||||
@ -1074,11 +1084,12 @@ _createcsr() {
|
|||||||
printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment" >"$csrconf"
|
printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment" >"$csrconf"
|
||||||
|
|
||||||
if [ "$acmeValidationv1" ]; then
|
if [ "$acmeValidationv1" ]; then
|
||||||
|
domainlist="$(_idn "$domainlist")"
|
||||||
printf -- "\nsubjectAltName=DNS:$domainlist" >>"$csrconf"
|
printf -- "\nsubjectAltName=DNS:$domainlist" >>"$csrconf"
|
||||||
elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then
|
elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then
|
||||||
#single domain
|
#single domain
|
||||||
_info "Single domain" "$domain"
|
_info "Single domain" "$domain"
|
||||||
printf -- "\nsubjectAltName=DNS:$domain" >>"$csrconf"
|
printf -- "\nsubjectAltName=DNS:$(_idn $domain)" >>"$csrconf"
|
||||||
else
|
else
|
||||||
domainlist="$(_idn "$domainlist")"
|
domainlist="$(_idn "$domainlist")"
|
||||||
_debug2 domainlist "$domainlist"
|
_debug2 domainlist "$domainlist"
|
||||||
@ -1312,13 +1323,19 @@ _create_account_key() {
|
|||||||
_initpath
|
_initpath
|
||||||
|
|
||||||
mkdir -p "$CA_DIR"
|
mkdir -p "$CA_DIR"
|
||||||
if [ -f "$ACCOUNT_KEY_PATH" ]; then
|
if [ -s "$ACCOUNT_KEY_PATH" ]; then
|
||||||
_info "Account key exists, skip"
|
_info "Account key exists, skip"
|
||||||
return
|
return 0
|
||||||
else
|
else
|
||||||
#generate account key
|
#generate account key
|
||||||
_createkey "$length" "$ACCOUNT_KEY_PATH"
|
if _createkey "$length" "$ACCOUNT_KEY_PATH"; then
|
||||||
chmod 600 "$ACCOUNT_KEY_PATH"
|
chmod 600 "$ACCOUNT_KEY_PATH"
|
||||||
|
_info "Create account key ok."
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Create account key error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1341,11 +1358,14 @@ createDomainKey() {
|
|||||||
|
|
||||||
_initpath "$domain" "$_cdl"
|
_initpath "$domain" "$_cdl"
|
||||||
|
|
||||||
if [ ! -f "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then
|
if [ ! -f "$CERT_KEY_PATH" ] || [ ! -s "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then
|
||||||
if _createkey "$_cdl" "$CERT_KEY_PATH"; then
|
if _createkey "$_cdl" "$CERT_KEY_PATH"; then
|
||||||
_savedomainconf Le_Keylength "$_cdl"
|
_savedomainconf Le_Keylength "$_cdl"
|
||||||
_info "The domain key is here: $(__green $CERT_KEY_PATH)"
|
_info "The domain key is here: $(__green $CERT_KEY_PATH)"
|
||||||
return 0
|
return 0
|
||||||
|
else
|
||||||
|
_err "Can not domain key"
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ "$IS_RENEW" ]; then
|
if [ "$IS_RENEW" ]; then
|
||||||
@ -3218,11 +3238,6 @@ _on_issue_success() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateaccount() {
|
|
||||||
_initpath
|
|
||||||
_regAccount
|
|
||||||
}
|
|
||||||
|
|
||||||
registeraccount() {
|
registeraccount() {
|
||||||
_reg_length="$1"
|
_reg_length="$1"
|
||||||
_initpath
|
_initpath
|
||||||
@ -3320,6 +3335,61 @@ _regAccount() {
|
|||||||
_info "ACCOUNT_THUMBPRINT" "$ACCOUNT_THUMBPRINT"
|
_info "ACCOUNT_THUMBPRINT" "$ACCOUNT_THUMBPRINT"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#implement updateaccount
|
||||||
|
updateaccount() {
|
||||||
|
_initpath
|
||||||
|
|
||||||
|
if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then
|
||||||
|
_info "mv $_OLD_ACCOUNT_KEY to $ACCOUNT_KEY_PATH"
|
||||||
|
mv "$_OLD_ACCOUNT_KEY" "$ACCOUNT_KEY_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$ACCOUNT_JSON_PATH" ] && [ -f "$_OLD_ACCOUNT_JSON" ]; then
|
||||||
|
_info "mv $_OLD_ACCOUNT_JSON to $ACCOUNT_JSON_PATH"
|
||||||
|
mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$ACCOUNT_KEY_PATH" ]; then
|
||||||
|
_err "Account key is not found at: $ACCOUNT_KEY_PATH"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_accUri=$(_readcaconf "ACCOUNT_URL")
|
||||||
|
_debug _accUri "$_accUri"
|
||||||
|
|
||||||
|
if [ -z "$_accUri" ]; then
|
||||||
|
_err "The account url is empty, please run '--update-account' first to update the account info first,"
|
||||||
|
_err "Then try again."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _calcjwk "$ACCOUNT_KEY_PATH"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_initAPI
|
||||||
|
|
||||||
|
if [ "$ACME_VERSION" = "2" ]; then
|
||||||
|
if [ "$ACCOUNT_EMAIL" ]; then
|
||||||
|
updjson='{"contact": ["mailto: '$ACCOUNT_EMAIL'"]}'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# ACMEv1: Updates happen the same way a registration is done.
|
||||||
|
# https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-6.3
|
||||||
|
_regAccount
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# this part handles ACMEv2 account updates.
|
||||||
|
_send_signed_request "$_accUri" "$updjson"
|
||||||
|
|
||||||
|
if [ "$code" = '200' ]; then
|
||||||
|
_info "account update success for $_accUri."
|
||||||
|
else
|
||||||
|
_info "Error. The account was not updated."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
#Implement deactivate account
|
#Implement deactivate account
|
||||||
deactivateaccount() {
|
deactivateaccount() {
|
||||||
_initpath
|
_initpath
|
||||||
@ -3538,7 +3608,9 @@ _check_dns_entries() {
|
|||||||
for entry in $dns_entries; do
|
for entry in $dns_entries; do
|
||||||
d=$(_getfield "$entry" 1)
|
d=$(_getfield "$entry" 1)
|
||||||
txtdomain=$(_getfield "$entry" 2)
|
txtdomain=$(_getfield "$entry" 2)
|
||||||
|
txtdomain=$(_idn $txtdomain)
|
||||||
aliasDomain=$(_getfield "$entry" 3)
|
aliasDomain=$(_getfield "$entry" 3)
|
||||||
|
aliasDomain=$(_idn $aliasDomain)
|
||||||
txt=$(_getfield "$entry" 5)
|
txt=$(_getfield "$entry" 5)
|
||||||
d_api=$(_getfield "$entry" 6)
|
d_api=$(_getfield "$entry" 6)
|
||||||
_debug "d" "$d"
|
_debug "d" "$d"
|
||||||
@ -3735,7 +3807,7 @@ issue() {
|
|||||||
if [ -z "$vlist" ]; then
|
if [ -z "$vlist" ]; then
|
||||||
if [ "$ACME_VERSION" = "2" ]; then
|
if [ "$ACME_VERSION" = "2" ]; then
|
||||||
#make new order request
|
#make new order request
|
||||||
_identifiers="{\"type\":\"dns\",\"value\":\"$_main_domain\"}"
|
_identifiers="{\"type\":\"dns\",\"value\":\"$(_idn $_main_domain)\"}"
|
||||||
_w_index=1
|
_w_index=1
|
||||||
while true; do
|
while true; do
|
||||||
d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")"
|
d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")"
|
||||||
@ -3832,7 +3904,7 @@ $_authorizations_map"
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$ACME_VERSION" = "2" ]; then
|
if [ "$ACME_VERSION" = "2" ]; then
|
||||||
response="$(echo "$_authorizations_map" | grep "^$d," | sed "s/$d,//")"
|
response="$(echo "$_authorizations_map" | grep "^$(_idn $d)," | sed "s/$d,//")"
|
||||||
_debug2 "response" "$response"
|
_debug2 "response" "$response"
|
||||||
if [ -z "$response" ]; then
|
if [ -z "$response" ]; then
|
||||||
_err "get to authz error."
|
_err "get to authz error."
|
||||||
@ -5795,6 +5867,7 @@ Parameters:
|
|||||||
--ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate.
|
--ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate.
|
||||||
--ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl.
|
--ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl.
|
||||||
--nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically.
|
--nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically.
|
||||||
|
--noprofile Only valid for '--install' command, which means: do not install aliases to user profile.
|
||||||
--no-color Do not output color text.
|
--no-color Do not output color text.
|
||||||
--force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
|
--force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
|
||||||
--ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR'
|
--ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR'
|
||||||
@ -5928,6 +6001,7 @@ _process() {
|
|||||||
_ca_bundle=""
|
_ca_bundle=""
|
||||||
_ca_path=""
|
_ca_path=""
|
||||||
_nocron=""
|
_nocron=""
|
||||||
|
_noprofile=""
|
||||||
_ecc=""
|
_ecc=""
|
||||||
_csr=""
|
_csr=""
|
||||||
_pre_hook=""
|
_pre_hook=""
|
||||||
@ -6272,6 +6346,9 @@ _process() {
|
|||||||
--nocron)
|
--nocron)
|
||||||
_nocron="1"
|
_nocron="1"
|
||||||
;;
|
;;
|
||||||
|
--noprofile)
|
||||||
|
_noprofile="1"
|
||||||
|
;;
|
||||||
--no-color)
|
--no-color)
|
||||||
export ACME_NO_COLOR=1
|
export ACME_NO_COLOR=1
|
||||||
;;
|
;;
|
||||||
@ -6430,7 +6507,7 @@ _process() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
case "${_CMD}" in
|
case "${_CMD}" in
|
||||||
install) install "$_nocron" "$_confighome" ;;
|
install) install "$_nocron" "$_confighome" "$_noprofile" ;;
|
||||||
uninstall) uninstall "$_nocron" ;;
|
uninstall) uninstall "$_nocron" ;;
|
||||||
upgrade) upgrade ;;
|
upgrade) upgrade ;;
|
||||||
issue)
|
issue)
|
||||||
|
@ -182,8 +182,11 @@ _cf_rest() {
|
|||||||
data="$3"
|
data="$3"
|
||||||
_debug "$ep"
|
_debug "$ep"
|
||||||
|
|
||||||
export _H1="X-Auth-Email: $CF_Email"
|
email_trimmed=$(echo $CF_Email | tr -d '"')
|
||||||
export _H2="X-Auth-Key: $CF_Key"
|
key_trimmed=$(echo $CF_Key | tr -d '"')
|
||||||
|
|
||||||
|
export _H1="X-Auth-Email: $email_trimmed"
|
||||||
|
export _H2="X-Auth-Key: $key_trimmed"
|
||||||
export _H3="Content-Type: application/json"
|
export _H3="Content-Type: application/json"
|
||||||
|
|
||||||
if [ "$m" != "GET" ]; then
|
if [ "$m" != "GET" ]; then
|
||||||
|
130
dnsapi/dns_ddnss.sh
Normal file
130
dnsapi/dns_ddnss.sh
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#Created by RaidenII, to use DuckDNS's API to add/remove text records
|
||||||
|
#modified by helbgd @ 03/13/2018 to support ddnss.de
|
||||||
|
#modified by mod242 @ 04/24/2018 to support different ddnss domains
|
||||||
|
#Please note: the Wildcard Feature must be turned on for the Host record
|
||||||
|
#and the checkbox for TXT needs to be enabled
|
||||||
|
|
||||||
|
# Pass credentials before "acme.sh --issue --dns dns_ddnss ..."
|
||||||
|
# --
|
||||||
|
# export DDNSS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
|
||||||
|
DDNSS_DNS_API="https://ddnss.de/upd.php"
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#Usage: dns_ddnss_add _acme-challenge.domain.ddnss.de "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_ddnss_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
DDNSS_Token="${DDNSS_Token:-$(_readaccountconf_mutable DDNSS_Token)}"
|
||||||
|
if [ -z "$DDNSS_Token" ]; then
|
||||||
|
_err "You must export variable: DDNSS_Token"
|
||||||
|
_err "The token for your DDNSS account is necessary."
|
||||||
|
_err "You can look it up in your DDNSS account."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Now save the credentials.
|
||||||
|
_saveaccountconf_mutable DDNSS_Token "$DDNSS_Token"
|
||||||
|
|
||||||
|
# Unfortunately, DDNSS does not seems to support lookup domain through API
|
||||||
|
# So I assume your credentials (which are your domain and token) are correct
|
||||||
|
# If something goes wrong, we will get a KO response from DDNSS
|
||||||
|
|
||||||
|
if ! _ddnss_get_domain; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Now add the TXT record to DDNSS DNS
|
||||||
|
_info "Trying to add TXT record"
|
||||||
|
if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=1&txt=$txtvalue"; then
|
||||||
|
if [ "$response" = "Updated 1 hostname." ]; then
|
||||||
|
_info "TXT record has been successfully added to your DDNSS domain."
|
||||||
|
_info "Note that all subdomains under this domain uses the same TXT record."
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Errors happened during adding the TXT record, response=$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_err "Errors happened during adding the TXT record."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#Usage: fulldomain txtvalue
|
||||||
|
#Remove the txt record after validation.
|
||||||
|
dns_ddnss_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
DDNSS_Token="${DDNSS_Token:-$(_readaccountconf_mutable DDNSS_Token)}"
|
||||||
|
if [ -z "$DDNSS_Token" ]; then
|
||||||
|
_err "You must export variable: DDNSS_Token"
|
||||||
|
_err "The token for your DDNSS account is necessary."
|
||||||
|
_err "You can look it up in your DDNSS account."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _ddnss_get_domain; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Now remove the TXT record from DDNS DNS
|
||||||
|
_info "Trying to remove TXT record"
|
||||||
|
if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=1&txt=."; then
|
||||||
|
if [ "$response" = "Updated 1 hostname." ]; then
|
||||||
|
_info "TXT record has been successfully removed from your DDNSS domain."
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Errors happened during removing the TXT record, response=$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_err "Errors happened during removing the TXT record."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
|
#fulldomain=_acme-challenge.domain.ddnss.de
|
||||||
|
#returns
|
||||||
|
# _ddnss_domain=domain
|
||||||
|
_ddnss_get_domain() {
|
||||||
|
|
||||||
|
# We'll extract the domain/username from full domain
|
||||||
|
_ddnss_domain="$(echo "$fulldomain" | _lower_case | _egrep_o '[.][^.][^.]*[.](ddnss|dyn-ip24|dyndns|dyn|dyndns1|home-webserver|myhome-server|dynip)\..*' | cut -d . -f 2-)"
|
||||||
|
|
||||||
|
if [ -z "$_ddnss_domain" ]; then
|
||||||
|
_err "Error extracting the domain."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#Usage: method URI
|
||||||
|
_ddnss_rest() {
|
||||||
|
method=$1
|
||||||
|
param="$2"
|
||||||
|
_debug param "$param"
|
||||||
|
url="$DDNSS_DNS_API?$param"
|
||||||
|
_debug url "$url"
|
||||||
|
|
||||||
|
# DDNSS uses GET to update domain info
|
||||||
|
if [ "$method" = "GET" ]; then
|
||||||
|
response="$(_get "$url" | sed 's/<[^>]*>//g;/</N;//ba' | _tail_n 1)"
|
||||||
|
else
|
||||||
|
_err "Unsupported method"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug2 response "$response"
|
||||||
|
return 0
|
||||||
|
}
|
@ -53,6 +53,18 @@ _hostingde_parse() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hostingde_parse_no_strip_whitespace() {
|
||||||
|
find="${1}"
|
||||||
|
if [ "${2}" ]; then
|
||||||
|
notfind="${2}"
|
||||||
|
fi
|
||||||
|
if [ "${notfind}" ]; then
|
||||||
|
_egrep_o \""${find}\":.*" | grep -v "${notfind}" | cut -d ':' -f 2 | cut -d ',' -f 1
|
||||||
|
else
|
||||||
|
_egrep_o \""${find}\":.*" | cut -d ':' -f 2 | cut -d ',' -f 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
_hostingde_getZoneConfig() {
|
_hostingde_getZoneConfig() {
|
||||||
_info "Getting ZoneConfig"
|
_info "Getting ZoneConfig"
|
||||||
curZone="${fulldomain#*.}"
|
curZone="${fulldomain#*.}"
|
||||||
@ -85,6 +97,22 @@ _hostingde_getZoneConfig() {
|
|||||||
zoneConfigDnsServerGroupId=$(echo "${curResult}" | _hostingde_parse "dnsServerGroupId")
|
zoneConfigDnsServerGroupId=$(echo "${curResult}" | _hostingde_parse "dnsServerGroupId")
|
||||||
zoneConfigEmailAddress=$(echo "${curResult}" | _hostingde_parse "emailAddress")
|
zoneConfigEmailAddress=$(echo "${curResult}" | _hostingde_parse "emailAddress")
|
||||||
zoneConfigDnsSecMode=$(echo "${curResult}" | _hostingde_parse "dnsSecMode")
|
zoneConfigDnsSecMode=$(echo "${curResult}" | _hostingde_parse "dnsSecMode")
|
||||||
|
zoneConfigTemplateValues=$(echo "${curResult}" | _hostingde_parse_no_strip_whitespace "templateValues")
|
||||||
|
|
||||||
|
if [ "$zoneConfigTemplateValues" != "null" ]; then
|
||||||
|
_debug "Zone is tied to a template."
|
||||||
|
zoneConfigTemplateValuesTemplateId=$(echo "${curResult}" | _hostingde_parse "templateId")
|
||||||
|
zoneConfigTemplateValuesTemplateName=$(echo "${curResult}" | _hostingde_parse_no_strip_whitespace "templateName")
|
||||||
|
zoneConfigTemplateValuesTemplateReplacementsIPv4=$(echo "${curResult}" | _hostingde_parse "ipv4Replacement")
|
||||||
|
zoneConfigTemplateValuesTemplateReplacementsIPv6=$(echo "${curResult}" | _hostingde_parse "ipv6Replacement")
|
||||||
|
zoneConfigTemplateValuesTemplateReplacementsMailIPv4=$(echo "${curResult}" | _hostingde_parse "mailIpv4Replacement")
|
||||||
|
zoneConfigTemplateValuesTemplateReplacementsMailIPv6=$(echo "${curResult}" | _hostingde_parse "mailIpv6Replacement")
|
||||||
|
zoneConfigTemplateValuesTemplateTieToTemplate=$(echo "${curResult}" | _hostingde_parse "tieToTemplate")
|
||||||
|
|
||||||
|
zoneConfigTemplateValues="{\"templateId\":${zoneConfigTemplateValuesTemplateId},\"templateName\":${zoneConfigTemplateValuesTemplateName},\"templateReplacements\":{\"ipv4Replacement\":${zoneConfigTemplateValuesTemplateReplacementsIPv4},\"ipv6Replacement\":${zoneConfigTemplateValuesTemplateReplacementsIPv6},\"mailIpv4Replacement\":${zoneConfigTemplateValuesTemplateReplacementsMailIPv4},\"mailIpv6Replacement\":${zoneConfigTemplateValuesTemplateReplacementsMailIPv6}},\"tieToTemplate\":${zoneConfigTemplateValuesTemplateTieToTemplate}}"
|
||||||
|
_debug "Template values: '{$zoneConfigTemplateValues}'"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "${zoneConfigType}" != "\"NATIVE\"" ]; then
|
if [ "${zoneConfigType}" != "\"NATIVE\"" ]; then
|
||||||
_err "Zone is not native"
|
_err "Zone is not native"
|
||||||
returnCode=1
|
returnCode=1
|
||||||
@ -122,7 +150,7 @@ _hostingde_addRecord() {
|
|||||||
_hostingde_getZoneStatus
|
_hostingde_getZoneStatus
|
||||||
_debug "Result of zoneStatus: '${zoneStatus}'"
|
_debug "Result of zoneStatus: '${zoneStatus}'"
|
||||||
done
|
done
|
||||||
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}"
|
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}},\"templateValues\":${zoneConfigTemplateValues}},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}"
|
||||||
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")"
|
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")"
|
||||||
_debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'"
|
_debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'"
|
||||||
_debug "Result of zoneUpdate: '$curResult'"
|
_debug "Result of zoneUpdate: '$curResult'"
|
||||||
@ -146,7 +174,7 @@ _hostingde_removeRecord() {
|
|||||||
_hostingde_getZoneStatus
|
_hostingde_getZoneStatus
|
||||||
_debug "Result of zoneStatus: '$zoneStatus'"
|
_debug "Result of zoneStatus: '$zoneStatus'"
|
||||||
done
|
done
|
||||||
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}"
|
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":${zoneConfigId},\"name\":${zoneConfigName},\"type\":${zoneConfigType},\"dnsServerGroupId\":${zoneConfigDnsServerGroupId},\"dnsSecMode\":${zoneConfigDnsSecMode},\"emailAddress\":${zoneConfigEmailAddress},\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}},\"templateValues\":${zoneConfigTemplateValues}},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}"
|
||||||
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")"
|
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")"
|
||||||
_debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'"
|
_debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'"
|
||||||
_debug "Result of zoneUpdate: '$curResult'"
|
_debug "Result of zoneUpdate: '$curResult'"
|
||||||
|
@ -4,8 +4,10 @@
|
|||||||
#LOOPIA_User="username"
|
#LOOPIA_User="username"
|
||||||
#
|
#
|
||||||
#LOOPIA_Password="password"
|
#LOOPIA_Password="password"
|
||||||
|
#
|
||||||
|
#LOOPIA_Api="https://api.loopia.<TLD>/RPCSERV"
|
||||||
|
|
||||||
LOOPIA_Api="https://api.loopia.se/RPCSERV"
|
LOOPIA_Api_Default="https://api.loopia.se/RPCSERV"
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
@ -14,19 +16,11 @@ dns_loopia_add() {
|
|||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}"
|
if ! _loopia_load_config; then
|
||||||
LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}"
|
|
||||||
if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then
|
|
||||||
LOOPIA_User=""
|
|
||||||
LOOPIA_Password=""
|
|
||||||
_err "You don't specify loopia user and password yet."
|
|
||||||
_err "Please create you key and try again."
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#save the api key and email to the account conf file.
|
_loopia_save_config
|
||||||
_saveaccountconf_mutable LOOPIA_User "$LOOPIA_User"
|
|
||||||
_saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password"
|
|
||||||
|
|
||||||
_debug "First detect the root zone"
|
_debug "First detect the root zone"
|
||||||
if ! _get_root "$fulldomain"; then
|
if ! _get_root "$fulldomain"; then
|
||||||
@ -47,19 +41,11 @@ dns_loopia_rm() {
|
|||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}"
|
if ! _loopia_load_config; then
|
||||||
LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}"
|
|
||||||
if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then
|
|
||||||
LOOPIA_User=""
|
|
||||||
LOOPIA_Password=""
|
|
||||||
_err "You don't specify LOOPIA user and password yet."
|
|
||||||
_err "Please create you key and try again."
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#save the api key and email to the account conf file.
|
_loopia_save_config
|
||||||
_saveaccountconf_mutable LOOPIA_User "$LOOPIA_User"
|
|
||||||
_saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password"
|
|
||||||
|
|
||||||
_debug "First detect the root zone"
|
_debug "First detect the root zone"
|
||||||
if ! _get_root "$fulldomain"; then
|
if ! _get_root "$fulldomain"; then
|
||||||
@ -84,7 +70,7 @@ dns_loopia_rm() {
|
|||||||
<value><string>%s</string></value>
|
<value><string>%s</string></value>
|
||||||
</param>
|
</param>
|
||||||
</params>
|
</params>
|
||||||
</methodCall>' $LOOPIA_User $LOOPIA_Password "$_domain" "$_sub_domain")
|
</methodCall>' "$LOOPIA_User" "$LOOPIA_Password" "$_domain" "$_sub_domain")
|
||||||
|
|
||||||
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
|
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
|
||||||
|
|
||||||
@ -96,6 +82,36 @@ dns_loopia_rm() {
|
|||||||
|
|
||||||
#################### Private functions below ##################################
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
|
_loopia_load_config() {
|
||||||
|
LOOPIA_Api="${LOOPIA_Api:-$(_readaccountconf_mutable LOOPIA_Api)}"
|
||||||
|
LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}"
|
||||||
|
LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}"
|
||||||
|
|
||||||
|
if [ -z "$LOOPIA_Api" ]; then
|
||||||
|
LOOPIA_Api="$LOOPIA_Api_Default"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then
|
||||||
|
LOOPIA_User=""
|
||||||
|
LOOPIA_Password=""
|
||||||
|
|
||||||
|
_err "A valid Loopia API user and password not provided."
|
||||||
|
_err "Please provide a valid API user and try again."
|
||||||
|
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_loopia_save_config() {
|
||||||
|
if [ "$LOOPIA_Api" != "$LOOPIA_Api_Default" ]; then
|
||||||
|
_saveaccountconf_mutable LOOPIA_Api "$LOOPIA_Api"
|
||||||
|
fi
|
||||||
|
_saveaccountconf_mutable LOOPIA_User "$LOOPIA_User"
|
||||||
|
_saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password"
|
||||||
|
}
|
||||||
|
|
||||||
_loopia_get_records() {
|
_loopia_get_records() {
|
||||||
domain=$1
|
domain=$1
|
||||||
sub_domain=$2
|
sub_domain=$2
|
||||||
|
Loading…
Reference in New Issue
Block a user