From eb207322d3ee34ddc2098c246f76fc980129fcc9 Mon Sep 17 00:00:00 2001 From: Meowthink Date: Sun, 14 Jan 2018 14:19:33 +0800 Subject: [PATCH] Add namesilo.com dns api support --- README.md | 1 + dnsapi/README.md | 15 +++++ dnsapi/dns_namesilo.sh | 137 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100755 dnsapi/dns_namesilo.sh diff --git a/README.md b/README.md index 0d942757..bd39a202 100644 --- a/README.md +++ b/README.md @@ -342,6 +342,7 @@ You don't have to do anything manually! 1. UnoEuro API (https://www.unoeuro.com/) 1. INWX (https://www.inwx.de/) 1. Servercow (https://servercow.de) +1. Namesilo (https://www.namesilo.com) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index d357c053..ed36b97c 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -651,6 +651,21 @@ acme.sh --issue --dns dns_servercow -d example.com -d www.example.com ``` Both, `SERVERCOW_API_Username` and `SERVERCOW_API_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 35. Use Namesilo.com API + +You'll need to generate an API key at https://www.namesilo.com/account_api.php +Optionally you may restrict the access to an IP range there. + +``` +export Namesilo_Key="xxxxxxxxxxxxxxxxxxxxxxxx" +``` + +And now you can issue certs with: + +``` +acme.sh --issue --dns dns_namesilo --dnssleep 900 -d example.com -d www.example.com +``` + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_namesilo.sh b/dnsapi/dns_namesilo.sh new file mode 100755 index 00000000..dc1a4fda --- /dev/null +++ b/dnsapi/dns_namesilo.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env sh + +#Author: meowthink +#Created 01/14/2017 +#Utilize namesilo.com API to finish dns-01 verifications. + +Namesilo_API="https://www.namesilo.com/api" + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_namesilo_add() { + fulldomain=$1 + txtvalue=$2 + + if [ -z "$Namesilo_Key" ]; then + Namesilo_Key="" + _err "API token for namesilo.com is missing." + _err "Please specify that in your environment variable." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf Namesilo_Key "$Namesilo_Key" + + if ! _get_root "$fulldomain"; then + _err "Unable to find domain specified." + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug txtvalue "$txtvalue" + if _namesilo_rest GET "dnsAddRecord?version=1&type=xml&key=$Namesilo_Key&domain=$_domain&rrtype=TXT&rrhost=$_sub_domain&rrvalue=$txtvalue"; then + retcode=$(printf "%s\n" "$response" | _egrep_o "300") + if [ "$retcode" ]; then + _info "Successfully added TXT record, ready for validation." + return 0 + else + _err "Unable to add the DNS record." + return 1 + fi + fi +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_namesilo_rm() { + fulldomain=$1 + txtvalue=$2 + + if ! _get_root "$fulldomain"; then + _err "Unable to find domain specified." + return 1 + fi + + # Get the record id. + if _namesilo_rest GET "dnsListRecords?version=1&type=xml&key=$Namesilo_Key&domain=$_domain"; then + retcode=$(printf "%s\n" "$response" | _egrep_o "300") + if [ "$retcode" ]; then + _record_id=$(printf "%s\n" "$response" | _egrep_o "([^<]*)TXT$fulldomain" | _egrep_o "([^<]*)" | sed -r "s/([^<]*)<\/record_id>/\1/" | tail -n 1) + _debug record_id "$_record_id" + _info "Successfully retrieved the record id for ACME challenge." + else + _err "Unable to retrieve the record id." + return 1 + fi + fi + + # Remove the DNS record using record id. + if _namesilo_rest GET "dnsDeleteRecord?version=1&type=xml&key=$Namesilo_Key&domain=$_domain&rrid=$_record_id"; then + retcode=$(printf "%s\n" "$response" | _egrep_o "300") + if [ "$retcode" ]; then + _info "Successfully removed the TXT record." + return 0 + else + _err "Unable to remove the DNS record." + return 1 + fi + fi +} + +#################### Private functions below ################################## + +# _acme-challenge.www.domain.com +# returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + i=2 + p=1 + + if ! _namesilo_rest GET "listDomains?version=1&type=xml&key=$Namesilo_Key"; then + return 1 + fi + + # Need to exclude the last field (tld) + numfields=$(echo "$domain" | _egrep_o "\." | wc -l) + while [ $i -le "$numfields" ]; do + host=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug host "$host" + 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 + return 1 +} + +_namesilo_rest() { + method=$1 + param=$2 + data=$3 + + if [ "$method" != "GET" ]; then + response="$(_post "$data" "$Namesilo_API/$param" "" "$method")" + else + response="$(_get "$Namesilo_API/$param")" + fi + + if [ "$?" != "0" ]; then + _err "error $param" + return 1 + fi + + _debug2 response "$response" + return 0 +}