Browse Source

Merge pull request #920 from Neilpang/dev

Dev
neil 7 years ago
parent
commit
c53f36a777
4 changed files with 316 additions and 1 deletions
  1. 2 1
      README.md
  2. 35 0
      dnsapi/README.md
  3. 91 0
      dnsapi/dns_duckdns.sh
  4. 188 0
      dnsapi/dns_namecom.sh

+ 2 - 1
README.md

@@ -334,7 +334,8 @@ You don't have to do anything manually!
 1. Dynu API (https://www.dynu.com)
 1. DNSimple API
 1. NS1.com API
-
+1. DuckDNS.org API
+1. Name.com API
 
 
 And: 

+ 35 - 0
dnsapi/README.md

@@ -505,6 +505,41 @@ Ok, let's issue a cert now:
 acme.sh --issue --dns dns_nsone -d example.com -d www.example.com
 ```
 
+## 27. Use DuckDNS.org API
+
+```
+export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
+```
+
+Please note that since DuckDNS uses StartSSL as their cert provider, thus 
+--insecure must be used when issuing certs:
+```
+acme.sh --insecure --issue --dns dns_duckdns -d mydomain.duckdns.org
+```
+
+Also, DuckDNS uses the domain name as username for recording changing, so the
+account file will always store the lastly used domain name.
+
+For issues, please report to https://github.com/raidenii/acme.sh/issues.
+
+## 28. Use Name.com API
+
+You'll need to fill out the form at https://www.name.com/reseller/apply to apply
+for API username and token.
+
+```
+export Namecom_Username="testuser"
+export Namecom_Token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+```
+
+And now you can issue certs with:
+
+```
+acme.sh --issue --dns dns_namecom -d example.com -d www.example.com
+```
+
+For issues, please report to https://github.com/raidenii/acme.sh/issues.
+
 # Use custom API
 
 If your API is not supported yet, you can write your own DNS API.

+ 91 - 0
dnsapi/dns_duckdns.sh

@@ -0,0 +1,91 @@
+#!/usr/bin/env sh
+
+#Created by RaidenII, to use DuckDNS's API to add/remove text records
+#06/27/2017
+
+# Currently only support single domain access
+# Due to the fact that DuckDNS uses StartSSL as cert provider, --insecure must be used with acme.sh
+
+DuckDNS_API="https://www.duckdns.org/update"
+API_Params="domains=$DuckDNS_Domain&token=$DuckDNS_Token"
+
+########  Public functions #####################
+
+#Usage: dns_duckdns_add _acme-challenge.domain.duckdns.org "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_duckdns_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  # We'll extract the domain/username from full domain
+  DuckDNS_Domain=$(echo "$fulldomain" | _lower_case | _egrep_o '.[^.]*.duckdns.org' | cut -d . -f 2)
+
+  if [ -z "$DuckDNS_Domain" ]; then
+    _err "Error extracting the domain."
+    return 1
+  fi
+
+  if [ -z "$DuckDNS_Token" ]; then
+    DuckDNS_Token=""
+    _err "The token for your DuckDNS account is necessary."
+    _err "You can look it up in your DuckDNS account."
+    return 1
+  fi
+
+  # Now save the credentials.
+  _saveaccountconf DuckDNS_Domain "$DuckDNS_Domain"
+  _saveaccountconf DuckDNS_Token "$DuckDNS_Token"
+
+  # Unfortunately, DuckDNS does not seems to support lookup domain through API
+  # So I assume your credentials (which are your domain and token) are correct
+  # If something goes wrong, we will get a KO response from DuckDNS
+
+  # Now add the TXT record to DuckDNS
+  _info "Trying to add TXT record"
+  if _duckdns_rest GET "$API_Params&txt=$txtvalue" && [ "$response" = "OK" ]; then
+    _info "TXT record has been successfully added to your DuckDNS domain."
+    _info "Note that all subdomains under this domain uses the same TXT record."
+    return 0
+  else
+    _err "Errors happened during adding the TXT record."
+    return 1
+  fi
+}
+
+#Usage: fulldomain txtvalue
+#Remove the txt record after validation.
+dns_duckdns_rm() {
+  fulldomain=$1
+  txtvalue=$2
+
+  # Now remove the TXT record from DuckDNS
+  _info "Trying to remove TXT record"
+  if _duckdns_rest GET "$API_Params&txt=&clear=true" && [ "$response" = "OK" ]; then
+    _info "TXT record has been successfully removed from your DuckDNS domain."
+    return 0
+  else
+    _err "Errors happened during removing the TXT record."
+    return 1
+  fi
+}
+
+####################  Private functions below ##################################
+
+#Usage: method URI
+_duckdns_rest() {
+  method=$1
+  param="$2"
+  _debug param "$param"
+  url="$DuckDNS_API?$param"
+  _debug url "$url"
+
+  # DuckDNS uses GET to update domain info
+  if [ "$method" = "GET" ]; then
+    response="$(_get "$url")"
+  else
+    _err "Unsupported method"
+    return 1
+  fi
+
+  _debug2 response "$response"
+  return 0
+}

+ 188 - 0
dnsapi/dns_namecom.sh

@@ -0,0 +1,188 @@
+#!/usr/bin/env sh
+
+#Author: RaidneII
+#Created 06/28/2017
+#Utilize name.com API to finish dns-01 verifications.
+########  Public functions #####################
+
+Namecom_API="https://api.name.com/api"
+
+#Usage: dns_namecom_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_namecom_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  # First we need name.com credentials.
+  if [ -z "$Namecom_Username" ]; then
+    Namecom_Username=""
+    _err "Username for name.com is missing."
+    _err "Please specify that in your environment variable."
+    return 1
+  fi
+
+  if [ -z "$Namecom_Token" ]; then
+    Namecom_Token=""
+    _err "API token for name.com is missing."
+    _err "Please specify that in your environment variable."
+    return 1
+  fi
+
+  # Save them in configuration.
+  _saveaccountconf Namecom_Username "$Namecom_Username"
+  _saveaccountconf Namecom_Token "$Namecom_Token"
+
+  # Login in using API
+  if ! _namecom_login; then
+    return 1
+  fi
+
+  # Find domain in domain list.
+  if ! _namecom_get_root "$fulldomain"; then
+    _err "Unable to find domain specified."
+    _namecom_logout
+    return 1
+  fi
+
+  # Add TXT record.
+  _namecom_addtxt_json="{\"hostname\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":\"300\",\"priority\":\"10\"}"
+  if _namecom_rest POST "dns/create/$_domain" "$_namecom_addtxt_json"; then
+    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
+    if [ "$retcode" ]; then
+      _info "Successfully added TXT record, ready for validation."
+      _namecom_logout
+      return 0
+    else
+      _err "Unable to add the DNS record."
+      _namecom_logout
+      return 1
+    fi
+  fi
+}
+
+#Usage: fulldomain txtvalue
+#Remove the txt record after validation.
+dns_namecom_rm() {
+  fulldomain=$1
+  txtvalue=$2
+
+  if ! _namecom_login; then
+    return 1
+  fi
+
+  # Find domain in domain list.
+  if ! _namecom_get_root "$fulldomain"; then
+    _err "Unable to find domain specified."
+    _namecom_logout
+    return 1
+  fi
+
+  # Get the record id.
+  if _namecom_rest GET "dns/list/$_domain"; then
+    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
+    if [ "$retcode" ]; then
+      _record_id=$(printf "%s\n" "$response" | _egrep_o "\"record_id\":\"[0-9]+\",\"name\":\"$fulldomain\",\"type\":\"TXT\"" | cut -d \" -f 4)
+      _debug record_id "$_record_id"
+      _info "Successfully retrieved the record id for ACME challenge."
+    else
+      _err "Unable to retrieve the record id."
+      _namecom_logout
+      return 1
+    fi
+  fi
+
+  # Remove the DNS record using record id.
+  _namecom_rmtxt_json="{\"record_id\":\"$_record_id\"}"
+  if _namecom_rest POST "dns/delete/$_domain" "$_namecom_rmtxt_json"; then
+    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
+    if [ "$retcode" ]; then
+      _info "Successfully removed the TXT record."
+      _namecom_logout
+      return 0
+    else
+      _err "Unable to remove the DNS record."
+      _namecom_logout
+      return 1
+    fi
+  fi
+}
+
+####################  Private functions below ##################################
+_namecom_rest() {
+  method=$1
+  param=$2
+  data=$3
+
+  export _H1="Content-Type: application/json"
+  export _H2="Api-Session-Token: $sessionkey"
+  if [ "$method" != "GET" ]; then
+    response="$(_post "$data" "$Namecom_API/$param" "" "$method")"
+  else
+    response="$(_get "$Namecom_API/$param")"
+  fi
+
+  if [ "$?" != "0" ]; then
+    _err "error $param"
+    return 1
+  fi
+
+  _debug2 response "$response"
+  return 0
+}
+
+_namecom_login() {
+  namecom_login_json="{\"username\":\"$Namecom_Username\",\"api_token\":\"$Namecom_Token\"}"
+
+  if _namecom_rest POST "login" "$namecom_login_json"; then
+    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
+    if [ "$retcode" ]; then
+      _info "Successfully logged in. Fetching session token..."
+      sessionkey=$(printf "%s\n" "$response" | _egrep_o "\"session_token\":\".+" | cut -d \" -f 4)
+      if [ ! -z "$sessionkey" ]; then
+        _debug sessionkey "$sessionkey"
+        _info "Session key obtained."
+      else
+        _err "Unable to get session key."
+        return 1
+      fi
+    else
+      _err "Logging in failed."
+      return 1
+    fi
+  fi
+}
+
+_namecom_logout() {
+  if _namecom_rest GET "logout"; then
+    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
+    if [ "$retcode" ]; then
+      _info "Successfully logged out."
+    else
+      _err "Error logging out."
+      return 1
+    fi
+  fi
+}
+
+_namecom_get_root() {
+  domain=$1
+  i=2
+  p=1
+
+  if _namecom_rest GET "domain/list"; then
+    while true; do
+      host=$(printf "%s" "$domain" | cut -d . -f $i-100)
+      if [ -z "$host" ]; then
+        return 1
+      fi
+
+      if _contains "$response" "$host"; then
+        _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
+        _domain="$host"
+        return 0
+      fi
+      p=$i
+      i=$(_math "$i" + 1)
+    done
+  fi
+  return 1
+}