Browse Source

Add support PowerDNS API (#322)

* Add support PowerDNS API

* Small fixes
Maxim Zalysin 8 years ago
parent
commit
d6f0c2b52b
4 changed files with 160 additions and 4 deletions
  1. 2 1
      README.md
  2. 7 0
      acme.sh
  3. 24 3
      dnsapi/README.md
  4. 127 0
      dnsapi/dns_pdns.sh

+ 2 - 1
README.md

@@ -241,7 +241,8 @@ You don't have do anything manually!
 4. Godaddy.com API
 4. Godaddy.com API
 5. OVH, kimsufi, soyoustart and runabove API
 5. OVH, kimsufi, soyoustart and runabove API
 6. AWS Route 53, see: https://github.com/Neilpang/acme.sh/issues/65
 6. AWS Route 53, see: https://github.com/Neilpang/acme.sh/issues/65
-7. lexicon dns api: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
+7. PowerDNS API, see: https://doc.powerdns.com/md/httpapi/README/
+8. lexicon dns api: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
    (DigitalOcean, DNSimple, DnsMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.)
    (DigitalOcean, DNSimple, DnsMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.)
 
 
 ##### More APIs are coming soon...
 ##### More APIs are coming soon...

+ 7 - 0
acme.sh

@@ -3173,6 +3173,13 @@ _initconf() {
 #
 #
 #GD_Secret=\"sADDsdasdfsdfdssdgdsf\"
 #GD_Secret=\"sADDsdasdfsdfdssdgdsf\"
 
 
+#######################
+#PowerDNS:
+#PDNS_Url=\"http://ns.example.com:8081\"
+#PDNS_ServerId=\"localhost\"
+#PDNS_Token=\"0123456789ABCDEF\"
+#PDNS_Ttl=60
+
     " > $ACCOUNT_CONF_PATH
     " > $ACCOUNT_CONF_PATH
   fi
   fi
 }
 }

+ 24 - 3
dnsapi/README.md

@@ -66,7 +66,7 @@ The `CX_Key` and `CX_Secret`  will be saved in `~/.acme.sh/account.conf`, when n
 
 
 ## Use Godaddy.com domain api to automatically issue cert
 ## Use Godaddy.com domain api to automatically issue cert
 
 
-We support Godaddy integeration.
+We support Godaddy integration.
 
 
 First you need to login to your Godaddy account to get your api key and api secret.
 First you need to login to your Godaddy account to get your api key and api secret.
 
 
@@ -89,6 +89,29 @@ acme.sh   --issue   --dns dns_gd   -d aa.com  -d www.aa.com
 
 
 The `GD_Key` and `GD_Secret`  will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key.
 The `GD_Key` and `GD_Secret`  will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key.
 
 
+## Use PowerDNS embedded api to automatically issue cert
+
+We support PowerDNS embedded API integration.
+
+First you need to enable api and set your api-token in PowerDNS configuration.
+
+https://doc.powerdns.com/md/httpapi/README/
+
+```
+export PDNS_Url="http://ns.example.com:8081"
+export PDNS_ServerId="localhost"
+export PDNS_Token="0123456789ABCDEF"
+export PDNS_Ttl=60
+
+```
+
+Ok, let's issue cert now:
+```
+acme.sh   --issue   --dns dns_pdns   -d aa.com  -d www.aa.com
+```
+
+The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf`.
+
 ## Use OVH/kimsufi/soyoustart/runabove API
 ## Use OVH/kimsufi/soyoustart/runabove API
 
 
 https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api
 https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api
@@ -109,8 +132,6 @@ acme.sh  --issue  --dns  dns_myapi  -d aa.com  -d www.aa.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)
 
 
-
-
 # Use lexicon dns api
 # 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

+ 127 - 0
dnsapi/dns_pdns.sh

@@ -0,0 +1,127 @@
+#!/usr/bin/env sh
+
+#PowerDNS Emdedded API
+#https://doc.powerdns.com/md/httpapi/api_spec/
+#
+#PDNS_Url="http://ns.example.com:8081"
+#PDNS_ServerId="localhost"
+#PDNS_Token="0123456789ABCDEF"
+#PDNS_Ttl=60
+
+########  Public functions #####################
+#Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000"
+dns_pdns_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  if [ -z "$PDNS_Url" ] ; then
+    _err "You don't specify PowerDNS address."
+    _err "Please set PDNS_Url and try again."
+    return 1
+  fi
+
+  if [ -z "$PDNS_ServerId" ] ; then
+    _err "You don't specify PowerDNS server id."
+    _err "Please set you PDNS_ServerId and try again."
+    return 1
+  fi
+
+  if [ -z "$PDNS_Token" ] ; then
+    _err "You don't specify PowerDNS token."
+    _err "Please create you PDNS_Token and try again."
+    return 1
+  fi
+
+  if [ -z "$PDNS_Ttl" ] ; then
+    PDNS_Ttl=60
+  fi
+
+  #save the api addr and key to the account conf file.
+  _saveaccountconf PDNS_Url "$PDNS_Url"
+  _saveaccountconf PDNS_ServerId "$PDNS_ServerId"
+  _saveaccountconf PDNS_Token "$PDNS_Token"
+
+  _debug "First detect the root zone"
+  if ! _get_root $fulldomain ; then
+    _err "invalid domain"
+    return 1
+  fi
+  _debug _domain "$_domain"
+
+  if ! set_record "$_domain" "$fulldomain" "$txtvalue" ; then
+    return 1
+  fi
+
+  return 0
+}
+
+set_record() {
+  _info "Adding record"
+  root=$1
+  full=$2
+  txtvalue=$3
+
+  if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"name\": \"$full.\", \"changetype\": \"REPLACE\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [{\"name\": \"$full.\", \"type\": \"TXT\", \"content\": \"\\\"$txtvalue\\\"\", \"disabled\": false, \"ttl\": $PDNS_Ttl}]}]}" ; then
+    _err "Set txt record error."
+    return 1
+  fi
+  if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_ServerId/zones/$root./notify" ; then
+    _err "Notify servers error."
+    return 1
+  fi
+  return 0
+}
+
+####################  Private functions bellow ##################################
+#_acme-challenge.www.domain.com
+#returns
+# _domain=domain.com
+_get_root() {
+  domain=$1
+  i=1
+  p=1
+
+  if _pdns_rest "GET" "/api/v1/servers/$PDNS_ServerId/zones" ; then
+    _zones_response=$response
+  fi
+
+  while [ '1' ] ; do
+    h=$(printf $domain | cut -d . -f $i-100)
+    if [ -z "$h" ] ; then
+      return 1
+    fi
+
+    if printf "$_zones_response" | grep "\"name\": \"$h.\"" >/dev/null ; then
+      _domain=$h
+      return 0
+    fi
+
+    p=$i
+    i=$(expr $i + 1)
+  done
+  _debug "$domain not found"
+  return 1
+}
+
+_pdns_rest() {
+  method=$1
+  ep=$2
+  data=$3
+
+  _H1="X-API-Key: $PDNS_Token"
+
+  if [ ! "$method" = "GET" ] ; then
+    _debug data "$data"
+    response="$(_post "$data" "$PDNS_Url$ep" "" "$method")"
+  else
+    response="$(_get "$PDNS_Url$ep")"
+  fi
+
+  if [ "$?" != "0" ] ; then
+    _err "error $ep"
+    return 1
+  fi
+  _debug2 response "$response"
+
+  return 0
+}