Browse Source

Merge pull request #2268 from Neilpang/dev

sync
neil 6 years ago
parent
commit
5f9378569b
7 changed files with 304 additions and 28 deletions
  1. 13 11
      acme.sh
  2. 1 1
      deploy/haproxy.sh
  3. 83 0
      dnsapi/dns_acmeproxy.sh
  4. 3 3
      dnsapi/dns_gcloud.sh
  5. 180 0
      dnsapi/dns_internetbs.sh
  6. 12 9
      dnsapi/dns_yandex.sh
  7. 12 4
      notify/mailgun.sh

+ 13 - 11
acme.sh

@@ -1114,14 +1114,14 @@ _createcsr() {
   elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then
     #single domain
     _info "Single domain" "$domain"
-    printf -- "\nsubjectAltName=DNS:$(_idn $domain)" >>"$csrconf"
+    printf -- "\nsubjectAltName=DNS:$(_idn "$domain")" >>"$csrconf"
   else
     domainlist="$(_idn "$domainlist")"
     _debug2 domainlist "$domainlist"
     if _contains "$domainlist" ","; then
-      alt="DNS:$(_idn $domain),DNS:$(echo "$domainlist" | sed "s/,,/,/g" | sed "s/,/,DNS:/g")"
+      alt="DNS:$(_idn "$domain"),DNS:$(echo "$domainlist" | sed "s/,,/,/g" | sed "s/,/,DNS:/g")"
     else
-      alt="DNS:$(_idn $domain),DNS:$domainlist"
+      alt="DNS:$(_idn "$domain"),DNS:$domainlist"
     fi
     #multi
     _info "Multi domain" "$alt"
@@ -3044,11 +3044,12 @@ _clearupdns() {
         _err "It seems that your api file doesn't define $rmcommand"
         return 1
       fi
-
+      _info "Removing txt: $txt for domain: $txtdomain"
       if ! $rmcommand "$txtdomain" "$txt"; then
         _err "Error removing txt for domain:$txtdomain"
         return 1
       fi
+      _info "Removed: Success"
     )
 
   done
@@ -3648,9 +3649,9 @@ _check_dns_entries() {
     for entry in $dns_entries; do
       d=$(_getfield "$entry" 1)
       txtdomain=$(_getfield "$entry" 2)
-      txtdomain=$(_idn $txtdomain)
+      txtdomain=$(_idn "$txtdomain")
       aliasDomain=$(_getfield "$entry" 3)
-      aliasDomain=$(_idn $aliasDomain)
+      aliasDomain=$(_idn "$aliasDomain")
       txt=$(_getfield "$entry" 5)
       d_api=$(_getfield "$entry" 6)
       _debug "d" "$d"
@@ -3847,7 +3848,7 @@ issue() {
   if [ -z "$vlist" ]; then
     if [ "$ACME_VERSION" = "2" ]; then
       #make new order request
-      _identifiers="{\"type\":\"dns\",\"value\":\"$(_idn $_main_domain)\"}"
+      _identifiers="{\"type\":\"dns\",\"value\":\"$(_idn "$_main_domain")\"}"
       _w_index=1
       while true; do
         d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")"
@@ -3856,7 +3857,7 @@ issue() {
         if [ -z "$d" ]; then
           break
         fi
-        _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn $d)\"}"
+        _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn "$d")\"}"
       done
       _debug2 _identifiers "$_identifiers"
       if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
@@ -3944,7 +3945,7 @@ $_authorizations_map"
       fi
 
       if [ "$ACME_VERSION" = "2" ]; then
-        response="$(echo "$_authorizations_map" | grep "^$(_idn $d)," | sed "s/$d,//")"
+        response="$(echo "$_authorizations_map" | grep "^$(_idn "$d")," | sed "s/$d,//")"
         _debug2 "response" "$response"
         if [ -z "$response" ]; then
           _err "get to authz error."
@@ -4063,7 +4064,7 @@ $_authorizations_map"
         dns_entry="$dns_entry$dvsep$txt${dvsep}$d_api"
         _debug2 dns_entry "$dns_entry"
         if [ "$d_api" ]; then
-          _info "Found domain api file: $d_api"
+          _debug "Found domain api file: $d_api"
         else
           if [ "$_currentRoot" != "$W_DNS" ]; then
             _err "Can not find dns api hook for: $_currentRoot"
@@ -4088,11 +4089,12 @@ $_authorizations_map"
             _err "It seems that your api file is not correct, it must have a function named: $addcommand"
             return 1
           fi
-
+          _info "Adding txt value: $txt for domain:  $txtdomain"
           if ! $addcommand "$txtdomain" "$txt"; then
             _err "Error add txt for domain:$txtdomain"
             return 1
           fi
+          _info "The txt record is added: Success."
         )
 
         if [ "$?" != "0" ]; then

+ 1 - 1
deploy/haproxy.sh

@@ -179,7 +179,7 @@ haproxy_deploy() {
       return ${_ret}
     fi
   else
-    [ -f "${_issuer}" ] _err "Issuer file update not requested but .issuer file exists"
+    [ -f "${_issuer}" ] && _err "Issuer file update not requested but .issuer file exists"
   fi
 
   # Update .ocsp file if certificate was requested with --ocsp/--ocsp-must-staple option

+ 83 - 0
dnsapi/dns_acmeproxy.sh

@@ -0,0 +1,83 @@
+#!/usr/bin/env sh
+
+## Acmeproxy DNS provider to be used with acmeproxy (http://github.com/mdbraber/acmeproxy)
+## API integration by Maarten den Braber
+##
+## Report any bugs via https://github.com/mdbraber/acme.sh
+
+dns_acmeproxy_add() {
+  fulldomain="${1}"
+  txtvalue="${2}"
+  action="present"
+
+  _debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'"
+  _acmeproxy_request "$fulldomain" "$txtvalue" "$action"
+}
+
+dns_acmeproxy_rm() {
+  fulldomain="${1}"
+  txtvalue="${2}"
+  action="cleanup"
+
+  _debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'"
+  _acmeproxy_request "$fulldomain" "$txtvalue" "$action"
+}
+
+_acmeproxy_request() {
+
+  ## Nothing to see here, just some housekeeping
+  fulldomain=$1
+  txtvalue=$2
+  action=$3
+
+  _info "Using acmeproxy"
+  _debug fulldomain "$fulldomain"
+  _debug txtvalue "$txtvalue"
+
+  ACMEPROXY_ENDPOINT="${ACMEPROXY_ENDPOINT:-$(_readaccountconf_mutable ACMEPROXY_ENDPOINT)}"
+  ACMEPROXY_USERNAME="${ACMEPROXY_USERNAME:-$(_readaccountconf_mutable ACMEPROXY_USERNAME)}"
+  ACMEPROXY_PASSWORD="${ACMEPROXY_PASSWORD:-$(_readaccountconf_mutable ACMEPROXY_PASSWORD)}"
+
+  ## Check for the endpoint
+  if [ -z "$ACMEPROXY_ENDPOINT" ]; then
+    ACMEPROXY_ENDPOINT=""
+    _err "You didn't specify the endpoint"
+    _err "Please set them via 'export ACMEPROXY_ENDPOINT=https://ip:port' and try again."
+    return 1
+  fi
+
+  ## Save the credentials to the account file
+  _saveaccountconf_mutable ACMEPROXY_ENDPOINT "$ACMEPROXY_ENDPOINT"
+  _saveaccountconf_mutable ACMEPROXY_USERNAME "$ACMEPROXY_USERNAME"
+  _saveaccountconf_mutable ACMEPROXY_PASSWORD "$ACMEPROXY_PASSWORD"
+
+  if [ -z "$ACMEPROXY_USERNAME" ] || [ -z "$ACMEPROXY_PASSWORD" ]; then
+    _info "ACMEPROXY_USERNAME and/or ACMEPROXY_PASSWORD not set - using without client authentication! Make sure you're using server authentication (e.g. IP-based)"
+    export _H1="Accept: application/json"
+    export _H2="Content-Type: application/json"
+  else
+    ## Base64 encode the credentials
+    credentials=$(printf "%b" "$ACMEPROXY_USERNAME:$ACMEPROXY_PASSWORD" | _base64)
+
+    ## Construct the HTTP Authorization header
+    export _H1="Authorization: Basic $credentials"
+    export _H2="Accept: application/json"
+    export _H3="Content-Type: application/json"
+  fi
+
+  ## Add the challenge record to the acmeproxy grid member
+  response="$(_post "{\"fqdn\": \"$fulldomain.\", \"value\": \"$txtvalue\"}" "$ACMEPROXY_ENDPOINT/$action" "" "POST")"
+
+  ## Let's see if we get something intelligible back from the unit
+  if echo "$response" | grep "\"$txtvalue\"" >/dev/null; then
+    _info "Successfully updated the txt record"
+    return 0
+  else
+    _err "Error encountered during record addition"
+    _err "$response"
+    return 1
+  fi
+
+}
+
+####################  Private functions below ##################################

+ 3 - 3
dnsapi/dns_gcloud.sh

@@ -134,14 +134,14 @@ _dns_gcloud_find_zone() {
   filter="$filter)"
   _debug filter "$filter"
 
-  # List domains and find the longest match (in case of some levels of delegation)
+  # List domains and find the zone with the deepest sub-domain (in case of some levels of delegation)
   if ! match=$(gcloud dns managed-zones list \
     --format="value(name, dnsName)" \
     --filter="$filter" \
     | while read -r dnsName name; do
-      printf "%s\t%s\t%s\n" "${#dnsName}" "$dnsName" "$name"
+      printf "%s\t%s\t%s\n" "$(echo "$name" | awk -F"." '{print NF-1}')" "$dnsName" "$name"
     done \
-    | sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then
+      | sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then
     _err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?"
     return 1
   fi

+ 180 - 0
dnsapi/dns_internetbs.sh

@@ -0,0 +1,180 @@
+#!/usr/bin/env sh
+
+#This is the Internet.BS api wrapper for acme.sh
+#
+#Author: <alexey@nelexa.ru> Ne-Lexa
+#Report Bugs here: https://github.com/Ne-Lexa/acme.sh
+
+#INTERNETBS_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
+#INTERNETBS_API_PASSWORD="sdfsdfsdfljlbjkljlkjsdfoiwje"
+
+INTERNETBS_API_URL="https://api.internet.bs"
+
+########  Public functions #####################
+
+#Usage: dns_myapi_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_internetbs_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  INTERNETBS_API_KEY="${INTERNETBS_API_KEY:-$(_readaccountconf_mutable INTERNETBS_API_KEY)}"
+  INTERNETBS_API_PASSWORD="${INTERNETBS_API_PASSWORD:-$(_readaccountconf_mutable INTERNETBS_API_PASSWORD)}"
+
+  if [ -z "$INTERNETBS_API_KEY" ] || [ -z "$INTERNETBS_API_PASSWORD" ]; then
+    INTERNETBS_API_KEY=""
+    INTERNETBS_API_PASSWORD=""
+    _err "You didn't specify the INTERNET.BS api key and password yet."
+    _err "Please create you key and try again."
+    return 1
+  fi
+
+  _saveaccountconf_mutable INTERNETBS_API_KEY "$INTERNETBS_API_KEY"
+  _saveaccountconf_mutable INTERNETBS_API_PASSWORD "$INTERNETBS_API_PASSWORD"
+
+  _debug "First detect the root zone"
+  if ! _get_root "$fulldomain"; then
+    _err "invalid domain"
+    return 1
+  fi
+
+  _debug _sub_domain "$_sub_domain"
+  _debug _domain "$_domain"
+
+  # https://testapi.internet.bs/Domain/DnsRecord/Add?ApiKey=testapi&Password=testpass&FullRecordName=w3.test-api-domain7.net&Type=CNAME&Value=www.internet.bs%&ResponseFormat=json
+  if _internetbs_rest POST "Domain/DnsRecord/Add" "FullRecordName=${_sub_domain}.${_domain}&Type=TXT&Value=${txtvalue}&ResponseFormat=json"; then
+    if ! _contains "$response" "\"status\":\"SUCCESS\""; then
+      _err "ERROR add TXT record"
+      _err "$response"
+      return 1
+    fi
+
+    _info "txt record add success."
+    return 0
+  fi
+
+  return 1
+}
+
+#Usage: fulldomain txtvalue
+#Remove the txt record after validation.
+dns_internetbs_rm() {
+  fulldomain=$1
+  txtvalue=$2
+
+  INTERNETBS_API_KEY="${INTERNETBS_API_KEY:-$(_readaccountconf_mutable INTERNETBS_API_KEY)}"
+  INTERNETBS_API_PASSWORD="${INTERNETBS_API_PASSWORD:-$(_readaccountconf_mutable INTERNETBS_API_PASSWORD)}"
+
+  if [ -z "$INTERNETBS_API_KEY" ] || [ -z "$INTERNETBS_API_PASSWORD" ]; then
+    INTERNETBS_API_KEY=""
+    INTERNETBS_API_PASSWORD=""
+    _err "You didn't specify the INTERNET.BS api key and password yet."
+    _err "Please create you key and try again."
+    return 1
+  fi
+
+  _debug "First detect the root zone"
+  if ! _get_root "$fulldomain"; then
+    _err "invalid domain"
+    return 1
+  fi
+
+  _debug _sub_domain "$_sub_domain"
+  _debug _domain "$_domain"
+
+  _debug "Getting txt records"
+  # https://testapi.internet.bs/Domain/DnsRecord/List?ApiKey=testapi&Password=testpass&Domain=test-api-domain7.net&FilterType=CNAME&ResponseFormat=json
+  _internetbs_rest POST "Domain/DnsRecord/List" "Domain=$_domain&FilterType=TXT&ResponseFormat=json"
+
+  if ! _contains "$response" "\"status\":\"SUCCESS\""; then
+    _err "ERROR list dns records"
+    _err "$response"
+    return 1
+  fi
+
+  if _contains "$response" "\name\":\"${_sub_domain}.${_domain}\""; then
+    _info "txt record find."
+
+    # https://testapi.internet.bs/Domain/DnsRecord/Remove?ApiKey=testapi&Password=testpass&FullRecordName=www.test-api-domain7.net&Type=cname&ResponseFormat=json
+    _internetbs_rest POST "Domain/DnsRecord/Remove" "FullRecordName=${_sub_domain}.${_domain}&Type=TXT&ResponseFormat=json"
+
+    if ! _contains "$response" "\"status\":\"SUCCESS\""; then
+      _err "ERROR remove dns record"
+      _err "$response"
+      return 1
+    fi
+
+    _info "txt record deleted success."
+    return 0
+  fi
+
+  return 1
+}
+
+####################  Private functions below ##################################
+#_acme-challenge.www.domain.com
+#returns
+# _sub_domain=_acme-challenge.www
+# _domain=domain.com
+# _domain_id=12345
+_get_root() {
+  domain=$1
+  i=2
+  p=1
+
+  # https://testapi.internet.bs/Domain/List?ApiKey=testapi&Password=testpass&CompactList=yes&ResponseFormat=json
+  if _internetbs_rest POST "Domain/List" "CompactList=yes&ResponseFormat=json"; then
+
+    if ! _contains "$response" "\"status\":\"SUCCESS\""; then
+      _err "ERROR fetch domain list"
+      _err "$response"
+      return 1
+    fi
+
+    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 _contains "$response" "\"$h\""; then
+        _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-${p})
+        _domain=${h}
+        return 0
+      fi
+
+      p=${i}
+      i=$(_math "$i" + 1)
+    done
+  fi
+  return 1
+}
+
+#Usage: method  URI  data
+_internetbs_rest() {
+  m="$1"
+  ep="$2"
+  data="$3"
+  url="${INTERNETBS_API_URL}/${ep}"
+
+  _debug url "$url"
+
+  apiKey="$(printf "%s" "${INTERNETBS_API_KEY}" | _url_encode)"
+  password="$(printf "%s" "${INTERNETBS_API_PASSWORD}" | _url_encode)"
+
+  if [ "$m" = "GET" ]; then
+    response="$(_get "${url}?ApiKey=${apiKey}&Password=${password}&${data}" | tr -d '\r')"
+  else
+    _debug2 data "$data"
+    response="$(_post "$data" "${url}?ApiKey=${apiKey}&Password=${password}" | tr -d '\r')"
+  fi
+
+  if [ "$?" != "0" ]; then
+    _err "error $ep"
+    return 1
+  fi
+
+  _debug2 response "$response"
+  return 0
+}

+ 12 - 9
dnsapi/dns_yandex.sh

@@ -16,7 +16,7 @@ dns_yandex_add() {
   _PDD_credentials || return 1
   export _H1="PddToken: $PDD_Token"
 
-  _PDD_get_domain "$fulldomain"
+  _PDD_get_domain "$fulldomain" || return 1
   _debug "Found suitable domain in pdd: $curDomain"
   curData="domain=${curDomain}&type=TXT&subdomain=${curSubdomain}&ttl=360&content=${txtvalue}"
   curUri="https://pddimp.yandex.ru/api2/admin/dns/add"
@@ -30,16 +30,19 @@ dns_yandex_rm() {
   _debug "Calling: dns_yandex_rm() '${fulldomain}'"
   _PDD_credentials || return 1
   export _H1="PddToken: $PDD_Token"
-  record_id=$(pdd_get_record_id "${fulldomain}")
-  _debug "Result: $record_id"
 
-  _PDD_get_domain "$fulldomain"
+  _PDD_get_domain "$fulldomain" || return 1
   _debug "Found suitable domain in pdd: $curDomain"
 
-  curUri="https://pddimp.yandex.ru/api2/admin/dns/del"
-  curData="domain=${curDomain}&record_id=${record_id}"
-  curResult="$(_post "${curData}" "${curUri}")"
-  _debug "Result: $curResult"
+  record_id=$(pdd_get_record_id "${fulldomain}")
+  _debug "Result: $record_id"
+
+  for rec_i in $record_id; do
+    curUri="https://pddimp.yandex.ru/api2/admin/dns/del"
+    curData="domain=${curDomain}&record_id=${rec_i}"
+    curResult="$(_post "${curData}" "${curUri}")"
+    _debug "Result: $curResult"
+  done
 }
 
 ####################  Private functions below ##################################
@@ -54,7 +57,7 @@ _PDD_get_domain() {
     _debug2 "res1" "$res1"
     __found="$(echo "$res1" | sed -n -e 's#.* "found": \([^,]*\),.*#\1#p')"
     _debug "found: $__found results on page"
-    if [ "$__found" -lt 20 ]; then
+    if [ "0$__found" -lt 20 ]; then
       _debug "last page: $__page"
       __last=1
     fi

+ 12 - 4
notify/mailgun.sh

@@ -9,7 +9,10 @@
 #MAILGUN_API_DOMAIN="xxxxxx.com"  #optional, use the default sandbox domain
 #MAILGUN_FROM="xxx@xxxxx.com"    #optional, use the default sendbox account
 
-_MAILGUN_BASE="https://api.mailgun.net/v3"
+_MAILGUN_BASE_US="https://api.mailgun.net/v3"
+_MAILGUN_BASE_EU="https://api.eu.mailgun.net/v3"
+
+_MAILGUN_BASE="$_MAILGUN_BASE_US"
 
 # subject  content statusCode
 mailgun_send() {
@@ -31,12 +34,17 @@ mailgun_send() {
   if [ -z "$MAILGUN_REGION" ]; then
     MAILGUN_REGION=""
     _debug "The MAILGUN_REGION is not set, so use the default us region."
-    _MAILGUN_BASE="https://api.mailgun.net/v3"
+    _MAILGUN_BASE="$_MAILGUN_BASE_US"
   else
+    MAILGUN_REGION="$(echo "$MAILGUN_REGION" | _lower_case)"
     _saveaccountconf_mutable MAILGUN_REGION "$MAILGUN_REGION"
-    _MAILGUN_BASE="https://api.eu.mailgun.net/v3"
+    if [ "$MAILGUN_REGION" = "us" ]; then
+      _MAILGUN_BASE="$_MAILGUN_BASE_US"
+    else
+      _MAILGUN_BASE="$_MAILGUN_BASE_EU"
+    fi
   fi
-
+  _debug _MAILGUN_BASE "$_MAILGUN_BASE"
   MAILGUN_TO="${MAILGUN_TO:-$(_readaccountconf_mutable MAILGUN_TO)}"
   if [ -z "$MAILGUN_TO" ]; then
     MAILGUN_TO=""