Merge branch 'Neilpang-dev' into Sp1l/CF-configurable
This commit is contained in:
commit
61574c2954
4
.github/ISSUE_TEMPLATE.md
vendored
4
.github/ISSUE_TEMPLATE.md
vendored
@ -1,5 +1,7 @@
|
||||
<!--
|
||||
请确保已经更新到最新的代码, 然后贴上来 `--debug 2` 的调试输出. 没有调试输出,我帮不了你.
|
||||
我很忙, 每天可能只有 几秒钟 时间看你的 issue, 如果不按照我的要求写 issue, 你可能不会得到任何回复, 石沉大海.
|
||||
|
||||
请确保已经更新到最新的代码, 然后贴上来 `--debug 2` 的调试输出. 没有调试信息. 我做不了什么.
|
||||
如何调试 https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh
|
||||
|
||||
If it is a bug report:
|
||||
|
||||
8
.github/PULL_REQUEST_TEMPLATE.md
vendored
8
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,9 +1,9 @@
|
||||
<!--
|
||||
|
||||
Do NOT send pull request to `master` branch.
|
||||
|
||||
1. Do NOT send pull request to `master` branch.
|
||||
Please send to `dev` branch instead.
|
||||
|
||||
Any PR to `master` branch will NOT be merged.
|
||||
|
||||
2. For dns api support, read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
|
||||
You will NOT get any review without passing this guide. You also need to fix the CI errors.
|
||||
|
||||
-->
|
||||
@ -1,4 +1,4 @@
|
||||
FROM alpine:3.9
|
||||
FROM alpine:3.10
|
||||
|
||||
RUN apk update -f \
|
||||
&& apk --no-cache add -f \
|
||||
@ -8,6 +8,8 @@ RUN apk update -f \
|
||||
curl \
|
||||
socat \
|
||||
tzdata \
|
||||
oath-toolkit-oathtool \
|
||||
tar \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
ENV LE_CONFIG_HOME /acme.sh
|
||||
|
||||
170
acme.sh
170
acme.sh
@ -2078,6 +2078,28 @@ _readdomainconf() {
|
||||
_read_conf "$DOMAIN_CONF" "$1"
|
||||
}
|
||||
|
||||
#key value base64encode
|
||||
_savedeployconf() {
|
||||
_savedomainconf "SAVED_$1" "$2" "$3"
|
||||
#remove later
|
||||
_cleardomainconf "$1"
|
||||
}
|
||||
|
||||
#key
|
||||
_getdeployconf() {
|
||||
_rac_key="$1"
|
||||
_rac_value="$(eval echo \$"$_rac_key")"
|
||||
if [ "$_rac_value" ]; then
|
||||
if _startswith "$_rac_value" '"' && _endswith "$_rac_value" '"'; then
|
||||
_debug2 "trim quotation marks"
|
||||
eval "export $_rac_key=$_rac_value"
|
||||
fi
|
||||
return 0 # do nothing
|
||||
fi
|
||||
_saved=$(_readdomainconf "SAVED_$_rac_key")
|
||||
eval "export $_rac_key=$_saved"
|
||||
}
|
||||
|
||||
#_saveaccountconf key value base64encode
|
||||
_saveaccountconf() {
|
||||
_save_conf "$ACCOUNT_CONF_PATH" "$@"
|
||||
@ -2428,7 +2450,7 @@ _initpath() {
|
||||
. "$ACCOUNT_CONF_PATH"
|
||||
fi
|
||||
|
||||
if [ "$IN_CRON" ]; then
|
||||
if [ "$ACME_IN_CRON" ]; then
|
||||
if [ ! "$_USER_PATH_EXPORTED" ]; then
|
||||
_USER_PATH_EXPORTED=1
|
||||
export PATH="$USER_PATH:$PATH"
|
||||
@ -3013,11 +3035,13 @@ _clearupdns() {
|
||||
d=$(_getfield "$entry" 1)
|
||||
txtdomain=$(_getfield "$entry" 2)
|
||||
aliasDomain=$(_getfield "$entry" 3)
|
||||
_currentRoot=$(_getfield "$entry" 4)
|
||||
txt=$(_getfield "$entry" 5)
|
||||
d_api=$(_getfield "$entry" 6)
|
||||
_debug "d" "$d"
|
||||
_debug "txtdomain" "$txtdomain"
|
||||
_debug "aliasDomain" "$aliasDomain"
|
||||
_debug "_currentRoot" "$_currentRoot"
|
||||
_debug "txt" "$txt"
|
||||
_debug "d_api" "$d_api"
|
||||
if [ "$d_api" = "$txt" ]; then
|
||||
@ -3194,14 +3218,6 @@ _on_issue_err() {
|
||||
_err "See: $_DEBUG_WIKI"
|
||||
fi
|
||||
|
||||
if [ "$IN_CRON" ]; then
|
||||
if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_ERROR ]; then
|
||||
if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then
|
||||
_send_notify "Renew $_main_domain error" "There is an error." "$NOTIFY_HOOK" 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
#run the post hook
|
||||
if [ "$_chk_post_hook" ]; then
|
||||
_info "Run post hook:'$_chk_post_hook'"
|
||||
@ -3244,13 +3260,7 @@ _on_issue_success() {
|
||||
_chk_post_hook="$1"
|
||||
_chk_renew_hook="$2"
|
||||
_debug _on_issue_success
|
||||
if [ "$IN_CRON" ]; then
|
||||
if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_RENEW ]; then
|
||||
if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then
|
||||
_send_notify "Renew $_main_domain success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
#run the post hook
|
||||
if [ "$_chk_post_hook" ]; then
|
||||
_info "Run post hook:'$_chk_post_hook'"
|
||||
@ -3620,7 +3630,7 @@ _ns_purge_cf() {
|
||||
if [ "$CLOUDFLARE_DNSPURGE_URL" ]; then
|
||||
_cf_purl="$CLOUDFLARE_DNSPURGE_URL?domain=$_cf_d&type=$_cf_d_type"
|
||||
else
|
||||
_cf_purl="https://one.one.one.one/api/v1/purge?domain=$_cf_d&type=$_cf_d_type"
|
||||
_cf_purl="https://1.0.0.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type"
|
||||
fi
|
||||
response="$(_post "" "$_cf_purl")"
|
||||
_debug2 response "$response"
|
||||
@ -3849,7 +3859,7 @@ issue() {
|
||||
_savedomainconf "Le_Keylength" "$_key_length"
|
||||
|
||||
vlist="$Le_Vlist"
|
||||
|
||||
_cleardomainconf "Le_Vlist"
|
||||
_info "Getting domain auth token for each domain"
|
||||
sep='#'
|
||||
dvsep=','
|
||||
@ -4492,14 +4502,12 @@ $_authorizations_map"
|
||||
_info "Your cert key is in $(__green " $CERT_KEY_PATH ")"
|
||||
fi
|
||||
|
||||
if [ ! "$USER_PATH" ] || [ ! "$IN_CRON" ]; then
|
||||
if [ ! "$USER_PATH" ] || [ ! "$ACME_IN_CRON" ]; then
|
||||
USER_PATH="$PATH"
|
||||
_saveaccountconf "USER_PATH" "$USER_PATH"
|
||||
fi
|
||||
fi
|
||||
|
||||
_cleardomainconf "Le_Vlist"
|
||||
|
||||
if [ "$ACME_VERSION" = "2" ]; then
|
||||
_debug "v2 chain."
|
||||
else
|
||||
@ -4674,19 +4682,10 @@ renew() {
|
||||
if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then
|
||||
_info "Skip, Next renewal time is: $(__green "$Le_NextRenewTimeStr")"
|
||||
_info "Add '$(__red '--force')' to force to renew."
|
||||
|
||||
if [ "$IN_CRON" = "1" ]; then
|
||||
if [ "$NOTIFY_LEVEL" ] && [ $NOTIFY_LEVEL -ge $NOTIFY_LEVEL_SKIP ]; then
|
||||
if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then
|
||||
_send_notify "Renew $Le_Domain skipped" "Good, the cert next renewal time is $Le_NextRenewTimeStr." "$NOTIFY_HOOK" "$RENEW_SKIP"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
return "$RENEW_SKIP"
|
||||
fi
|
||||
|
||||
if [ "$IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then
|
||||
if [ "$ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then
|
||||
_info "Skip invalid cert for: $Le_Domain"
|
||||
return $RENEW_SKIP
|
||||
fi
|
||||
@ -4721,6 +4720,10 @@ renewAll() {
|
||||
_success_msg=""
|
||||
_error_msg=""
|
||||
_skipped_msg=""
|
||||
_error_level=$NOTIFY_LEVEL_SKIP
|
||||
_notify_code=$RENEW_SKIP
|
||||
_set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT}
|
||||
_debug "_set_level" "$_set_level"
|
||||
for di in "${CERT_HOME}"/*.*/; do
|
||||
_debug di "$di"
|
||||
if ! [ -d "$di" ]; then
|
||||
@ -4738,49 +4741,84 @@ renewAll() {
|
||||
)
|
||||
rc="$?"
|
||||
_debug "Return code: $rc"
|
||||
if [ "$rc" != "0" ]; then
|
||||
if [ "$rc" = "$RENEW_SKIP" ]; then
|
||||
_info "Skipped $d"
|
||||
_skipped_msg="${_skipped_msg} $d
|
||||
"
|
||||
else
|
||||
_error_msg="${_error_msg} $d
|
||||
"
|
||||
if [ "$_stopRenewOnError" ]; then
|
||||
_err "Error renew $d, stop now."
|
||||
_ret="$rc"
|
||||
break
|
||||
else
|
||||
_ret="$rc"
|
||||
_err "Error renew $d."
|
||||
if [ "$rc" = "0" ]; then
|
||||
if [ $_error_level -gt $NOTIFY_LEVEL_RENEW ]; then
|
||||
_error_level="$NOTIFY_LEVEL_RENEW"
|
||||
_notify_code=0
|
||||
fi
|
||||
if [ "$ACME_IN_CRON" ]; then
|
||||
if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then
|
||||
if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then
|
||||
_send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
_success_msg="${_success_msg} $d
|
||||
"
|
||||
elif [ "$rc" = "$RENEW_SKIP" ]; then
|
||||
if [ $_error_level -gt $NOTIFY_LEVEL_SKIP ]; then
|
||||
_error_level="$NOTIFY_LEVEL_SKIP"
|
||||
_notify_code=$RENEW_SKIP
|
||||
fi
|
||||
if [ "$ACME_IN_CRON" ]; then
|
||||
if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then
|
||||
if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then
|
||||
_send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
_info "Skipped $d"
|
||||
_skipped_msg="${_skipped_msg} $d
|
||||
"
|
||||
else
|
||||
if [ $_error_level -gt $NOTIFY_LEVEL_ERROR ]; then
|
||||
_error_level="$NOTIFY_LEVEL_ERROR"
|
||||
_notify_code=1
|
||||
fi
|
||||
if [ "$ACME_IN_CRON" ]; then
|
||||
if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then
|
||||
if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then
|
||||
_send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
_error_msg="${_error_msg} $d
|
||||
"
|
||||
if [ "$_stopRenewOnError" ]; then
|
||||
_err "Error renew $d, stop now."
|
||||
_ret="$rc"
|
||||
break
|
||||
else
|
||||
_ret="$rc"
|
||||
_err "Error renew $d."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$IN_CRON" = "1" ]; then
|
||||
_debug _error_level "$_error_level"
|
||||
_debug _set_level "$_set_level"
|
||||
if [ "$ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then
|
||||
if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then
|
||||
_msg_subject="Renew"
|
||||
if [ "$_error_msg" ]; then
|
||||
_msg_subject="${_msg_subject} Error"
|
||||
_msg_data="Error certs:
|
||||
${_error_msg}
|
||||
"
|
||||
fi
|
||||
if [ "$_success_msg" ]; then
|
||||
_msg_subject="${_msg_subject} Success"
|
||||
_msg_data="${_msg_data}Success certs:
|
||||
${_success_msg}
|
||||
"
|
||||
fi
|
||||
if [ "$_skipped_msg" ]; then
|
||||
_msg_subject="${_msg_subject} Skipped"
|
||||
fi
|
||||
_msg_data="Error certs:
|
||||
${_error_msg}
|
||||
Success certs:
|
||||
${_success_msg}
|
||||
Skipped certs:
|
||||
$_skipped_msg
|
||||
_msg_data="${_msg_data}Skipped certs:
|
||||
${_skipped_msg}
|
||||
"
|
||||
_send_notify "$_msg_subject" "$_msg_data" "$NOTIFY_HOOK" 0
|
||||
fi
|
||||
|
||||
_send_notify "$_msg_subject" "$_msg_data" "$NOTIFY_HOOK" "$_notify_code"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -5696,7 +5734,7 @@ install() {
|
||||
_debug "Skip install cron job"
|
||||
fi
|
||||
|
||||
if [ "$IN_CRON" != "1" ]; then
|
||||
if [ "$ACME_IN_CRON" != "1" ]; then
|
||||
if ! _precheck "$_nocron"; then
|
||||
_err "Pre-check failed, can not install."
|
||||
return 1
|
||||
@ -5753,7 +5791,7 @@ install() {
|
||||
|
||||
_info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY"
|
||||
|
||||
if [ "$IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then
|
||||
if [ "$ACME_IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then
|
||||
_installalias "$_c_home"
|
||||
fi
|
||||
|
||||
@ -5851,7 +5889,7 @@ _uninstallalias() {
|
||||
}
|
||||
|
||||
cron() {
|
||||
export IN_CRON=1
|
||||
export ACME_IN_CRON=1
|
||||
_initpath
|
||||
_info "$(__green "===Starting cron===")"
|
||||
if [ "$AUTO_UPGRADE" = "1" ]; then
|
||||
@ -5872,7 +5910,7 @@ cron() {
|
||||
fi
|
||||
renewAll
|
||||
_ret="$?"
|
||||
IN_CRON=""
|
||||
ACME_IN_CRON=""
|
||||
_info "$(__green "===End cron===")"
|
||||
exit $_ret
|
||||
}
|
||||
@ -6094,11 +6132,11 @@ Parameters:
|
||||
|
||||
--notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT.
|
||||
0: disabled, no notification will be sent.
|
||||
1: send notification only when there is an error. No news is good news.
|
||||
2: send notification when a cert is successfully renewed, or there is an error
|
||||
3: send notification when a cert is skipped, renewdd, or error
|
||||
1: send notifications only when there is an error.
|
||||
2: send notifications when a cert is successfully renewed, or there is an error.
|
||||
3: send notifications when a cert is skipped, renewed, or error.
|
||||
--notify-mode 0|1 Set notification mode. Default value is $NOTIFY_MODE_DEFAULT.
|
||||
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.
|
||||
--notify-hook [hookname] Set the notify hook
|
||||
|
||||
@ -6759,7 +6797,7 @@ _process() {
|
||||
_debug "Using server: $_server"
|
||||
fi
|
||||
fi
|
||||
|
||||
_debug "Running cmd: ${_CMD}"
|
||||
case "${_CMD}" in
|
||||
install) install "$_nocron" "$_confighome" "$_noprofile" ;;
|
||||
uninstall) uninstall "$_nocron" ;;
|
||||
|
||||
287
deploy/docker.sh
Executable file
287
deploy/docker.sh
Executable file
@ -0,0 +1,287 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#DEPLOY_DOCKER_CONTAINER_LABEL="xxxxxxx"
|
||||
|
||||
#DEPLOY_DOCKER_CONTAINER_KEY_FILE="/path/to/key.pem"
|
||||
#DEPLOY_DOCKER_CONTAINER_CERT_FILE="/path/to/cert.pem"
|
||||
#DEPLOY_DOCKER_CONTAINER_CA_FILE="/path/to/ca.pem"
|
||||
#DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/path/to/fullchain.pem"
|
||||
#DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload"
|
||||
|
||||
_DEPLOY_DOCKER_WIKI="https://github.com/Neilpang/acme.sh/wiki/deploy-to-docker-containers"
|
||||
|
||||
_DOCKER_HOST_DEFAULT="/var/run/docker.sock"
|
||||
|
||||
docker_deploy() {
|
||||
_cdomain="$1"
|
||||
_ckey="$2"
|
||||
_ccert="$3"
|
||||
_cca="$4"
|
||||
_cfullchain="$5"
|
||||
_debug _cdomain "$_cdomain"
|
||||
_getdeployconf DEPLOY_DOCKER_CONTAINER_LABEL
|
||||
_debug2 DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
|
||||
if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then
|
||||
_err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container."
|
||||
_err "See: $_DEPLOY_DOCKER_WIKI"
|
||||
fi
|
||||
|
||||
_savedeployconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
|
||||
|
||||
if [ "$DOCKER_HOST" ]; then
|
||||
_saveaccountconf DOCKER_HOST "$DOCKER_HOST"
|
||||
fi
|
||||
|
||||
if _exists docker && docker version | grep -i docker >/dev/null; then
|
||||
_info "Using docker command"
|
||||
export _USE_DOCKER_COMMAND=1
|
||||
else
|
||||
export _USE_DOCKER_COMMAND=
|
||||
fi
|
||||
|
||||
export _USE_UNIX_SOCKET=
|
||||
if [ -z "$_USE_DOCKER_COMMAND" ]; then
|
||||
export _USE_REST=
|
||||
if [ "$DOCKER_HOST" ]; then
|
||||
_debug "Try use docker host: $DOCKER_HOST"
|
||||
export _USE_REST=1
|
||||
else
|
||||
export _DOCKER_SOCK="$_DOCKER_HOST_DEFAULT"
|
||||
_debug "Try use $_DOCKER_SOCK"
|
||||
if [ ! -e "$_DOCKER_SOCK" ] || [ ! -w "$_DOCKER_SOCK" ]; then
|
||||
_err "$_DOCKER_SOCK is not available"
|
||||
return 1
|
||||
fi
|
||||
export _USE_UNIX_SOCKET=1
|
||||
if ! _exists "curl"; then
|
||||
_err "Please install curl first."
|
||||
_err "We need curl to work."
|
||||
return 1
|
||||
fi
|
||||
if ! _check_curl_version; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
_getdeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE
|
||||
_debug2 DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
|
||||
_savedeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
|
||||
fi
|
||||
|
||||
_getdeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE
|
||||
_debug2 DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
|
||||
_savedeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
|
||||
fi
|
||||
|
||||
_getdeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE
|
||||
_debug2 DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
|
||||
_savedeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
|
||||
fi
|
||||
|
||||
_getdeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE
|
||||
_debug2 DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
|
||||
_savedeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
|
||||
fi
|
||||
|
||||
_getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD
|
||||
_debug2 DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
|
||||
_savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
|
||||
fi
|
||||
|
||||
_cid="$(_get_id "$DEPLOY_DOCKER_CONTAINER_LABEL")"
|
||||
_info "Container id: $_cid"
|
||||
if [ -z "$_cid" ]; then
|
||||
_err "can not find container id"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
|
||||
if ! _docker_cp "$_cid" "$_ckey" "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
|
||||
if ! _docker_cp "$_cid" "$_ccert" "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
|
||||
if ! _docker_cp "$_cid" "$_cca" "$DEPLOY_DOCKER_CONTAINER_CA_FILE"; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
|
||||
if ! _docker_cp "$_cid" "$_cfullchain" "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
|
||||
_info "Reloading: $DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
|
||||
if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
#label
|
||||
_get_id() {
|
||||
_label="$1"
|
||||
if [ "$_USE_DOCKER_COMMAND" ]; then
|
||||
docker ps -f label="$_label" --format "{{.ID}}"
|
||||
elif [ "$_USE_REST" ]; then
|
||||
_err "Not implemented yet."
|
||||
return 1
|
||||
elif [ "$_USE_UNIX_SOCKET" ]; then
|
||||
_req="{\"label\":[\"$_label\"]}"
|
||||
_debug2 _req "$_req"
|
||||
_req="$(printf "%s" "$_req" | _url_encode)"
|
||||
_debug2 _req "$_req"
|
||||
listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")"
|
||||
_debug2 "listjson" "$listjson"
|
||||
echo "$listjson" | tr '{,' '\n' | grep -i '"id":' | _head_n 1 | cut -d '"' -f 4
|
||||
else
|
||||
_err "Not implemented yet."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#id cmd
|
||||
_docker_exec() {
|
||||
_eargs="$*"
|
||||
_debug2 "_docker_exec $_eargs"
|
||||
_dcid="$1"
|
||||
shift
|
||||
if [ "$_USE_DOCKER_COMMAND" ]; then
|
||||
docker exec -i "$_dcid" sh -c "$*"
|
||||
elif [ "$_USE_REST" ]; then
|
||||
_err "Not implemented yet."
|
||||
return 1
|
||||
elif [ "$_USE_UNIX_SOCKET" ]; then
|
||||
_cmd="$*"
|
||||
#_cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')"
|
||||
_debug2 _cmd "$_cmd"
|
||||
#create exec instance:
|
||||
cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"sh\", \"-c\", \"$_cmd\"]}")"
|
||||
_debug2 cjson "$cjson"
|
||||
execid="$(echo "$cjson" | cut -d '"' -f 4)"
|
||||
_debug execid "$execid"
|
||||
ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")"
|
||||
_debug2 ejson "$ejson"
|
||||
if [ "$ejson" ]; then
|
||||
_err "$ejson"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_err "Not implemented yet."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#id from to
|
||||
_docker_cp() {
|
||||
_dcid="$1"
|
||||
_from="$2"
|
||||
_to="$3"
|
||||
_info "Copying file from $_from to $_to"
|
||||
_dir="$(dirname "$_to")"
|
||||
_debug2 _dir "$_dir"
|
||||
if ! _docker_exec "$_dcid" mkdir -p "$_dir"; then
|
||||
_err "Can not create dir: $_dir"
|
||||
return 1
|
||||
fi
|
||||
if [ "$_USE_DOCKER_COMMAND" ]; then
|
||||
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
|
||||
_docker_exec "$_dcid" tee "$_to" <"$_from"
|
||||
else
|
||||
_docker_exec "$_dcid" tee "$_to" <"$_from" >/dev/null
|
||||
fi
|
||||
if [ "$?" = "0" ]; then
|
||||
_info "Success"
|
||||
return 0
|
||||
else
|
||||
_info "Error"
|
||||
return 1
|
||||
fi
|
||||
elif [ "$_USE_REST" ]; then
|
||||
_err "Not implemented yet."
|
||||
return 1
|
||||
elif [ "$_USE_UNIX_SOCKET" ]; then
|
||||
_frompath="$_from"
|
||||
if _startswith "$_frompath" '/'; then
|
||||
_frompath="$(echo "$_from" | cut -b 2-)" #remove the first '/' char
|
||||
fi
|
||||
_debug2 "_frompath" "$_frompath"
|
||||
_toname="$(basename "$_to")"
|
||||
_debug2 "_toname" "$_toname"
|
||||
_debug2 "_from" "$_from"
|
||||
if ! tar --transform="s,$(printf "%s" "$_frompath" | tr '*' .),$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then
|
||||
_err "copy error"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
_err "Not implemented yet."
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#sock method endpoint data content-type
|
||||
_curl_unix_sock() {
|
||||
_socket="$1"
|
||||
_method="$2"
|
||||
_endpoint="$3"
|
||||
_data="$4"
|
||||
_ctype="$5"
|
||||
if [ -z "$_ctype" ]; then
|
||||
_ctype="Content-Type: application/json"
|
||||
fi
|
||||
_debug _data "$_data"
|
||||
_debug2 "url" "http://localhost$_endpoint"
|
||||
if [ "$_CURL_NO_HOST" ]; then
|
||||
_cux_url="http:$_endpoint"
|
||||
else
|
||||
_cux_url="http://localhost$_endpoint"
|
||||
fi
|
||||
|
||||
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
|
||||
curl -vvv --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url"
|
||||
else
|
||||
curl --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
_check_curl_version() {
|
||||
_cversion="$(curl -V | grep '^curl ' | cut -d ' ' -f 2)"
|
||||
_debug2 "_cversion" "$_cversion"
|
||||
|
||||
_major="$(_getfield "$_cversion" 1 '.')"
|
||||
_debug2 "_major" "$_major"
|
||||
|
||||
_minor="$(_getfield "$_cversion" 2 '.')"
|
||||
_debug2 "_minor" "$_minor"
|
||||
|
||||
if [ "$_major$_minor" -lt "740" ]; then
|
||||
_err "curl v$_cversion doesn't support unit socket"
|
||||
return 1
|
||||
fi
|
||||
if [ "$_major$_minor" -lt "750" ]; then
|
||||
_debug "Use short host name"
|
||||
export _CURL_NO_HOST=1
|
||||
else
|
||||
export _CURL_NO_HOST=
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@ -85,30 +85,27 @@ routeros_deploy() {
|
||||
scp "$_ckey" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.key"
|
||||
_info "Trying to push cert '$_cfullchain' to router"
|
||||
scp "$_cfullchain" "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST:$_cdomain.cer"
|
||||
DEPLOY_SCRIPT_CMD="/system script add name=\"LE Cert Deploy - $_cdomain\" owner=admin policy=ftp,read,write,password,sensitive
|
||||
source=\"## generated by routeros deploy script in acme.sh
|
||||
\n/certificate remove [ find name=$_cdomain.cer_0 ]
|
||||
\n/certificate remove [ find name=$_cdomain.cer_1 ]
|
||||
\ndelay 1
|
||||
\n/certificate import file-name=$_cdomain.cer passphrase=\\\"\\\"
|
||||
\n/certificate import file-name=$_cdomain.key passphrase=\\\"\\\"
|
||||
\ndelay 1
|
||||
\n/file remove $_cdomain.cer
|
||||
\n/file remove $_cdomain.key
|
||||
\ndelay 2
|
||||
\n/ip service set www-ssl certificate=$_cdomain.cer_0
|
||||
\n$ROUTER_OS_ADDITIONAL_SERVICES
|
||||
\n\"
|
||||
"
|
||||
# shellcheck disable=SC2029
|
||||
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" bash -c "'
|
||||
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "$DEPLOY_SCRIPT_CMD"
|
||||
# shellcheck disable=SC2029
|
||||
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script run \"LE Cert Deploy - $_cdomain\""
|
||||
# shellcheck disable=SC2029
|
||||
ssh "$ROUTER_OS_USERNAME@$ROUTER_OS_HOST" "/system script remove \"LE Cert Deploy - $_cdomain\""
|
||||
|
||||
/certificate remove $_cdomain.cer_0
|
||||
|
||||
/certificate remove $_cdomain.cer_1
|
||||
|
||||
delay 1
|
||||
|
||||
/certificate import file-name=$_cdomain.cer passphrase=\"\"
|
||||
|
||||
/certificate import file-name=$_cdomain.key passphrase=\"\"
|
||||
|
||||
delay 1
|
||||
|
||||
/file remove $_cdomain.cer
|
||||
|
||||
/file remove $_cdomain.key
|
||||
|
||||
delay 2
|
||||
|
||||
/ip service set www-ssl certificate=$_cdomain.cer_0
|
||||
$ROUTER_OS_ADDITIONAL_SERVICES
|
||||
|
||||
'"
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -317,7 +317,7 @@ _get_root() {
|
||||
## Per https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits#dns-limits you are limited to 100 Zone/subscriptions anyways
|
||||
##
|
||||
_azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken"
|
||||
# Find matching domain name is Json response
|
||||
# Find matching domain name in Json response
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug2 "Checking domain: $h"
|
||||
@ -328,7 +328,7 @@ _get_root() {
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
|
||||
_domain_id=$(echo "$response" | _egrep_o "\\{\"id\":\"[^\"]*$h\"" | head -n 1 | cut -d : -f 2 | tr -d \")
|
||||
_domain_id=$(echo "$response" | _egrep_o "\\{\"id\":\"[^\"]*\\/$h\"" | head -n 1 | cut -d : -f 2 | tr -d \")
|
||||
if [ "$_domain_id" ]; then
|
||||
if [ "$i" = 1 ]; then
|
||||
#create the record at the domain apex (@) if only the domain name was provided as --domain-alias
|
||||
|
||||
@ -5,6 +5,9 @@
|
||||
#
|
||||
#CF_Email="xxxx@sss.com"
|
||||
|
||||
#CF_Token="xxxx"
|
||||
#CF_Account_ID="xxxx"
|
||||
|
||||
CF_Api="https://api.cloudflare.com/client/v4"
|
||||
|
||||
######## Public functions #####################
|
||||
@ -14,25 +17,32 @@ dns_cf_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}"
|
||||
CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}"
|
||||
CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}"
|
||||
CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}"
|
||||
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
|
||||
CF_Key=""
|
||||
CF_Email=""
|
||||
_err "You didn't specify a Cloudflare api key and email yet."
|
||||
_err "You can get yours from here https://dash.cloudflare.com/profile."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$CF_Email" "@"; then
|
||||
_err "It seems that the CF_Email=$CF_Email is not a valid email address."
|
||||
_err "Please check and retry."
|
||||
return 1
|
||||
fi
|
||||
if [ "$CF_Token" ]; then
|
||||
_saveaccountconf_mutable CF_Token "$CF_Token"
|
||||
_saveaccountconf_mutable CF_Account_ID "$CF_Account_ID"
|
||||
else
|
||||
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
|
||||
CF_Key=""
|
||||
CF_Email=""
|
||||
_err "You didn't specify a Cloudflare api key and email yet."
|
||||
_err "You can get yours from here https://dash.cloudflare.com/profile."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable CF_Key "$CF_Key"
|
||||
_saveaccountconf_mutable CF_Email "$CF_Email"
|
||||
if ! _contains "$CF_Email" "@"; then
|
||||
_err "It seems that the CF_Email=$CF_Email is not a valid email address."
|
||||
_err "Please check and retry."
|
||||
return 1
|
||||
fi
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable CF_Key "$CF_Key"
|
||||
_saveaccountconf_mutable CF_Email "$CF_Email"
|
||||
fi
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
@ -71,19 +81,6 @@ dns_cf_add() {
|
||||
fi
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
# else
|
||||
# _info "Updating record"
|
||||
# record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1)
|
||||
# _debug "record_id" "$record_id"
|
||||
#
|
||||
# _cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}"
|
||||
# if [ "$?" = "0" ]; then
|
||||
# _info "Updated, OK"
|
||||
# return 0
|
||||
# fi
|
||||
# _err "Update error"
|
||||
# return 1
|
||||
# fi
|
||||
|
||||
}
|
||||
|
||||
@ -92,15 +89,10 @@ dns_cf_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}"
|
||||
CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}"
|
||||
CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}"
|
||||
CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}"
|
||||
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
|
||||
CF_Key=""
|
||||
CF_Email=""
|
||||
_err "You didn't specify a Cloudflare api key and email yet."
|
||||
_err "You can get yours from here https://dash.cloudflare.com/profile."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
@ -157,8 +149,14 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _cf_rest GET "zones?name=$h"; then
|
||||
return 1
|
||||
if [ "$CF_Account_ID" ]; then
|
||||
if ! _cf_rest GET "zones?name=$h&account.id=$CF_Account_ID"; then
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
if ! _cf_rest GET "zones?name=$h"; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then
|
||||
@ -182,12 +180,17 @@ _cf_rest() {
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
|
||||
email_trimmed=$(echo $CF_Email | tr -d '"')
|
||||
key_trimmed=$(echo $CF_Key | tr -d '"')
|
||||
email_trimmed=$(echo "$CF_Email" | tr -d '"')
|
||||
key_trimmed=$(echo "$CF_Key" | tr -d '"')
|
||||
token_trimmed=$(echo "$CF_Token" | tr -d '"')
|
||||
|
||||
export _H1="X-Auth-Email: $email_trimmed"
|
||||
export _H2="X-Auth-Key: $key_trimmed"
|
||||
export _H3="Content-Type: application/json"
|
||||
export _H1="Content-Type: application/json"
|
||||
if [ "$token_trimmed" ]; then
|
||||
export _H2="Authorization: Bearer $token_trimmed"
|
||||
else
|
||||
export _H2="X-Auth-Email: $email_trimmed"
|
||||
export _H3="X-Auth-Key: $key_trimmed"
|
||||
fi
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#
|
||||
#Author: David Kerr
|
||||
#Report Bugs here: https://github.com/dkerr64/acme.sh
|
||||
#or here... https://github.com/Neilpang/acme.sh/issues/2305
|
||||
#
|
||||
######## Public functions #####################
|
||||
|
||||
@ -46,76 +47,34 @@ dns_freedns_add() {
|
||||
|
||||
_saveaccountconf FREEDNS_COOKIE "$FREEDNS_COOKIE"
|
||||
|
||||
# split our full domain name into two parts...
|
||||
i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)"
|
||||
i="$(_math "$i" - 1)"
|
||||
top_domain="$(echo "$fulldomain" | cut -d. -f "$i"-100)"
|
||||
i="$(_math "$i" - 1)"
|
||||
sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")"
|
||||
# We may have to cycle through the domain name to find the
|
||||
# TLD that we own...
|
||||
i=1
|
||||
wmax="$(echo "$fulldomain" | tr '.' ' ' | wc -w)"
|
||||
while [ "$i" -lt "$wmax" ]; do
|
||||
# split our full domain name into two parts...
|
||||
sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")"
|
||||
i="$(_math "$i" + 1)"
|
||||
top_domain="$(echo "$fulldomain" | cut -d. -f "$i"-100)"
|
||||
_debug "sub_domain: $sub_domain"
|
||||
_debug "top_domain: $top_domain"
|
||||
|
||||
_debug "top_domain: $top_domain"
|
||||
_debug "sub_domain: $sub_domain"
|
||||
|
||||
# Sometimes FreeDNS does not return the subdomain page but rather
|
||||
# returns a page regarding becoming a premium member. This usually
|
||||
# happens after a period of inactivity. Immediately trying again
|
||||
# returns the correct subdomain page. So, we will try twice to
|
||||
# load the page and obtain our domain ID
|
||||
attempts=2
|
||||
while [ "$attempts" -gt "0" ]; do
|
||||
attempts="$(_math "$attempts" - 1)"
|
||||
|
||||
htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
|
||||
if [ "$?" != "0" ]; then
|
||||
if [ "$using_cached_cookies" = "true" ]; then
|
||||
_err "Has your FreeDNS username and password changed? If so..."
|
||||
_err "Please export as FREEDNS_User / FREEDNS_Password and try again."
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$top_domain")"
|
||||
_debug3 "subdomain_csv: $subdomain_csv"
|
||||
|
||||
# The above beauty ends with striping out rows that do not have an
|
||||
# href to edit.php and do not have the top domain we are looking for.
|
||||
# So all we should be left with is CSV of table of subdomains we are
|
||||
# interested in.
|
||||
|
||||
# Now we have to read through this table and extract the data we need
|
||||
lines="$(echo "$subdomain_csv" | wc -l)"
|
||||
i=0
|
||||
found=0
|
||||
DNSdomainid=""
|
||||
while [ "$i" -lt "$lines" ]; do
|
||||
i="$(_math "$i" + 1)"
|
||||
line="$(echo "$subdomain_csv" | sed -n "${i}p")"
|
||||
_debug2 "line: $line"
|
||||
if [ $found = 0 ] && _contains "$line" "<td>$top_domain</td>"; then
|
||||
# this line will contain DNSdomainid for the top_domain
|
||||
DNSdomainid="$(echo "$line" | _egrep_o "edit_domain_id *= *.*>" | cut -d = -f 2 | cut -d '>' -f 1)"
|
||||
_debug2 "DNSdomainid: $DNSdomainid"
|
||||
found=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$DNSdomainid" ]; then
|
||||
# If domain ID is empty then something went wrong (top level
|
||||
# domain not found at FreeDNS).
|
||||
if [ "$attempts" = "0" ]; then
|
||||
# exhausted maximum retry attempts
|
||||
_err "Domain $top_domain not found at FreeDNS"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
# break out of the 'retry' loop... we have found our domain ID
|
||||
DNSdomainid="$(_freedns_domain_id "$top_domain")"
|
||||
if [ "$?" = "0" ]; then
|
||||
_info "Domain $top_domain found at FreeDNS, domain_id $DNSdomainid"
|
||||
break
|
||||
else
|
||||
_info "Domain $top_domain not found at FreeDNS, try with next level of TLD"
|
||||
fi
|
||||
_info "Domain $top_domain not found at FreeDNS"
|
||||
_info "Retry loading subdomain page ($attempts attempts remaining)"
|
||||
done
|
||||
|
||||
if [ -z "$DNSdomainid" ]; then
|
||||
# If domain ID is empty then something went wrong (top level
|
||||
# domain not found at FreeDNS).
|
||||
_err "Domain $top_domain not found at FreeDNS"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Add in new TXT record with the value provided
|
||||
_debug "Adding TXT record for $fulldomain, $txtvalue"
|
||||
_freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
|
||||
@ -134,80 +93,47 @@ dns_freedns_rm() {
|
||||
|
||||
# Need to read cookie from conf file again in case new value set
|
||||
# during login to FreeDNS when TXT record was created.
|
||||
# acme.sh does not have a _readaccountconf() function
|
||||
FREEDNS_COOKIE="$(_read_conf "$ACCOUNT_CONF_PATH" "FREEDNS_COOKIE")"
|
||||
FREEDNS_COOKIE="$(_readaccountconf "FREEDNS_COOKIE")"
|
||||
_debug "FreeDNS login cookies: $FREEDNS_COOKIE"
|
||||
|
||||
# Sometimes FreeDNS does not return the subdomain page but rather
|
||||
# returns a page regarding becoming a premium member. This usually
|
||||
# happens after a period of inactivity. Immediately trying again
|
||||
# returns the correct subdomain page. So, we will try twice to
|
||||
# load the page and obtain our TXT record.
|
||||
attempts=2
|
||||
while [ "$attempts" -gt "0" ]; do
|
||||
attempts="$(_math "$attempts" - 1)"
|
||||
TXTdataid="$(_freedns_data_id "$fulldomain" "TXT")"
|
||||
if [ "$?" != "0" ]; then
|
||||
_info "Cannot delete TXT record for $fulldomain, record does not exist at FreeDNS"
|
||||
return 1
|
||||
fi
|
||||
_debug "Data ID's found, $TXTdataid"
|
||||
|
||||
htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
|
||||
# now we have one (or more) TXT record data ID's. Load the page
|
||||
# for that record and search for the record txt value. If match
|
||||
# then we can delete it.
|
||||
lines="$(echo "$TXTdataid" | wc -l)"
|
||||
_debug "Found $lines TXT data records for $fulldomain"
|
||||
i=0
|
||||
while [ "$i" -lt "$lines" ]; do
|
||||
i="$(_math "$i" + 1)"
|
||||
dataid="$(echo "$TXTdataid" | sed -n "${i}p")"
|
||||
_debug "$dataid"
|
||||
|
||||
htmlpage="$(_freedns_retrieve_data_page "$FREEDNS_COOKIE" "$dataid")"
|
||||
if [ "$?" != "0" ]; then
|
||||
if [ "$using_cached_cookies" = "true" ]; then
|
||||
_err "Has your FreeDNS username and password changed? If so..."
|
||||
_err "Please export as FREEDNS_User / FREEDNS_Password and try again."
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$fulldomain")"
|
||||
_debug3 "subdomain_csv: $subdomain_csv"
|
||||
|
||||
# The above beauty ends with striping out rows that do not have an
|
||||
# href to edit.php and do not have the domain name we are looking for.
|
||||
# So all we should be left with is CSV of table of subdomains we are
|
||||
# interested in.
|
||||
|
||||
# Now we have to read through this table and extract the data we need
|
||||
lines="$(echo "$subdomain_csv" | wc -l)"
|
||||
i=0
|
||||
found=0
|
||||
DNSdataid=""
|
||||
while [ "$i" -lt "$lines" ]; do
|
||||
i="$(_math "$i" + 1)"
|
||||
line="$(echo "$subdomain_csv" | sed -n "${i}p")"
|
||||
_debug3 "line: $line"
|
||||
DNSname="$(echo "$line" | _egrep_o 'edit.php.*</a>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug2 "DNSname: $DNSname"
|
||||
if [ "$DNSname" = "$fulldomain" ]; then
|
||||
DNStype="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '4p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug2 "DNStype: $DNStype"
|
||||
if [ "$DNStype" = "TXT" ]; then
|
||||
DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)"
|
||||
_debug2 "DNSdataid: $DNSdataid"
|
||||
DNSvalue="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '5p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
if _startswith "$DNSvalue" """; then
|
||||
# remove the quotation from the start
|
||||
DNSvalue="$(echo "$DNSvalue" | cut -c 7-)"
|
||||
fi
|
||||
if _endswith "$DNSvalue" "..."; then
|
||||
# value was truncated, remove the dot dot dot from the end
|
||||
DNSvalue="$(echo "$DNSvalue" | sed 's/...$//')"
|
||||
elif _endswith "$DNSvalue" """; then
|
||||
# else remove the closing quotation from the end
|
||||
DNSvalue="$(echo "$DNSvalue" | sed 's/......$//')"
|
||||
fi
|
||||
_debug2 "DNSvalue: $DNSvalue"
|
||||
|
||||
if [ -n "$DNSdataid" ] && _startswith "$txtvalue" "$DNSvalue"; then
|
||||
# Found a match. But note... Website is truncating the
|
||||
# value field so we are only testing that part that is not
|
||||
# truncated. This should be accurate enough.
|
||||
_debug "Deleting TXT record for $fulldomain, $txtvalue"
|
||||
_freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"
|
||||
return $?
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo "$htmlpage" | grep "value=\""$txtvalue"\"" >/dev/null
|
||||
if [ "$?" = "0" ]; then
|
||||
# Found a match... delete the record and return
|
||||
_info "Deleting TXT record for $fulldomain, $txtvalue"
|
||||
_freedns_delete_txt_record "$FREEDNS_COOKIE" "$dataid"
|
||||
return $?
|
||||
fi
|
||||
done
|
||||
|
||||
# If we get this far we did not find a match (after two attempts)
|
||||
# If we get this far we did not find a match
|
||||
# Not necessarily an error, but log anyway.
|
||||
_debug3 "$subdomain_csv"
|
||||
_info "Cannot delete TXT record for $fulldomain, $txtvalue. Does not exist at FreeDNS"
|
||||
return 0
|
||||
}
|
||||
@ -271,6 +197,33 @@ _freedns_retrieve_subdomain_page() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# usage _freedns_retrieve_data_page login_cookies data_id
|
||||
# echo page retrieved (html)
|
||||
# returns 0 success
|
||||
_freedns_retrieve_data_page() {
|
||||
export _H1="Cookie:$1"
|
||||
export _H2="Accept-Language:en-US"
|
||||
data_id="$2"
|
||||
url="https://freedns.afraid.org/subdomain/edit.php?data_id=$2"
|
||||
|
||||
_debug "Retrieve data page for ID $data_id from FreeDNS"
|
||||
|
||||
htmlpage="$(_get "$url")"
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "FreeDNS retrieve data page failed bad RC from _get"
|
||||
return 1
|
||||
elif [ -z "$htmlpage" ]; then
|
||||
_err "FreeDNS returned empty data page"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug3 "htmlpage: $htmlpage"
|
||||
|
||||
printf "%s" "$htmlpage"
|
||||
return 0
|
||||
}
|
||||
|
||||
# usage _freedns_add_txt_record login_cookies domain_id subdomain value
|
||||
# returns 0 success
|
||||
_freedns_add_txt_record() {
|
||||
@ -324,3 +277,95 @@ _freedns_delete_txt_record() {
|
||||
_info "Deleted acme challenge TXT record for $fulldomain at FreeDNS"
|
||||
return 0
|
||||
}
|
||||
|
||||
# usage _freedns_domain_id domain_name
|
||||
# echo the domain_id if found
|
||||
# return 0 success
|
||||
_freedns_domain_id() {
|
||||
# Start by escaping the dots in the domain name
|
||||
search_domain="$(echo "$1" | sed 's/\./\\./g')"
|
||||
|
||||
# Sometimes FreeDNS does not return the subdomain page but rather
|
||||
# returns a page regarding becoming a premium member. This usually
|
||||
# happens after a period of inactivity. Immediately trying again
|
||||
# returns the correct subdomain page. So, we will try twice to
|
||||
# load the page and obtain our domain ID
|
||||
attempts=2
|
||||
while [ "$attempts" -gt "0" ]; do
|
||||
attempts="$(_math "$attempts" - 1)"
|
||||
|
||||
htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
|
||||
if [ "$?" != "0" ]; then
|
||||
if [ "$using_cached_cookies" = "true" ]; then
|
||||
_err "Has your FreeDNS username and password changed? If so..."
|
||||
_err "Please export as FREEDNS_User / FREEDNS_Password and try again."
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
domain_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's/<tr>/@<tr>/g' | tr '@' '\n' \
|
||||
| grep "<td>$search_domain</td>\|<td>$search_domain(.*)</td>" \
|
||||
| _egrep_o "edit\.php\?edit_domain_id=[0-9a-zA-Z]+" \
|
||||
| cut -d = -f 2)"
|
||||
# The above beauty extracts domain ID from the html page...
|
||||
# strip out all blank space and new lines. Then insert newlines
|
||||
# before each table row <tr>
|
||||
# search for the domain within each row (which may or may not have
|
||||
# a text string in brackets (.*) after it.
|
||||
# And finally extract the domain ID.
|
||||
if [ -n "$domain_id" ]; then
|
||||
printf "%s" "$domain_id"
|
||||
return 0
|
||||
fi
|
||||
_debug "Domain $search_domain not found. Retry loading subdomain page ($attempts attempts remaining)"
|
||||
done
|
||||
_debug "Domain $search_domain not found after retry"
|
||||
return 1
|
||||
}
|
||||
|
||||
# usage _freedns_data_id domain_name record_type
|
||||
# echo the data_id(s) if found
|
||||
# return 0 success
|
||||
_freedns_data_id() {
|
||||
# Start by escaping the dots in the domain name
|
||||
search_domain="$(echo "$1" | sed 's/\./\\./g')"
|
||||
record_type="$2"
|
||||
|
||||
# Sometimes FreeDNS does not return the subdomain page but rather
|
||||
# returns a page regarding becoming a premium member. This usually
|
||||
# happens after a period of inactivity. Immediately trying again
|
||||
# returns the correct subdomain page. So, we will try twice to
|
||||
# load the page and obtain our domain ID
|
||||
attempts=2
|
||||
while [ "$attempts" -gt "0" ]; do
|
||||
attempts="$(_math "$attempts" - 1)"
|
||||
|
||||
htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
|
||||
if [ "$?" != "0" ]; then
|
||||
if [ "$using_cached_cookies" = "true" ]; then
|
||||
_err "Has your FreeDNS username and password changed? If so..."
|
||||
_err "Please export as FREEDNS_User / FREEDNS_Password and try again."
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
data_id="$(echo "$htmlpage" | tr -d "[:space:]" | sed 's/<tr>/@<tr>/g' | tr '@' '\n' \
|
||||
| grep "<td[a-zA-Z=#]*>$record_type</td>" \
|
||||
| grep "<ahref.*>$search_domain</a>" \
|
||||
| _egrep_o "edit\.php\?data_id=[0-9a-zA-Z]+" \
|
||||
| cut -d = -f 2)"
|
||||
# The above beauty extracts data ID from the html page...
|
||||
# strip out all blank space and new lines. Then insert newlines
|
||||
# before each table row <tr>
|
||||
# search for the record type withing each row (e.g. TXT)
|
||||
# search for the domain within each row (which is within a <a..>
|
||||
# </a> anchor. And finally extract the domain ID.
|
||||
if [ -n "$data_id" ]; then
|
||||
printf "%s" "$data_id"
|
||||
return 0
|
||||
fi
|
||||
_debug "Domain $search_domain not found. Retry loading subdomain page ($attempts attempts remaining)"
|
||||
done
|
||||
_debug "Domain $search_domain not found after retry"
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ _dns_gcloud_execute_tr() {
|
||||
}
|
||||
|
||||
_dns_gcloud_remove_rrs() {
|
||||
if ! xargs --no-run-if-empty gcloud dns record-sets transaction remove \
|
||||
if ! xargs -r gcloud dns record-sets transaction remove \
|
||||
--name="$fulldomain." \
|
||||
--ttl="$ttl" \
|
||||
--type=TXT \
|
||||
@ -108,7 +108,7 @@ _dns_gcloud_remove_rrs() {
|
||||
|
||||
_dns_gcloud_add_rrs() {
|
||||
ttl=60
|
||||
if ! xargs --no-run-if-empty gcloud dns record-sets transaction add \
|
||||
if ! xargs -r gcloud dns record-sets transaction add \
|
||||
--name="$fulldomain." \
|
||||
--ttl="$ttl" \
|
||||
--type=TXT \
|
||||
|
||||
156
dnsapi/dns_hexonet.sh
Executable file
156
dnsapi/dns_hexonet.sh
Executable file
@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Hexonet_Login="username!roleId"
|
||||
#
|
||||
# Hexonet_Password="rolePassword"
|
||||
|
||||
Hexonet_Api="https://coreapi.1api.net/api/call.cgi"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_hexonet_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}"
|
||||
Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}"
|
||||
if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then
|
||||
Hexonet_Login=""
|
||||
Hexonet_Password=""
|
||||
_err "You must export variables: Hexonet_Login and Hexonet_Password"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$Hexonet_Login" "!"; then
|
||||
_err "It seems that the Hexonet_Login=$Hexonet_Login is not a restrivteed user."
|
||||
_err "Please check and retry."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the username and password to the account conf file.
|
||||
_saveaccountconf_mutable Hexonet_Login "$Hexonet_Login"
|
||||
_saveaccountconf_mutable Hexonet_Password "$Hexonet_Password"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting txt records"
|
||||
_hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT"
|
||||
|
||||
if ! _contains "$response" "CODE=200"; then
|
||||
_err "Error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Adding record"
|
||||
if _hexonet_rest "command=UpdateDNSZone&dnszone=${_domain}.&addrr0=${_sub_domain}%20IN%20TXT%20${txtvalue}"; then
|
||||
if _contains "$response" "CODE=200"; then
|
||||
_info "Added, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
|
||||
}
|
||||
|
||||
#fulldomain txtvalue
|
||||
dns_hexonet_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}"
|
||||
Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}"
|
||||
if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then
|
||||
Hexonet_Login=""
|
||||
Hexonet_Password=""
|
||||
_err "You must export variables: Hexonet_Login and Hexonet_Password"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting txt records"
|
||||
_hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT&RR=${txtvalue}"
|
||||
|
||||
if ! _contains "$response" "CODE=200"; then
|
||||
_err "Error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
count=$(printf "%s\n" "$response" | _egrep_o "PROPERTY[TOTAL][0]=" | cut -d = -f 2)
|
||||
_debug count "$count"
|
||||
if [ "$count" = "0" ]; then
|
||||
_info "Don't need to remove."
|
||||
else
|
||||
if ! _hexonet_rest "&command=UpdateDNSZone&dnszone=${_domain}.&delrr0='${_sub_domain}%20IN%20TXT%20\"${txtvalue}\""; then
|
||||
_err "Delete record error."
|
||||
return 1
|
||||
fi
|
||||
_contains "$response" "CODE=200"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
_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 ! _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}."; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "CODE=200"; 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
|
||||
}
|
||||
|
||||
_hexonet_rest() {
|
||||
query_params="$1"
|
||||
_debug "$query_params"
|
||||
|
||||
response="$(_get "${Hexonet_Api}?s_login=${Hexonet_Login}&s_pw=${Hexonet_Password}&${query_params}")"
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $query_params"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
286
dnsapi/dns_jd.sh
Normal file
286
dnsapi/dns_jd.sh
Normal file
@ -0,0 +1,286 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
#JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||
#JD_ACCESS_KEY_SECRET="xxxxxxx"
|
||||
#JD_REGION="cn-north-1"
|
||||
|
||||
_JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey"
|
||||
|
||||
_JD_PROD="clouddnsservice"
|
||||
_JD_API="jdcloud-api.com"
|
||||
|
||||
_JD_API_VERSION="v1"
|
||||
_JD_DEFAULT_REGION="cn-north-1"
|
||||
|
||||
_JD_HOST="$_JD_PROD.$_JD_API"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_jd_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}"
|
||||
JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}"
|
||||
JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}"
|
||||
|
||||
if [ -z "$JD_ACCESS_KEY_ID" ] || [ -z "$JD_ACCESS_KEY_SECRET" ]; then
|
||||
JD_ACCESS_KEY_ID=""
|
||||
JD_ACCESS_KEY_SECRET=""
|
||||
_err "You haven't specifed the jdcloud api key id or api key secret yet."
|
||||
_err "Please create your key and try again. see $(__green $_JD_ACCOUNT)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable JD_ACCESS_KEY_ID "$JD_ACCESS_KEY_ID"
|
||||
_saveaccountconf_mutable JD_ACCESS_KEY_SECRET "$JD_ACCESS_KEY_SECRET"
|
||||
if [ -z "$JD_REGION" ]; then
|
||||
_debug "Using default region: $_JD_DEFAULT_REGION"
|
||||
JD_REGION="$_JD_DEFAULT_REGION"
|
||||
else
|
||||
_saveaccountconf_mutable JD_REGION "$JD_REGION"
|
||||
fi
|
||||
_JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION"
|
||||
|
||||
_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 getViewTree"
|
||||
|
||||
_debug "Adding records"
|
||||
|
||||
_addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":300,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}"
|
||||
#_addrr='{"req":{"hostRecord":"xx","hostValue":"\"value4\"","jcloudRes":false,"mxPriority":null,"port":null,"ttl":300,"type":"TXT","weight":null,"viewValue":-1},"regionId":"cn-north-1","domainId":"8824"}'
|
||||
if jd_rest POST "domain/$_domain_id/RRAdd" "" "$_addrr"; then
|
||||
_rid="$(echo "$response" | tr '{},' '\n' | grep '"id":' | cut -d : -f 2)"
|
||||
if [ -z "$_rid" ]; then
|
||||
_err "Can not find record id from the result."
|
||||
return 1
|
||||
fi
|
||||
_info "TXT record added successfully."
|
||||
_srid="$(_readdomainconf "JD_CLOUD_RIDS")"
|
||||
if [ "$_srid" ]; then
|
||||
_rid="$_srid,$_rid"
|
||||
fi
|
||||
_savedomainconf "JD_CLOUD_RIDS" "$_rid"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
dns_jd_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}"
|
||||
JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}"
|
||||
JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}"
|
||||
|
||||
if [ -z "$JD_REGION" ]; then
|
||||
_debug "Using default region: $_JD_DEFAULT_REGION"
|
||||
JD_REGION="$_JD_DEFAULT_REGION"
|
||||
fi
|
||||
|
||||
_JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION"
|
||||
|
||||
_info "Getting existing records for $fulldomain"
|
||||
_srid="$(_readdomainconf "JD_CLOUD_RIDS")"
|
||||
_debug _srid "$_srid"
|
||||
|
||||
if [ -z "$_srid" ]; then
|
||||
_err "Not rid skip"
|
||||
return 0
|
||||
fi
|
||||
|
||||
_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"
|
||||
|
||||
_cleardomainconf JD_CLOUD_RIDS
|
||||
|
||||
_aws_tmpl_xml="{\"ids\":[$_srid],\"action\":\"del\",\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}"
|
||||
|
||||
if jd_rest POST "domain/$_domain_id/RROperate" "" "$_aws_tmpl_xml" && _contains "$response" "\"code\":\"OK\""; then
|
||||
_info "TXT record deleted successfully."
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=1
|
||||
p=1
|
||||
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug2 "Checking domain: $h"
|
||||
if ! jd_rest GET "domain"; then
|
||||
_err "error get domain list"
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
_err "Invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"domainName\":\"$h\""; then
|
||||
hostedzone="$(echo "$response" | tr '{}' '\n' | grep "\"domainName\":\"$h\"")"
|
||||
_debug hostedzone "$hostedzone"
|
||||
if [ "$hostedzone" ]; then
|
||||
_domain_id="$(echo "$hostedzone" | tr ',' '\n' | grep "\"id\":" | cut -d : -f 2)"
|
||||
if [ "$_domain_id" ]; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain=$h
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
_err "Can't find domain with id: $h"
|
||||
return 1
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#method uri qstr data
|
||||
jd_rest() {
|
||||
mtd="$1"
|
||||
ep="$2"
|
||||
qsr="$3"
|
||||
data="$4"
|
||||
|
||||
_debug mtd "$mtd"
|
||||
_debug ep "$ep"
|
||||
_debug qsr "$qsr"
|
||||
_debug data "$data"
|
||||
|
||||
CanonicalURI="/$_JD_BASE_URI/$ep"
|
||||
_debug2 CanonicalURI "$CanonicalURI"
|
||||
|
||||
CanonicalQueryString="$qsr"
|
||||
_debug2 CanonicalQueryString "$CanonicalQueryString"
|
||||
|
||||
RequestDate="$(date -u +"%Y%m%dT%H%M%SZ")"
|
||||
#RequestDate="20190713T082155Z" ######################################################
|
||||
_debug2 RequestDate "$RequestDate"
|
||||
export _H1="X-Jdcloud-Date: $RequestDate"
|
||||
|
||||
RequestNonce="2bd0852a-8bae-4087-b2d5-$(_time)"
|
||||
#RequestNonce="894baff5-72d4-4244-883a-7b2eb51e7fbe" #################################
|
||||
_debug2 RequestNonce "$RequestNonce"
|
||||
export _H2="X-Jdcloud-Nonce: $RequestNonce"
|
||||
|
||||
if [ "$data" ]; then
|
||||
CanonicalHeaders="content-type:application/json\n"
|
||||
SignedHeaders="content-type;"
|
||||
else
|
||||
CanonicalHeaders=""
|
||||
SignedHeaders=""
|
||||
fi
|
||||
CanonicalHeaders="${CanonicalHeaders}host:$_JD_HOST\nx-jdcloud-date:$RequestDate\nx-jdcloud-nonce:$RequestNonce\n"
|
||||
SignedHeaders="${SignedHeaders}host;x-jdcloud-date;x-jdcloud-nonce"
|
||||
|
||||
_debug2 CanonicalHeaders "$CanonicalHeaders"
|
||||
_debug2 SignedHeaders "$SignedHeaders"
|
||||
|
||||
Hash="sha256"
|
||||
|
||||
RequestPayload="$data"
|
||||
_debug2 RequestPayload "$RequestPayload"
|
||||
|
||||
RequestPayloadHash="$(printf "%s" "$RequestPayload" | _digest "$Hash" hex | _lower_case)"
|
||||
_debug2 RequestPayloadHash "$RequestPayloadHash"
|
||||
|
||||
CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$RequestPayloadHash"
|
||||
_debug2 CanonicalRequest "$CanonicalRequest"
|
||||
|
||||
HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)"
|
||||
_debug2 HashedCanonicalRequest "$HashedCanonicalRequest"
|
||||
|
||||
Algorithm="JDCLOUD2-HMAC-SHA256"
|
||||
_debug2 Algorithm "$Algorithm"
|
||||
|
||||
RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8)"
|
||||
_debug2 RequestDateOnly "$RequestDateOnly"
|
||||
|
||||
Region="$JD_REGION"
|
||||
Service="$_JD_PROD"
|
||||
|
||||
CredentialScope="$RequestDateOnly/$Region/$Service/jdcloud2_request"
|
||||
_debug2 CredentialScope "$CredentialScope"
|
||||
|
||||
StringToSign="$Algorithm\n$RequestDate\n$CredentialScope\n$HashedCanonicalRequest"
|
||||
|
||||
_debug2 StringToSign "$StringToSign"
|
||||
|
||||
kSecret="JDCLOUD2$JD_ACCESS_KEY_SECRET"
|
||||
|
||||
_secure_debug2 kSecret "$kSecret"
|
||||
|
||||
kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")"
|
||||
_secure_debug2 kSecretH "$kSecretH"
|
||||
|
||||
kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)"
|
||||
_debug2 kDateH "$kDateH"
|
||||
|
||||
kRegionH="$(printf "$Region%s" | _hmac "$Hash" "$kDateH" hex)"
|
||||
_debug2 kRegionH "$kRegionH"
|
||||
|
||||
kServiceH="$(printf "$Service%s" | _hmac "$Hash" "$kRegionH" hex)"
|
||||
_debug2 kServiceH "$kServiceH"
|
||||
|
||||
kSigningH="$(printf "%s" "jdcloud2_request" | _hmac "$Hash" "$kServiceH" hex)"
|
||||
_debug2 kSigningH "$kSigningH"
|
||||
|
||||
signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)"
|
||||
_debug2 signature "$signature"
|
||||
|
||||
Authorization="$Algorithm Credential=$JD_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature"
|
||||
_debug2 Authorization "$Authorization"
|
||||
|
||||
_H3="Authorization: $Authorization"
|
||||
_debug _H3 "$_H3"
|
||||
|
||||
url="https://$_JD_HOST$CanonicalURI"
|
||||
if [ "$qsr" ]; then
|
||||
url="https://$_JD_HOST$CanonicalURI?$qsr"
|
||||
fi
|
||||
|
||||
if [ "$mtd" = "GET" ]; then
|
||||
response="$(_get "$url")"
|
||||
else
|
||||
response="$(_post "$data" "$url" "" "$mtd" "application/json")"
|
||||
fi
|
||||
|
||||
_ret="$?"
|
||||
_debug2 response "$response"
|
||||
if [ "$_ret" = "0" ]; then
|
||||
if _contains "$response" "\"error\""; then
|
||||
_err "Response error:$response"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return "$_ret"
|
||||
}
|
||||
69
dnsapi/dns_maradns.sh
Executable file
69
dnsapi/dns_maradns.sh
Executable file
@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Usage: dns_maradns_add _acme-challenge.www.domain.com "token"
|
||||
dns_maradns_add() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
MARA_ZONE_FILE="${MARA_ZONE_FILE:-$(_readaccountconf_mutable MARA_ZONE_FILE)}"
|
||||
MARA_DUENDE_PID_PATH="${MARA_DUENDE_PID_PATH:-$(_readaccountconf_mutable MARA_DUENDE_PID_PATH)}"
|
||||
|
||||
_check_zone_file "$MARA_ZONE_FILE" || return 1
|
||||
_check_duende_pid_path "$MARA_DUENDE_PID_PATH" || return 1
|
||||
|
||||
_saveaccountconf_mutable MARA_ZONE_FILE "$MARA_ZONE_FILE"
|
||||
_saveaccountconf_mutable MARA_DUENDE_PID_PATH "$MARA_DUENDE_PID_PATH"
|
||||
|
||||
printf "%s. TXT '%s' ~\n" "$fulldomain" "$txtvalue" >>"$MARA_ZONE_FILE"
|
||||
_reload_maradns "$MARA_DUENDE_PID_PATH" || return 1
|
||||
}
|
||||
|
||||
#Usage: dns_maradns_rm _acme-challenge.www.domain.com "token"
|
||||
dns_maradns_rm() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
MARA_ZONE_FILE="${MARA_ZONE_FILE:-$(_readaccountconf_mutable MARA_ZONE_FILE)}"
|
||||
MARA_DUENDE_PID_PATH="${MARA_DUENDE_PID_PATH:-$(_readaccountconf_mutable MARA_DUENDE_PID_PATH)}"
|
||||
|
||||
_check_zone_file "$MARA_ZONE_FILE" || return 1
|
||||
_check_duende_pid_path "$MARA_DUENDE_PID_PATH" || return 1
|
||||
|
||||
_saveaccountconf_mutable MARA_ZONE_FILE "$MARA_ZONE_FILE"
|
||||
_saveaccountconf_mutable MARA_DUENDE_PID_PATH "$MARA_DUENDE_PID_PATH"
|
||||
|
||||
_sed_i "/^$fulldomain.\+TXT '$txtvalue' ~/d" "$MARA_ZONE_FILE"
|
||||
_reload_maradns "$MARA_DUENDE_PID_PATH" || return 1
|
||||
}
|
||||
|
||||
_check_zone_file() {
|
||||
zonefile="$1"
|
||||
if [ -z "$zonefile" ]; then
|
||||
_err "MARA_ZONE_FILE not passed!"
|
||||
return 1
|
||||
elif [ ! -w "$zonefile" ]; then
|
||||
_err "MARA_ZONE_FILE not writable: $zonefile"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
_check_duende_pid_path() {
|
||||
pidpath="$1"
|
||||
if [ -z "$pidpath" ]; then
|
||||
_err "MARA_DUENDE_PID_PATH not passed!"
|
||||
return 1
|
||||
fi
|
||||
if [ ! -r "$pidpath" ]; then
|
||||
_err "MARA_DUENDE_PID_PATH not readable: $pidpath"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
_reload_maradns() {
|
||||
pidpath="$1"
|
||||
kill -s HUP -- "$(cat "$pidpath")"
|
||||
if [ $? -ne 0 ]; then
|
||||
_err "Unable to reload MaraDNS, kill returned $?"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@ -11,6 +11,8 @@
|
||||
#
|
||||
######## Public functions #####################
|
||||
|
||||
# Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
|
||||
|
||||
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_myapi_add() {
|
||||
fulldomain=$1
|
||||
|
||||
@ -164,7 +164,7 @@ _namecheap_set_publicip() {
|
||||
_debug sourceip "$NAMECHEAP_SOURCEIP"
|
||||
|
||||
ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
|
||||
addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*')
|
||||
addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https):\/\/.*')
|
||||
|
||||
_debug2 ip "$ip"
|
||||
_debug2 addr "$addr"
|
||||
|
||||
@ -59,9 +59,14 @@ dns_namesilo_rm() {
|
||||
if _namesilo_rest GET "dnsListRecords?version=1&type=xml&key=$Namesilo_Key&domain=$_domain"; then
|
||||
retcode=$(printf "%s\n" "$response" | _egrep_o "<code>300")
|
||||
if [ "$retcode" ]; then
|
||||
_record_id=$(printf "%s\n" "$response" | _egrep_o "<record_id>([^<]*)</record_id><type>TXT</type><host>$fulldomain</host>" | _egrep_o "<record_id>([^<]*)</record_id>" | sed -r "s/<record_id>([^<]*)<\/record_id>/\1/" | tail -n 1)
|
||||
_debug record_id "$_record_id"
|
||||
_info "Successfully retrieved the record id for ACME challenge."
|
||||
_record_id=$(echo "$response" | _egrep_o "<record_id>([^<]*)</record_id><type>TXT</type><host>$fulldomain</host>" | _egrep_o "<record_id>([^<]*)</record_id>" | sed -r "s/<record_id>([^<]*)<\/record_id>/\1/" | tail -n 1)
|
||||
_debug _record_id "$_record_id"
|
||||
if [ "$_record_id" ]; then
|
||||
_info "Successfully retrieved the record id for ACME challenge."
|
||||
else
|
||||
_info "Empty record id, it seems no such record."
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
_err "Unable to retrieve the record id."
|
||||
return 1
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
# one.com ui wrapper for acme.sh
|
||||
# Author: github: @diseq
|
||||
# Created: 2019-02-17
|
||||
# Fixed by: @der-berni
|
||||
# Modified: 2019-05-31
|
||||
#
|
||||
# export ONECOM_User="username"
|
||||
# export ONECOM_Password="password"
|
||||
@ -14,49 +16,29 @@
|
||||
# only single domain supported atm
|
||||
|
||||
dns_one_add() {
|
||||
mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev)
|
||||
mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev)
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
# get credentials
|
||||
ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}"
|
||||
ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}"
|
||||
if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then
|
||||
ONECOM_User=""
|
||||
ONECOM_Password=""
|
||||
_err "You didn't specify a one.com username and password yet."
|
||||
_err "Please create the key and try again."
|
||||
if ! _dns_one_login; then
|
||||
_err "login failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable ONECOM_User "$ONECOM_User"
|
||||
_saveaccountconf_mutable ONECOM_Password "$ONECOM_Password"
|
||||
_debug "detect the root domain"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "root domain not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Login with user and password
|
||||
postdata="loginDomain=true"
|
||||
postdata="$postdata&displayUsername=$ONECOM_User"
|
||||
postdata="$postdata&username=$ONECOM_User"
|
||||
postdata="$postdata&targetDomain=$mydomain"
|
||||
postdata="$postdata&password1=$ONECOM_Password"
|
||||
postdata="$postdata&loginTarget="
|
||||
#_debug postdata "$postdata"
|
||||
|
||||
response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")"
|
||||
#_debug response "$response"
|
||||
|
||||
JSESSIONID="$(grep "JSESSIONID" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')"
|
||||
_debug jsessionid "$JSESSIONID"
|
||||
|
||||
export _H1="Cookie: ${JSESSIONID}"
|
||||
mysubdomain=$_sub_domain
|
||||
mydomain=$_domain
|
||||
_debug mysubdomain "$mysubdomain"
|
||||
_debug mydomain "$mydomain"
|
||||
|
||||
# get entries
|
||||
response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")"
|
||||
_debug response "$response"
|
||||
|
||||
CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')"
|
||||
export _H2="Cookie: ${CSRF_G_TOKEN}"
|
||||
|
||||
# Update the IP address for domain entry
|
||||
postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}"
|
||||
_debug postdata "$postdata"
|
||||
@ -77,45 +59,30 @@ dns_one_add() {
|
||||
}
|
||||
|
||||
dns_one_rm() {
|
||||
mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev)
|
||||
mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev)
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
# get credentials
|
||||
ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}"
|
||||
ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}"
|
||||
if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then
|
||||
ONECOM_User=""
|
||||
ONECOM_Password=""
|
||||
_err "You didn't specify a one.com username and password yet."
|
||||
_err "Please create the key and try again."
|
||||
if ! _dns_one_login; then
|
||||
_err "login failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Login with user and password
|
||||
postdata="loginDomain=true"
|
||||
postdata="$postdata&displayUsername=$ONECOM_User"
|
||||
postdata="$postdata&username=$ONECOM_User"
|
||||
postdata="$postdata&targetDomain=$mydomain"
|
||||
postdata="$postdata&password1=$ONECOM_Password"
|
||||
postdata="$postdata&loginTarget="
|
||||
_debug "detect the root domain"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "root domain not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")"
|
||||
#_debug response "$response"
|
||||
|
||||
JSESSIONID="$(grep "JSESSIONID" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')"
|
||||
_debug jsessionid "$JSESSIONID"
|
||||
|
||||
export _H1="Cookie: ${JSESSIONID}"
|
||||
mysubdomain=$_sub_domain
|
||||
mydomain=$_domain
|
||||
_debug mysubdomain "$mysubdomain"
|
||||
_debug mydomain "$mydomain"
|
||||
|
||||
# get entries
|
||||
response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")"
|
||||
response="$(echo "$response" | _normalizeJson)"
|
||||
_debug response "$response"
|
||||
|
||||
CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')"
|
||||
export _H2="Cookie: ${CSRF_G_TOKEN}"
|
||||
|
||||
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")
|
||||
|
||||
if [ -z "$id" ]; then
|
||||
@ -137,3 +104,76 @@ dns_one_rm() {
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#_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
|
||||
|
||||
response="$(_get "https://www.one.com/admin/api/domains/$h/dns/custom_records")"
|
||||
|
||||
if ! _contains "$response" "CRMRST_000302"; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain="$h"
|
||||
return 0
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
_err "Unable to parse this domain"
|
||||
return 1
|
||||
}
|
||||
|
||||
_dns_one_login() {
|
||||
|
||||
# get credentials
|
||||
ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}"
|
||||
ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}"
|
||||
if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then
|
||||
ONECOM_User=""
|
||||
ONECOM_Password=""
|
||||
_err "You didn't specify a one.com username and password yet."
|
||||
_err "Please create the key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable ONECOM_User "$ONECOM_User"
|
||||
_saveaccountconf_mutable ONECOM_Password "$ONECOM_Password"
|
||||
|
||||
# Login with user and password
|
||||
postdata="loginDomain=true"
|
||||
postdata="$postdata&displayUsername=$ONECOM_User"
|
||||
postdata="$postdata&username=$ONECOM_User"
|
||||
postdata="$postdata&targetDomain="
|
||||
postdata="$postdata&password1=$ONECOM_Password"
|
||||
postdata="$postdata&loginTarget="
|
||||
#_debug postdata "$postdata"
|
||||
|
||||
response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")"
|
||||
#_debug response "$response"
|
||||
|
||||
# Get SessionID
|
||||
JSESSIONID="$(grep "OneSIDCrmAdmin" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _head_n 1 | _egrep_o 'OneSIDCrmAdmin=[^;]*;' | tr -d ';')"
|
||||
_debug jsessionid "$JSESSIONID"
|
||||
|
||||
if [ -z "$JSESSIONID" ]; then
|
||||
_err "error sessionid cookie not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
export _H1="Cookie: ${JSESSIONID}"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ _initAuth() {
|
||||
|
||||
_info "Checking authentication"
|
||||
|
||||
if ! _ovh_rest GET "domain" || _contains "$response" "INVALID_CREDENTIAL"; then
|
||||
if ! _ovh_rest GET "domain" || _contains "$response" "INVALID_CREDENTIAL" || _contains "$response" "NOT_CREDENTIAL"; then
|
||||
_err "The consumer key is invalid: $OVH_CK"
|
||||
_err "Please retry to create a new one."
|
||||
_clearaccountconf OVH_CK
|
||||
|
||||
63
dnsapi/dns_regru.sh
Normal file
63
dnsapi/dns_regru.sh
Normal file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# REGRU_API_Username="test"
|
||||
#
|
||||
# REGRU_API_Password="test"
|
||||
#
|
||||
_domain=$_domain
|
||||
|
||||
REGRU_API_URL="https://api.reg.ru/api/regru2"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
dns_regru_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
REGRU_API_Username="${REGRU_API_Username:-$(_readaccountconf_mutable REGRU_API_Username)}"
|
||||
REGRU_API_Password="${REGRU_API_Password:-$(_readaccountconf_mutable REGRU_API_Password)}"
|
||||
if [ -z "$REGRU_API_Username" ] || [ -z "$REGRU_API_Password" ]; then
|
||||
REGRU_API_Username=""
|
||||
REGRU_API_Password=""
|
||||
_err "You don't specify regru password or username."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable REGRU_API_Username "$REGRU_API_Username"
|
||||
_saveaccountconf_mutable REGRU_API_Password "$REGRU_API_Password"
|
||||
|
||||
_info "Adding TXT record to ${fulldomain}"
|
||||
response="$(_get "$REGRU_API_URL/zone/add_txt?input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json")"
|
||||
|
||||
if _contains "${response}" 'success'; then
|
||||
return 0
|
||||
fi
|
||||
_err "Could not create resource record, check logs"
|
||||
_err "${response}"
|
||||
return 1
|
||||
}
|
||||
|
||||
dns_regru_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
REGRU_API_Username="${REGRU_API_Username:-$(_readaccountconf_mutable REGRU_API_Username)}"
|
||||
REGRU_API_Password="${REGRU_API_Password:-$(_readaccountconf_mutable REGRU_API_Password)}"
|
||||
if [ -z "$REGRU_API_Username" ] || [ -z "$REGRU_API_Password" ]; then
|
||||
REGRU_API_Username=""
|
||||
REGRU_API_Password=""
|
||||
_err "You don't specify regru password or username."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Deleting resource record $fulldomain"
|
||||
response="$(_get "$REGRU_API_URL/zone/remove_record?input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json")"
|
||||
|
||||
if _contains "${response}" 'success'; then
|
||||
return 0
|
||||
fi
|
||||
_err "Could not delete resource record, check logs"
|
||||
_err "${response}"
|
||||
return 1
|
||||
}
|
||||
163
dnsapi/dns_vultr.sh
Normal file
163
dnsapi/dns_vultr.sh
Normal file
@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
#VULTR_API_KEY=000011112222333344445555666677778888
|
||||
|
||||
VULTR_Api="https://api.vultr.com/v1"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_vultr_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}"
|
||||
if test -z "$VULTR_API_KEY"; then
|
||||
VULTR_API_KEY=''
|
||||
_err 'VULTR_API_KEY was not exported'
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY"
|
||||
|
||||
_debug 'First detect the root zone'
|
||||
if ! _get_root "$fulldomain"; then
|
||||
return 1
|
||||
fi
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug 'Getting txt records'
|
||||
_vultr_rest GET "dns/records?domain=$_domain"
|
||||
|
||||
if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
|
||||
_err 'Error'
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 _response "$response"
|
||||
return 0
|
||||
}
|
||||
|
||||
#fulldomain txtvalue
|
||||
dns_vultr_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}"
|
||||
if test -z "$VULTR_API_KEY"; then
|
||||
VULTR_API_KEY=""
|
||||
_err 'VULTR_API_KEY was not exported'
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY"
|
||||
|
||||
_debug 'First detect the root zone'
|
||||
if ! _get_root "$fulldomain"; then
|
||||
return 1
|
||||
fi
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug 'Getting txt records'
|
||||
_vultr_rest GET "dns/records?domain=$_domain"
|
||||
|
||||
if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
|
||||
_err 'Error'
|
||||
return 1
|
||||
fi
|
||||
|
||||
_record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)"
|
||||
_debug _record_id "$_record_id"
|
||||
if [ "$_record_id" ]; then
|
||||
_info "Successfully retrieved the record id for ACME challenge."
|
||||
else
|
||||
_info "Empty record id, it seems no such record."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 _response "$response"
|
||||
return 0
|
||||
}
|
||||
|
||||
#################### 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
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug h "$h"
|
||||
if [ -z "$h" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _vultr_rest GET "dns/list"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then
|
||||
if _contains "$response" "\"domain\":\"$_domain\""; then
|
||||
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
|
||||
_domain=$_domain
|
||||
return 0
|
||||
else
|
||||
_err 'Invalid domain'
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
_vultr_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
|
||||
api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"')
|
||||
|
||||
export _H1="Api-Key: $api_key_trimmed"
|
||||
export _H2='Content-Type: application/x-www-form-urlencoded'
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$VULTR_Api/$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$VULTR_Api/$ep")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "Error $ep"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
58
notify/postmark.sh
Normal file
58
notify/postmark.sh
Normal file
@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support postmarkapp.com API (https://postmarkapp.com/developer/user-guide/sending-email/sending-with-api)
|
||||
|
||||
#POSTMARK_TOKEN=""
|
||||
#POSTMARK_TO="xxxx@xxx.com"
|
||||
#POSTMARK_FROM="xxxx@cccc.com"
|
||||
|
||||
postmark_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
POSTMARK_TOKEN="${POSTMARK_TOKEN:-$(_readaccountconf_mutable POSTMARK_TOKEN)}"
|
||||
if [ -z "$POSTMARK_TOKEN" ]; then
|
||||
POSTMARK_TOKEN=""
|
||||
_err "You didn't specify a POSTMARK api token POSTMARK_TOKEN yet ."
|
||||
_err "You can get yours from here https://account.postmarkapp.com"
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable POSTMARK_TOKEN "$POSTMARK_TOKEN"
|
||||
|
||||
POSTMARK_TO="${POSTMARK_TO:-$(_readaccountconf_mutable POSTMARK_TO)}"
|
||||
if [ -z "$POSTMARK_TO" ]; then
|
||||
POSTMARK_TO=""
|
||||
_err "You didn't specify an email to POSTMARK_TO receive messages."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable POSTMARK_TO "$POSTMARK_TO"
|
||||
|
||||
POSTMARK_FROM="${POSTMARK_FROM:-$(_readaccountconf_mutable POSTMARK_FROM)}"
|
||||
if [ -z "$POSTMARK_FROM" ]; then
|
||||
POSTMARK_FROM=""
|
||||
_err "You didn't specify an email from POSTMARK_FROM receive messages."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable POSTMARK_FROM "$POSTMARK_FROM"
|
||||
|
||||
export _H1="Accept: application/json"
|
||||
export _H2="Content-Type: application/json"
|
||||
export _H3="X-Postmark-Server-Token: $POSTMARK_TOKEN"
|
||||
|
||||
_content="$(echo "$_content" | _json_encode)"
|
||||
_data="{\"To\": \"$POSTMARK_TO\", \"From\": \"$POSTMARK_FROM\", \"Subject\": \"$_subject\", \"TextBody\": \"$_content\"}"
|
||||
if _post "$_data" "https://api.postmarkapp.com/email"; then
|
||||
# shellcheck disable=SC2154
|
||||
_message=$(printf "%s\n" "$response" | _lower_case | _egrep_o "\"message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1)
|
||||
if [ "$_message" = "ok" ]; then
|
||||
_info "postmark send success."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
_err "postmark send error."
|
||||
_err "$response"
|
||||
return 1
|
||||
|
||||
}
|
||||
63
notify/pushover.sh
Normal file
63
notify/pushover.sh
Normal file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support for pushover.net's api. Push notification platform for multiple platforms
|
||||
#PUSHOVER_TOKEN="" Required, pushover application token
|
||||
#PUSHOVER_USER="" Required, pushover userkey
|
||||
#PUSHOVER_DEVICE="" Optional, Specific device or devices by hostnames, joining multiples with a comma (such as device=iphone,nexus5)
|
||||
#PUSHOVER_PRIORITY="" Optional, Lowest Priority (-2), Low Priority (-1), Normal Priority (0), High Priority (1)
|
||||
|
||||
PUSHOVER_URI="https://api.pushover.net/1/messages.json"
|
||||
|
||||
pushover_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
PUSHOVER_TOKEN="${PUSHOVER_TOKEN:-$(_readaccountconf_mutable PUSHOVER_TOKEN)}"
|
||||
if [ -z "$PUSHOVER_TOKEN" ]; then
|
||||
PUSHOVER_TOKEN=""
|
||||
_err "You didn't specify a PushOver application token yet."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable PUSHOVER_TOKEN "$PUSHOVER_TOKEN"
|
||||
|
||||
PUSHOVER_USER="${PUSHOVER_USER:-$(_readaccountconf_mutable PUSHOVER_USER)}"
|
||||
if [ -z "$PUSHOVER_USER" ]; then
|
||||
PUSHOVER_USER=""
|
||||
_err "You didn't specify a PushOver UserKey yet."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable PUSHOVER_USER "$PUSHOVER_USER"
|
||||
|
||||
PUSHOVER_DEVICE="${PUSHOVER_DEVICE:-$(_readaccountconf_mutable PUSHOVER_DEVICE)}"
|
||||
if [ "$PUSHOVER_DEVICE" ]; then
|
||||
_saveaccountconf_mutable PUSHOVER_DEVICE "$PUSHOVER_DEVICE"
|
||||
fi
|
||||
|
||||
PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-$(_readaccountconf_mutable PUSHOVER_PRIORITY)}"
|
||||
if [ "$PUSHOVER_PRIORITY" ]; then
|
||||
_saveaccountconf_mutable PUSHOVER_PRIORITY "$PUSHOVER_PRIORITY"
|
||||
fi
|
||||
|
||||
PUSHOVER_SOUND="${PUSHOVER_SOUND:-$(_readaccountconf_mutable PUSHOVER_SOUND)}"
|
||||
if [ "$PUSHOVER_SOUND" ]; then
|
||||
_saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND"
|
||||
fi
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
_content="$(printf "*%s*\n" "$_content" | _json_encode)"
|
||||
_subject="$(printf "*%s*\n" "$_subject" | _json_encode)"
|
||||
_data="{\"token\": \"$PUSHOVER_TOKEN\",\"user\": \"$PUSHOVER_USER\",\"title\": \"$_subject\",\"message\": \"$_content\",\"sound\": \"$PUSHOVER_SOUND\", \"device\": \"$PUSHOVER_DEVICE\", \"priority\": \"$PUSHOVER_PRIORITY\"}"
|
||||
|
||||
response="" #just make shellcheck happy
|
||||
if _post "$_data" "$PUSHOVER_URI"; then
|
||||
if _contains "$response" "{\"status\":1"; then
|
||||
_info "PUSHOVER send success."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
_err "PUSHOVER send error."
|
||||
_err "$response"
|
||||
return 1
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user