Merge remote-tracking branch 'upstream/master' into FreeDNS

This commit is contained in:
David Kerr 2017-01-31 17:47:59 -05:00
commit d85dab440f
9 changed files with 219 additions and 16 deletions

View File

@ -269,6 +269,7 @@ You don't have to do anything manually!
1. aliyun.com(阿里云) API 1. aliyun.com(阿里云) API
1. ISPConfig 3.1 API 1. ISPConfig 3.1 API
1. Alwaysdata.com API 1. Alwaysdata.com API
1. Linode.com API
**More APIs coming soon...** **More APIs coming soon...**

View File

@ -344,11 +344,7 @@ _is_solaris() {
#input:"abc" #input:"abc"
#output: " 61 62 63" #output: " 61 62 63"
_hex_dump() { _hex_dump() {
if _is_solaris; then od -A n -v -t x1 | tr -d "\r\t" | tr -s " " | sed "s/ $//" | tr -d "\n"
od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | tr -d "\n"
else
od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | sed "s/ $//" | tr -d "\n"
fi
} }
#url encode, no-preserved chars #url encode, no-preserved chars

View File

@ -257,6 +257,27 @@ acme.sh --issue --dns dns_ad -d example.com -d www.example.com
The `AD_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused The `AD_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused
when needed. when needed.
## 14. Use Linode domain API
First you need to login to your Linode account to get your API Key.
[https://manager.linode.com/profile/api](https://manager.linode.com/profile/api)
Then add an API key with label *ACME* and copy the new key.
```sh
export LINODE_API_KEY="..."
```
Due to the reload time of any changes in the DNS records, we have to use the `dnssleep` option to wait at least 15 minutes for the changes to take effect.
Ok, let's issue a cert now:
```sh
acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.com
```
The `LINODE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
# Use custom API # Use custom API
If your API is not supported yet, you can write your own DNS API. If your API is not supported yet, you can write your own DNS API.

View File

@ -67,7 +67,7 @@ _get_root() {
} }
_ali_rest() { _ali_rest() {
signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | sed "s/ //g")" | _base64) signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64)
signature=$(_ali_urlencode "$signature") signature=$(_ali_urlencode "$signature")
url="$Ali_API?$query&Signature=$signature" url="$Ali_API?$query&Signature=$signature"

View File

@ -93,7 +93,7 @@ _get_root() {
fi fi
if _contains "$response" "<Name>$h.</Name>"; then if _contains "$response" "<Name>$h.</Name>"; then
hostedzone="$(echo "$response" | sed 's/<HostedZone>/\n&/g' | _egrep_o "<HostedZone>.*?<Name>$h.<.Name>.*?<.HostedZone>")" hostedzone="$(echo "$response" | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<.HostedZone>")"
_debug hostedzone "$hostedzone" _debug hostedzone "$hostedzone"
if [ -z "$hostedzone" ]; then if [ -z "$hostedzone" ]; then
_err "Error, can not get hostedzone." _err "Error, can not get hostedzone."
@ -183,7 +183,7 @@ aws_rest() {
_debug2 kSecret "$kSecret" _debug2 kSecret "$kSecret"
kSecretH="$(printf "%s" "$kSecret" | _hex_dump | sed "s/ //g")" kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")"
_debug2 kSecretH "$kSecretH" _debug2 kSecretH "$kSecretH"
kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)"

View File

@ -82,7 +82,7 @@ existing_records() {
return 1 return 1
fi fi
seg=$(printf "%s\n" "$response" | _egrep_o '[^{]*host":"'"$_sub_domain"'"[^}]*\}') seg=$(printf "%s\n" "$response" | _egrep_o '"record_id":[^{]*host":"'"$_sub_domain"'"[^}]*\}')
_debug seg "$seg" _debug seg "$seg"
if [ -z "$seg" ]; then if [ -z "$seg" ]; then
return 0 return 0
@ -155,7 +155,7 @@ _get_root() {
fi fi
if _contains "$response" "$h."; then if _contains "$response" "$h."; then
seg=$(printf "%s\n" "$response" | _egrep_o '[^{]*"'"$h"'."[^}]*}') seg=$(printf "%s\n" "$response" | _egrep_o '"id":[^{]*"'"$h"'."[^}]*}')
_debug seg "$seg" _debug seg "$seg"
_domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")
_debug _domain_id "$_domain_id" _debug _domain_id "$_domain_id"

183
dnsapi/dns_linode.sh Executable file
View File

@ -0,0 +1,183 @@
#!/usr/bin/env sh
#Author: Philipp Grosswiler <philipp.grosswiler@swiss-design.net>
LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action="
######## Public functions #####################
#Usage: dns_linode_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_linode_add() {
fulldomain="${1}"
txtvalue="${2}"
if ! _Linode_API; then
return 1
fi
_info "Using Linode"
_debug "Calling: dns_linode_add() '${fulldomain}' '${txtvalue}'"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "Domain does not exist."
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_parameters="&DomainID=$_domain_id&Type=TXT&Name=$_sub_domain&Target=$txtvalue"
if _rest GET "domain.resource.create" "$_parameters" && [ -n "$response" ]; then
_resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1)
_debug _resource_id "$_resource_id"
if [ -z "$_resource_id" ]; then
_err "Error adding the domain resource."
return 1
fi
_info "Domain resource successfully added."
return 0
fi
return 1
}
#Usage: dns_linode_rm _acme-challenge.www.domain.com
dns_linode_rm() {
fulldomain="${1}"
if ! _Linode_API; then
return 1
fi
_info "Using Linode"
_debug "Calling: dns_linode_rm() '${fulldomain}'"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "Domain does not exist."
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_parameters="&DomainID=$_domain_id"
if _rest GET "domain.resource.list" "$_parameters" && [ -n "$response" ]; then
response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"
resource="$(echo "$response" | _egrep_o "{.*\"NAME\":\s*\"$_sub_domain\".*}")"
if [ "$resource" ]; then
_resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"RESOURCEID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
if [ "$_resource_id" ]; then
_debug _resource_id "$_resource_id"
_parameters="&DomainID=$_domain_id&ResourceID=$_resource_id"
if _rest GET "domain.resource.delete" "$_parameters" && [ -n "$response" ]; then
_resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1)
_debug _resource_id "$_resource_id"
if [ -z "$_resource_id" ]; then
_err "Error deleting the domain resource."
return 1
fi
_info "Domain resource successfully deleted."
return 0
fi
fi
return 1
fi
return 0
fi
return 1
}
#################### Private functions below ##################################
_Linode_API() {
if [ -z "$LINODE_API_KEY" ]; then
LINODE_API_KEY=""
_err "You didn't specify the Linode API key yet."
_err "Please create your key and try again."
return 1
fi
_saveaccountconf LINODE_API_KEY "$LINODE_API_KEY"
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=12345
_get_root() {
domain=$1
i=2
p=1
if _rest GET "domain.list"; then
response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
hostedzone="$(echo "$response" | _egrep_o "{.*\"DOMAIN\":\s*\"$h\".*}")"
if [ "$hostedzone" ]; then
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"DOMAINID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
fi
return 1
}
#method method action data
_rest() {
mtd="$1"
ep="$2"
data="$3"
_debug mtd "$mtd"
_debug ep "$ep"
export _H1="Accept: application/json"
export _H2="Content-Type: application/json"
if [ "$mtd" != "GET" ]; then
# both POST and DELETE.
_debug data "$data"
response="$(_post "$data" "$LINODE_API_URL$ep" "" "$mtd")"
else
response="$(_get "$LINODE_API_URL$ep$data")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@ -46,12 +46,12 @@ dns_lua_add() {
return 1 return 1
fi fi
count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l) count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | wc -l | tr -d " ")
_debug count "$count" _debug count "$count"
if [ "$count" = "0" ]; then if [ "$count" = "0" ]; then
_info "Adding record" _info "Adding record"
if _LUA_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"ttl\":120}"; then if _LUA_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then if _contains "$response" "$fulldomain"; then
_info "Added" _info "Added"
#todo: check if the record takes effect #todo: check if the record takes effect
return 0 return 0
@ -63,11 +63,11 @@ dns_lua_add() {
_err "Add txt record error." _err "Add txt record error."
else else
_info "Updating record" _info "Updating record"
record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | cut -d: -f2 | cut -d, -f1) record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | _head_n 1 | cut -d: -f2 | cut -d, -f1)
_debug "record_id" "$record_id" _debug "record_id" "$record_id"
_LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"ttl\":120}" _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":$record_id,\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":$_domain_id,\"ttl\":120}"
if [ "$?" = "0" ]; then if [ "$?" = "0" ] && _contains "$response" "updated_at" ; then
_info "Updated!" _info "Updated!"
#todo: check if the record takes effect #todo: check if the record takes effect
return 0 return 0
@ -99,6 +99,7 @@ _get_root() {
fi fi
while true; do while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100) h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then if [ -z "$h" ]; then
#not valid #not valid
return 1 return 1
@ -106,6 +107,7 @@ _get_root() {
if _contains "$response" "\"name\":\"$h\""; then if _contains "$response" "\"name\":\"$h\""; then
_domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$h\"" | cut -d : -f 2 | cut -d , -f 1) _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$h\"" | cut -d : -f 2 | cut -d , -f 1)
_debug _domain_id "$_domain_id"
if [ "$_domain_id" ]; then if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="$h" _domain="$h"

View File

@ -124,7 +124,7 @@ _me_rest() {
_debug "$ep" _debug "$ep"
cdate=$(date -u +"%a, %d %b %Y %T %Z") cdate=$(date -u +"%a, %d %b %Y %T %Z")
hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(printf "%s" "$ME_Secret" | _hex_dump | sed "s/ //g")" hex) hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(printf "%s" "$ME_Secret" | _hex_dump | tr -d " ")" hex)
export _H1="x-dnsme-apiKey: $ME_Key" export _H1="x-dnsme-apiKey: $ME_Key"
export _H2="x-dnsme-requestDate: $cdate" export _H2="x-dnsme-requestDate: $cdate"