Browse Source

Support for MyDevil.net (#2076)

support mydevil
Marcin Konicki 6 years ago
parent
commit
16a0f40ac2
5 changed files with 187 additions and 0 deletions
  1. 1 0
      README.md
  2. 10 0
      deploy/README.md
  3. 59 0
      deploy/mydevil.sh
  4. 20 0
      dnsapi/README.md
  5. 97 0
      dnsapi/dns_mydevil.sh

+ 1 - 0
README.md

@@ -356,6 +356,7 @@ You don't have to do anything manually!
 1. Futurehosting API (https://www.futurehosting.com)
 1. Rackspace Cloud DNS (https://www.rackspace.com)
 1. Online.net API (https://online.net/)
+1. MyDevil.net (https://www.mydevil.net/)
 
 And:
 

+ 10 - 0
deploy/README.md

@@ -381,3 +381,13 @@ you want to update:
 $ export QINIU_CDN_DOMAIN="cdn.example.com"
 $ acme.sh --deploy -d example.com --deploy-hook qiniu
 ```
+
+## 14. Deploy your cert on MyDevil.net
+
+Once you have acme.sh installed and certificate issued (see info in [DNS API](../dnsapi/README.md#61-use-mydevilnet)), you can install it by following command:
+
+```sh
+acme.sh --deploy --deploy-hook mydevil -d example.com
+```
+
+That will remove old certificate and install new one.

+ 59 - 0
deploy/mydevil.sh

@@ -0,0 +1,59 @@
+#!/usr/bin/env sh
+
+# MyDevil.net API (2019-02-03)
+#
+# MyDevil.net already supports automatic Let's Encrypt certificates,
+# except for wildcard domains.
+#
+# This script depends on `devil` command that MyDevil.net provides,
+# which means that it works only on server side.
+#
+# Author: Marcin Konicki <https://ahwayakchih.neoni.net>
+#
+########  Public functions #####################
+
+# Usage: mydevil_deploy domain keyfile certfile cafile fullchain
+mydevil_deploy() {
+  _cdomain="$1"
+  _ckey="$2"
+  _ccert="$3"
+  _cca="$4"
+  _cfullchain="$5"
+  ip=""
+
+  _debug _cdomain "$_cdomain"
+  _debug _ckey "$_ckey"
+  _debug _ccert "$_ccert"
+  _debug _cca "$_cca"
+  _debug _cfullchain "$_cfullchain"
+
+  if ! _exists "devil"; then
+    _err "Could not find 'devil' command."
+    return 1
+  fi
+
+  ip=$(mydevil_get_ip "$_cdomain")
+  if [ -z "$ip" ]; then
+    _err "Could not find IP for domain $_cdomain."
+    return 1
+  fi
+
+  # Delete old certificate first
+  _info "Removing old certificate for $_cdomain at $ip"
+  devil ssl www del "$ip" "$_cdomain"
+
+  # Add new certificate
+  _info "Adding new certificate for $_cdomain at $ip"
+  devil ssl www add "$ip" "$_cfullchain" "$_ckey" "$_cdomain" || return 1
+
+  return 0
+}
+
+####################  Private functions below ##################################
+
+# Usage: ip=$(mydevil_get_ip domain.com)
+#        echo $ip
+mydevil_get_ip() {
+  devil dns list "$1" | cut -w -s -f 3,7 | grep "^A$(printf '\t')" | cut -w -s -f 2 || return 1
+  return 0
+}

+ 20 - 0
dnsapi/README.md

@@ -1259,6 +1259,26 @@ acme.sh --issue --dns dns_online -d example.com -d www.example.com
 
 `ONLINE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 
+## 66. Use MyDevil.net
+
+Make sure that you can execute own binaries:
+
+```sh
+devil binexec on
+```
+
+Install acme.sh, or simply `git clone` it into some directory on your MyDevil host account (in which case you should link to it from your `~/bin` directory).
+
+If you're not using private IP and depend on default IP provided by host, you may want to edit `crontab` too, and make sure that `acme.sh --cron` is run also after reboot (you can find out how to do that on their wiki pages).
+
+To issue a new certificate, run:
+
+```sh
+acme.sh --issue --dns dns_mydevil -d example.com -d *.example.com
+```
+
+After certificate is ready, you can install it with [deploy command](../deploy/README.md#14-deploy-your-cert-on-mydevilnet).
+
 # Use custom API
 
 If your API is not supported yet, you can write your own DNS API.

+ 97 - 0
dnsapi/dns_mydevil.sh

@@ -0,0 +1,97 @@
+#!/usr/bin/env sh
+
+# MyDevil.net API (2019-02-03)
+#
+# MyDevil.net already supports automatic Let's Encrypt certificates,
+# except for wildcard domains.
+#
+# This script depends on `devil` command that MyDevil.net provides,
+# which means that it works only on server side.
+#
+# Author: Marcin Konicki <https://ahwayakchih.neoni.net>
+#
+########  Public functions #####################
+
+#Usage: dns_mydevil_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_mydevil_add() {
+  fulldomain=$1
+  txtvalue=$2
+  domain=""
+
+  if ! _exists "devil"; then
+    _err "Could not find 'devil' command."
+    return 1
+  fi
+
+  _info "Using mydevil"
+
+  domain=$(mydevil_get_domain "$fulldomain")
+  if [ -z "$domain" ]; then
+    _err "Invalid domain name: could not find root domain of $fulldomain."
+    return 1
+  fi
+
+  # No need to check if record name exists, `devil` always adds new record.
+  # In worst case scenario, we end up with multiple identical records.
+
+  _info "Adding $fulldomain record for domain $domain"
+  if devil dns add "$domain" "$fulldomain" TXT "$txtvalue"; then
+    _info "Successfully added TXT record, ready for validation."
+    return 0
+  else
+    _err "Unable to add DNS record."
+    return 1
+  fi
+}
+
+#Usage: fulldomain txtvalue
+#Remove the txt record after validation.
+dns_mydevil_rm() {
+  fulldomain=$1
+  txtvalue=$2
+  domain=""
+
+  if ! _exists "devil"; then
+    _err "Could not find 'devil' command."
+    return 1
+  fi
+
+  _info "Using mydevil"
+
+  domain=$(mydevil_get_domain "$fulldomain")
+  if [ -z "$domain" ]; then
+    _err "Invalid domain name: could not find root domain of $fulldomain."
+    return 1
+  fi
+
+  # catch one or more numbers
+  num='[0-9][0-9]*'
+  # catch one or more whitespace
+  w=$(printf '[\t ][\t ]*')
+  # catch anything, except newline
+  any='.*'
+  # filter to make sure we do not delete other records
+  validRecords="^${num}${w}${fulldomain}${w}TXT${w}${any}${txtvalue}$"
+  for id in $(devil dns list "$domain" | tail -n+2 | grep "${validRecords}" | cut -w -s -f 1); do
+    _info "Removing record $id from domain $domain"
+    devil dns del "$domain" "$id" || _err "Could not remove DNS record."
+  done
+}
+
+####################  Private functions below ##################################
+
+# Usage: domain=$(mydevil_get_domain "_acme-challenge.www.domain.com" || _err "Invalid domain name")
+#        echo $domain
+mydevil_get_domain() {
+  fulldomain=$1
+  domain=""
+
+  for domain in $(devil dns list | cut -w -s -f 1 | tail -n+2); do
+    if _endswith "$fulldomain" "$domain"; then
+      printf -- "%s" "$domain"
+      return 0
+    fi
+  done
+
+  return 1
+}