mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2026-01-04 04:02:09 +08:00
Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev
# Conflicts: # README.md # dnsapi/README.md
This commit is contained in:
@@ -1122,21 +1122,67 @@ export EXOSCALE_SECRET_KEY='xxx'
|
||||
|
||||
Now, let's issue a cert:
|
||||
```
|
||||
acme.sh --issue --dns dns_netcup -d example.com -d www.example.com
|
||||
acme.sh --issue --dns dns_exoscale -d example.com -d www.example.com
|
||||
```
|
||||
|
||||
The `EXOSCALE_API_KEY` and `EXOSCALE_SECRET_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
|
||||
|
||||
## 58. Use Internet.bs
|
||||
## 58. Using PointHQ API to issue certs
|
||||
|
||||
First you need to create/obtain API credentials on your Internet.bs (https://internetbs.net) account. Go to the "Get my API Key" section in the "My Domains" section.
|
||||
Log into [PointHQ account management](https://app.pointhq.com/profile) and copy the API key from the page there.
|
||||
|
||||
```export PointHQ_Key="apikeystringgoeshere"
|
||||
exportPointHQ_Email="accountemail@yourdomain.com"
|
||||
```
|
||||
|
||||
You can then issue certs by using:
|
||||
```acme.sh --issue --dns dns_pointhq -d example.com -d www.example.com
|
||||
```
|
||||
|
||||
## 59. Use Active24 API
|
||||
|
||||
Create an API token in the Active24 account section, documentation on https://faq.active24.com/cz/790131-REST-API-rozhran%C3%AD.
|
||||
|
||||
Set your API token:
|
||||
|
||||
```
|
||||
export ACTIVE24_Token='xxx'
|
||||
```
|
||||
|
||||
Now, let's issue a cert, set `dnssleep` for propagation new DNS record:
|
||||
```
|
||||
acme.sh --issue --dns dns_active24 -d example.com -d www.example.com --dnssleep 1000
|
||||
```
|
||||
|
||||
The `ACTIVE24_Token` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
|
||||
|
||||
## 60. Use do.de API
|
||||
|
||||
Create an API token in your do.de account.
|
||||
|
||||
Set your API token:
|
||||
```
|
||||
export DO_LETOKEN='FmD408PdqT1E269gUK57'
|
||||
```
|
||||
|
||||
To issue a certificate run:
|
||||
```
|
||||
acme.sh --issue --dns dns_doapi -d example.com -d *.example.com
|
||||
```
|
||||
|
||||
The API token will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
|
||||
|
||||
## 61. Use internetbs.net API
|
||||
|
||||
Create an API token in your internetbs.net account.
|
||||
|
||||
Set your API token:
|
||||
```
|
||||
export INTERNETBS_API_KEY="..."
|
||||
export INTERNETBS_API_PASSWORD="..."
|
||||
```
|
||||
|
||||
Ok, let's issue a cert now:
|
||||
To issue a certificate run:
|
||||
```
|
||||
acme.sh --issue --dns dns_internetbs -d example.com -d www.example.com
|
||||
```
|
||||
|
||||
141
dnsapi/dns_active24.sh
Executable file
141
dnsapi/dns_active24.sh
Executable file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#ACTIVE24_Token="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||
|
||||
ACTIVE24_Api="https://api.active24.com"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
# Used to add txt record
|
||||
dns_active24_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_active24_init
|
||||
|
||||
_info "Adding txt record"
|
||||
if _active24_rest POST "dns/$_domain/txt/v1" "{\"name\":\"$_sub_domain\",\"text\":\"$txtvalue\",\"ttl\":0}"; then
|
||||
if _contains "$response" "errors"; then
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
else
|
||||
_info "Added, OK"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
}
|
||||
|
||||
# Usage: fulldomain txtvalue
|
||||
# Used to remove the txt record after validation
|
||||
dns_active24_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_active24_init
|
||||
|
||||
_debug "Getting txt records"
|
||||
_active24_rest GET "dns/$_domain/records/v1"
|
||||
|
||||
if _contains "$response" "errors"; then
|
||||
_err "Error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
hash_ids=$(echo "$response" | _egrep_o "[^{]+${txtvalue}[^}]+" | _egrep_o "hashId\":\"[^\"]+" | cut -c10-)
|
||||
|
||||
for hash_id in $hash_ids; do
|
||||
_debug "Removing hash_id" "$hash_id"
|
||||
if _active24_rest DELETE "dns/$_domain/$hash_id/v1" ""; then
|
||||
if _contains "$response" "errors"; then
|
||||
_err "Unable to remove txt record."
|
||||
return 1
|
||||
else
|
||||
_info "Removed txt record."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
_err "No txt records found."
|
||||
return 1
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
# _domain_id=sdjkglgdfewsdfg
|
||||
_get_root() {
|
||||
domain=$1
|
||||
|
||||
if ! _active24_rest GET "dns/domains/v1"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
i=2
|
||||
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 _contains "$response" "\"$h\"" >/dev/null; 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
|
||||
}
|
||||
|
||||
_active24_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
|
||||
export _H1="Authorization: Bearer $ACTIVE24_Token"
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug "data" "$data"
|
||||
response="$(_post "$data" "$ACTIVE24_Api/$ep" "" "$m" "application/json")"
|
||||
else
|
||||
response="$(_get "$ACTIVE24_Api/$ep")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $ep"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
|
||||
_active24_init() {
|
||||
ACTIVE24_Token="${ACTIVE24_Token:-$(_readaccountconf_mutable ACTIVE24_Token)}"
|
||||
if [ -z "$ACTIVE24_Token" ]; then
|
||||
ACTIVE24_Token=""
|
||||
_err "You didn't specify a Active24 api token yet."
|
||||
_err "Please create the token and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable ACTIVE24_Token "ACTIVE24_Token"
|
||||
|
||||
_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"
|
||||
}
|
||||
@@ -19,8 +19,8 @@ dns_cf_add() {
|
||||
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 "Please create the key and try again."
|
||||
_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
|
||||
|
||||
@@ -34,9 +34,6 @@ dns_cf_add() {
|
||||
_saveaccountconf_mutable CF_Key "$CF_Key"
|
||||
_saveaccountconf_mutable CF_Email "$CF_Email"
|
||||
|
||||
_DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '@.' '__')"
|
||||
_cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
@@ -100,21 +97,16 @@ dns_cf_rm() {
|
||||
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 "Please create the key and try again."
|
||||
_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
|
||||
|
||||
_DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '@.' '__')"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_"
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_"
|
||||
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
@@ -154,21 +146,6 @@ dns_cf_rm() {
|
||||
# _domain=domain.com
|
||||
# _domain_id=sdjkglgdfewsdfg
|
||||
_get_root() {
|
||||
|
||||
_cf_zones="$(_readdomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_")"
|
||||
_debug2 "_cf_zones" "$_cf_zones"
|
||||
if [ -z "$_cf_zones" ]; then
|
||||
_debug "$_DOMAIN_CF_ZONES_CACHE_NAME_ is none, so get it."
|
||||
if ! _cf_rest GET "zones"; then
|
||||
return 1
|
||||
fi
|
||||
_cf_zones="$response"
|
||||
_savedomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" "$(echo "$_cf_zones" | _base64)"
|
||||
else
|
||||
_debug "$_DOMAIN_CF_ZONES_CACHE_NAME_ found"
|
||||
_cf_zones="$(echo "$_cf_zones" | _dbase64)"
|
||||
fi
|
||||
|
||||
domain=$1
|
||||
i=2
|
||||
p=1
|
||||
@@ -180,8 +157,12 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$_cf_zones" "\"name\":\"$h\"" >/dev/null; then
|
||||
_domain_id=$(echo "$_cf_zones" | tr '{' "\n" | grep "\"name\":\"$h\"" | _egrep_o "^\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
|
||||
if ! _cf_rest GET "zones?name=$h"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
|
||||
_domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
|
||||
if [ "$_domain_id" ]; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain=$h
|
||||
|
||||
@@ -104,48 +104,60 @@ dns_dgon_rm() {
|
||||
## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
|
||||
GURL="https://api.digitalocean.com/v2/domains/$_domain/records"
|
||||
|
||||
## while we dont have a record ID we keep going
|
||||
while [ -z "$record" ]; do
|
||||
## Get all the matching records
|
||||
while true; do
|
||||
## 1) get the URL
|
||||
## the create request - get
|
||||
## args: URL, [onlyheader, timeout]
|
||||
domain_list="$(_get "$GURL")"
|
||||
## 2) find record
|
||||
## check for what we are looing for: "type":"A","name":"$_sub_domain"
|
||||
record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
|
||||
## 3) check record and get next page
|
||||
if [ -z "$record" ]; then
|
||||
## find the next page if we dont have a match
|
||||
nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")"
|
||||
if [ -z "$nextpage" ]; then
|
||||
_err "no record and no nextpage in digital ocean DNS removal"
|
||||
return 1
|
||||
fi
|
||||
_debug2 nextpage "$nextpage"
|
||||
GURL="$nextpage"
|
||||
|
||||
## check response
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error in domain_list response: $domain_list"
|
||||
return 1
|
||||
fi
|
||||
## we break out of the loop when we have a record
|
||||
_debug2 domain_list "$domain_list"
|
||||
|
||||
## 2) find records
|
||||
## check for what we are looking for: "type":"A","name":"$_sub_domain"
|
||||
record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
|
||||
|
||||
if [ ! -z "$record" ]; then
|
||||
|
||||
## we found records
|
||||
rec_ids="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
|
||||
_debug rec_ids "$rec_ids"
|
||||
if [ ! -z "$rec_ids" ]; then
|
||||
echo "$rec_ids" | while IFS= read -r rec_id; do
|
||||
## delete the record
|
||||
## delete URL for removing the one we dont want
|
||||
DURL="https://api.digitalocean.com/v2/domains/$_domain/records/$rec_id"
|
||||
|
||||
## the create request - delete
|
||||
## args: BODY, URL, [need64, httpmethod]
|
||||
response="$(_post "" "$DURL" "" "DELETE")"
|
||||
|
||||
## check response (sort of)
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error in remove response: $response"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
## 3) find the next page
|
||||
nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")"
|
||||
if [ -z "$nextpage" ]; then
|
||||
break
|
||||
fi
|
||||
_debug2 nextpage "$nextpage"
|
||||
GURL="$nextpage"
|
||||
|
||||
done
|
||||
|
||||
## we found the record
|
||||
rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
|
||||
_debug rec_id "$rec_id"
|
||||
|
||||
## delete the record
|
||||
## delete URL for removing the one we dont want
|
||||
DURL="https://api.digitalocean.com/v2/domains/$_domain/records/$rec_id"
|
||||
|
||||
## the create request - delete
|
||||
## args: BODY, URL, [need64, httpmethod]
|
||||
response="$(_post "" "$DURL" "" "DELETE")"
|
||||
|
||||
## check response (sort of)
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error in remove response: $response"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
|
||||
## finished correctly
|
||||
return 0
|
||||
}
|
||||
@@ -178,44 +190,57 @@ _get_base_domain() {
|
||||
export _H2="Authorization: Bearer $DO_API_KEY"
|
||||
_debug DO_API_KEY "$DO_API_KEY"
|
||||
## get URL for the list of domains
|
||||
## havent seen this request paginated, tested with 18 domains (more requires manual requests with DO)
|
||||
## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
|
||||
DOMURL="https://api.digitalocean.com/v2/domains"
|
||||
|
||||
## get the domain list (DO gives basically a full XFER!)
|
||||
domain_list="$(_get "$DOMURL")"
|
||||
## while we dont have a matching domain we keep going
|
||||
while [ -z "$found" ]; do
|
||||
## get the domain list (current page)
|
||||
domain_list="$(_get "$DOMURL")"
|
||||
|
||||
## check response
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error in domain_list response: $domain_list"
|
||||
return 1
|
||||
fi
|
||||
_debug2 domain_list "$domain_list"
|
||||
|
||||
## for each shortening of our $fulldomain, check if it exists in the $domain_list
|
||||
## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge"
|
||||
i=2
|
||||
while [ $i -gt 0 ]; do
|
||||
## get next longest domain
|
||||
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
|
||||
## check we got something back from our cut (or are we at the end)
|
||||
if [ -z "$_domain" ]; then
|
||||
## we got to the end of the domain - invalid domain
|
||||
_err "domain not found in DigitalOcean account"
|
||||
## check response
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error in domain_list response: $domain_list"
|
||||
return 1
|
||||
fi
|
||||
## we got part of a domain back - grep it out
|
||||
found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")"
|
||||
## check if it exists
|
||||
if [ ! -z "$found" ]; then
|
||||
## exists - exit loop returning the parts
|
||||
sub_point=$(_math $i - 1)
|
||||
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")
|
||||
_debug _domain "$_domain"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
return 0
|
||||
_debug2 domain_list "$domain_list"
|
||||
|
||||
## for each shortening of our $fulldomain, check if it exists in the $domain_list
|
||||
## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge"
|
||||
i=2
|
||||
while [ $i -gt 0 ]; do
|
||||
## get next longest domain
|
||||
_domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
|
||||
## check we got something back from our cut (or are we at the end)
|
||||
if [ -z "$_domain" ]; then
|
||||
break
|
||||
fi
|
||||
## we got part of a domain back - grep it out
|
||||
found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")"
|
||||
## check if it exists
|
||||
if [ ! -z "$found" ]; then
|
||||
## exists - exit loop returning the parts
|
||||
sub_point=$(_math $i - 1)
|
||||
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")
|
||||
_debug _domain "$_domain"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
return 0
|
||||
fi
|
||||
## increment cut point $i
|
||||
i=$(_math $i + 1)
|
||||
done
|
||||
|
||||
if [ -z "$found" ]; then
|
||||
## find the next page if we dont have a match
|
||||
nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")"
|
||||
if [ -z "$nextpage" ]; then
|
||||
_err "no record and no nextpage in digital ocean DNS removal"
|
||||
return 1
|
||||
fi
|
||||
_debug2 nextpage "$nextpage"
|
||||
DOMURL="$nextpage"
|
||||
fi
|
||||
## increment cut point $i
|
||||
i=$(_math $i + 1)
|
||||
|
||||
done
|
||||
|
||||
## we went through the entire domain zone list and dint find one that matched
|
||||
|
||||
@@ -152,7 +152,7 @@ _get_records() {
|
||||
sub_domain=$3
|
||||
|
||||
_debug "fetching txt records"
|
||||
_dnsimple_rest GET "$account_id/zones/$domain/records?per_page=100"
|
||||
_dnsimple_rest GET "$account_id/zones/$domain/records?per_page=5000&sort=id:desc"
|
||||
|
||||
if ! _contains "$response" "\"id\":"; then
|
||||
_err "failed to retrieve records"
|
||||
|
||||
59
dnsapi/dns_doapi.sh
Executable file
59
dnsapi/dns_doapi.sh
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Official Let's Encrypt API for do.de / Domain-Offensive
|
||||
#
|
||||
# This is different from the dns_do adapter, because dns_do is only usable for enterprise customers
|
||||
# This API is also available to private customers/individuals
|
||||
#
|
||||
# Provide the required LetsEncrypt token like this:
|
||||
# DO_LETOKEN="FmD408PdqT1E269gUK57"
|
||||
|
||||
DO_API="https://www.do.de/api/letsencrypt"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_doapi_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
DO_LETOKEN="${DO_LETOKEN:-$(_readaccountconf_mutable DO_LETOKEN)}"
|
||||
if [ -z "$DO_LETOKEN" ]; then
|
||||
DO_LETOKEN=""
|
||||
_err "You didn't configure a do.de API token yet."
|
||||
_err "Please set DO_LETOKEN and try again."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN"
|
||||
|
||||
_info "Adding TXT record to ${fulldomain}"
|
||||
response="$(_get "$DO_API?token=$DO_LETOKEN&domain=${fulldomain}&value=${txtvalue}")"
|
||||
if _contains "${response}" 'success'; then
|
||||
return 0
|
||||
fi
|
||||
_err "Could not create resource record, check logs"
|
||||
_err "${response}"
|
||||
return 1
|
||||
}
|
||||
|
||||
dns_doapi_rm() {
|
||||
fulldomain=$1
|
||||
|
||||
DO_LETOKEN="${DO_LETOKEN:-$(_readaccountconf_mutable DO_LETOKEN)}"
|
||||
if [ -z "$DO_LETOKEN" ]; then
|
||||
DO_LETOKEN=""
|
||||
_err "You didn't configure a do.de API token yet."
|
||||
_err "Please set DO_LETOKEN and try again."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable DO_LETOKEN "$DO_LETOKEN"
|
||||
|
||||
_info "Deleting resource record $fulldomain"
|
||||
response="$(_get "$DO_API?token=$DO_LETOKEN&domain=${fulldomain}&action=delete")"
|
||||
if _contains "${response}" 'success'; then
|
||||
return 0
|
||||
fi
|
||||
_err "Could not delete resource record, check logs"
|
||||
_err "${response}"
|
||||
return 1
|
||||
}
|
||||
@@ -63,7 +63,7 @@ dns_dp_rm() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'"$txtvalue"'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \")
|
||||
record_id=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2)
|
||||
_debug record_id "$record_id"
|
||||
if [ -z "$record_id" ]; then
|
||||
_err "Can not get record id."
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
Dynu_Token=""
|
||||
#
|
||||
#Endpoint
|
||||
Dynu_EndPoint="https://api.dynu.com/v1"
|
||||
Dynu_EndPoint="https://api.dynu.com/v2"
|
||||
#
|
||||
#Author: Dynu Systems, Inc.
|
||||
#Report Bugs here: https://github.com/shar0119/acme.sh
|
||||
@@ -51,11 +51,11 @@ dns_dynu_add() {
|
||||
_debug _domain_name "$_domain_name"
|
||||
|
||||
_info "Creating TXT record."
|
||||
if ! _dynu_rest POST "dns/record/add" "{\"domain_name\":\"$_domain_name\",\"node_name\":\"$_node\",\"record_type\":\"TXT\",\"text_data\":\"$txtvalue\",\"state\":true,\"ttl\":90}"; then
|
||||
if ! _dynu_rest POST "dns/$dnsId/record" "{\"domainId\":\"$dnsId\",\"nodeName\":\"$_node\",\"recordType\":\"TXT\",\"textData\":\"$txtvalue\",\"state\":true,\"ttl\":90}"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$response" "text_data"; then
|
||||
if ! _contains "$response" "200"; then
|
||||
_err "Could not add TXT record."
|
||||
return 1
|
||||
fi
|
||||
@@ -132,11 +132,12 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _dynu_rest GET "dns/get/$h"; then
|
||||
if ! _dynu_rest GET "dns/getroot/$h"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
|
||||
if _contains "$response" "\"domainName\":\"$h\"" >/dev/null; then
|
||||
dnsId=$(printf "%s" "$response" | tr -d "{}" | cut -d , -f 2 | cut -d : -f 2)
|
||||
_domain_name=$h
|
||||
_node=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
return 0
|
||||
@@ -152,7 +153,7 @@ _get_recordid() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
if ! _dynu_rest GET "dns/record/get?hostname=$fulldomain&rrtype=TXT"; then
|
||||
if ! _dynu_rest GET "dns/$dnsId/record"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -161,19 +162,18 @@ _get_recordid() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
_dns_record_id=$(printf "%s" "$response" | _egrep_o "{[^}]*}" | grep "\"text_data\":\"$txtvalue\"" | _egrep_o ",[^,]*," | grep ',"id":' | tr -d ",," | cut -d : -f 2)
|
||||
|
||||
_dns_record_id=$(printf "%s" "$response" | sed -e 's/[^{]*\({[^}]*}\)[^{]*/\1\n/g' | grep "\"textData\":\"$txtvalue\"" | sed -e 's/.*"id":\([^,]*\).*/\1/')
|
||||
return 0
|
||||
}
|
||||
|
||||
_delete_txt_record() {
|
||||
_dns_record_id=$1
|
||||
|
||||
if ! _dynu_rest GET "dns/record/delete/$_dns_record_id"; then
|
||||
if ! _dynu_rest DELETE "dns/$dnsId/record/$_dns_record_id"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$response" "true"; then
|
||||
if ! _contains "$response" "200"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -189,7 +189,7 @@ _dynu_rest() {
|
||||
export _H1="Authorization: Bearer $Dynu_Token"
|
||||
export _H2="Content-Type: application/json"
|
||||
|
||||
if [ "$data" ]; then
|
||||
if [ "$data" ] || [ "$m" = "DELETE" ]; then
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$Dynu_EndPoint/$ep" "" "$m")"
|
||||
else
|
||||
@@ -216,8 +216,8 @@ _dynu_authentication() {
|
||||
_err "Authentication failed."
|
||||
return 1
|
||||
fi
|
||||
if _contains "$response" "accessToken"; then
|
||||
Dynu_Token=$(printf "%s" "$response" | tr -d "[]" | cut -d , -f 2 | cut -d : -f 2 | cut -d '"' -f 2)
|
||||
if _contains "$response" "access_token"; then
|
||||
Dynu_Token=$(printf "%s" "$response" | tr -d "{}" | cut -d , -f 1 | cut -d : -f 2 | cut -d '"' -f 2)
|
||||
fi
|
||||
if _contains "$Dynu_Token" "null"; then
|
||||
Dynu_Token=""
|
||||
|
||||
60
dnsapi/dns_gandi_livedns.sh
Executable file → Normal file
60
dnsapi/dns_gandi_livedns.sh
Executable file → Normal file
@@ -7,6 +7,7 @@
|
||||
# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
|
||||
#
|
||||
#Author: Frédéric Crozat <fcrozat@suse.com>
|
||||
# Dominik Röttsches <drott@google.com>
|
||||
#Report Bugs here: https://github.com/fcrozat/acme.sh
|
||||
#
|
||||
######## Public functions #####################
|
||||
@@ -36,9 +37,7 @@ dns_gandi_livedns_add() {
|
||||
_debug domain "$_domain"
|
||||
_debug sub_domain "$_sub_domain"
|
||||
|
||||
_gandi_livedns_rest PUT "domains/$_domain/records/$_sub_domain/TXT" "{\"rrset_ttl\": 300, \"rrset_values\":[\"$txtvalue\"]}" \
|
||||
&& _contains "$response" '{"message": "DNS Record Created"}' \
|
||||
&& _info "Add $(__green "success")"
|
||||
_dns_gandi_append_record "$_domain" "$_sub_domain" "$txtvalue"
|
||||
}
|
||||
|
||||
#Usage: fulldomain txtvalue
|
||||
@@ -56,9 +55,23 @@ dns_gandi_livedns_rm() {
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug domain "$_domain"
|
||||
_debug sub_domain "$_sub_domain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
_gandi_livedns_rest DELETE "domains/$_domain/records/$_sub_domain/TXT" ""
|
||||
if ! _dns_gandi_existing_rrset_values "$_domain" "$_sub_domain"; then
|
||||
return 1
|
||||
fi
|
||||
_new_rrset_values=$(echo "$_rrset_values" | sed "s/...$txtvalue...//g")
|
||||
# Cleanup dangling commata.
|
||||
_new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, ,/ ,/g")
|
||||
_new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, *\]/\]/g")
|
||||
_new_rrset_values=$(echo "$_new_rrset_values" | sed "s/\[ *,/\[/g")
|
||||
_debug "New rrset_values" "$_new_rrset_values"
|
||||
|
||||
_gandi_livedns_rest PUT \
|
||||
"domains/$_domain/records/$_sub_domain/TXT" \
|
||||
"{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" \
|
||||
&& _contains "$response" '{"message": "DNS Record Created"}' \
|
||||
&& _info "Removing record $(__green "success")"
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
@@ -98,6 +111,45 @@ _get_root() {
|
||||
return 1
|
||||
}
|
||||
|
||||
_dns_gandi_append_record() {
|
||||
domain=$1
|
||||
sub_domain=$2
|
||||
txtvalue=$3
|
||||
|
||||
if _dns_gandi_existing_rrset_values "$domain" "$sub_domain"; then
|
||||
_debug "Appending new value"
|
||||
_rrset_values=$(echo "$_rrset_values" | sed "s/\"]/\",\"$txtvalue\"]/")
|
||||
else
|
||||
_debug "Creating new record" "$_rrset_values"
|
||||
_rrset_values="[\"$txtvalue\"]"
|
||||
fi
|
||||
_debug new_rrset_values "$_rrset_values"
|
||||
_gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \
|
||||
"{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" \
|
||||
&& _contains "$response" '{"message": "DNS Record Created"}' \
|
||||
&& _info "Adding record $(__green "success")"
|
||||
}
|
||||
|
||||
_dns_gandi_existing_rrset_values() {
|
||||
domain=$1
|
||||
sub_domain=$2
|
||||
if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then
|
||||
return 1
|
||||
fi
|
||||
if ! _contains "$response" '"rrset_type": "TXT"'; then
|
||||
_debug "Does not have a _acme-challenge TXT record yet."
|
||||
return 1
|
||||
fi
|
||||
if _contains "$response" '"rrset_values": \[\]'; then
|
||||
_debug "Empty rrset_values for TXT record, no previous TXT record."
|
||||
return 1
|
||||
fi
|
||||
_debug "Already has TXT record."
|
||||
_rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' \
|
||||
| _egrep_o '\[".*\"]')
|
||||
return 0
|
||||
}
|
||||
|
||||
_gandi_livedns_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
|
||||
@@ -59,9 +59,22 @@ _hostingde_getZoneConfig() {
|
||||
if _contains "${curResult}" '"totalEntries": 1'; then
|
||||
_info "Retrieved zone data."
|
||||
_debug "Zone data: '${curResult}'"
|
||||
|
||||
# read ZoneConfigId for later update
|
||||
zoneConfigId=$(echo "${curResult}" | _egrep_o '"id":.*' | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
zoneConfigName=$(echo "${curResult}" | _egrep_o '"name":.*' | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
zoneConfigType=$(echo "${curResult}" | grep -v "FindZoneConfigsResult" | _egrep_o '"type":.*' | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
zoneConfigExpire=$(echo "${curResult}" | _egrep_o '"expire":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1)
|
||||
zoneConfigNegativeTtl=$(echo "${curResult}" | _egrep_o '"negativeTtl":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1)
|
||||
zoneConfigRefresh=$(echo "${curResult}" | _egrep_o '"refresh":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1)
|
||||
zoneConfigRetry=$(echo "${curResult}" | _egrep_o '"retry":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1)
|
||||
zoneConfigTtl=$(echo "${curResult}" | _egrep_o '"ttl":.*' | cut -d ':' -f 2 | cut -d '"' -f 2 | cut -d ',' -f 1)
|
||||
zoneConfigDnsServerGroupId=$(echo "${curResult}" | _egrep_o '"dnsServerGroupId":.*' | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
zoneConfigEmailAddress=$(echo "${curResult}" | _egrep_o '"emailAddress":.*' | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
zoneConfigDnsSecMode=$(echo "${curResult}" | _egrep_o '"dnsSecMode":.*' | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
if [ "${zoneConfigType}" != "NATIVE" ]; then
|
||||
_err "Zone is not native"
|
||||
returnCode=1
|
||||
break
|
||||
fi
|
||||
_debug "zoneConfigId '${zoneConfigId}'"
|
||||
returnCode=0
|
||||
break
|
||||
@@ -74,9 +87,27 @@ _hostingde_getZoneConfig() {
|
||||
return $returnCode
|
||||
}
|
||||
|
||||
_hostingde_getZoneStatus() {
|
||||
_debug "Checking Zone status"
|
||||
curData="{\"filter\":{\"field\":\"zoneConfigId\",\"value\":\"${zoneConfigId}\"},\"limit\":1,\"authToken\":\"${HOSTINGDE_APIKEY}\"}"
|
||||
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zonesFind")"
|
||||
_debug "Calling zonesFind '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zonesFind'"
|
||||
_debug "Result of zonesFind '$curResult'"
|
||||
zoneStatus=$(echo "${curResult}" | grep -v success | _egrep_o '"status":.*' | cut -d ':' -f 2 | cut -d '"' -f 2)
|
||||
_debug "zoneStatus '${zoneStatus}'"
|
||||
return 0
|
||||
}
|
||||
|
||||
_hostingde_addRecord() {
|
||||
_info "Adding record to zone"
|
||||
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\"},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}"
|
||||
_hostingde_getZoneStatus
|
||||
_debug "Result of zoneStatus: '${zoneStatus}'"
|
||||
while [ "${zoneStatus}" != "active" ]; do
|
||||
_sleep 5
|
||||
_hostingde_getZoneStatus
|
||||
_debug "Result of zoneStatus: '${zoneStatus}'"
|
||||
done
|
||||
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\",\"name\":\"${zoneConfigName}\",\"type\":\"${zoneConfigType}\",\"dnsServerGroupId\":\"${zoneConfigDnsServerGroupId}\",\"dnsSecMode\":\"${zoneConfigDnsSecMode}\",\"emailAddress\":\"${zoneConfigEmailAddress}\",\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToAdd\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\",\"ttl\":3600}]}"
|
||||
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")"
|
||||
_debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'"
|
||||
_debug "Result of zoneUpdate: '$curResult'"
|
||||
@@ -93,7 +124,14 @@ _hostingde_addRecord() {
|
||||
|
||||
_hostingde_removeRecord() {
|
||||
_info "Removing record from zone"
|
||||
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\"},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}"
|
||||
_hostingde_getZoneStatus
|
||||
_debug "Result of zoneStatus: '$zoneStatus'"
|
||||
while [ "$zoneStatus" != "active" ]; do
|
||||
_sleep 5
|
||||
_hostingde_getZoneStatus
|
||||
_debug "Result of zoneStatus: '$zoneStatus'"
|
||||
done
|
||||
curData="{\"authToken\":\"${HOSTINGDE_APIKEY}\",\"zoneConfig\":{\"id\":\"${zoneConfigId}\",\"name\":\"${zoneConfigName}\",\"type\":\"${zoneConfigType}\",\"dnsServerGroupId\":\"${zoneConfigDnsServerGroupId}\",\"dnsSecMode\":\"${zoneConfigDnsSecMode}\",\"emailAddress\":\"${zoneConfigEmailAddress}\",\"soaValues\":{\"expire\":${zoneConfigExpire},\"negativeTtl\":${zoneConfigNegativeTtl},\"refresh\":${zoneConfigRefresh},\"retry\":${zoneConfigRetry},\"ttl\":${zoneConfigTtl}}},\"recordsToDelete\":[{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"\\\"${txtvalue}\\\"\"}]}"
|
||||
curResult="$(_post "${curData}" "${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate")"
|
||||
_debug "Calling zoneUpdate: '${curData}' '${HOSTINGDE_ENDPOINT}/api/dns/v1/json/zoneUpdate'"
|
||||
_debug "Result of zoneUpdate: '$curResult'"
|
||||
|
||||
@@ -158,7 +158,8 @@ _inwx_login() {
|
||||
export _H1
|
||||
|
||||
#https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71
|
||||
if _contains "$response" "tfa"; then
|
||||
if _contains "$response" "<member><name>code</name><value><int>1000</int></value></member>" \
|
||||
&& _contains "$response" "<member><name>tfa</name><value><string>GOOGLE-AUTH</string></value></member>"; then
|
||||
if [ -z "$INWX_Shared_Secret" ]; then
|
||||
_err "Mobile TAN detected."
|
||||
_err "Please define a shared secret."
|
||||
|
||||
@@ -8,7 +8,7 @@ LINODE_V4_API_URL="https://api.linode.com/v4/domains"
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: dns_linode_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_linode_add() {
|
||||
dns_linode_v4_add() {
|
||||
fulldomain="${1}"
|
||||
txtvalue="${2}"
|
||||
|
||||
@@ -51,7 +51,7 @@ dns_linode_add() {
|
||||
}
|
||||
|
||||
#Usage: dns_linode_rm _acme-challenge.www.domain.com
|
||||
dns_linode_rm() {
|
||||
dns_linode_v4_rm() {
|
||||
fulldomain="${1}"
|
||||
|
||||
if ! _Linode_API; then
|
||||
|
||||
@@ -38,8 +38,8 @@ dns_loopia_add() {
|
||||
|
||||
_info "Adding record"
|
||||
|
||||
_loopia_add_record "$_domain" "$_sub_domain"
|
||||
_loopia_update_record "$_domain" "$_sub_domain" "$txtvalue"
|
||||
_loopia_add_sub_domain "$_domain" "$_sub_domain"
|
||||
_loopia_add_record "$_domain" "$_sub_domain" "$txtvalue"
|
||||
|
||||
}
|
||||
|
||||
@@ -96,6 +96,37 @@ dns_loopia_rm() {
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
_loopia_get_records() {
|
||||
domain=$1
|
||||
sub_domain=$2
|
||||
|
||||
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>getZoneRecords</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value><string>%s</string></value>
|
||||
</param>
|
||||
<param>
|
||||
<value><string>%s</string></value>
|
||||
</param>
|
||||
<param>
|
||||
<value><string>%s</string></value>
|
||||
</param>
|
||||
<param>
|
||||
<value><string>%s</string></value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain")
|
||||
|
||||
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
|
||||
if ! _contains "$response" "<array>"; then
|
||||
_err "Error"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_get_root() {
|
||||
domain=$1
|
||||
_debug "get root"
|
||||
@@ -137,14 +168,14 @@ _get_root() {
|
||||
|
||||
}
|
||||
|
||||
_loopia_update_record() {
|
||||
_loopia_add_record() {
|
||||
domain=$1
|
||||
sub_domain=$2
|
||||
txtval=$3
|
||||
|
||||
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>updateZoneRecord</methodName>
|
||||
<methodName>addZoneRecord</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value><string>%s</string></value>
|
||||
@@ -176,10 +207,6 @@ _loopia_update_record() {
|
||||
<name>rdata</name>
|
||||
<value><string>%s</string></value>
|
||||
</member>
|
||||
<member>
|
||||
<name>record_id</name>
|
||||
<value><int>0</int></value>
|
||||
</member>
|
||||
</struct>
|
||||
</param>
|
||||
</params>
|
||||
@@ -194,10 +221,42 @@ _loopia_update_record() {
|
||||
return 0
|
||||
}
|
||||
|
||||
_loopia_add_record() {
|
||||
_sub_domain_exists() {
|
||||
domain=$1
|
||||
sub_domain=$2
|
||||
|
||||
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>getSubdomains</methodName>
|
||||
<params>
|
||||
<param>
|
||||
<value><string>%s</string></value>
|
||||
</param>
|
||||
<param>
|
||||
<value><string>%s</string></value>
|
||||
</param>
|
||||
<param>
|
||||
<value><string>%s</string></value>
|
||||
</param>
|
||||
</params>
|
||||
</methodCall>' $LOOPIA_User $LOOPIA_Password "$domain")
|
||||
|
||||
response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
|
||||
|
||||
if _contains "$response" "$sub_domain"; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
_loopia_add_sub_domain() {
|
||||
domain=$1
|
||||
sub_domain=$2
|
||||
|
||||
if _sub_domain_exists "$domain" "$sub_domain"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<methodCall>
|
||||
<methodName>addSubdomain</methodName>
|
||||
|
||||
@@ -3,16 +3,15 @@
|
||||
# Namecheap API
|
||||
# https://www.namecheap.com/support/api/intro.aspx
|
||||
#
|
||||
# Requires Namecheap API key set in NAMECHEAP_API_KEY, NAMECHEAP_SOURCEIP and NAMECHEAP_USERNAME set as environment variable
|
||||
# Requires Namecheap API key set in
|
||||
#NAMECHEAP_API_KEY,
|
||||
#NAMECHEAP_USERNAME,
|
||||
#NAMECHEAP_SOURCEIP
|
||||
# Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
if [ "$STAGE" -eq 1 ]; then
|
||||
NAMECHEAP_API="https://api.sandbox.namecheap.com/xml.response"
|
||||
else
|
||||
NAMECHEAP_API="https://api.namecheap.com/xml.response"
|
||||
fi
|
||||
NAMECHEAP_API="https://api.namecheap.com/xml.response"
|
||||
|
||||
#Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_namecheap_add() {
|
||||
@@ -144,7 +143,7 @@ _namecheap_set_publicip() {
|
||||
_namecheap_post() {
|
||||
command=$1
|
||||
data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}"
|
||||
|
||||
_debug2 "_namecheap_post data" "$data"
|
||||
response="$(_post "$data" "$NAMECHEAP_API" "" "POST")"
|
||||
_debug2 response "$response"
|
||||
|
||||
@@ -161,12 +160,12 @@ _namecheap_parse_host() {
|
||||
_host=$1
|
||||
_debug _host "$_host"
|
||||
|
||||
_hostid=$(echo "$_host" | _egrep_o '\sHostId="[^"]*' | cut -d '"' -f 2)
|
||||
_hostname=$(echo "$_host" | _egrep_o '\sName="[^"]*' | cut -d '"' -f 2)
|
||||
_hosttype=$(echo "$_host" | _egrep_o '\sType="[^"]*' | cut -d '"' -f 2)
|
||||
_hostaddress=$(echo "$_host" | _egrep_o '\sAddress="[^"]*' | cut -d '"' -f 2)
|
||||
_hostmxpref=$(echo "$_host" | _egrep_o '\sMXPref="[^"]*' | cut -d '"' -f 2)
|
||||
_hostttl=$(echo "$_host" | _egrep_o '\sTTL="[^"]*' | cut -d '"' -f 2)
|
||||
_hostid=$(echo "$_host" | _egrep_o ' HostId="[^"]*' | cut -d '"' -f 2)
|
||||
_hostname=$(echo "$_host" | _egrep_o ' Name="[^"]*' | cut -d '"' -f 2)
|
||||
_hosttype=$(echo "$_host" | _egrep_o ' Type="[^"]*' | cut -d '"' -f 2)
|
||||
_hostaddress=$(echo "$_host" | _egrep_o ' Address="[^"]*' | cut -d '"' -f 2)
|
||||
_hostmxpref=$(echo "$_host" | _egrep_o ' MXPref="[^"]*' | cut -d '"' -f 2)
|
||||
_hostttl=$(echo "$_host" | _egrep_o ' TTL="[^"]*' | cut -d '"' -f 2)
|
||||
|
||||
_debug hostid "$_hostid"
|
||||
_debug hostname "$_hostname"
|
||||
@@ -199,9 +198,12 @@ _namecheap_check_config() {
|
||||
_set_namecheap_TXT() {
|
||||
subdomain=$2
|
||||
txt=$3
|
||||
tld=$(echo "$1" | cut -d '.' -f 2)
|
||||
sld=$(echo "$1" | cut -d '.' -f 1)
|
||||
request="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld"
|
||||
|
||||
if ! _namecheap_set_tld_sld "$1"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}"
|
||||
|
||||
if ! _namecheap_post "$request"; then
|
||||
_err "$error"
|
||||
@@ -221,6 +223,12 @@ _set_namecheap_TXT() {
|
||||
while read -r host; do
|
||||
if _contains "$host" "<host"; then
|
||||
_namecheap_parse_host "$host"
|
||||
_debug2 _hostname "_hostname"
|
||||
_debug2 _hosttype "_hosttype"
|
||||
_debug2 _hostaddress "_hostaddress"
|
||||
_debug2 _hostmxpref "_hostmxpref"
|
||||
_hostaddress="$(printf "%s" "$_hostaddress" | _url_encode)"
|
||||
_debug2 "encoded _hostaddress" "_hostaddress"
|
||||
_namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
|
||||
fi
|
||||
done <<EOT
|
||||
@@ -231,7 +239,7 @@ EOT
|
||||
|
||||
_debug hostrequestfinal "$_hostrequest"
|
||||
|
||||
request="namecheap.domains.dns.setHosts&SLD=${sld}&TLD=${tld}${_hostrequest}"
|
||||
request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
|
||||
|
||||
if ! _namecheap_post "$request"; then
|
||||
_err "$error"
|
||||
@@ -244,9 +252,12 @@ EOT
|
||||
_del_namecheap_TXT() {
|
||||
subdomain=$2
|
||||
txt=$3
|
||||
tld=$(echo "$1" | cut -d '.' -f 2)
|
||||
sld=$(echo "$1" | cut -d '.' -f 1)
|
||||
request="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld"
|
||||
|
||||
if ! _namecheap_set_tld_sld "$1"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
request="namecheap.domains.dns.getHosts&SLD=${_sld}&TLD=${_tld}"
|
||||
|
||||
if ! _namecheap_post "$request"; then
|
||||
_err "$error"
|
||||
@@ -272,6 +283,7 @@ _del_namecheap_TXT() {
|
||||
_debug "TXT entry found"
|
||||
found=1
|
||||
else
|
||||
_hostaddress="$(printf "%s" "$_hostaddress" | _url_encode)"
|
||||
_namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl"
|
||||
fi
|
||||
fi
|
||||
@@ -286,7 +298,7 @@ EOT
|
||||
|
||||
_debug hostrequestfinal "$_hostrequest"
|
||||
|
||||
request="namecheap.domains.dns.setHosts&SLD=${sld}&TLD=${tld}${_hostrequest}"
|
||||
request="namecheap.domains.dns.setHosts&SLD=${_sld}&TLD=${_tld}${_hostrequest}"
|
||||
|
||||
if ! _namecheap_post "$request"; then
|
||||
_err "$error"
|
||||
@@ -306,3 +318,45 @@ _namecheap_add_host() {
|
||||
_hostindex=$(_math "$_hostindex" + 1)
|
||||
_hostrequest=$(printf '%s&HostName%d=%s&RecordType%d=%s&Address%d=%s&MXPref%d=%d&TTL%d=%d' "$_hostrequest" "$_hostindex" "$1" "$_hostindex" "$2" "$_hostindex" "$3" "$_hostindex" "$4" "$_hostindex" "$5")
|
||||
}
|
||||
|
||||
_namecheap_set_tld_sld() {
|
||||
domain=$1
|
||||
_tld=""
|
||||
_sld=""
|
||||
|
||||
i=2
|
||||
|
||||
while true; do
|
||||
|
||||
_tld=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug tld "$_tld"
|
||||
|
||||
if [ -z "$_tld" ]; then
|
||||
_debug "invalid tld"
|
||||
return 1
|
||||
fi
|
||||
|
||||
j=$(_math "$i" - 1)
|
||||
|
||||
_sld=$(printf "%s" "$domain" | cut -d . -f 1-"$j")
|
||||
_debug sld "$_sld"
|
||||
|
||||
if [ -z "$_sld" ]; then
|
||||
_debug "invalid sld"
|
||||
return 1
|
||||
fi
|
||||
|
||||
request="namecheap.domains.dns.getHosts&SLD=$_sld&TLD=$_tld"
|
||||
|
||||
if ! _namecheap_post "$request"; then
|
||||
_debug "sld($_sld)/tld($_tld) not found"
|
||||
else
|
||||
_debug "sld($_sld)/tld($_tld) found"
|
||||
return 0
|
||||
fi
|
||||
|
||||
i=$(_math "$i" + 1)
|
||||
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
164
dnsapi/dns_pointhq.sh
Normal file
164
dnsapi/dns_pointhq.sh
Normal file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
#PointHQ_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||
#
|
||||
#PointHQ_Email="xxxx@sss.com"
|
||||
|
||||
PointHQ_Api="https://api.pointhq.com"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_pointhq_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
PointHQ_Key="${PointHQ_Key:-$(_readaccountconf_mutable PointHQ_Key)}"
|
||||
PointHQ_Email="${PointHQ_Email:-$(_readaccountconf_mutable PointHQ_Email)}"
|
||||
if [ -z "$PointHQ_Key" ] || [ -z "$PointHQ_Email" ]; then
|
||||
PointHQ_Key=""
|
||||
PointHQ_Email=""
|
||||
_err "You didn't specify a PointHQ API key and email yet."
|
||||
_err "Please create the key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$PointHQ_Email" "@"; then
|
||||
_err "It seems that the PointHQ_Email=$PointHQ_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 PointHQ_Key "$PointHQ_Key"
|
||||
_saveaccountconf_mutable PointHQ_Email "$PointHQ_Email"
|
||||
|
||||
_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"
|
||||
|
||||
_info "Adding record"
|
||||
if _pointhq_rest POST "zones/$_domain/records" "{\"zone_record\": {\"name\":\"$_sub_domain\",\"record_type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":3600}}"; then
|
||||
if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; 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_pointhq_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
PointHQ_Key="${PointHQ_Key:-$(_readaccountconf_mutable PointHQ_Key)}"
|
||||
PointHQ_Email="${PointHQ_Email:-$(_readaccountconf_mutable PointHQ_Email)}"
|
||||
if [ -z "$PointHQ_Key" ] || [ -z "$PointHQ_Email" ]; then
|
||||
PointHQ_Key=""
|
||||
PointHQ_Email=""
|
||||
_err "You didn't specify a PointHQ API key and email yet."
|
||||
_err "Please create the key and try again."
|
||||
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"
|
||||
_pointhq_rest GET "zones/${_domain}/records?record_type=TXT&name=$_sub_domain"
|
||||
|
||||
if ! printf "%s" "$response" | grep "^\[" >/dev/null; then
|
||||
_err "Error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$response" = "[]" ]; then
|
||||
_info "No records to remove."
|
||||
else
|
||||
record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | cut -d : -f 2 | tr -d \" | head -n 1)
|
||||
_debug "record_id" "$record_id"
|
||||
if [ -z "$record_id" ]; then
|
||||
_err "Can not get record id to remove."
|
||||
return 1
|
||||
fi
|
||||
if ! _pointhq_rest DELETE "zones/$_domain/records/$record_id"; then
|
||||
_err "Delete record error."
|
||||
return 1
|
||||
fi
|
||||
_contains "$response" '"status":"OK"'
|
||||
fi
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_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)
|
||||
_debug h "$h"
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _pointhq_rest GET "zones"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"name\":\"$h\"" >/dev/null; 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
|
||||
}
|
||||
|
||||
_pointhq_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
|
||||
_pointhq_auth=$(printf "%s:%s" "$PointHQ_Email" "$PointHQ_Key" | _base64)
|
||||
|
||||
export _H1="Authorization: Basic $_pointhq_auth"
|
||||
export _H2="Content-Type: application/json"
|
||||
export _H3="Accept: application/json"
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$PointHQ_Api/$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$PointHQ_Api/$ep")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $ep"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user