Browse Source

Added ISPConfig DNS API

sjau 8 years ago
parent
commit
192ede5e64
3 changed files with 183 additions and 2 deletions
  1. 1 0
      README.md
  2. 24 2
      dnsapi/README.md
  3. 158 0
      dnsapi/dns_ispconfig.sh

+ 1 - 0
README.md

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

+ 24 - 2
dnsapi/README.md

@@ -218,7 +218,29 @@ 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.
 The `Ali_Key` and `Ali_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 
 
-# 12. Use custom API
+## 12. Use ISPConfig 3.1 API
+
+This only works for ISPConfig 3.1 (and newer).
+
+Create a Remote User in the ISPConfig Control Panel. The Remote User must have access to at least `DNS zone functions` and `DNS txt functions`.
+
+```
+export ISPC_User="xxx"
+export ISPC_Password="xxx"
+export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php"
+export ISPC_Api_Insecure=1
+```
+If you have installed ISPConfig on a different port, then alter the 8080 accordingly.
+Leaver ISPC_Api_Insecure set to 1 if you have not a valid ssl cert for your installation. Change it to 0 if you have a valid ssl cert.
+
+To issue a cert:
+```
+acme.sh --issue --dns dns_ispconfig -d example.com -d www.example.com
+```
+
+The `ISPC_User`, `ISPC_Password`, `ISPC_Api`and `ISPC_Api_Insecure` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
+
+# 13. 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.
 
 
@@ -235,6 +257,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)
 
 
 
 
-## 13. Use lexicon DNS API
+## 14. 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

+ 158 - 0
dnsapi/dns_ispconfig.sh

@@ -0,0 +1,158 @@
+#!/usr/bin/env sh
+
+# ISPConfig 3.1 API
+# User must provide login data and URL to the ISPConfig installation incl. port. The remote user in ISPConfig must have access to:
+# - DNS zone Functions
+# - DNS txt Functions
+
+# Report bugs to https://github.com/sjau/acme.sh
+
+# Values to export:
+# export ISPC_User="remoteUser"
+# export ISPC_Password="remotePasword"
+# export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php"
+# export ISPC_Api_Insecure=1     # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1)
+
+########  Public functions #####################
+
+#Usage: dns_myapi_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_ispconfig_add() {
+  fulldomain="${1}"
+  txtvalue="${2}"
+  _ISPC_credentials && _ISPC_login && _ISPC_getZoneInfo && _ISPC_addTxt
+}
+
+#Usage: dns_myapi_rm   _acme-challenge.www.domain.com
+dns_ispconfig_rm() {
+  fulldomain="${1}"
+  _ISPC_credentials && _ISPC_login && _ISPC_rmTxt
+}
+
+####################  Private functions bellow ##################################
+
+_ISPC_credentials() {
+  if [ -z "${ISPC_User}" ] || [ -z "$ISPC_Password" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then
+    ISPC_User=""
+    ISPC_Password=""
+    ISPC_Api=""
+    ISPC_Api_Insecure=""
+    _err "You haven't specified the ISPConfig Login data, URL and whether you want check the ISPC SSL cert. Please try again."
+    return 1
+  else
+    _saveaccountconf ISPC_User "${ISPC_User}"
+    _saveaccountconf ISPC_Password "${ISPC_Password}"
+    _saveaccountconf ISPC_Api "${ISPC_Api}"
+    _saveaccountconf ISPC_Api_Insecure "${ISPC_Api_Insecure}"
+    # Set whether curl should use secure or insecure mode
+    HTTPS_INSECURE="${ISPC_Api_Insecure}"
+  fi
+}
+
+_ISPC_login() {
+  _info "Getting Session ID"
+  curData="{\"username\":\"${ISPC_User}\",\"password\":\"${ISPC_Password}\",\"client_login\":false}"
+  curResult="$(_post "${curData}" "${ISPC_Api}?login")"
+  if _contains "${curResult}" '"code":"ok"'; then
+    sessionID=$(echo "${curResult}" | _egrep_o "response.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
+    _info "Retrieved Session ID."
+  else
+    _err "Couldn't retrieve the Session ID."
+    return 1
+  fi
+}
+
+_ISPC_getZoneInfo() {
+  _info "Getting Zoneinfo"
+  zoneEnd=false
+  curZone="${fulldomain}"
+  while [ "${zoneEnd}" = false ]; do
+    # we can strip the first part of the fulldomain, since it's just the _acme-challenge string
+    curZone="${curZone#*.}"
+    # suffix . needed for zone -> domain.tld.
+    curData="{\"session_id\":\"${sessionID}\",\"primary_id\":[{\"origin\":\"${curZone}.\"}]}"
+    curResult="$(_post "${curData}" "${ISPC_Api}?dns_zone_get")"
+    if _contains "${curResult}" '"id":"'; then
+      zoneFound=true
+      zoneEnd=true
+      _info "Retrieved zone data."
+    fi
+    if [ "${curZone#*.}" != "$curZone" ]; then
+      _debug2 "$curZone still contains a '.' - so we can check next higher level"
+    else
+      zoneEnd=true
+      _err "Couldn't retrieve zone data."
+      return 1
+    fi
+  done
+  if [ "${zoneFound}" ]; then
+    server_id=$(echo "${curResult}" | _egrep_o "server_id.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
+    case "${server_id}" in
+      '' | *[!0-9]*)
+        _err "Server ID is not numeric."
+        return 1
+        ;;
+      *) _info "Retrieved Server ID" ;;
+    esac
+    zone=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
+    case "${zone}" in
+      '' | *[!0-9]*)
+        _err "Zone ID is not numeric."
+        return 1
+        ;;
+      *) _info "Retrieved Zone ID" ;;
+    esac
+    client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
+    case "${client_id}" in
+      '' | *[!0-9]*)
+        _err "Client ID is not numeric."
+        return 1
+        ;;
+      *) _info "Retrieved Client ID." ;;
+    esac
+    zoneFound=""
+    zoneEnd=""
+  fi
+}
+
+_ISPC_addTxt() {
+  curSerial="$(date +%s)"
+  curStamp="$(date +'%F %T')"
+  params="\"server_id\":\"${server_id}\",\"zone\":\"${zone}\",\"name\":\"${fulldomain}.\",\"type\":\"txt\",\"data\":\"${txtvalue}\",\"aux\":\"0\",\"ttl\":\"3600\",\"active\":\"y\",\"stamp\":\"${curStamp}\",\"serial\":\"${curSerial}\""
+  curData="{\"session_id\":\"${sessionID}\",\"client_id\":\"${client_id}\",\"params\":{${params}}}"
+  curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_add")"
+  record_id=$(echo "${curResult}" | _egrep_o "\"response.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
+  case "${record_id}" in
+    '' | *[!0-9]*)
+      _err "Couldn't add ACME Challenge TXT record to zone."
+      return 1
+      ;;
+    *) _info "Added ACME Challenge TXT record to zone." ;;
+  esac
+}
+
+_ISPC_rmTxt() {
+  # Need to get the record ID.
+  curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"name\":\"${fulldomain}.\",\"type\":\"TXT\"}}"
+  curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_get")"
+  if _contains "${curResult}" '"code":"ok"'; then
+    record_id=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2)
+    case "${record_id}" in
+      '' | *[!0-9]*)
+        _err "Record ID is not numeric."
+        return 1
+        ;;
+      *)
+        unset IFS
+        _info "Retrieved Record ID."
+        curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\"}"
+        curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")"
+        if _contains "${curResult}" '"code":"ok"'; then
+          _info "Removed ACME Challenge TXT record from zone."
+        else
+          _err "Couldn't remove ACME Challenge TXT record from zone."
+          return 1
+        fi
+        ;;
+    esac
+  fi
+}