No known key found for this signature in database
GPG Key ID: F1A1FA427709F5EF
16 changed files with 1173 additions and 288 deletions
-
4.github/ISSUE_TEMPLATE.md
-
8.github/PULL_REQUEST_TEMPLATE.md
-
6Dockerfile
-
164acme.sh
-
285deploy/docker.sh
-
43deploy/routeros.sh
-
4dnsapi/dns_azure.sh
-
307dnsapi/dns_freedns.sh
-
286dnsapi/dns_jd.sh
-
69dnsapi/dns_maradns.sh
-
2dnsapi/dns_myapi.sh
-
2dnsapi/dns_namecheap.sh
-
158dnsapi/dns_one.sh
-
2dnsapi/dns_ovh.sh
-
63dnsapi/dns_regru.sh
-
58notify/postmark.sh
@ -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. |
Please send to `dev` branch instead. |
||||
|
|
||||
Any PR to `master` branch will NOT be merged. |
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. |
||||
|
|
||||
--> |
--> |
||||
@ -0,0 +1,285 @@ |
|||||
|
#!/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 |
||||
|
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" |
||||
|
if ! tar --transform="s,$_frompath,$_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 |
||||
|
} |
||||
@ -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" |
||||
|
} |
||||
@ -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 |
||||
|
} |
||||
@ -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 |
||||
|
} |
||||
@ -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 |
||||
|
|
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue