diff --git a/README.md b/README.md index 90a648d5..aeeca5f4 100644 --- a/README.md +++ b/README.md @@ -351,6 +351,7 @@ You don't have to do anything manually! 1. PointDNS API (https://pointhq.com/) 1. Active24.cz API (https://www.active24.cz/) 1. do.de API (https://www.do.de/) +1. MyDevil.net (https://www.mydevil.net/) And: diff --git a/deploy/README.md b/deploy/README.md index 091e9feb..939865b3 100644 --- a/deploy/README.md +++ b/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 certificate on MyDevil.net + +Once you have acme.sh installed and certificate issued (see info in [DNS API](../dnsapi/README.md)), 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. diff --git a/deploy/mydevil.sh b/deploy/mydevil.sh new file mode 100755 index 00000000..0a061aec --- /dev/null +++ b/deploy/mydevil.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +# MyDevil.net API (2019-02-03) +# +# MyDevil.net already supports automatic Let's Encrypt certificates, +# except for wildcard domains. +# +# This script depends on `devil dns` that MyDevil.net provides, +# which means that it works only on server side. +# +# Author: Marcin Konicki +# +######## Public functions ##################### + +# Usage: mydevil_deploy domain keyfile certfile cafile fullchain +mydevil_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + local 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() { + local domain=$1 + + devil dns list "$domain" | awk '{print $3"\t"$7}' | grep "^A$(printf '\t')" | awk '{print $2}' || return 1 + return 0 +} diff --git a/dnsapi/README.md b/dnsapi/README.md index 4f9b4100..955e36c5 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1172,6 +1172,30 @@ acme.sh --issue --dns dns_doapi -d example.com -d *.example.com The API token will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 61. Use MyDevil.net + +Make sure that you can execute own binaries: + +```sh +devil binexec on +``` + +Install acme.sh somewhere on your mydevil host account, probably in your home directory. +Once it is installed, add it to your bin directory (and make sure it exists first): + +```sh +mkdir ~/bin +ln -s /path/to/installed/directory/of/.acme.sh/acme.sh ~/bin/acme.sh +``` + +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). + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_mydevil.sh b/dnsapi/dns_mydevil.sh new file mode 100755 index 00000000..6cdc42d8 --- /dev/null +++ b/dnsapi/dns_mydevil.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +# MyDevil.net API (2019-02-03) +# +# MyDevil.net already supports automatic Let's Encrypt certificates, +# except for wildcard domains. +# +# This script depends on `devil dns` that MyDevil.net provides, +# which means that it works only on server side. +# +# Author: Marcin Konicki +# +######## Public functions ##################### + +#Usage: dns_mydevil_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_mydevil_add() { + local fulldomain=$1 + local txtvalue=$2 + local domain=$(mydevil_get_domain "$fulldomain") + + _info "Using mydevil" + + if ! mydevil_check_record $fulldomain ; then + _err "Invalid record name: does not start with '_acme-challenge'." + return 1 + fi + + if [ -z "$domain" ] ; then + _err "Invalid domain name: could not find root domain of $fulldomain." + return 1 + fi + + _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() { + local fulldomain=$1 + local txtvalue=$2 + local domain=$(mydevil_get_domain "$fulldomain") + + _info "Using mydevil" + + if ! mydevil_check_record $fulldomain ; then + _err "Invalid record name: does not start with '_acme-challenge'." + return 1 + fi + + if [ -z "$domain" ] ; then + _err "Invalid domain name: could not find root domain of $fulldomain." + return 1 + fi + + for id in `devil dns list "$domain" | grep "$fulldomain" | awk '{print $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: mydevil_check_record "_acme-challenge.www.domain.com" || _err "Invalid record name" +mydevil_check_record() { + local record=$1 + + case "$record" in + "_acme-challenge."*) + return 0 + ;; + *) + return 1 + ;; + esac +} + +# Usage: domain=$(mydevil_get_domain "_acme-challenge.www.domain.com" || _err "Invalid domain name") +# echo $domain +mydevil_get_domain() { + local fulldomain=$1 + local domain="" + + for domain in `devil dns list | grep . | awk '{if(NR>1)print $1}'` ; do + if _endswith "$fulldomain" "$domain" ; then + printf -- "%s" "$domain" + return 0 + fi + done + + return 1 +}