Browse Source

Merge pull request #1958 from Neilpang/dev

sync
neil 6 years ago
parent
commit
8907e2d850
6 changed files with 258 additions and 31 deletions
  1. 3 2
      README.md
  2. 1 1
      acme.sh
  3. 24 2
      dnsapi/README.md
  4. 29 7
      dnsapi/dns_cf.sh
  5. 20 19
      dnsapi/dns_linode.sh
  6. 181 0
      dnsapi/dns_neodigit.sh

+ 3 - 2
README.md

@@ -35,7 +35,7 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
 - [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709)
 - [discourse.org](https://meta.discourse.org/t/setting-up-lets-encrypt/40709)
 - [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html)
 - [Centminmod](https://centminmod.com/letsencrypt-acmetool-https.html)
 - [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
 - [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
-- [archlinux](https://aur.archlinux.org/packages/acme.sh-git/)
+- [archlinux](https://www.archlinux.org/packages/community/any/acme.sh)
 - [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient)
 - [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient)
 - [CentOS Web Panel](http://centos-webpanel.com/)
 - [CentOS Web Panel](http://centos-webpanel.com/)
 - [lnmp.org](https://lnmp.org/)
 - [lnmp.org](https://lnmp.org/)
@@ -329,8 +329,9 @@ You don't have to do anything manually!
 1. Namecheap API (https://www.namecheap.com/)
 1. Namecheap API (https://www.namecheap.com/)
 1. MyDNS.JP API (https://www.mydns.jp/)
 1. MyDNS.JP API (https://www.mydns.jp/)
 1. hosting.de (https://www.hosting.de)
 1. hosting.de (https://www.hosting.de)
+1. Neodigit.net API (https://www.neodigit.net)
 
 
-And: 
+And:
 
 
 **lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
 **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.)**

+ 1 - 1
acme.sh

@@ -2839,7 +2839,7 @@ _isRealNginxConf() {
         _skip_ssl=1
         _skip_ssl=1
         for _listen_i in $(echo "$_seg_n" | tr "\t" ' ' | grep "^ *listen" | tr -d " "); do
         for _listen_i in $(echo "$_seg_n" | tr "\t" ' ' | grep "^ *listen" | tr -d " "); do
           if [ "$_listen_i" ]; then
           if [ "$_listen_i" ]; then
-            if [ "$(echo "$_listen_i" | _egrep_o "listen.*ssl[ |;]")" ]; then
+            if [ "$(echo "$_listen_i" | _egrep_o "listen.*ssl")" ]; then
               _debug2 "$_listen_i is ssl"
               _debug2 "$_listen_i is ssl"
             else
             else
               _debug2 "$_listen_i is plain text"
               _debug2 "$_listen_i is plain text"

+ 24 - 2
dnsapi/README.md

@@ -264,9 +264,18 @@ when needed.
 ## 14. Use Linode domain API
 ## 14. Use Linode domain API
 
 
 First you need to login to your Linode account to get your API Key.
 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.
+  * [Classic Manager](https://manager.linode.com/profile/api)
+
+   Under "Add an API key", Give the new key a "Label" (we recommend *ACME*),
+   set the expiry to never, "Create API Key", and copy the new key into the `LINODE_API_KEY` command
+   below.
+
+  * [Cloud Manager](https://cloud.linode.com/profile/tokens)
+
+   Click on "Add a Personal Access Token". Give the new key a "Label" (we
+   recommend *ACME*), give it Read/Write access to "Domains". "Submit", and
+   copy the new key into the `LINODE_API_KEY` command below.
 
 
 ```sh
 ```sh
 export LINODE_API_KEY="..."
 export LINODE_API_KEY="..."
@@ -1054,6 +1063,19 @@ acme.sh --issue --dns dns_hostingde -d example.com -d *.example.com
 
 
 The hosting.de API key and endpoint will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 The hosting.de API key and endpoint will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 
 
+## 56. Use Neodigit.net API
+
+```
+export NEODIGIT_API_TOKEN="eXJxTkdUVUZmcHQ3QWJackQ4ZGlMejRDSklRYmo5VG5zcFFKK2thYnE0WnVnNnMy"
+```
+
+Ok, let's issue a cert now:
+```
+acme.sh --issue --dns dns_neodigit -d example.com -d www.example.com
+```
+
+Neodigit API Token will be saved in `~/.acme.sh/account.conf` and will be used 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.

+ 29 - 7
dnsapi/dns_cf.sh

@@ -34,6 +34,9 @@ dns_cf_add() {
   _saveaccountconf_mutable CF_Key "$CF_Key"
   _saveaccountconf_mutable CF_Key "$CF_Key"
   _saveaccountconf_mutable CF_Email "$CF_Email"
   _saveaccountconf_mutable CF_Email "$CF_Email"
 
 
+  _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '@.' '__')"
+  _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_"
+
   _debug "First detect the root zone"
   _debug "First detect the root zone"
   if ! _get_root "$fulldomain"; then
   if ! _get_root "$fulldomain"; then
     _err "invalid domain"
     _err "invalid domain"
@@ -58,9 +61,12 @@ dns_cf_add() {
   #  if [ "$count" = "0" ]; then
   #  if [ "$count" = "0" ]; then
   _info "Adding record"
   _info "Adding record"
   if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
   if _cf_rest POST "zones/$_domain_id/dns_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, OK"
       _info "Added, OK"
       return 0
       return 0
+    elif _contains "$response" "The record already exists"; then
+      _info "Already exists, OK"
+      return 0
     else
     else
       _err "Add txt record error."
       _err "Add txt record error."
       return 1
       return 1
@@ -99,11 +105,16 @@ dns_cf_rm() {
     return 1
     return 1
   fi
   fi
 
 
+  _DOMAIN_CF_ZONES_CACHE_NAME_="$(echo "${CF_Email}_CF_ZONES_" | tr '@.' '__')"
+
   _debug "First detect the root zone"
   _debug "First detect the root zone"
   if ! _get_root "$fulldomain"; then
   if ! _get_root "$fulldomain"; then
+    _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_"
     _err "invalid domain"
     _err "invalid domain"
     return 1
     return 1
   fi
   fi
+  _cleardomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_"
+
   _debug _domain_id "$_domain_id"
   _debug _domain_id "$_domain_id"
   _debug _sub_domain "$_sub_domain"
   _debug _sub_domain "$_sub_domain"
   _debug _domain "$_domain"
   _debug _domain "$_domain"
@@ -143,6 +154,21 @@ dns_cf_rm() {
 # _domain=domain.com
 # _domain=domain.com
 # _domain_id=sdjkglgdfewsdfg
 # _domain_id=sdjkglgdfewsdfg
 _get_root() {
 _get_root() {
+
+  _cf_zones="$(_readdomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_")"
+  _debug2 "_cf_zones" "$_cf_zones"
+  if [ -z "$_cf_zones" ]; then
+    _debug "$_DOMAIN_CF_ZONES_CACHE_NAME_ is none, so get it."
+    if ! _cf_rest GET "zones"; then
+      return 1
+    fi
+    _cf_zones="$response"
+    _savedomainconf "$_DOMAIN_CF_ZONES_CACHE_NAME_" "$(echo "$_cf_zones" | _base64)"
+  else
+    _debug "$_DOMAIN_CF_ZONES_CACHE_NAME_ found"
+    _cf_zones="$(echo "$_cf_zones" | _dbase64)"
+  fi
+
   domain=$1
   domain=$1
   i=2
   i=2
   p=1
   p=1
@@ -154,12 +180,8 @@ _get_root() {
       return 1
       return 1
     fi
     fi
 
 
-    if ! _cf_rest GET "zones?name=$h"; then
-      return 1
-    fi
-
-    if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
-      _domain_id=$(printf "%s\n" "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \")
+    if _contains "$_cf_zones" "\"name\":\"$h\"" >/dev/null; then
+      _domain_id=$(printf "%s\n" "$_cf_zones" | _egrep_o "\[.\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \")
       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

+ 20 - 19
dnsapi/dns_linode.sh

@@ -2,7 +2,7 @@
 
 
 #Author: Philipp Grosswiler <philipp.grosswiler@swiss-design.net>
 #Author: Philipp Grosswiler <philipp.grosswiler@swiss-design.net>
 
 
-LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action="
+LINODE_API_URL="https://api.linode.com/v4/domains"
 
 
 ########  Public functions #####################
 ########  Public functions #####################
 
 
@@ -27,10 +27,14 @@ dns_linode_add() {
   _debug _sub_domain "$_sub_domain"
   _debug _sub_domain "$_sub_domain"
   _debug _domain "$_domain"
   _debug _domain "$_domain"
 
 
-  _parameters="&DomainID=$_domain_id&Type=TXT&Name=$_sub_domain&Target=$txtvalue"
+  _payload="{
+              \"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)
+  if _rest POST "/$_domain_id/records" "$_payload" && [ -n "$response" ]; then
+    _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1)
     _debug _resource_id "$_resource_id"
     _debug _resource_id "$_resource_id"
 
 
     if [ -z "$_resource_id" ]; then
     if [ -z "$_resource_id" ]; then
@@ -65,25 +69,21 @@ dns_linode_rm() {
   _debug _sub_domain "$_sub_domain"
   _debug _sub_domain "$_sub_domain"
   _debug _domain "$_domain"
   _debug _domain "$_domain"
 
 
-  _parameters="&DomainID=$_domain_id"
-
-  if _rest GET "domain.resource.list" "$_parameters" && [ -n "$response" ]; then
+  if _rest GET "/$_domain_id/records" && [ -n "$response" ]; then
     response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
     response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
 
 
-    resource="$(echo "$response" | _egrep_o "{.*\"NAME\":\s*\"$_sub_domain\".*}")"
+    resource="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$_sub_domain\".*}")"
     if [ "$resource" ]; then
     if [ "$resource" ]; then
-      _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"RESOURCEID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
+      _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
       if [ "$_resource_id" ]; then
       if [ "$_resource_id" ]; then
         _debug _resource_id "$_resource_id"
         _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 _rest DELETE "/$_domain_id/records/$_resource_id" && [ -n "$response" ]; then
+          # On 200/OK, empty set is returned. Check for error, if any.
+          _error_response=$(printf "%s\n" "$response" | _egrep_o "\"errors\"" | cut -d : -f 2 | tr -d " " | _head_n 1)
 
 
-          if [ -z "$_resource_id" ]; then
-            _err "Error deleting the domain resource."
+          if [ -n "$_error_response" ]; then
+            _err "Error deleting the domain resource: $_error_response"
             return 1
             return 1
           fi
           fi
 
 
@@ -127,7 +127,7 @@ _get_root() {
   i=2
   i=2
   p=1
   p=1
 
 
-  if _rest GET "domain.list"; then
+  if _rest GET; then
     response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
     response="$(echo "$response" | tr -d "\n" | tr '{' "|" | sed 's/|/&{/g' | tr "|" "\n")"
     while true; do
     while true; do
       h=$(printf "%s" "$domain" | cut -d . -f $i-100)
       h=$(printf "%s" "$domain" | cut -d . -f $i-100)
@@ -137,9 +137,9 @@ _get_root() {
         return 1
         return 1
       fi
       fi
 
 
-      hostedzone="$(echo "$response" | _egrep_o "{.*\"DOMAIN\":\s*\"$h\".*}")"
+      hostedzone="$(echo "$response" | _egrep_o "{.*\"domain\":\s*\"$h\".*}")"
       if [ "$hostedzone" ]; then
       if [ "$hostedzone" ]; then
-        _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"DOMAINID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
+        _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ )
         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
@@ -165,6 +165,7 @@ _rest() {
 
 
   export _H1="Accept: application/json"
   export _H1="Accept: application/json"
   export _H2="Content-Type: application/json"
   export _H2="Content-Type: application/json"
+  export _H3="Authorization: Bearer $LINODE_API_KEY"
 
 
   if [ "$mtd" != "GET" ]; then
   if [ "$mtd" != "GET" ]; then
     # both POST and DELETE.
     # both POST and DELETE.

+ 181 - 0
dnsapi/dns_neodigit.sh

@@ -0,0 +1,181 @@
+#!/usr/bin/env sh
+
+#
+# NEODIGIT_API_TOKEN="jasdfhklsjadhflnhsausdfas"
+
+# This is Neodigit.net api wrapper for acme.sh
+#
+# Author: Adrian Almenar
+# Report Bugs here: https://github.com/tecnocratica/acme.sh
+#
+NEODIGIT_API_URL="https://api.neodigit.net/v1"
+#
+########  Public functions #####################
+
+# Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_neodigit_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}"
+  if [ -z "$NEODIGIT_API_TOKEN" ]; then
+    NEODIGIT_API_TOKEN=""
+    _err "You haven't specified a Token api key."
+    _err "Please create the key and try again."
+    return 1
+  fi
+
+  #save the api key and email to the account conf file.
+  _saveaccountconf_mutable NEODIGIT_API_TOKEN "$NEODIGIT_API_TOKEN"
+
+  _debug "First detect the root zone"
+  if ! _get_root "$fulldomain"; then
+    _err "invalid domain"
+    return 1
+  fi
+
+  _debug fulldomain "$fulldomain"
+  _debug txtvalue "$txtvalue"
+  _debug domain "$_domain"
+  _debug sub_domain "$_sub_domain"
+
+  _debug "Getting txt records"
+  _neo_rest GET "dns/zones/${_domain_id}/records?type=TXT&name=$fulldomain"
+
+  _debug _code "$_code"
+
+  if [ "$_code" != "200" ]; then
+    _err "error retrieving data!"
+    return 1
+  fi
+
+  _debug fulldomain "$fulldomain"
+  _debug txtvalue "$txtvalue"
+  _debug domain "$_domain"
+  _debug sub_domain "$_sub_domain"
+
+  _info "Adding record"
+  if _neo_rest POST "dns/zones/$_domain_id/records" "{\"record\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":60}}"; then
+    if printf -- "%s" "$response" | grep "$_sub_domain" >/dev/null; then
+      _info "Added, OK"
+      return 0
+    else
+      _err "Add txt record error."
+      return 1
+    fi
+  fi
+  _err "Add txt record error."
+  return 1
+}
+
+#fulldomain txtvalue
+dns_neodigit_rm() {
+  fulldomain=$1
+  txtvalue=$2
+
+  NEODIGIT_API_TOKEN="${NEODIGIT_API_TOKEN:-$(_readaccountconf_mutable NEODIGIT_API_TOKEN)}"
+  if [ -z "$NEODIGIT_API_TOKEN" ]; then
+    NEODIGIT_API_TOKEN=""
+    _err "You haven't specified a Token api key."
+    _err "Please create the key and try again."
+    return 1
+  fi
+
+  #save the api key and email to the account conf file.
+  _saveaccountconf_mutable NEODIGIT_API_TOKEN "$NEODIGIT_API_TOKEN"
+
+  _debug "First detect the root zone"
+  if ! _get_root "$fulldomain"; then
+    _err "invalid domain"
+    return 1
+  fi
+
+  _debug _domain_id "$_domain_id"
+  _debug _sub_domain "$_sub_domain"
+  _debug _domain "$_domain"
+
+  _debug "Getting txt records"
+  _neo_rest GET "dns/zones/${_domain_id}/records?type=TXT&name=$fulldomain&content=$txtvalue"
+
+  if [ "$_code" != "200" ]; then
+    _err "error retrieving data!"
+    return 1
+  fi
+
+  record_id=$(echo "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1)
+  _debug "record_id" "$record_id"
+  if [ -z "$record_id" ]; then
+    _err "Can not get record id to remove."
+    return 1
+  fi
+  if ! _neo_rest DELETE "dns/zones/$_domain_id/records/$record_id"; then
+    _err "Delete record error."
+    return 1
+  fi
+
+}
+
+####################  Private functions below ##################################
+#_acme-challenge.www.domain.com
+#returns
+# _sub_domain=_acme-challenge.www
+# _domain=domain.com
+# _domain_id=dasfdsafsadg5ythd
+_get_root() {
+  domain=$1
+  i=2
+  p=1
+  while true; do
+    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
+    _debug h "$h"
+    if [ -z "$h" ]; then
+      #not valid
+      return 1
+    fi
+
+    if ! _neo_rest GET "dns/zones?name=$h"; then
+      return 1
+    fi
+
+    _debug p "$p"
+
+    if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
+      _domain_id=$(echo "$response" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d: -f2 | cut -d, -f1)
+      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
+  return 1
+}
+
+_neo_rest() {
+  m=$1
+  ep="$2"
+  data="$3"
+  _debug "$ep"
+
+  export _H1="X-TCPanel-Token: $NEODIGIT_API_TOKEN"
+  export _H2="Content-Type: application/json"
+
+  if [ "$m" != "GET" ]; then
+    _debug data "$data"
+    response="$(_post "$data" "$NEODIGIT_API_URL/$ep" "" "$m")"
+  else
+    response="$(_get "$NEODIGIT_API_URL/$ep")"
+  fi
+
+  _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
+
+  if [ "$?" != "0" ]; then
+    _err "error $ep"
+    return 1
+  fi
+  _debug2 response "$response"
+  return 0
+}