]> git.proxmox.com Git - mirror_acme.sh.git/commitdiff
support cloudxns.com api
authorneil <git@byneil.com>
Sun, 7 Feb 2016 10:26:12 +0000 (18:26 +0800)
committerneil <git@byneil.com>
Sun, 7 Feb 2016 10:26:12 +0000 (18:26 +0800)
README.md
dnsapi/dns-cx.sh [new file with mode: 0644]
dnsapi/dns-dp.sh
le.sh

index ccff7febe67b5bbbc966e25d83d9f31fc3230e33..497dce3e9fa84492477977eb76b22ec67a8985d8 100644 (file)
--- a/README.md
+++ b/README.md
@@ -163,69 +163,21 @@ le renew  aa.com
 Ok, it's finished.
 
 
+#Automatic dns api integeration
 
-# Use CloudFlare domain api to automatically issue cert
+If your dns provider support api access,  we can use api to automatically issue certs.
+You don't have do anything manually.
 
-For now, we support clourflare integeration.
+Current we support:
+## Cloudflare.com  api
+## Dnspod.cn  api
+## Cloudxns.com  api
 
-First you need to login to your clourflare account to get your api key.
-
-```
-export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
-
-export CF_Email="xxxx@sss.com"
-
-```
-
-Ok, let's issue cert now:
-```
-le.sh   issue   dns-cf   aa.com  www.aa.com
-```
-
-The `CF_Key` and `CF_Email`  will be saved in `~/.le/account.conf`, when next time you use cloudflare api, it will reuse this key.
-
-
-More api integerations are coming. Godaddy, etc....
-
-# Use Dnspod.cn domain api to automatically issue cert
-
-For now, we support dnspod.cn integeration.
-
-First you need to login to your dnspod.cn account to get your api key and key id.
-
-```
-export DP_Id="1234"
-
-export DP_Key="sADDsdasdgdsf"
-
-```
-
-Ok, let's issue cert now:
-```
-le.sh   issue   dns-dp   aa.com  www.aa.com
-```
-
-The `DP_Id` and `DP_Key`  will be saved in `~/.le/account.conf`, when next time you use dnspod.cn api, it will reuse this key.
-
-
-
-# Use custom api
-
-If your api is not supported yet,  you can write your own dns api.
-
-Let's assume you want to name it 'myapi',
-
-1. Create a bash script named  `~/.le/dns-myapi.sh`,
-2. In the scrypt, you must have a function named `dns-myapi-add()`. Which will be called by le.sh to add dns records.
-3. Then you can use your api to issue cert like:
-
-```
-le.sh  issue  dns-myapi  aa.com  www.aa.com
-```
-
-For more details, please check our sample script: `dnsapi/dns-myapi.sh`
+More apis are comming soon....
 
+##If your dns provider is not in the supported list above, you write your own script api easily.
 
+For more details: [How to use dns api](/Neilpang/le/blob/master/dnsapi/README.md)
 
 
 #Under the Hood
diff --git a/dnsapi/dns-cx.sh b/dnsapi/dns-cx.sh
new file mode 100644 (file)
index 0000000..07c9cf0
--- /dev/null
@@ -0,0 +1,234 @@
+#!/bin/bash
+
+# Cloudxns.com Domain api
+#
+#CX_Key="1234"
+#
+#CX_Secret="sADDsdasdgdsf"
+
+
+CX_Api="https://www.cloudxns.net/api2"
+
+
+#REST_API
+########  Public functions #####################
+
+#Usage: add  _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns-cx-add() {
+  fulldomain=$1
+  txtvalue=$2
+  
+  if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ] ; then
+    _err "You don't specify cloudxns.com  api key or secret yet."
+    _err "Please create you key and try again."
+    return 1
+  fi
+  
+  REST_API=$CX_Api
+  
+  #save the api key and email to the account conf file.
+  _saveaccountconf CX_Key "$CX_Key"
+  _saveaccountconf CX_Secret "$CX_Secret"
+  
+  _debug "First detect the root zone"
+  if ! _get_root $fulldomain ; then
+    _err "invalid domain"
+    return 1
+  fi
+  
+  existing_records  $_domain  $_sub_domain
+  _debug count "$count"
+  if [ "$?" != "0" ] ; then
+    _err "Error get existing records."
+    return 1
+  fi
+
+  if [ "$count" == "0" ] ; then
+    add_record $_domain $_sub_domain $txtvalue
+  else
+    update_record $_domain $_sub_domain $txtvalue
+  fi
+  
+  if [ "$?" == "0" ] ; then
+    return 0
+  fi
+  return 1
+}
+
+#usage:  root  sub
+#return if the sub record already exists.
+#echos the existing records count.
+# '0' means doesn't exist
+existing_records() {
+  _debug "Getting txt records"
+  root=$1
+  sub=$2
+  
+  if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100" ; then
+    return 1
+  fi
+  count=0
+  seg=$(printf "$response" | grep -o "{[^{]*host\":\"$_sub_domain[^}]*}")
+  _debug seg "$seg"
+  if [ -z "$seg" ] ; then
+    return 0
+  fi
+
+  if printf "$response" | grep '"type":"TXT"' > /dev/null ; then
+    count=1
+    record_id=$(printf "$seg" | grep -o \"record_id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \")
+    _debug record_id "$record_id"
+    return 0    
+  fi
+  
+}
+
+#add the txt record.
+#usage: root  sub  txtvalue
+add_record() {
+  root=$1
+  sub=$2
+  txtvalue=$3
+  fulldomain=$sub.$root
+  
+  _info "Adding record"
+  
+  if ! _rest POST "record" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}"; then
+    return 1
+  fi
+  
+  return 0
+}
+
+#update the txt record
+#Usage: root sub txtvalue
+update_record() {
+  root=$1
+  sub=$2
+  txtvalue=$3
+  fulldomain=$sub.$root
+  
+  _info "Updating record"
+  
+  if _rest PUT "record/$record_id" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}" ; then
+    return 0
+  fi
+  
+  return 1
+}
+
+
+
+
+####################  Private functions bellow ##################################
+#_acme-challenge.www.domain.com
+#returns
+# _sub_domain=_acme-challenge.www
+# _domain=domain.com
+# _domain_id=sdjkglgdfewsdfg
+_get_root() {
+  domain=$1
+  i=2
+  p=1
+  
+  if ! _rest GET "domain" ; then
+    return 1
+  fi
+  
+  while [ '1' ] ; do
+    h=$(printf $domain | cut -d . -f $i-100)
+    _debug h "$h"
+    if [ -z "$h" ] ; then
+      #not valid
+      return 1;
+    fi
+
+    if printf "$response" | grep "$h." ; then
+      seg=$(printf "$response" | grep -o "{[^{]*$h\.[^}]*\}" )
+      _debug seg "$seg"
+      _domain_id=$(printf "$seg" | grep -o \"id\":\"[^\"]*\" | cut -d : -f 2 | tr -d \")
+      _debug _domain_id "$_domain_id"
+      if [ "$_domain_id" ] ; then
+        _sub_domain=$(printf $domain | cut -d . -f 1-$p)
+        _debug _sub_domain $_sub_domain
+        _domain=$h
+        _debug _domain $_domain
+        return 0
+      fi
+      return 1
+    fi
+    p=$i
+    let "i+=1"
+  done
+  return 1
+}
+
+
+#Usage: method  URI  data
+_rest() {
+  m=$1
+  ep="$2"
+  _debug $ep
+  url="$REST_API/$ep"
+  _debug url "$url"
+  
+  cdate=$(date -u  "+%Y-%m-%d %H:%M:%S UTC")
+  _debug cdate "$cdate"
+  
+  data="$3"
+  _debug data "$data"
+    
+  sec="$CX_Key$url$data$cdate$CX_Secret"
+  _debug sec "$sec"
+  hmac=$(printf "$sec"| openssl md5 |cut -d " " -f 2)
+  _debug hmac "$hmac"
+    
+  if [ "$3" ] ; then
+    response="$(curl --silent -X $m "$url" -H "API-KEY: $CX_Key" -H "API-REQUEST-DATE: $cdate" -H "API-HMAC: $hmac" -H 'Content-Type: application/json'  -d "$data")"
+  else
+    response="$(curl --silent -X $m "$url" -H "API-KEY: $CX_Key" -H "API-REQUEST-DATE: $cdate" -H "API-HMAC: $hmac" -H 'Content-Type: application/json')"
+  fi
+  
+  if [ "$?" != "0" ] ; then
+    _err "error $ep"
+    return 1
+  fi
+  _debug response "$response"
+  if ! printf "$response" | grep '"message":"success"' > /dev/null ; then
+    return 1
+  fi
+  return 0
+}
+
+
+_debug() {
+
+  if [ -z "$DEBUG" ] ; then
+    return
+  fi
+  
+  if [ -z "$2" ] ; then
+    echo $1
+  else
+    echo "$1"="$2"
+  fi
+}
+
+_info() {
+  if [ -z "$2" ] ; then
+    echo "$1"
+  else
+    echo "$1"="$2"
+  fi
+}
+
+_err() {
+  if [ -z "$2" ] ; then
+    echo "$1" >&2
+  else
+    echo "$1"="$2" >&2
+  fi
+}
+
+
index 4786b2ed2768255d91a8505be91ae53e177e7087..b39e3c40b5efcc3d75eb66b88faabc91a14392e8 100644 (file)
@@ -89,7 +89,7 @@ add_record() {
   root=$1
   sub=$2
   txtvalue=$3
-  fulldomain=$sub.$$root
+  fulldomain=$sub.$root
   
   _info "Adding record"
   
diff --git a/le.sh b/le.sh
index d0a06f932caa3c47af5aac8fddb05cce1fe0399b..64f6cede1d6fed318cbb3abe783fea1f1e552b53 100755 (executable)
--- a/le.sh
+++ b/le.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-VER=1.1.4
+VER=1.1.5
 PROJECT="https://github.com/Neilpang/le"
 
 DEFAULT_CA="https://acme-v01.api.letsencrypt.org"
@@ -1066,6 +1066,7 @@ _initconf() {
 
 #STAGE=1 # Use the staging api
 #FORCE=1 # Force to issue cert
+#DEBUG=1 # Debug mode
 
 #dns api
 #######################
@@ -1082,6 +1083,12 @@ _initconf() {
 #api key
 #DP_Key="sADDsdasdgdsf"
 
+#######################
+#Cloudxns.com:
+#CX_Key="1234"
+#
+#CX_Secret="sADDsdasdgdsf"
+
     " > $ACCOUNT_CONF_PATH
   fi
 }