Merge branch 'dev' of github.com:ThiloGa/acme.sh into dev
This commit is contained in:
commit
999c953f17
40
.github/auto-comment.yml
vendored
Normal file
40
.github/auto-comment.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Comment to a new issue.
|
||||||
|
issuesOpened: >
|
||||||
|
If this is a bug report, please upgrade to the latest code and try again:
|
||||||
|
|
||||||
|
如果有 bug, 请先更新到最新版试试:
|
||||||
|
|
||||||
|
```
|
||||||
|
acme.sh --upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
please also provide the log with `--debug 2`.
|
||||||
|
|
||||||
|
同时请提供调试输出 `--debug 2`
|
||||||
|
|
||||||
|
see: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh
|
||||||
|
|
||||||
|
Without `--debug 2` log, your issue will NEVER get replied.
|
||||||
|
|
||||||
|
没有调试输出, 你的 issue 不会得到任何解答.
|
||||||
|
|
||||||
|
|
||||||
|
pullRequestOpened: >
|
||||||
|
First, NEVER send a PR to `master` branch, it will NEVER be accepted. Please send to the `dev` branch instead.
|
||||||
|
|
||||||
|
If this is a PR to support new DNS API or new notification API, please read this guide first:
|
||||||
|
https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide
|
||||||
|
|
||||||
|
Please check the guide items one by one.
|
||||||
|
|
||||||
|
Then add your usage here:
|
||||||
|
https://github.com/acmesh-official/acme.sh/wiki/dnsapi
|
||||||
|
|
||||||
|
Or some other wiki pages:
|
||||||
|
|
||||||
|
https://github.com/acmesh-official/acme.sh/wiki/deployhooks
|
||||||
|
|
||||||
|
https://github.com/acmesh-official/acme.sh/wiki/notify
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
65
acme.sh
65
acme.sh
@ -48,8 +48,6 @@ LOCAL_ANY_ADDRESS="0.0.0.0"
|
|||||||
|
|
||||||
DEFAULT_RENEW=60
|
DEFAULT_RENEW=60
|
||||||
|
|
||||||
DEFAULT_DNS_SLEEP=120
|
|
||||||
|
|
||||||
NO_VALUE="no"
|
NO_VALUE="no"
|
||||||
|
|
||||||
W_DNS="dns"
|
W_DNS="dns"
|
||||||
@ -140,6 +138,8 @@ _NOTIFY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/notify"
|
|||||||
|
|
||||||
_SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo"
|
_SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo"
|
||||||
|
|
||||||
|
_REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert"
|
||||||
|
|
||||||
_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"
|
||||||
@ -848,6 +848,14 @@ _json_encode() {
|
|||||||
echo "$_j_str" | _hex_dump | _lower_case | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n"
|
echo "$_j_str" | _hex_dump | _lower_case | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#from: http:\/\/ to http://
|
||||||
|
_json_decode() {
|
||||||
|
_j_str="$(sed 's#\\/#/#g')"
|
||||||
|
_debug3 "_json_decode"
|
||||||
|
_debug3 "_j_str" "$_j_str"
|
||||||
|
echo "$_j_str"
|
||||||
|
}
|
||||||
|
|
||||||
#options file
|
#options file
|
||||||
_sed_i() {
|
_sed_i() {
|
||||||
options="$1"
|
options="$1"
|
||||||
@ -3418,13 +3426,13 @@ _regAccount() {
|
|||||||
if [ "$ACME_VERSION" = "2" ]; then
|
if [ "$ACME_VERSION" = "2" ]; then
|
||||||
regjson='{"termsOfServiceAgreed": true}'
|
regjson='{"termsOfServiceAgreed": true}'
|
||||||
if [ "$ACCOUNT_EMAIL" ]; then
|
if [ "$ACCOUNT_EMAIL" ]; then
|
||||||
regjson='{"contact": ["mailto: '$ACCOUNT_EMAIL'"], "termsOfServiceAgreed": true}'
|
regjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"], "termsOfServiceAgreed": true}'
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
_reg_res="$ACME_NEW_ACCOUNT_RES"
|
_reg_res="$ACME_NEW_ACCOUNT_RES"
|
||||||
regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}'
|
regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}'
|
||||||
if [ "$ACCOUNT_EMAIL" ]; then
|
if [ "$ACCOUNT_EMAIL" ]; then
|
||||||
regjson='{"resource": "'$_reg_res'", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}'
|
regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$ACCOUNT_EMAIL'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}'
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -3504,7 +3512,9 @@ updateaccount() {
|
|||||||
|
|
||||||
if [ "$ACME_VERSION" = "2" ]; then
|
if [ "$ACME_VERSION" = "2" ]; then
|
||||||
if [ "$ACCOUNT_EMAIL" ]; then
|
if [ "$ACCOUNT_EMAIL" ]; then
|
||||||
updjson='{"contact": ["mailto: '$ACCOUNT_EMAIL'"]}'
|
updjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"]}'
|
||||||
|
else
|
||||||
|
updjson='{"contact": []}'
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# ACMEv1: Updates happen the same way a registration is done.
|
# ACMEv1: Updates happen the same way a registration is done.
|
||||||
@ -3517,6 +3527,7 @@ updateaccount() {
|
|||||||
_send_signed_request "$_accUri" "$updjson"
|
_send_signed_request "$_accUri" "$updjson"
|
||||||
|
|
||||||
if [ "$code" = '200' ]; then
|
if [ "$code" = '200' ]; then
|
||||||
|
echo "$response" >"$ACCOUNT_JSON_PATH"
|
||||||
_info "account update success for $_accUri."
|
_info "account update success for $_accUri."
|
||||||
else
|
else
|
||||||
_info "Error. The account was not updated."
|
_info "Error. The account was not updated."
|
||||||
@ -4019,7 +4030,7 @@ issue() {
|
|||||||
#for dns manual mode
|
#for dns manual mode
|
||||||
_savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize"
|
_savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize"
|
||||||
|
|
||||||
_authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')"
|
_authorizations_seg="$(echo "$response" | _json_decode | _egrep_o '"authorizations" *: *\[[^\[]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')"
|
||||||
_debug2 _authorizations_seg "$_authorizations_seg"
|
_debug2 _authorizations_seg "$_authorizations_seg"
|
||||||
if [ -z "$_authorizations_seg" ]; then
|
if [ -z "$_authorizations_seg" ]; then
|
||||||
_err "_authorizations_seg not found."
|
_err "_authorizations_seg not found."
|
||||||
@ -4540,7 +4551,7 @@ $_authorizations_map"
|
|||||||
_savedomainconf "Le_LinkOrder" "$Le_LinkOrder"
|
_savedomainconf "Le_LinkOrder" "$Le_LinkOrder"
|
||||||
|
|
||||||
_link_cert_retry=0
|
_link_cert_retry=0
|
||||||
_MAX_CERT_RETRY=5
|
_MAX_CERT_RETRY=30
|
||||||
while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do
|
while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do
|
||||||
if _contains "$response" "\"status\":\"valid\""; then
|
if _contains "$response" "\"status\":\"valid\""; then
|
||||||
_debug "Order status is valid."
|
_debug "Order status is valid."
|
||||||
@ -5446,6 +5457,7 @@ uninstallcronjob() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#domain isECC revokeReason
|
||||||
revoke() {
|
revoke() {
|
||||||
Le_Domain="$1"
|
Le_Domain="$1"
|
||||||
if [ -z "$Le_Domain" ]; then
|
if [ -z "$Le_Domain" ]; then
|
||||||
@ -5454,7 +5466,10 @@ revoke() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
_isEcc="$2"
|
_isEcc="$2"
|
||||||
|
_reason="$3"
|
||||||
|
if [ -z "$_reason" ]; then
|
||||||
|
_reason="0"
|
||||||
|
fi
|
||||||
_initpath "$Le_Domain" "$_isEcc"
|
_initpath "$Le_Domain" "$_isEcc"
|
||||||
if [ ! -f "$DOMAIN_CONF" ]; then
|
if [ ! -f "$DOMAIN_CONF" ]; then
|
||||||
_err "$Le_Domain is not a issued domain, skip."
|
_err "$Le_Domain is not a issued domain, skip."
|
||||||
@ -5476,7 +5491,7 @@ revoke() {
|
|||||||
_initAPI
|
_initAPI
|
||||||
|
|
||||||
if [ "$ACME_VERSION" = "2" ]; then
|
if [ "$ACME_VERSION" = "2" ]; then
|
||||||
data="{\"certificate\": \"$cert\"}"
|
data="{\"certificate\": \"$cert\",\"reason\":$_reason}"
|
||||||
else
|
else
|
||||||
data="{\"resource\": \"revoke-cert\", \"certificate\": \"$cert\"}"
|
data="{\"resource\": \"revoke-cert\", \"certificate\": \"$cert\"}"
|
||||||
fi
|
fi
|
||||||
@ -6222,7 +6237,7 @@ Parameters:
|
|||||||
--stateless Use stateless mode, see: $_STATELESS_WIKI
|
--stateless Use stateless mode, see: $_STATELESS_WIKI
|
||||||
--apache Use apache mode.
|
--apache Use apache mode.
|
||||||
--dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api.
|
--dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api.
|
||||||
--dnssleep [$DEFAULT_DNS_SLEEP] The time in seconds to wait for all the txt records to take effect in dns api mode. Default $DEFAULT_DNS_SLEEP seconds.
|
--dnssleep 300 The time in seconds to wait for all the txt records to take effect in dns api mode. It's not necessary to use this by default, $PROJECT_NAME polls dns status automatically.
|
||||||
|
|
||||||
--keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521.
|
--keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521.
|
||||||
--accountkeylength, -ak [2048] Specifies the account key length: 2048, 3072, 4096
|
--accountkeylength, -ak [2048] Specifies the account key length: 2048, 3072, 4096
|
||||||
@ -6285,6 +6300,7 @@ Parameters:
|
|||||||
0: Bulk mode. Send all the domain's notifications in one message(mail).
|
0: Bulk mode. Send all the domain's notifications in one message(mail).
|
||||||
1: Cert mode. Send a message for every single cert.
|
1: Cert mode. Send a message for every single cert.
|
||||||
--notify-hook [hookname] Set the notify hook
|
--notify-hook [hookname] Set the notify hook
|
||||||
|
--revoke-reason [0-10] The reason for '--revoke' command. See: $_REVOKE_WIKI
|
||||||
|
|
||||||
"
|
"
|
||||||
}
|
}
|
||||||
@ -6317,7 +6333,7 @@ _installOnline() {
|
|||||||
if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then
|
if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then
|
||||||
_info "Install success!"
|
_info "Install success!"
|
||||||
_initpath
|
_initpath
|
||||||
_saveaccountconf "UPGRADE_HASH" "$(_getMasterHash)"
|
_saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
@ -6327,19 +6343,27 @@ _installOnline() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
_getMasterHash() {
|
_getRepoHash() {
|
||||||
|
_hash_path=$1
|
||||||
|
shift
|
||||||
|
_hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/$_hash_path"
|
||||||
|
_get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4
|
||||||
|
}
|
||||||
|
|
||||||
|
_getUpgradeHash() {
|
||||||
_b="$BRANCH"
|
_b="$BRANCH"
|
||||||
if [ -z "$_b" ]; then
|
if [ -z "$_b" ]; then
|
||||||
_b="master"
|
_b="master"
|
||||||
fi
|
fi
|
||||||
_hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/heads/$_b"
|
_hash=$(_getRepoHash "heads/$_b")
|
||||||
_get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4
|
if [ -z "$_hash" ]; then _hash=$(_getRepoHash "tags/$_b"); fi
|
||||||
|
echo $_hash
|
||||||
}
|
}
|
||||||
|
|
||||||
upgrade() {
|
upgrade() {
|
||||||
if (
|
if (
|
||||||
_initpath
|
_initpath
|
||||||
[ -z "$FORCE" ] && [ "$(_getMasterHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0
|
[ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0
|
||||||
export LE_WORKING_DIR
|
export LE_WORKING_DIR
|
||||||
cd "$LE_WORKING_DIR"
|
cd "$LE_WORKING_DIR"
|
||||||
_installOnline "nocron" "noprofile"
|
_installOnline "nocron" "noprofile"
|
||||||
@ -6452,6 +6476,7 @@ _process() {
|
|||||||
_notify_hook=""
|
_notify_hook=""
|
||||||
_notify_level=""
|
_notify_level=""
|
||||||
_notify_mode=""
|
_notify_mode=""
|
||||||
|
_revoke_reason=""
|
||||||
while [ ${#} -gt 0 ]; do
|
while [ ${#} -gt 0 ]; do
|
||||||
case "${1}" in
|
case "${1}" in
|
||||||
|
|
||||||
@ -6924,6 +6949,14 @@ _process() {
|
|||||||
_notify_mode="$_nmode"
|
_notify_mode="$_nmode"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--revoke-reason)
|
||||||
|
_revoke_reason="$2"
|
||||||
|
if _startswith "$_revoke_reason" "-"; then
|
||||||
|
_err "'$_revoke_reason' is not a integer for '$1'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
_err "Unknown parameter : $1"
|
_err "Unknown parameter : $1"
|
||||||
return 1
|
return 1
|
||||||
@ -7011,7 +7044,7 @@ _process() {
|
|||||||
renewAll "$_stopRenewOnError"
|
renewAll "$_stopRenewOnError"
|
||||||
;;
|
;;
|
||||||
revoke)
|
revoke)
|
||||||
revoke "$_domain" "$_ecc"
|
revoke "$_domain" "$_ecc" "$_revoke_reason"
|
||||||
;;
|
;;
|
||||||
remove)
|
remove)
|
||||||
remove "$_domain" "$_ecc"
|
remove "$_domain" "$_ecc"
|
||||||
|
|||||||
@ -47,24 +47,24 @@ deployer() {
|
|||||||
#Set Header
|
#Set Header
|
||||||
export _H1="Content-Type: multipart/form-data; boundary=$delim"
|
export _H1="Content-Type: multipart/form-data; boundary=$delim"
|
||||||
if [ "$type" = 'cert' ]; then
|
if [ "$type" = 'cert' ]; then
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport"
|
panos_url="${panos_url}?type=import"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\ncertificate"
|
content="--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\ncertificate"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_cdomain"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n\r\n$_panos_key"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\n\r\npem"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")"
|
||||||
fi
|
fi
|
||||||
if [ "$type" = 'key' ]; then
|
if [ "$type" = 'key' ]; then
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"type\"\r\n\r\n\r\nimport"
|
panos_url="${panos_url}?type=import"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\n\r\nprivate-key"
|
content="--$delim${nl}Content-Disposition: form-data; name=\"category\"\r\n\r\nprivate-key"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n\r\n$_cdomain"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"certificate-name\"\r\n\r\n$_cdomain"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n\r\n$_panos_key"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\n\r\npem"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n\r\n123456"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456"
|
||||||
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
|
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
|
||||||
fi
|
fi
|
||||||
#Close multipart
|
#Close multipart
|
||||||
content="$content${nl}--$delim--${nl}"
|
content="$content${nl}--$delim--${nl}${nl}"
|
||||||
#Convert CRLF
|
#Convert CRLF
|
||||||
content=$(printf %b "$content")
|
content=$(printf %b "$content")
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
# export QINIU_AK="QINIUACCESSKEY"
|
# export QINIU_AK="QINIUACCESSKEY"
|
||||||
# export QINIU_SK="QINIUSECRETKEY"
|
# export QINIU_SK="QINIUSECRETKEY"
|
||||||
# export QINIU_CDN_DOMAIN="cdn.example.com"
|
# export QINIU_CDN_DOMAIN="cdn.example.com"
|
||||||
|
# If you have more than one domain, just
|
||||||
|
# export QINIU_CDN_DOMAIN="cdn1.example.com cdn2.example.com"
|
||||||
|
|
||||||
QINIU_API_BASE="https://api.qiniu.com"
|
QINIU_API_BASE="https://api.qiniu.com"
|
||||||
|
|
||||||
@ -67,21 +69,23 @@ qiniu_deploy() {
|
|||||||
_debug certId "$_certId"
|
_debug certId "$_certId"
|
||||||
|
|
||||||
## update domain ssl config
|
## update domain ssl config
|
||||||
update_path="/domain/$QINIU_CDN_DOMAIN/httpsconf"
|
|
||||||
update_body="{\"certid\":$_certId,\"forceHttps\":false}"
|
update_body="{\"certid\":$_certId,\"forceHttps\":false}"
|
||||||
update_access_token="$(_make_access_token "$update_path")"
|
for domain in $QINIU_CDN_DOMAIN; do
|
||||||
_debug update_access_token "$update_access_token"
|
update_path="/domain/$domain/httpsconf"
|
||||||
export _H1="Authorization: QBox $update_access_token"
|
update_access_token="$(_make_access_token "$update_path")"
|
||||||
update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64 "multiline")
|
_debug update_access_token "$update_access_token"
|
||||||
|
export _H1="Authorization: QBox $update_access_token"
|
||||||
|
update_response=$(_post "$update_body" "$QINIU_API_BASE$update_path" 0 "PUT" "application/json" | _dbase64 "multiline")
|
||||||
|
|
||||||
if _contains "$update_response" "error"; then
|
if _contains "$update_response" "error"; then
|
||||||
_err "Error in updating domain httpsconf:"
|
_err "Error in updating domain $domain httpsconf:"
|
||||||
_err "$update_response"
|
_err "$update_response"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_debug update_response "$update_response"
|
_debug update_response "$update_response"
|
||||||
_info "Certificate successfully deployed"
|
_info "Domain $domain certificate has been deployed successfully"
|
||||||
|
done
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
128
deploy/ssh.sh
128
deploy/ssh.sh
@ -12,7 +12,7 @@
|
|||||||
# Only a username is required. All others are optional.
|
# Only a username is required. All others are optional.
|
||||||
#
|
#
|
||||||
# The following examples are for QNAP NAS running QTS 4.2
|
# The following examples are for QNAP NAS running QTS 4.2
|
||||||
# export DEPLOY_SSH_CMD="" # defaults to ssh
|
# export DEPLOY_SSH_CMD="" # defaults to "ssh -T"
|
||||||
# export DEPLOY_SSH_USER="admin" # required
|
# export DEPLOY_SSH_USER="admin" # required
|
||||||
# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name
|
# export DEPLOY_SSH_SERVER="qnap" # defaults to domain name
|
||||||
# export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem"
|
# export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem"
|
||||||
@ -20,7 +20,9 @@
|
|||||||
# export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem"
|
# export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem"
|
||||||
# export DEPLOY_SSH_FULLCHAIN=""
|
# export DEPLOY_SSH_FULLCHAIN=""
|
||||||
# export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart"
|
# export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart"
|
||||||
# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes
|
# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value
|
||||||
|
# export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy
|
||||||
|
# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value
|
||||||
#
|
#
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
@ -31,10 +33,10 @@ ssh_deploy() {
|
|||||||
_ccert="$3"
|
_ccert="$3"
|
||||||
_cca="$4"
|
_cca="$4"
|
||||||
_cfullchain="$5"
|
_cfullchain="$5"
|
||||||
|
_err_code=0
|
||||||
_cmdstr=""
|
_cmdstr=""
|
||||||
_homedir='~'
|
_backupprefix=""
|
||||||
_backupprefix="$_homedir/.acme_ssh_deploy/$_cdomain-backup"
|
_backupdir=""
|
||||||
_backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')"
|
|
||||||
|
|
||||||
if [ -f "$DOMAIN_CONF" ]; then
|
if [ -f "$DOMAIN_CONF" ]; then
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
@ -71,18 +73,62 @@ ssh_deploy() {
|
|||||||
Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD"
|
Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD"
|
||||||
_savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd"
|
_savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd"
|
||||||
elif [ -z "$Le_Deploy_ssh_cmd" ]; then
|
elif [ -z "$Le_Deploy_ssh_cmd" ]; then
|
||||||
Le_Deploy_ssh_cmd="ssh"
|
Le_Deploy_ssh_cmd="ssh -T"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# BACKUP is optional. If not provided then default to yes
|
# BACKUP is optional. If not provided then default to previously saved value or yes.
|
||||||
if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then
|
if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then
|
||||||
Le_Deploy_ssh_backup="no"
|
Le_Deploy_ssh_backup="no"
|
||||||
elif [ -z "$Le_Deploy_ssh_backup" ]; then
|
elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then
|
||||||
Le_Deploy_ssh_backup="yes"
|
Le_Deploy_ssh_backup="yes"
|
||||||
fi
|
fi
|
||||||
_savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup"
|
_savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup"
|
||||||
|
|
||||||
|
# BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy
|
||||||
|
if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then
|
||||||
|
Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH"
|
||||||
|
elif [ -z "$Le_Deploy_ssh_backup_path" ]; then
|
||||||
|
Le_Deploy_ssh_backup_path=".acme_ssh_deploy"
|
||||||
|
fi
|
||||||
|
_savedomainconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path"
|
||||||
|
|
||||||
|
# MULTI_CALL is optional. If not provided then default to previously saved
|
||||||
|
# value (which may be undefined... equivalent to "no").
|
||||||
|
if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then
|
||||||
|
Le_Deploy_ssh_multi_call="yes"
|
||||||
|
_savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call"
|
||||||
|
elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then
|
||||||
|
Le_Deploy_ssh_multi_call=""
|
||||||
|
_cleardomainconf Le_Deploy_ssh_multi_call
|
||||||
|
fi
|
||||||
|
|
||||||
_info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server"
|
_info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server"
|
||||||
|
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
||||||
|
_info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host"
|
||||||
|
else
|
||||||
|
_info "Required commands batched and sent in single call to remote host"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
||||||
|
_backupprefix="$Le_Deploy_ssh_backup_path/$_cdomain-backup"
|
||||||
|
_backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')"
|
||||||
|
# run cleanup on the backup directory, erase all older
|
||||||
|
# than 180 days (15552000 seconds).
|
||||||
|
_cmdstr="{ now=\"\$(date -u +%s)\"; for fn in $_backupprefix*; \
|
||||||
|
do if [ -d \"\$fn\" ] && [ \"\$(expr \$now - \$(date -ur \$fn +%s) )\" -ge \"15552000\" ]; \
|
||||||
|
then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; done; }; $_cmdstr"
|
||||||
|
# Alternate version of above... _cmdstr="find $_backupprefix* -type d -mtime +180 2>/dev/null | xargs rm -rf; $_cmdstr"
|
||||||
|
# Create our backup directory for overwritten cert files.
|
||||||
|
_cmdstr="mkdir -p $_backupdir; $_cmdstr"
|
||||||
|
_info "Backup of old certificate files will be placed in remote directory $_backupdir"
|
||||||
|
_info "Backup directories erased after 180 days."
|
||||||
|
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# KEYFILE is optional.
|
# KEYFILE is optional.
|
||||||
# If provided then private key will be copied to provided filename.
|
# If provided then private key will be copied to provided filename.
|
||||||
@ -98,6 +144,12 @@ ssh_deploy() {
|
|||||||
# copy new certificate into file.
|
# copy new certificate into file.
|
||||||
_cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;"
|
_cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;"
|
||||||
_info "will copy private key to remote file $Le_Deploy_ssh_keyfile"
|
_info "will copy private key to remote file $Le_Deploy_ssh_keyfile"
|
||||||
|
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# CERTFILE is optional.
|
# CERTFILE is optional.
|
||||||
@ -118,6 +170,12 @@ ssh_deploy() {
|
|||||||
# copy new certificate into file.
|
# copy new certificate into file.
|
||||||
_cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;"
|
_cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;"
|
||||||
_info "will copy certificate to remote file $Le_Deploy_ssh_certfile"
|
_info "will copy certificate to remote file $Le_Deploy_ssh_certfile"
|
||||||
|
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# CAFILE is optional.
|
# CAFILE is optional.
|
||||||
@ -139,6 +197,12 @@ ssh_deploy() {
|
|||||||
# copy new certificate into file.
|
# copy new certificate into file.
|
||||||
_cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;"
|
_cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;"
|
||||||
_info "will copy CA file to remote file $Le_Deploy_ssh_cafile"
|
_info "will copy CA file to remote file $Le_Deploy_ssh_cafile"
|
||||||
|
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# FULLCHAIN is optional.
|
# FULLCHAIN is optional.
|
||||||
@ -161,6 +225,12 @@ ssh_deploy() {
|
|||||||
# copy new certificate into file.
|
# copy new certificate into file.
|
||||||
_cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;"
|
_cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;"
|
||||||
_info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain"
|
_info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain"
|
||||||
|
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# REMOTE_CMD is optional.
|
# REMOTE_CMD is optional.
|
||||||
@ -172,34 +242,36 @@ ssh_deploy() {
|
|||||||
if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then
|
if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then
|
||||||
_cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;"
|
_cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;"
|
||||||
_info "Will execute remote command $Le_Deploy_ssh_remote_cmd"
|
_info "Will execute remote command $Le_Deploy_ssh_remote_cmd"
|
||||||
|
if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then
|
||||||
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
|
return $_err_code
|
||||||
|
fi
|
||||||
|
_cmdstr=""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$_cmdstr" ]; then
|
# if commands not all sent in multiple calls then all commands sent in a single SSH call now...
|
||||||
_err "No remote commands to excute. Failed to deploy certificates to remote server"
|
if [ -n "$_cmdstr" ]; then
|
||||||
return 1
|
if ! _ssh_remote_cmd "$_cmdstr"; then
|
||||||
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
return $_err_code
|
||||||
# run cleanup on the backup directory, erase all older
|
fi
|
||||||
# than 180 days (15552000 seconds).
|
|
||||||
_cmdstr="{ now=\"\$(date -u +%s)\"; for fn in $_backupprefix*; \
|
|
||||||
do if [ -d \"\$fn\" ] && [ \"\$(expr \$now - \$(date -ur \$fn +%s) )\" -ge \"15552000\" ]; \
|
|
||||||
then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; done; }; $_cmdstr"
|
|
||||||
# Alternate version of above... _cmdstr="find $_backupprefix* -type d -mtime +180 2>/dev/null | xargs rm -rf; $_cmdstr"
|
|
||||||
# Create our backup directory for overwritten cert files.
|
|
||||||
_cmdstr="mkdir -p $_backupdir; $_cmdstr"
|
|
||||||
_info "Backup of old certificate files will be placed in remote directory $_backupdir"
|
|
||||||
_info "Backup directories erased after 180 days."
|
|
||||||
fi
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
_secure_debug "Remote commands to execute: " "$_cmdstr"
|
#cmd
|
||||||
|
_ssh_remote_cmd() {
|
||||||
|
_cmd="$1"
|
||||||
|
_secure_debug "Remote commands to execute: $_cmd"
|
||||||
_info "Submitting sequence of commands to remote server by ssh"
|
_info "Submitting sequence of commands to remote server by ssh"
|
||||||
# quotations in bash cmd below intended. Squash travis spellcheck error
|
# quotations in bash cmd below intended. Squash travis spellcheck error
|
||||||
# shellcheck disable=SC2029
|
# shellcheck disable=SC2029
|
||||||
$Le_Deploy_ssh_cmd -T "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'"
|
$Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'"
|
||||||
_ret="$?"
|
_err_code="$?"
|
||||||
|
|
||||||
if [ "$_ret" != "0" ]; then
|
if [ "$_err_code" != "0" ]; then
|
||||||
_err "Error code $_ret returned from $Le_Deploy_ssh_cmd"
|
_err "Error code $_err_code returned from ssh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return $_ret
|
return $_err_code
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
# SYNO_Scheme - defaults to http
|
# SYNO_Scheme - defaults to http
|
||||||
# SYNO_Hostname - defaults to localhost
|
# SYNO_Hostname - defaults to localhost
|
||||||
# SYNO_Port - defaults to 5000
|
# SYNO_Port - defaults to 5000
|
||||||
|
# SYNO_DID - device ID to skip OTP - defaults to empty
|
||||||
#
|
#
|
||||||
#returns 0 means success, otherwise error.
|
#returns 0 means success, otherwise error.
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ synology_dsm_deploy() {
|
|||||||
_getdeployconf SYNO_Username
|
_getdeployconf SYNO_Username
|
||||||
_getdeployconf SYNO_Password
|
_getdeployconf SYNO_Password
|
||||||
_getdeployconf SYNO_Create
|
_getdeployconf SYNO_Create
|
||||||
|
_getdeployconf SYNO_DID
|
||||||
if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then
|
if [ -z "$SYNO_Username" ] || [ -z "$SYNO_Password" ]; then
|
||||||
SYNO_Username=""
|
SYNO_Username=""
|
||||||
SYNO_Password=""
|
SYNO_Password=""
|
||||||
@ -79,7 +81,7 @@ synology_dsm_deploy() {
|
|||||||
|
|
||||||
# Login, get the token from JSON and session id from cookie
|
# Login, get the token from JSON and session id from cookie
|
||||||
_info "Logging into $SYNO_Hostname:$SYNO_Port"
|
_info "Logging into $SYNO_Hostname:$SYNO_Port"
|
||||||
response=$(_get "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes")
|
response=$(_get "$_base_url/webman/login.cgi?username=$SYNO_Username&passwd=$SYNO_Password&enable_syno_token=yes&device_id=$SYNO_DID")
|
||||||
token=$(echo "$response" | grep "SynoToken" | sed -n 's/.*"SynoToken" *: *"\([^"]*\).*/\1/p')
|
token=$(echo "$response" | grep "SynoToken" | sed -n 's/.*"SynoToken" *: *"\([^"]*\).*/\1/p')
|
||||||
_debug3 response "$response"
|
_debug3 response "$response"
|
||||||
|
|
||||||
@ -99,6 +101,7 @@ synology_dsm_deploy() {
|
|||||||
# Now that we know the username and password are good, save them
|
# Now that we know the username and password are good, save them
|
||||||
_savedeployconf SYNO_Username "$SYNO_Username"
|
_savedeployconf SYNO_Username "$SYNO_Username"
|
||||||
_savedeployconf SYNO_Password "$SYNO_Password"
|
_savedeployconf SYNO_Password "$SYNO_Password"
|
||||||
|
_savedeployconf SYNO_DID "$SYNO_DID"
|
||||||
_debug token "$token"
|
_debug token "$token"
|
||||||
|
|
||||||
_info "Getting certificates in Synology DSM"
|
_info "Getting certificates in Synology DSM"
|
||||||
|
|||||||
254
dnsapi/dns_1984hosting.sh
Executable file
254
dnsapi/dns_1984hosting.sh
Executable file
@ -0,0 +1,254 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
#This file name is "dns_1984hosting.sh"
|
||||||
|
#So, here must be a method dns_1984hosting_add()
|
||||||
|
#Which will be called by acme.sh to add the txt record to your api system.
|
||||||
|
#returns 0 means success, otherwise error.
|
||||||
|
#
|
||||||
|
#Author: Adrian Fedoreanu
|
||||||
|
#Report Bugs here: https://github.com/acmesh-official/acme.sh
|
||||||
|
# or here... https://github.com/acmesh-official/acme.sh/issues/2851
|
||||||
|
#
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
# Export 1984HOSTING username and password in following variables
|
||||||
|
#
|
||||||
|
# One984HOSTING_Username=username
|
||||||
|
# One984HOSTING_Password=password
|
||||||
|
#
|
||||||
|
# sessionid cookie is saved in ~/.acme.sh/account.conf
|
||||||
|
# username/password need to be set only when changed.
|
||||||
|
|
||||||
|
#Usage: dns_1984hosting_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_1984hosting_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
_info "Add TXT record using 1984Hosting"
|
||||||
|
_debug fulldomain "$fulldomain"
|
||||||
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
|
if ! _1984hosting_login; then
|
||||||
|
_err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug "First detect the root zone"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain" "$fulldomain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_1984hosting_add_txt_record "$_domain" "$_sub_domain" "$txtvalue"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
#Usage: fulldomain txtvalue
|
||||||
|
#Remove the txt record after validation.
|
||||||
|
dns_1984hosting_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
_info "Delete TXT record using 1984Hosting"
|
||||||
|
_debug fulldomain "$fulldomain"
|
||||||
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
|
if ! _1984hosting_login; then
|
||||||
|
_err "1984Hosting login failed for user $One984HOSTING_Username. Check $HTTP_HEADER file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug "First detect the root zone"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain" "$fulldomain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_1984hosting_delete_txt_record "$_domain" "$_sub_domain"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
|
# usage _1984hosting_add_txt_record domain subdomain value
|
||||||
|
# returns 0 success
|
||||||
|
_1984hosting_add_txt_record() {
|
||||||
|
_debug "Add TXT record $1 with value '$3'"
|
||||||
|
domain="$1"
|
||||||
|
subdomain="$2"
|
||||||
|
value="$(printf '%s' "$3" | _url_encode)"
|
||||||
|
url="https://management.1984hosting.com/domains/entry/"
|
||||||
|
|
||||||
|
postdata="entry=new"
|
||||||
|
postdata="$postdata&type=TXT"
|
||||||
|
postdata="$postdata&ttl=3600"
|
||||||
|
postdata="$postdata&zone=$domain"
|
||||||
|
postdata="$postdata&host=$subdomain"
|
||||||
|
postdata="$postdata&rdata=%22$value%22"
|
||||||
|
_debug2 postdata "$postdata"
|
||||||
|
|
||||||
|
_authpost "$postdata" "$url"
|
||||||
|
response="$(echo "$_response" | _normalizeJson)"
|
||||||
|
_debug2 response "$response"
|
||||||
|
|
||||||
|
if _contains "$response" '"haserrors": true'; then
|
||||||
|
_err "1984Hosting failed to add TXT record for $subdomain bad RC from _post"
|
||||||
|
return 1
|
||||||
|
elif _contains "$response" "<html>"; then
|
||||||
|
_err "1984Hosting failed to add TXT record for $subdomain. Check $HTTP_HEADER file"
|
||||||
|
return 1
|
||||||
|
elif [ "$response" = '{"auth": false, "ok": false}' ]; then
|
||||||
|
_err "1984Hosting failed to add TXT record for $subdomain. Invalid or expired cookie"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "Added acme challenge TXT record for $fulldomain at 1984Hosting"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# usage _1984hosting_delete_txt_record entry_id
|
||||||
|
# returns 0 success
|
||||||
|
_1984hosting_delete_txt_record() {
|
||||||
|
_debug "Delete $fulldomain TXT record"
|
||||||
|
domain="$1"
|
||||||
|
subdomain="$2"
|
||||||
|
url="https://management.1984hosting.com/domains"
|
||||||
|
|
||||||
|
_htmlget "$url" "$domain"
|
||||||
|
_debug2 _response "$_response"
|
||||||
|
zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')"
|
||||||
|
_debug2 zone_id "$zone_id"
|
||||||
|
if [ -z "$zone_id" ]; then
|
||||||
|
_err "Error getting zone_id for $1"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_htmlget "$url/$zone_id" "$subdomain"
|
||||||
|
_debug2 _response "$_response"
|
||||||
|
entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')"
|
||||||
|
_debug2 entry_id "$entry_id"
|
||||||
|
if [ -z "$entry_id" ]; then
|
||||||
|
_err "Error getting TXT entry_id for $1"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_authpost "entry=$entry_id" "$url/delentry/"
|
||||||
|
response="$(echo "$_response" | _normalizeJson)"
|
||||||
|
_debug2 response "$response"
|
||||||
|
|
||||||
|
if ! _contains "$response" '"ok": true'; then
|
||||||
|
_err "1984Hosting failed to delete TXT record for $entry_id bad RC from _post"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "Deleted acme challenge TXT record for $fulldomain at 1984Hosting"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# usage: _1984hosting_login username password
|
||||||
|
# returns 0 success
|
||||||
|
_1984hosting_login() {
|
||||||
|
if ! _check_credentials; then return 1; fi
|
||||||
|
|
||||||
|
if _check_cookie; then
|
||||||
|
_debug "Already logged in"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug "Login to 1984Hosting as user $One984HOSTING_Username"
|
||||||
|
username=$(printf '%s' "$One984HOSTING_Username" | _url_encode)
|
||||||
|
password=$(printf '%s' "$One984HOSTING_Password" | _url_encode)
|
||||||
|
url="https://management.1984hosting.com/accounts/checkuserauth/"
|
||||||
|
|
||||||
|
response="$(_post "username=$username&password=$password&otpkey=" "$url")"
|
||||||
|
response="$(echo "$response" | _normalizeJson)"
|
||||||
|
_debug2 response "$response"
|
||||||
|
|
||||||
|
if [ "$response" = '{"loggedin": true, "ok": true}' ]; then
|
||||||
|
One984HOSTING_COOKIE="$(grep '^Set-Cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')"
|
||||||
|
export One984HOSTING_COOKIE
|
||||||
|
_saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_check_credentials() {
|
||||||
|
if [ -z "$One984HOSTING_Username" ] || [ -z "$One984HOSTING_Password" ]; then
|
||||||
|
One984HOSTING_Username=""
|
||||||
|
One984HOSTING_Password=""
|
||||||
|
_err "You haven't specified 1984Hosting username or password yet."
|
||||||
|
_err "Please export as One984HOSTING_Username / One984HOSTING_Password and try again."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_check_cookie() {
|
||||||
|
One984HOSTING_COOKIE="${One984HOSTING_COOKIE:-$(_readaccountconf_mutable One984HOSTING_COOKIE)}"
|
||||||
|
if [ -z "$One984HOSTING_COOKIE" ]; then
|
||||||
|
_debug "No cached cookie found"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_authget "https://management.1984hosting.com/accounts/loginstatus/"
|
||||||
|
response="$(echo "$_response" | _normalizeJson)"
|
||||||
|
if [ "$_response" = '{"ok": true}' ]; then
|
||||||
|
_debug "Cached cookie still valid"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
_debug "Cached cookie no longer valid"
|
||||||
|
One984HOSTING_COOKIE=""
|
||||||
|
_saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#_acme-challenge.www.domain.com
|
||||||
|
#returns
|
||||||
|
# _sub_domain=_acme-challenge.www
|
||||||
|
# _domain=domain.com
|
||||||
|
_get_root() {
|
||||||
|
domain="$1"
|
||||||
|
i=2
|
||||||
|
p=1
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
#not valid
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_authget "https://management.1984hosting.com/domains/soacheck/?zone=$h&nameserver=ns0.1984.is."
|
||||||
|
if _contains "$_response" "serial"; then
|
||||||
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
|
_domain="$h"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
p=$i
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# add extra headers to request
|
||||||
|
_authget() {
|
||||||
|
export _H1="Cookie: $One984HOSTING_COOKIE"
|
||||||
|
_response=$(_get "$1")
|
||||||
|
}
|
||||||
|
|
||||||
|
# truncate huge HTML response
|
||||||
|
# echo: Argument list too long
|
||||||
|
_htmlget() {
|
||||||
|
export _H1="Cookie: $One984HOSTING_COOKIE"
|
||||||
|
_response=$(_get "$1" | grep "$2" | _head_n 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
# add extra headers to request
|
||||||
|
_authpost() {
|
||||||
|
export _H1="Cookie: $One984HOSTING_COOKIE"
|
||||||
|
_response=$(_post "$1" "$2")
|
||||||
|
}
|
||||||
163
dnsapi/dns_arvan.sh
Normal file
163
dnsapi/dns_arvan.sh
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#Arvan_Token="xxxx"
|
||||||
|
|
||||||
|
ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains"
|
||||||
|
|
||||||
|
#Author: Ehsan Aliakbar
|
||||||
|
#Report Bugs here: https://github.com/Neilpang/acme.sh
|
||||||
|
#
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_arvan_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
_info "Using Arvan"
|
||||||
|
|
||||||
|
Arvan_Token="${Arvan_Token:-$(_readaccountconf_mutable Arvan_Token)}"
|
||||||
|
|
||||||
|
if [ -z "$Arvan_Token" ]; then
|
||||||
|
_err "You didn't specify \"Arvan_Token\" token yet."
|
||||||
|
_err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
#save the api token to the account conf file.
|
||||||
|
_saveaccountconf_mutable Arvan_Token "$Arvan_Token"
|
||||||
|
|
||||||
|
_debug "First detect the root zone"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug _domain_id "$_domain_id"
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_info "Adding record"
|
||||||
|
if _arvan_rest POST "$_domain/dns-records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":{\"text\":\"$txtvalue\"},\"ttl\":120}"; then
|
||||||
|
if _contains "$response" "$txtvalue"; then
|
||||||
|
_info "Added, OK"
|
||||||
|
return 0
|
||||||
|
elif _contains "$response" "Record Data is Duplicated"; then
|
||||||
|
_info "Already exists, OK"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Add txt record error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_err "Add txt record error."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#Usage: fulldomain txtvalue
|
||||||
|
#Remove the txt record after validation.
|
||||||
|
dns_arvan_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
_info "Using Arvan"
|
||||||
|
_debug fulldomain "$fulldomain"
|
||||||
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
|
Arvan_Token="${Arvan_Token:-$(_readaccountconf_mutable Arvan_Token)}"
|
||||||
|
|
||||||
|
_debug "First detect the root zone"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _domain_id "$_domain_id"
|
||||||
|
_debug _sub_domain "$_sub_domain"
|
||||||
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_debug "Getting txt records"
|
||||||
|
shorted_txtvalue=$(printf "%s" "$txtvalue" | cut -d "-" -d "_" -f1)
|
||||||
|
_arvan_rest GET "${_domain}/dns-records?search=$shorted_txtvalue"
|
||||||
|
|
||||||
|
if ! printf "%s" "$response" | grep \"current_page\":1 >/dev/null; then
|
||||||
|
_err "Error on Arvan Api"
|
||||||
|
_err "Please create a github issue with debbug log"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
count=$(printf "%s\n" "$response" | _egrep_o "\"total\":[^,]*" | cut -d : -f 2)
|
||||||
|
_debug count "$count"
|
||||||
|
if [ "$count" = "0" ]; then
|
||||||
|
_info "Don't need to remove."
|
||||||
|
else
|
||||||
|
record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1)
|
||||||
|
_debug "record_id" "$record_id"
|
||||||
|
if [ -z "$record_id" ]; then
|
||||||
|
_err "Can not get record id to remove."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if ! _arvan_rest "DELETE" "${_domain}/dns-records/$record_id"; then
|
||||||
|
_err "Delete record error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug "$response"
|
||||||
|
_contains "$response" 'dns record deleted'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
|
#_acme-challenge.www.domain.com
|
||||||
|
#returns
|
||||||
|
# _sub_domain=_acme-challenge.www
|
||||||
|
# _domain=domain.com
|
||||||
|
# _domain_id=sdjkglgdfewsdfg
|
||||||
|
_get_root() {
|
||||||
|
domain=$1
|
||||||
|
i=1
|
||||||
|
p=1
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
_debug h "$h"
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
#not valid
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _arvan_rest GET "?search=$h"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _contains "$response" "\"domain\":\"$h\"" || _contains "$response" '"total":1'; then
|
||||||
|
_domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
|
||||||
|
if [ "$_domain_id" ]; then
|
||||||
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
|
_domain=$h
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
p=$i
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_arvan_rest() {
|
||||||
|
mtd="$1"
|
||||||
|
ep="$2"
|
||||||
|
data="$3"
|
||||||
|
|
||||||
|
token_trimmed=$(echo "$Arvan_Token" | tr -d '"')
|
||||||
|
|
||||||
|
export _H1="Authorization: $token_trimmed"
|
||||||
|
|
||||||
|
if [ "$mtd" = "DELETE" ]; then
|
||||||
|
#DELETE Request shouldn't have Content-Type
|
||||||
|
_debug data "$data"
|
||||||
|
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
|
||||||
|
elif [ "$mtd" = "POST" ]; then
|
||||||
|
export _H2="Content-Type: application/json"
|
||||||
|
_debug data "$data"
|
||||||
|
response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")"
|
||||||
|
else
|
||||||
|
response="$(_get "$ARVAN_API_URL/$ep$data")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
@ -23,6 +23,7 @@ dns_aws_add() {
|
|||||||
|
|
||||||
AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}"
|
AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}"
|
||||||
AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}"
|
AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}"
|
||||||
|
AWS_DNS_SLOWRATE="${AWS_DNS_SLOWRATE:-$(_readaccountconf_mutable AWS_DNS_SLOWRATE)}"
|
||||||
|
|
||||||
if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
|
if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
|
||||||
_use_container_role || _use_instance_role
|
_use_container_role || _use_instance_role
|
||||||
@ -40,6 +41,7 @@ dns_aws_add() {
|
|||||||
if [ -z "$_using_role" ]; then
|
if [ -z "$_using_role" ]; then
|
||||||
_saveaccountconf_mutable AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID"
|
_saveaccountconf_mutable AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID"
|
||||||
_saveaccountconf_mutable AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY"
|
_saveaccountconf_mutable AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY"
|
||||||
|
_saveaccountconf_mutable AWS_DNS_SLOWRATE "$AWS_DNS_SLOWRATE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_debug "First detect the root zone"
|
_debug "First detect the root zone"
|
||||||
@ -77,7 +79,13 @@ dns_aws_add() {
|
|||||||
|
|
||||||
if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then
|
if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then
|
||||||
_info "TXT record updated successfully."
|
_info "TXT record updated successfully."
|
||||||
_sleep 1
|
if [ -n "$AWS_DNS_SLOWRATE" ]; then
|
||||||
|
_info "Slow rate activated: sleeping for $AWS_DNS_SLOWRATE seconds"
|
||||||
|
_sleep "$AWS_DNS_SLOWRATE"
|
||||||
|
else
|
||||||
|
_sleep 1
|
||||||
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
_sleep 1
|
_sleep 1
|
||||||
@ -91,6 +99,7 @@ dns_aws_rm() {
|
|||||||
|
|
||||||
AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}"
|
AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$(_readaccountconf_mutable AWS_ACCESS_KEY_ID)}"
|
||||||
AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}"
|
AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$(_readaccountconf_mutable AWS_SECRET_ACCESS_KEY)}"
|
||||||
|
AWS_DNS_SLOWRATE="${AWS_DNS_SLOWRATE:-$(_readaccountconf_mutable AWS_DNS_SLOWRATE)}"
|
||||||
|
|
||||||
if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
|
if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
|
||||||
_use_container_role || _use_instance_role
|
_use_container_role || _use_instance_role
|
||||||
@ -125,7 +134,13 @@ dns_aws_rm() {
|
|||||||
|
|
||||||
if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then
|
if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then
|
||||||
_info "TXT record deleted successfully."
|
_info "TXT record deleted successfully."
|
||||||
_sleep 1
|
if [ -n "$AWS_DNS_SLOWRATE" ]; then
|
||||||
|
_info "Slow rate activated: sleeping for $AWS_DNS_SLOWRATE seconds"
|
||||||
|
_sleep "$AWS_DNS_SLOWRATE"
|
||||||
|
else
|
||||||
|
_sleep 1
|
||||||
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
_sleep 1
|
_sleep 1
|
||||||
|
|||||||
@ -94,6 +94,7 @@ dns_cf_rm() {
|
|||||||
|
|
||||||
CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}"
|
CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}"
|
||||||
CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}"
|
CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}"
|
||||||
|
CF_Zone_ID="${CF_Zone_ID:-$(_readaccountconf_mutable CF_Zone_ID)}"
|
||||||
CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}"
|
CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}"
|
||||||
CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}"
|
CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}"
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ dns_cf_rm() {
|
|||||||
_cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain&content=$txtvalue"
|
_cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain&content=$txtvalue"
|
||||||
|
|
||||||
if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then
|
if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then
|
||||||
_err "Error"
|
_err "Error: $response"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@ -86,12 +86,12 @@ _get_root() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _constellix_rest GET "domains"; then
|
if ! _constellix_rest GET "domains/search?exact=$h"; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$response" "\"name\":\"$h\""; then
|
if _contains "$response" "\"name\":\"$h\""; then
|
||||||
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | head -n 1 | cut -d ':' -f 2 | tr -d '}')
|
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+" | cut -d ':' -f 2)
|
||||||
if [ "$_domain_id" ]; then
|
if [ "$_domain_id" ]; then
|
||||||
_sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p)
|
_sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p)
|
||||||
_domain="$h"
|
_domain="$h"
|
||||||
|
|||||||
@ -119,7 +119,7 @@ _ddnss_rest() {
|
|||||||
|
|
||||||
# DDNSS uses GET to update domain info
|
# DDNSS uses GET to update domain info
|
||||||
if [ "$method" = "GET" ]; then
|
if [ "$method" = "GET" ]; then
|
||||||
response="$(_get "$url" | sed 's/<[a-zA-Z\/][^>]*>//g' | _tail_n 1)"
|
response="$(_get "$url" | sed 's/<[a-zA-Z\/][^>]*>//g' | tr -s "\n" | _tail_n 1)"
|
||||||
else
|
else
|
||||||
_err "Unsupported method"
|
_err "Unsupported method"
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@ -53,7 +53,7 @@ dns_dp_rm() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _rest POST "Record.List" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain"; then
|
if ! _rest POST "Record.List" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain"; then
|
||||||
_err "Record.Lis error."
|
_err "Record.Lis error."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -70,12 +70,12 @@ dns_dp_rm() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _rest POST "Record.Remove" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then
|
if ! _rest POST "Record.Remove" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&record_id=$record_id"; then
|
||||||
_err "Record.Remove error."
|
_err "Record.Remove error."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_contains "$response" "Action completed successful"
|
_contains "$response" "successful"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,11 +89,11 @@ add_record() {
|
|||||||
|
|
||||||
_info "Adding record"
|
_info "Adding record"
|
||||||
|
|
||||||
if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then
|
if ! _rest POST "Record.Create" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=默认"; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_contains "$response" "Action completed successful" || _contains "$response" "Domain record already exists"
|
_contains "$response" "successful" || _contains "$response" "Domain record already exists"
|
||||||
}
|
}
|
||||||
|
|
||||||
#################### Private functions below ##################################
|
#################### Private functions below ##################################
|
||||||
@ -113,11 +113,11 @@ _get_root() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _rest POST "Domain.Info" "login_token=$DP_Id,$DP_Key&format=json&domain=$h"; then
|
if ! _rest POST "Domain.Info" "login_token=$DP_Id,$DP_Key&format=json&lang=en&domain=$h"; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$response" "Action completed successful"; then
|
if _contains "$response" "successful"; then
|
||||||
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")
|
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")
|
||||||
_debug _domain_id "$_domain_id"
|
_debug _domain_id "$_domain_id"
|
||||||
if [ "$_domain_id" ]; then
|
if [ "$_domain_id" ]; then
|
||||||
|
|||||||
@ -4,8 +4,7 @@
|
|||||||
#
|
#
|
||||||
# easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh
|
# easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh
|
||||||
#
|
#
|
||||||
# Please note: # API is currently beta and subject to constant change
|
# API Documentation: https://sandbox.rest.easydns.net:3001/
|
||||||
# http://sandbox.rest.easydns.net:3000/
|
|
||||||
#
|
#
|
||||||
# Author: wurzelpanzer [wurzelpanzer@maximolider.net]
|
# Author: wurzelpanzer [wurzelpanzer@maximolider.net]
|
||||||
# Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2647
|
# Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2647
|
||||||
@ -25,7 +24,7 @@ dns_easydns_add() {
|
|||||||
EASYDNS_Key="${EASYDNS_Key:-$(_readaccountconf_mutable EASYDNS_Key)}"
|
EASYDNS_Key="${EASYDNS_Key:-$(_readaccountconf_mutable EASYDNS_Key)}"
|
||||||
|
|
||||||
if [ -z "$EASYDNS_Token" ] || [ -z "$EASYDNS_Key" ]; then
|
if [ -z "$EASYDNS_Token" ] || [ -z "$EASYDNS_Key" ]; then
|
||||||
_err "You didn't specify an easydns.net token or api key. Please sign up at http://docs.sandbox.rest.easydns.net/beta_signup.php"
|
_err "You didn't specify an easydns.net token or api key. Signup at https://cp.easydns.com/manage/security/api/signup.php"
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
_saveaccountconf_mutable EASYDNS_Token "$EASYDNS_Token"
|
_saveaccountconf_mutable EASYDNS_Token "$EASYDNS_Token"
|
||||||
|
|||||||
@ -24,7 +24,7 @@ dns_he_add() {
|
|||||||
if [ -z "$HE_Username" ] || [ -z "$HE_Password" ]; then
|
if [ -z "$HE_Username" ] || [ -z "$HE_Password" ]; then
|
||||||
HE_Username=
|
HE_Username=
|
||||||
HE_Password=
|
HE_Password=
|
||||||
_err "No auth details provided. Please set user credentials using the \$HE_Username and \$HE_Password envoronment variables."
|
_err "No auth details provided. Please set user credentials using the \$HE_Username and \$HE_Password environment variables."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_saveaccountconf_mutable HE_Username "$HE_Username"
|
_saveaccountconf_mutable HE_Username "$HE_Username"
|
||||||
|
|||||||
@ -34,6 +34,10 @@ dns_inwx_add() {
|
|||||||
_saveaccountconf_mutable INWX_Password "$INWX_Password"
|
_saveaccountconf_mutable INWX_Password "$INWX_Password"
|
||||||
_saveaccountconf_mutable INWX_Shared_Secret "$INWX_Shared_Secret"
|
_saveaccountconf_mutable INWX_Shared_Secret "$INWX_Shared_Secret"
|
||||||
|
|
||||||
|
if ! _inwx_login; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
_debug "First detect the root zone"
|
_debug "First detect the root zone"
|
||||||
if ! _get_root "$fulldomain"; then
|
if ! _get_root "$fulldomain"; then
|
||||||
_err "invalid domain"
|
_err "invalid domain"
|
||||||
@ -55,6 +59,7 @@ dns_inwx_rm() {
|
|||||||
|
|
||||||
INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
|
INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
|
||||||
INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
|
INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
|
||||||
|
INWX_Shared_Secret="${INWX_Shared_Secret:-$(_readaccountconf_mutable INWX_Shared_Secret)}"
|
||||||
if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
|
if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
|
||||||
INWX_User=""
|
INWX_User=""
|
||||||
INWX_Password=""
|
INWX_Password=""
|
||||||
@ -63,9 +68,9 @@ dns_inwx_rm() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#save the api key and email to the account conf file.
|
if ! _inwx_login; then
|
||||||
_saveaccountconf_mutable INWX_User "$INWX_User"
|
return 1
|
||||||
_saveaccountconf_mutable INWX_Password "$INWX_Password"
|
fi
|
||||||
|
|
||||||
_debug "First detect the root zone"
|
_debug "First detect the root zone"
|
||||||
if ! _get_root "$fulldomain"; then
|
if ! _get_root "$fulldomain"; then
|
||||||
@ -126,8 +131,42 @@ dns_inwx_rm() {
|
|||||||
|
|
||||||
#################### Private functions below ##################################
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
|
_inwx_check_cookie() {
|
||||||
|
INWX_Cookie="${INWX_Cookie:-$(_readaccountconf_mutable INWX_Cookie)}"
|
||||||
|
if [ -z "$INWX_Cookie" ]; then
|
||||||
|
_debug "No cached cookie found"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_H1="$INWX_Cookie"
|
||||||
|
export _H1
|
||||||
|
|
||||||
|
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<methodCall>
|
||||||
|
<methodName>account.info</methodName>
|
||||||
|
</methodCall>')
|
||||||
|
|
||||||
|
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
|
||||||
|
|
||||||
|
if _contains "$response" "<member><name>code</name><value><int>1000</int></value></member>"; then
|
||||||
|
_debug "Cached cookie still valid"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug "Cached cookie no longer valid"
|
||||||
|
_H1=""
|
||||||
|
export _H1
|
||||||
|
INWX_Cookie=""
|
||||||
|
_saveaccountconf_mutable INWX_Cookie "$INWX_Cookie"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
_inwx_login() {
|
_inwx_login() {
|
||||||
|
|
||||||
|
if _inwx_check_cookie; then
|
||||||
|
_debug "Already logged in"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
|
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<methodCall>
|
<methodCall>
|
||||||
<methodName>account.login</methodName>
|
<methodName>account.login</methodName>
|
||||||
@ -151,17 +190,25 @@ _inwx_login() {
|
|||||||
</value>
|
</value>
|
||||||
</param>
|
</param>
|
||||||
</params>
|
</params>
|
||||||
</methodCall>' $INWX_User $INWX_Password)
|
</methodCall>' "$INWX_User" "$INWX_Password")
|
||||||
|
|
||||||
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
|
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
|
||||||
_H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
|
|
||||||
|
INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
|
||||||
|
_H1=$INWX_Cookie
|
||||||
export _H1
|
export _H1
|
||||||
|
export INWX_Cookie
|
||||||
|
_saveaccountconf_mutable INWX_Cookie "$INWX_Cookie"
|
||||||
|
|
||||||
|
if ! _contains "$response" "<member><name>code</name><value><int>1000</int></value></member>"; then
|
||||||
|
_err "INWX API: Authentication error (username/password correct?)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
#https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71
|
#https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71
|
||||||
if _contains "$response" "<member><name>code</name><value><int>1000</int></value></member>" \
|
if _contains "$response" "<member><name>tfa</name><value><string>GOOGLE-AUTH</string></value></member>"; then
|
||||||
&& _contains "$response" "<member><name>tfa</name><value><string>GOOGLE-AUTH</string></value></member>"; then
|
|
||||||
if [ -z "$INWX_Shared_Secret" ]; then
|
if [ -z "$INWX_Shared_Secret" ]; then
|
||||||
_err "Mobile TAN detected."
|
_err "INWX API: Mobile TAN detected."
|
||||||
_err "Please define a shared secret."
|
_err "Please define a shared secret."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -194,6 +241,11 @@ _inwx_login() {
|
|||||||
</methodCall>' "$tan")
|
</methodCall>' "$tan")
|
||||||
|
|
||||||
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
|
response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
|
||||||
|
|
||||||
|
if ! _contains "$response" "<member><name>code</name><value><int>1000</int></value></member>"; then
|
||||||
|
_err "INWX API: Mobile TAN not correct."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -206,8 +258,6 @@ _get_root() {
|
|||||||
i=2
|
i=2
|
||||||
p=1
|
p=1
|
||||||
|
|
||||||
_inwx_login
|
|
||||||
|
|
||||||
xml_content='<?xml version="1.0" encoding="UTF-8"?>
|
xml_content='<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<methodCall>
|
<methodCall>
|
||||||
<methodName>nameserver.list</methodName>
|
<methodName>nameserver.list</methodName>
|
||||||
|
|||||||
129
dnsapi/dns_joker.sh
Normal file
129
dnsapi/dns_joker.sh
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Joker.com API for acme.sh
|
||||||
|
#
|
||||||
|
# This script adds the necessary TXT record to a domain in Joker.com.
|
||||||
|
#
|
||||||
|
# You must activate Dynamic DNS in Joker.com DNS configuration first.
|
||||||
|
# Username and password below refer to Dynamic DNS authentication,
|
||||||
|
# not your Joker.com login credentials.
|
||||||
|
# See: https://joker.com/faq/content/11/427/en/what-is-dynamic-dns-dyndns.html
|
||||||
|
#
|
||||||
|
# NOTE: This script does not support wildcard certificates, because
|
||||||
|
# Joker.com API does not support adding two TXT records with the same
|
||||||
|
# subdomain. Adding the second record will overwrite the first one.
|
||||||
|
# See: https://joker.com/faq/content/6/496/en/let_s-encrypt-support.html
|
||||||
|
# "... this request will replace all TXT records for the specified
|
||||||
|
# label by the provided content"
|
||||||
|
#
|
||||||
|
# Author: aattww (https://github.com/aattww/)
|
||||||
|
#
|
||||||
|
# Report bugs to https://github.com/acmesh-official/acme.sh/issues/2840
|
||||||
|
#
|
||||||
|
# JOKER_USERNAME="xxxx"
|
||||||
|
# JOKER_PASSWORD="xxxx"
|
||||||
|
|
||||||
|
JOKER_API="https://svc.joker.com/nic/replace"
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#Usage: dns_joker_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_joker_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
JOKER_USERNAME="${JOKER_USERNAME:-$(_readaccountconf_mutable JOKER_USERNAME)}"
|
||||||
|
JOKER_PASSWORD="${JOKER_PASSWORD:-$(_readaccountconf_mutable JOKER_PASSWORD)}"
|
||||||
|
|
||||||
|
if [ -z "$JOKER_USERNAME" ] || [ -z "$JOKER_PASSWORD" ]; then
|
||||||
|
_err "No Joker.com username and password specified."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_saveaccountconf_mutable JOKER_USERNAME "$JOKER_USERNAME"
|
||||||
|
_saveaccountconf_mutable JOKER_PASSWORD "$JOKER_PASSWORD"
|
||||||
|
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "Invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "Adding TXT record"
|
||||||
|
if _joker_rest "username=$JOKER_USERNAME&password=$JOKER_PASSWORD&zone=$_domain&label=$_sub_domain&type=TXT&value=$txtvalue"; then
|
||||||
|
if _startswith "$response" "OK"; then
|
||||||
|
_info "Added, OK"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_err "Error adding TXT record."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#fulldomain txtvalue
|
||||||
|
dns_joker_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
JOKER_USERNAME="${JOKER_USERNAME:-$(_readaccountconf_mutable JOKER_USERNAME)}"
|
||||||
|
JOKER_PASSWORD="${JOKER_PASSWORD:-$(_readaccountconf_mutable JOKER_PASSWORD)}"
|
||||||
|
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "Invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "Removing TXT record"
|
||||||
|
# TXT record is removed by setting its value to empty.
|
||||||
|
if _joker_rest "username=$JOKER_USERNAME&password=$JOKER_PASSWORD&zone=$_domain&label=$_sub_domain&type=TXT&value="; then
|
||||||
|
if _startswith "$response" "OK"; then
|
||||||
|
_info "Removed, OK"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_err "Error removing TXT record."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
#_acme-challenge.www.domain.com
|
||||||
|
#returns
|
||||||
|
# _sub_domain=_acme-challenge.www
|
||||||
|
# _domain=domain.com
|
||||||
|
_get_root() {
|
||||||
|
fulldomain=$1
|
||||||
|
i=1
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$fulldomain" | cut -d . -f $i-100)
|
||||||
|
_debug h "$h"
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Try to remove a test record. With correct root domain, username and password this will return "OK: ..." regardless
|
||||||
|
# of record in question existing or not.
|
||||||
|
if _joker_rest "username=$JOKER_USERNAME&password=$JOKER_PASSWORD&zone=$h&label=jokerTXTUpdateTest&type=TXT&value="; then
|
||||||
|
if _startswith "$response" "OK"; then
|
||||||
|
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$h\$//")"
|
||||||
|
_domain=$h
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
|
||||||
|
_debug "Root domain not found"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_joker_rest() {
|
||||||
|
data="$1"
|
||||||
|
_debug data "$data"
|
||||||
|
|
||||||
|
if ! response="$(_post "$data" "$JOKER_API" "" "POST")"; then
|
||||||
|
_err "Error POSTing"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug response "$response"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
@ -114,7 +114,7 @@ _get_root() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$response" "\"name\":\"$h\""; then
|
if _contains "$response" "\"name\":\"$h\""; then
|
||||||
_domain_id=$(printf "%s\n" "$response" | cut -c 2- | head -c -2 | sed 's/{.*}//' | sed -r 's/^.*"id":([0-9]+).*$/\1/')
|
_domain_id=$(printf "%s\n" "$response" | sed 's/^{//; s/}$//; s/{.*}//' | sed -r 's/^.*"id":([0-9]+).*$/\1/')
|
||||||
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"
|
||||||
|
|||||||
@ -1,92 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
# https://namemaster.de hook script for acme.sh
|
|
||||||
#
|
|
||||||
# Environment variables:
|
|
||||||
#
|
|
||||||
# - $NM_user (your namemaster.de API username)
|
|
||||||
# - $NM_md5 (your namemaster.de API password_as_md5hash)
|
|
||||||
#
|
|
||||||
# Author: Thilo Gass <thilo.gass@gmail.com>
|
|
||||||
# Git repo: https://github.com/ThiloGa/acme.sh
|
|
||||||
|
|
||||||
#-- dns_nm_add() - Add TXT record --------------------------------------
|
|
||||||
# Usage: dns_nm_add _acme-challenge.subdomain.domain.com "XyZ123..."
|
|
||||||
|
|
||||||
dns_nm_add() {
|
|
||||||
fulldomain=$1
|
|
||||||
txt_value=$2
|
|
||||||
_info "Using DNS-01 namemaster hook"
|
|
||||||
|
|
||||||
NM_user="${NM_user:-$(_readaccountconf_mutable NM_user)}"
|
|
||||||
NM_md5="${NM_md5:-$(_readaccountconf_mutable NM_md5)}"
|
|
||||||
if [ -z "$NM_user" ] || [ -z "$NM_md5" ]; then
|
|
||||||
NM_user=""
|
|
||||||
NM_md5=""
|
|
||||||
_err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
#save the api user and md5 password to the account conf file.
|
|
||||||
_debug "Save user and hash"
|
|
||||||
_saveaccountconf_mutable NM_user "$NM_user"
|
|
||||||
_saveaccountconf_mutable NM_md5 "$NM_md5"
|
|
||||||
|
|
||||||
zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")"
|
|
||||||
get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=ACME&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Auto&Lifetime=3600"
|
|
||||||
erg="$(_get "$get")"
|
|
||||||
|
|
||||||
exit_code="$?"
|
|
||||||
if [ "$exit_code" != 0 ]; then
|
|
||||||
_err "error Ading $zone TXT: $txt_value"
|
|
||||||
_err "Error $exit_code"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if _contains "$erg" "Success"; then
|
|
||||||
_info "Success, TXT Added, OK"
|
|
||||||
else
|
|
||||||
_err "error Adding $zone TXT: $txt_value erg: $erg"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
_debug "ok Auto $zone TXT: $txt_value erg: $erg"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
dns_nm_rm() {
|
|
||||||
|
|
||||||
fulldomain=$1
|
|
||||||
txt_value=$2
|
|
||||||
|
|
||||||
NM_user="${NM_user:-$(_readaccountconf_mutable NM_user)}"
|
|
||||||
NM_md5="${NM_md5:-$(_readaccountconf_mutable NM_md5)}"
|
|
||||||
if [ -z "$NM_user" ] || [ -z "$NM_md5" ]; then
|
|
||||||
NM_user=""
|
|
||||||
NM_md5=""
|
|
||||||
_err "No auth details provided. Please set user credentials using the \$NM_user and \$NM_md5 environment variables."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
zone="$(echo $fulldomain | _egrep_o "[^.]+.[^.]+$")"
|
|
||||||
get="https://namemaster.de/api/api.php?User=$NM_user&Password=$NM_md5&Antwort=csv&Int=0&Typ=TXT&Zone=$zone&hostname=$fulldomain&TXT=$txt_value&Action=Delete_IN&TTL=0"
|
|
||||||
erg="$(_get "$get")"
|
|
||||||
|
|
||||||
exit_code="$?"
|
|
||||||
if [ "$exit_code" != "0" ]; then
|
|
||||||
_err "error Deleting $zone TXT: $txt_value"
|
|
||||||
_err "Error $exit_code"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if _contains "$erg" "Success"; then
|
|
||||||
_info "Success, TXT removed, OK"
|
|
||||||
else
|
|
||||||
_err "error Auto $zone TXT: $txt_value erg: $erg"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
_debug "ok Auto $zone TXT: $txt_value erg: $erg"
|
|
||||||
return 0
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -5,8 +5,11 @@
|
|||||||
# Author: github: @diseq
|
# Author: github: @diseq
|
||||||
# Created: 2019-02-17
|
# Created: 2019-02-17
|
||||||
# Fixed by: @der-berni
|
# Fixed by: @der-berni
|
||||||
# Modified: 2019-05-31
|
# Modified: 2020-04-07
|
||||||
#
|
#
|
||||||
|
# Use ONECOM_KeepCnameProxy to keep the CNAME DNS record
|
||||||
|
# export ONECOM_KeepCnameProxy="1"
|
||||||
|
#
|
||||||
# export ONECOM_User="username"
|
# export ONECOM_User="username"
|
||||||
# export ONECOM_Password="password"
|
# export ONECOM_Password="password"
|
||||||
#
|
#
|
||||||
@ -30,32 +33,45 @@ dns_one_add() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mysubdomain=$_sub_domain
|
subdomain="${_sub_domain}"
|
||||||
mydomain=$_domain
|
maindomain=${_domain}
|
||||||
_debug mysubdomain "$mysubdomain"
|
|
||||||
_debug mydomain "$mydomain"
|
|
||||||
|
|
||||||
# get entries
|
useProxy=0
|
||||||
response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")"
|
if [ "${_sub_domain}" = "_acme-challenge" ]; then
|
||||||
_debug response "$response"
|
subdomain="proxy${_sub_domain}"
|
||||||
|
useProxy=1
|
||||||
|
fi
|
||||||
|
|
||||||
# Update the IP address for domain entry
|
_debug subdomain "$subdomain"
|
||||||
postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}"
|
_debug maindomain "$maindomain"
|
||||||
_debug postdata "$postdata"
|
|
||||||
response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records" "" "POST" "application/json")"
|
|
||||||
response="$(echo "$response" | _normalizeJson)"
|
|
||||||
_debug response "$response"
|
|
||||||
|
|
||||||
id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p")
|
if [ $useProxy -eq 1 ]; then
|
||||||
|
#Check if the CNAME exists
|
||||||
|
_dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain"
|
||||||
|
if [ -z "$id" ]; then
|
||||||
|
_info "$(__red "Add CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")"
|
||||||
|
_dns_one_addrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain"
|
||||||
|
|
||||||
if [ -z "$id" ]; then
|
_info "Not valid yet, let's wait 1 hour to take effect."
|
||||||
_err "Add txt record error."
|
_sleep 3600
|
||||||
return 1
|
fi
|
||||||
else
|
fi
|
||||||
_info "Added, OK ($id)"
|
|
||||||
|
#Check if the TXT exists
|
||||||
|
_dns_one_getrecord "TXT" "$subdomain" "$txtvalue"
|
||||||
|
if [ -n "$id" ]; then
|
||||||
|
_info "$(__green "Txt record with the same value found. Skip adding.")"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
_dns_one_addrecord "TXT" "$subdomain" "$txtvalue"
|
||||||
|
if [ -z "$id" ]; then
|
||||||
|
_err "Add TXT record error."
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
_info "$(__green "Added, OK ($id)")"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_one_rm() {
|
dns_one_rm() {
|
||||||
@ -73,36 +89,45 @@ dns_one_rm() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mysubdomain=$_sub_domain
|
subdomain="${_sub_domain}"
|
||||||
mydomain=$_domain
|
maindomain=${_domain}
|
||||||
_debug mysubdomain "$mysubdomain"
|
|
||||||
_debug mydomain "$mydomain"
|
|
||||||
|
|
||||||
# get entries
|
useProxy=0
|
||||||
response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")"
|
if [ "${_sub_domain}" = "_acme-challenge" ]; then
|
||||||
response="$(echo "$response" | _normalizeJson)"
|
subdomain="proxy${_sub_domain}"
|
||||||
_debug response "$response"
|
useProxy=1
|
||||||
|
fi
|
||||||
|
|
||||||
id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}.*/\1/p")
|
_debug subdomain "$subdomain"
|
||||||
|
_debug maindomain "$maindomain"
|
||||||
|
if [ $useProxy -eq 1 ]; then
|
||||||
|
if [ "$ONECOM_KeepCnameProxy" = "1" ]; then
|
||||||
|
_info "$(__red "Keeping CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")"
|
||||||
|
else
|
||||||
|
#Check if the CNAME exists
|
||||||
|
_dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain"
|
||||||
|
if [ -n "$id" ]; then
|
||||||
|
_info "$(__red "Removing CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")"
|
||||||
|
_dns_one_delrecord "$id"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Check if the TXT exists
|
||||||
|
_dns_one_getrecord "TXT" "$subdomain" "$txtvalue"
|
||||||
if [ -z "$id" ]; then
|
if [ -z "$id" ]; then
|
||||||
_err "Txt record not found."
|
_err "Txt record not found."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# delete entry
|
# delete entry
|
||||||
response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records/$id" "" "DELETE" "application/json")"
|
if _dns_one_delrecord "$id"; then
|
||||||
response="$(echo "$response" | _normalizeJson)"
|
_info "$(__green Removed, OK)"
|
||||||
_debug response "$response"
|
|
||||||
|
|
||||||
if [ "$response" = '{"result":null,"metadata":null}' ]; then
|
|
||||||
_info "Removed, OK"
|
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
_err "Removing txt record error."
|
_err "Removing txt record error."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#_acme-challenge.www.domain.com
|
#_acme-challenge.www.domain.com
|
||||||
@ -138,6 +163,8 @@ _get_root() {
|
|||||||
_dns_one_login() {
|
_dns_one_login() {
|
||||||
|
|
||||||
# get credentials
|
# get credentials
|
||||||
|
ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-$(_readaccountconf_mutable ONECOM_KeepCnameProxy)}"
|
||||||
|
ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-0}"
|
||||||
ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}"
|
ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}"
|
||||||
ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}"
|
ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}"
|
||||||
if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then
|
if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then
|
||||||
@ -149,6 +176,7 @@ _dns_one_login() {
|
|||||||
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 ONECOM_KeepCnameProxy "$ONECOM_KeepCnameProxy"
|
||||||
_saveaccountconf_mutable ONECOM_User "$ONECOM_User"
|
_saveaccountconf_mutable ONECOM_User "$ONECOM_User"
|
||||||
_saveaccountconf_mutable ONECOM_Password "$ONECOM_Password"
|
_saveaccountconf_mutable ONECOM_Password "$ONECOM_Password"
|
||||||
|
|
||||||
@ -177,3 +205,75 @@ _dns_one_login() {
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_dns_one_getrecord() {
|
||||||
|
type="$1"
|
||||||
|
name="$2"
|
||||||
|
value="$3"
|
||||||
|
if [ -z "$type" ]; then
|
||||||
|
type="TXT"
|
||||||
|
fi
|
||||||
|
if [ -z "$name" ]; then
|
||||||
|
_err "Record name is empty."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
response="$(_get "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records")"
|
||||||
|
response="$(echo "$response" | _normalizeJson)"
|
||||||
|
_debug response "$response"
|
||||||
|
|
||||||
|
if [ -z "${value}" ]; then
|
||||||
|
id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"[^\"]*\",\"priority\":0,\"ttl\":600}.*/\1/p")
|
||||||
|
response=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"[^\"]*\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"\([^\"]*\)\",\"priority\":0,\"ttl\":600}.*/\1/p")
|
||||||
|
else
|
||||||
|
id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"${value}\",\"priority\":0,\"ttl\":600}.*/\1/p")
|
||||||
|
fi
|
||||||
|
if [ -z "$id" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_dns_one_addrecord() {
|
||||||
|
type="$1"
|
||||||
|
name="$2"
|
||||||
|
value="$3"
|
||||||
|
if [ -z "$type" ]; then
|
||||||
|
type="TXT"
|
||||||
|
fi
|
||||||
|
if [ -z "$name" ]; then
|
||||||
|
_err "Record name is empty."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"${type}\",\"prefix\":\"${name}\",\"content\":\"${value}\"}}"
|
||||||
|
_debug postdata "$postdata"
|
||||||
|
response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records" "" "POST" "application/json")"
|
||||||
|
response="$(echo "$response" | _normalizeJson)"
|
||||||
|
_debug response "$response"
|
||||||
|
|
||||||
|
id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$subdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p")
|
||||||
|
|
||||||
|
if [ -z "$id" ]; then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_dns_one_delrecord() {
|
||||||
|
id="$1"
|
||||||
|
if [ -z "$id" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
response="$(_post "" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records/$id" "" "DELETE" "application/json")"
|
||||||
|
response="$(echo "$response" | _normalizeJson)"
|
||||||
|
_debug response "$response"
|
||||||
|
|
||||||
|
if [ "$response" = '{"result":null,"metadata":null}' ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|||||||
@ -1,277 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
#OPNsense Bind API
|
|
||||||
#https://docs.opnsense.org/development/api.html
|
|
||||||
#
|
|
||||||
#OPNs_Host="opnsense.example.com"
|
|
||||||
#OPNs_Port="443"
|
|
||||||
# optional, defaults to 443 if unset
|
|
||||||
#OPNs_Key="qocfU9RSbt8vTIBcnW8bPqCrpfAHMDvj5OzadE7Str+rbjyCyk7u6yMrSCHtBXabgDDXx/dY0POUp7ZA"
|
|
||||||
#OPNs_Token="pZEQ+3ce8dDlfBBdg3N8EpqpF5I1MhFqdxX06le6Gl8YzyQvYCfCzNaFX9O9+IOSyAs7X71fwdRiZ+Lv"
|
|
||||||
#OPNs_Api_Insecure=0
|
|
||||||
# optional, defaults to 0 if unset
|
|
||||||
# Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1)
|
|
||||||
|
|
||||||
######## Public functions #####################
|
|
||||||
#Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000"
|
|
||||||
#fulldomain
|
|
||||||
#txtvalue
|
|
||||||
OPNs_DefaultPort=443
|
|
||||||
OPNs_DefaultApi_Insecure=0
|
|
||||||
|
|
||||||
dns_opnsense_add() {
|
|
||||||
fulldomain=$1
|
|
||||||
txtvalue=$2
|
|
||||||
|
|
||||||
_opns_check_auth || return 1
|
|
||||||
|
|
||||||
if ! set_record "$fulldomain" "$txtvalue"; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
#fulldomain
|
|
||||||
dns_opnsense_rm() {
|
|
||||||
fulldomain=$1
|
|
||||||
txtvalue=$2
|
|
||||||
|
|
||||||
_opns_check_auth || return 1
|
|
||||||
|
|
||||||
if ! rm_record "$fulldomain" "$txtvalue"; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
set_record() {
|
|
||||||
fulldomain=$1
|
|
||||||
new_challenge=$2
|
|
||||||
_info "Adding record $fulldomain with challenge: $new_challenge"
|
|
||||||
|
|
||||||
_debug "Detect root zone"
|
|
||||||
if ! _get_root "$fulldomain"; then
|
|
||||||
_err "invalid domain"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
_debug _domain "$_domain"
|
|
||||||
_debug _host "$_host"
|
|
||||||
_debug _domainid "$_domainid"
|
|
||||||
_return_str=""
|
|
||||||
_record_string=""
|
|
||||||
_build_record_string "$_domainid" "$_host" "$new_challenge"
|
|
||||||
_uuid=""
|
|
||||||
if _existingchallenge "$_domain" "$_host" "$new_challenge"; then
|
|
||||||
# Update
|
|
||||||
if _opns_rest "POST" "/record/setRecord/${_uuid}" "$_record_string"; then
|
|
||||||
_return_str="$response"
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
#create
|
|
||||||
if _opns_rest "POST" "/record/addRecord" "$_record_string"; then
|
|
||||||
_return_str="$response"
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if echo "$_return_str" | _egrep_o "\"result\":\"saved\"" >/dev/null; then
|
|
||||||
_opns_rest "POST" "/service/reconfigure" "{}"
|
|
||||||
_debug "Record created"
|
|
||||||
else
|
|
||||||
_err "Error creating record $_record_string"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
rm_record() {
|
|
||||||
fulldomain=$1
|
|
||||||
new_challenge="$2"
|
|
||||||
_info "Remove record $fulldomain with challenge: $new_challenge"
|
|
||||||
|
|
||||||
_debug "Detect root zone"
|
|
||||||
if ! _get_root "$fulldomain"; then
|
|
||||||
_err "invalid domain"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
_debug _domain "$_domain"
|
|
||||||
_debug _host "$_host"
|
|
||||||
_debug _domainid "$_domainid"
|
|
||||||
_uuid=""
|
|
||||||
if _existingchallenge "$_domain" "$_host" "$new_challenge"; then
|
|
||||||
# Delete
|
|
||||||
if _opns_rest "POST" "/record/delRecord/${_uuid}" "\{\}"; then
|
|
||||||
if echo "$_return_str" | _egrep_o "\"result\":\"deleted\"" >/dev/null; then
|
|
||||||
_opns_rest "POST" "/service/reconfigure" "{}"
|
|
||||||
_debug "Record deleted"
|
|
||||||
else
|
|
||||||
_err "Error deleting record $_host from domain $fulldomain"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
_err "Error deleting record $_host from domain $fulldomain"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
_info "Record not found, nothing to remove"
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
#################### Private functions below ##################################
|
|
||||||
#_acme-challenge.www.domain.com
|
|
||||||
#returns
|
|
||||||
# _domainid=domid
|
|
||||||
#_domain=domain.com
|
|
||||||
_get_root() {
|
|
||||||
domain=$1
|
|
||||||
i=2
|
|
||||||
p=1
|
|
||||||
if _opns_rest "GET" "/domain/get"; then
|
|
||||||
_domain_response="$response"
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
|
||||||
if [ -z "$h" ]; then
|
|
||||||
#not valid
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
_debug h "$h"
|
|
||||||
<<<<<<< HEAD
|
|
||||||
id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2)
|
|
||||||
=======
|
|
||||||
id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\"(,\"allownotifyslave\":{\"\":{[^}]*}},|,)\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2)
|
|
||||||
>>>>>>> Allow old and new API response
|
|
||||||
|
|
||||||
if [ -n "$id" ]; then
|
|
||||||
_debug id "$id"
|
|
||||||
_host=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
|
||||||
_domain="${h}"
|
|
||||||
_domainid="${id}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
p=$i
|
|
||||||
i=$(_math $i + 1)
|
|
||||||
done
|
|
||||||
_debug "$domain not found"
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
_opns_rest() {
|
|
||||||
method=$1
|
|
||||||
ep=$2
|
|
||||||
data=$3
|
|
||||||
#Percent encode user and token
|
|
||||||
key=$(echo "$OPNs_Key" | tr -d "\n\r" | _url_encode)
|
|
||||||
token=$(echo "$OPNs_Token" | tr -d "\n\r" | _url_encode)
|
|
||||||
|
|
||||||
opnsense_url="https://${key}:${token}@${OPNs_Host}:${OPNs_Port:-$OPNs_DefaultPort}/api/bind${ep}"
|
|
||||||
export _H1="Content-Type: application/json"
|
|
||||||
_debug2 "Try to call api: https://${OPNs_Host}:${OPNs_Port:-$OPNs_DefaultPort}/api/bind${ep}"
|
|
||||||
if [ ! "$method" = "GET" ]; then
|
|
||||||
_debug data "$data"
|
|
||||||
export _H1="Content-Type: application/json"
|
|
||||||
response="$(_post "$data" "$opnsense_url" "" "$method")"
|
|
||||||
else
|
|
||||||
export _H1=""
|
|
||||||
response="$(_get "$opnsense_url")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$?" != "0" ]; then
|
|
||||||
_err "error $ep"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
_debug2 response "$response"
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
_build_record_string() {
|
|
||||||
_record_string="{\"record\":{\"enabled\":\"1\",\"domain\":\"$1\",\"name\":\"$2\",\"type\":\"TXT\",\"value\":\"$3\"}}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_existingchallenge() {
|
|
||||||
if _opns_rest "GET" "/record/searchRecord"; then
|
|
||||||
_record_response="$response"
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
_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)
|
|
||||||
|
|
||||||
if [ -n "$_uuid" ]; then
|
|
||||||
_debug uuid "$_uuid"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
_debug "${2}.$1{1} record not found"
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
_opns_check_auth() {
|
|
||||||
OPNs_Host="${OPNs_Host:-$(_readaccountconf_mutable OPNs_Host)}"
|
|
||||||
OPNs_Port="${OPNs_Port:-$(_readaccountconf_mutable OPNs_Port)}"
|
|
||||||
OPNs_Key="${OPNs_Key:-$(_readaccountconf_mutable OPNs_Key)}"
|
|
||||||
OPNs_Token="${OPNs_Token:-$(_readaccountconf_mutable OPNs_Token)}"
|
|
||||||
OPNs_Api_Insecure="${OPNs_Api_Insecure:-$(_readaccountconf_mutable OPNs_Api_Insecure)}"
|
|
||||||
|
|
||||||
if [ -z "$OPNs_Host" ]; then
|
|
||||||
_err "You don't specify OPNsense address."
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
_saveaccountconf_mutable OPNs_Host "$OPNs_Host"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! printf '%s' "$OPNs_Port" | grep '^[0-9]*$' >/dev/null; then
|
|
||||||
_err 'OPNs_Port specified but not numeric value'
|
|
||||||
return 1
|
|
||||||
elif [ -z "$OPNs_Port" ]; then
|
|
||||||
_info "OPNSense port not specified. Defaulting to using port $OPNs_DefaultPort"
|
|
||||||
else
|
|
||||||
_saveaccountconf_mutable OPNs_Port "$OPNs_Port"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! printf '%s' "$OPNs_Api_Insecure" | grep '^[01]$' >/dev/null; then
|
|
||||||
_err 'OPNs_Api_Insecure specified but not 0/1 value'
|
|
||||||
return 1
|
|
||||||
elif [ -n "$OPNs_Api_Insecure" ]; then
|
|
||||||
_saveaccountconf_mutable OPNs_Api_Insecure "$OPNs_Api_Insecure"
|
|
||||||
fi
|
|
||||||
export HTTPS_INSECURE="${OPNs_Api_Insecure:-$OPNs_DefaultApi_Insecure}"
|
|
||||||
|
|
||||||
if [ -z "$OPNs_Key" ]; then
|
|
||||||
_err "you have not specified your OPNsense api key id."
|
|
||||||
_err "Please set OPNs_Key and try again."
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
_saveaccountconf_mutable OPNs_Key "$OPNs_Key"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$OPNs_Token" ]; then
|
|
||||||
_err "you have not specified your OPNsense token."
|
|
||||||
_err "Please create OPNs_Token and try again."
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
_saveaccountconf_mutable OPNs_Token "$OPNs_Token"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! _opns_rest "GET" "/general/get"; then
|
|
||||||
_err "Call to OPNsense API interface failed. Unable to access OPNsense API."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
@ -6,6 +6,7 @@
|
|||||||
#MAIL_FROM="yyyy@gmail.com"
|
#MAIL_FROM="yyyy@gmail.com"
|
||||||
#MAIL_TO="yyyy@gmail.com"
|
#MAIL_TO="yyyy@gmail.com"
|
||||||
#MAIL_NOVALIDATE=""
|
#MAIL_NOVALIDATE=""
|
||||||
|
#MAIL_MSMTP_ACCOUNT=""
|
||||||
|
|
||||||
mail_send() {
|
mail_send() {
|
||||||
_subject="$1"
|
_subject="$1"
|
||||||
@ -76,18 +77,17 @@ mail_send() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_mail_bin() {
|
_mail_bin() {
|
||||||
if [ -n "$MAIL_BIN" ]; then
|
_MAIL_BIN=""
|
||||||
_MAIL_BIN="$MAIL_BIN"
|
|
||||||
elif _exists "sendmail"; then
|
for b in "$MAIL_BIN" sendmail ssmtp mutt mail msmtp; do
|
||||||
_MAIL_BIN="sendmail"
|
if _exists "$b"; then
|
||||||
elif _exists "ssmtp"; then
|
_MAIL_BIN="$b"
|
||||||
_MAIL_BIN="ssmtp"
|
break
|
||||||
elif _exists "mutt"; then
|
fi
|
||||||
_MAIL_BIN="mutt"
|
done
|
||||||
elif _exists "mail"; then
|
|
||||||
_MAIL_BIN="mail"
|
if [ -z "$_MAIL_BIN" ]; then
|
||||||
else
|
_err "Please install sendmail, ssmtp, mutt, mail or msmtp first."
|
||||||
_err "Please install sendmail, ssmtp, mutt or mail first."
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -95,30 +95,35 @@ _mail_bin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_mail_cmnd() {
|
_mail_cmnd() {
|
||||||
|
_MAIL_ARGS=""
|
||||||
|
|
||||||
case $(basename "$_MAIL_BIN") in
|
case $(basename "$_MAIL_BIN") in
|
||||||
sendmail)
|
sendmail)
|
||||||
if [ -n "$MAIL_FROM" ]; then
|
if [ -n "$MAIL_FROM" ]; then
|
||||||
echo "'$_MAIL_BIN' -f '$MAIL_FROM' '$MAIL_TO'"
|
_MAIL_ARGS="-f '$MAIL_FROM'"
|
||||||
else
|
|
||||||
echo "'$_MAIL_BIN' '$MAIL_TO'"
|
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
ssmtp)
|
|
||||||
echo "'$_MAIL_BIN' '$MAIL_TO'"
|
|
||||||
;;
|
|
||||||
mutt | mail)
|
mutt | mail)
|
||||||
echo "'$_MAIL_BIN' -s '$_subject' '$MAIL_TO'"
|
_MAIL_ARGS="-s '$_subject'"
|
||||||
;;
|
;;
|
||||||
*)
|
msmtp)
|
||||||
_err "Command $MAIL_BIN is not supported, use sendmail, ssmtp, mutt or mail."
|
if [ -n "$MAIL_FROM" ]; then
|
||||||
return 1
|
_MAIL_ARGS="-f '$MAIL_FROM'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$MAIL_MSMTP_ACCOUNT" ]; then
|
||||||
|
_MAIL_ARGS="$_MAIL_ARGS -a '$MAIL_MSMTP_ACCOUNT'"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
|
*) ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
echo "'$_MAIL_BIN' $_MAIL_ARGS '$MAIL_TO'"
|
||||||
}
|
}
|
||||||
|
|
||||||
_mail_body() {
|
_mail_body() {
|
||||||
case $(basename "$_MAIL_BIN") in
|
case $(basename "$_MAIL_BIN") in
|
||||||
sendmail | ssmtp)
|
sendmail | ssmtp | msmtp)
|
||||||
if [ -n "$MAIL_FROM" ]; then
|
if [ -n "$MAIL_FROM" ]; then
|
||||||
echo "From: $MAIL_FROM"
|
echo "From: $MAIL_FROM"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user