Browse Source

Add DNS API support for aliyun (#410)

* Add DNS API support for aliyun

* Update README.md

* format

* format

* format

* format...

* format...

* format

* format

* fix bug

* fix bug

* code format

* code format

* fix bug

* just ok...

* fix bug

* fix bug

* fix bug

* change "echo" to "printf"

* fix bug

* code format

* fix bug."head -c" in function _ali_nonce not supported by solaris

* fix bug."head -c" in function _ali_nonce not supported by solaris

* format

* fix bug._ali_nonce not work on solaris

* fix bug. _ali_nonce not work on solaris

* fix bug. _ali_nonce not work on solaris

* add aliyun.com to README.md
baiyangliu 8 years ago
parent
commit
be39ab32d1
3 changed files with 206 additions and 2 deletions
  1. 1 0
      README.md
  2. 19 2
      dnsapi/README.md
  3. 186 0
      dnsapi/dns_ali.sh

+ 1 - 0
README.md

@@ -260,6 +260,7 @@ You don't have to do anything manually!
 1. LuaDNS.com API
 1. LuaDNS.com API
 1. DNSMadeEasy.com API
 1. DNSMadeEasy.com API
 1. nsupdate API
 1. nsupdate API
+1. aliyun.com(阿里云) API
 
 
 **More APIs coming soon...**
 **More APIs coming soon...**
 
 

+ 19 - 2
dnsapi/README.md

@@ -201,7 +201,24 @@ acme.sh --issue --dns dns_aws -d example.com -d www.example.com
 
 
 The `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 The `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 
 
-# 11. Use custom API
+## 11. Use Aliyun domain API to automatically issue cert
+
+First you need to login to your Aliyun account to get your API key.
+[https://ak-console.aliyun.com/#/accesskey](https://ak-console.aliyun.com/#/accesskey)
+
+```
+export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
+export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"
+```
+
+Ok, let's issue a cert now:
+```
+acme.sh --issue --dns dns_ali -d example.com -d www.example.com
+```
+
+The `Ali_Key` and `Ali_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
+
+# 12. 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.
 
 
@@ -218,6 +235,6 @@ acme.sh --issue --dns dns_myapi -d example.com -d www.example.com
 For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh)
 For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh)
 
 
 
 
-## 12. Use lexicon DNS API
+## 13. Use lexicon DNS API
 
 
 https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
 https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api

+ 186 - 0
dnsapi/dns_ali.sh

@@ -0,0 +1,186 @@
+#!/usr/bin/env sh
+
+Ali_API="https://alidns.aliyuncs.com/"
+
+#Ali_Key="LTqIA87hOKdjevsf5"
+#Ali_Secret="0p5EYueFNq501xnCPzKNbx6K51qPH2"
+
+#Usage: dns_ali_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_ali_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then
+    Ali_Key=""
+    Ali_Secret=""
+    _err "You don't specify aliyun api key and secret yet."
+    return 1
+  fi
+
+  #save the api key and secret to the account conf file.
+  _saveaccountconf Ali_Key "$Ali_Key"
+  _saveaccountconf Ali_Secret "$Ali_Secret"
+
+  _debug "First detect the root zone"
+  if ! _get_root "$fulldomain"; then
+    return 1
+  fi
+
+  _add_record_query "$_domain" "$_sub_domain" "$txtvalue" && _ali_rest "Add record"
+}
+
+dns_ali_rm() {
+  fulldomain=$1
+  _clean
+}
+
+####################  Private functions bellow ##################################
+
+_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
+
+    _describe_records_query "$h"
+    if ! _ali_rest "Get root" "ignore"; then
+      return 1
+    fi
+
+    if _contains "$response" "PageNumber"; then
+      _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
+      _debug _sub_domain "$_sub_domain"
+      _domain="$h"
+      _debug _domain "$_domain"
+      return 0
+    fi
+    p="$i"
+    i=$(_math "$i" + 1)
+  done
+  return 1
+}
+
+_ali_rest() {
+  signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(_hex "$Ali_Secret&")" | _base64)
+  signature=$(_ali_urlencode "$signature")
+  url="$Ali_API?$query&Signature=$signature"
+
+  if ! response="$(_get "$url")"; then
+    _err "Error <$1>"
+    return 1
+  fi
+
+  if [ -z "$2" ]; then
+    message="$(printf "%s" "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
+    if [ -n "$message" ]; then
+      _err "$message"
+      return 1
+    fi
+  fi
+
+  _debug2 response "$response"
+  return 0
+}
+
+_ali_urlencode() {
+  _str="$1"
+  _str_len=${#_str}
+  _u_i=1
+  while [ "$_u_i" -le "$_str_len" ]; do
+    _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")"
+    case $_str_c in [a-zA-Z0-9.~_-])
+      printf "%s" "$_str_c"
+      ;;
+    *)
+      printf "%%%02X" "'$_str_c"
+      ;;
+    esac
+    _u_i="$(_math "$_u_i" + 1)"
+  done
+}
+
+_ali_nonce() {
+  #_head_n 1 </dev/urandom | _digest "sha256" hex | cut -c 1-31
+  #Not so good...
+  date +"%s%N"
+}
+
+_check_exist_query() {
+  query=''
+  query=$query'AccessKeyId='$Ali_Key
+  query=$query'&Action=DescribeDomainRecords'
+  query=$query'&DomainName='$1
+  query=$query'&Format=json'
+  query=$query'&RRKeyWord=_acme-challenge'
+  query=$query'&SignatureMethod=HMAC-SHA1'
+  query=$query"&SignatureNonce=$(_ali_nonce)"
+  query=$query'&SignatureVersion=1.0'
+  query=$query'&Timestamp='$(_timestamp)
+  query=$query'&TypeKeyWord=TXT'
+  query=$query'&Version=2015-01-09'
+}
+
+_add_record_query() {
+  query=''
+  query=$query'AccessKeyId='$Ali_Key
+  query=$query'&Action=AddDomainRecord'
+  query=$query'&DomainName='$1
+  query=$query'&Format=json'
+  query=$query'&RR='$2
+  query=$query'&SignatureMethod=HMAC-SHA1'
+  query=$query"&SignatureNonce=$(_ali_nonce)"
+  query=$query'&SignatureVersion=1.0'
+  query=$query'&Timestamp='$(_timestamp)
+  query=$query'&Type=TXT'
+  query=$query'&Value='$3
+  query=$query'&Version=2015-01-09'
+}
+
+_delete_record_query() {
+  query=''
+  query=$query'AccessKeyId='$Ali_Key
+  query=$query'&Action=DeleteDomainRecord'
+  query=$query'&Format=json'
+  query=$query'&RecordId='$1
+  query=$query'&SignatureMethod=HMAC-SHA1'
+  query=$query"&SignatureNonce=$(_ali_nonce)"
+  query=$query'&SignatureVersion=1.0'
+  query=$query'&Timestamp='$(_timestamp)
+  query=$query'&Version=2015-01-09'
+}
+
+_describe_records_query() {
+  query=''
+  query=$query'AccessKeyId='$Ali_Key
+  query=$query'&Action=DescribeDomainRecords'
+  query=$query'&DomainName='$1
+  query=$query'&Format=json'
+  query=$query'&SignatureMethod=HMAC-SHA1'
+  query=$query"&SignatureNonce=$(_ali_nonce)"
+  query=$query'&SignatureVersion=1.0'
+  query=$query'&Timestamp='$(_timestamp)
+  query=$query'&Version=2015-01-09'
+}
+
+_clean() {
+  _check_exist_query "$_domain"
+  if ! _ali_rest "Check exist records" "ignore"; then
+    return 1
+  fi
+
+  records="$(echo "$response" -n | _egrep_o "\"RecordId\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")"
+  printf "%s" "$records" \
+    | while read -r record_id; do
+      _delete_record_query "$record_id"
+      _ali_rest "Delete record $record_id" "ignore"
+    done
+}
+
+_timestamp() {
+  date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ"
+}