From e9782c3219722e590f84f2aa3d6cc056564a141e Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 15 May 2018 13:18:50 +0200 Subject: [PATCH 01/59] Create dns_netcup.sh --- dnsapi/dns_netcup.sh | 146 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 dnsapi/dns_netcup.sh diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh new file mode 100644 index 0000000..7a8002a --- /dev/null +++ b/dnsapi/dns_netcup.sh @@ -0,0 +1,146 @@ +#!/usr/bin/env sh + +#Requirments: jq +#developed by linux-insideDE + +NC_Apikey="${NC_Apikey:-$(_readaccountconf_mutable NC_Apikey)}" +NC_Apipw="${NC_Apipw:-$(_readaccountconf_mutable NC_Apipw)}" +NC_CID="${NC_CID:-$(_readaccountconf_mutable NC_CID)}" +end="https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON" +client="" + +dns_netcup_add() { + login + if [ "$NC_Apikey" = "" ] || [ "$NC_Apipw" = "" ] || [ "$NC_CID" = "" ]; then + _err "No Credentials given" + return 1 + fi + _saveaccountconf_mutable NC_Apikey "$NC_Apikey" + _saveaccountconf_mutable NC_Apipw "$NC_Apipw" + _saveaccountconf_mutable NC_CID "$NC_CID" + fulldomain=$1 + txtvalue=$2 + tld="" + domain="" + exit=0 + i=20 + while [ "$i" -gt 0 ]; + do + tmp=$(echo "$fulldomain" | cut -d'.' -f$i) + if [ "$tmp" != "" ]; then + if [ "$tld" = "" ]; then + tld=$tmp + else + domain=$tmp + exit=$i + break; + fi + fi + i=$((i - 1)) + done + inc="" + i=1 + while [ "$i" -lt "$exit" ]; + do + if [ "$((exit-1))" = "$i" ]; then + inc="$inc$i" + break; + else + if [ "$inc" = "" ]; then + inc="$i," + else + inc="$inc$i," + fi + fi + i=$((i + 1)) + done + + tmp=$(echo "$fulldomain" | cut -d'.' -f$inc) + msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain.$tld\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"\", \"hostname\": \"$tmp\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"false\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") + _debug "$msg" + if [ "$(echo "$msg" | jq -r .status)" != "success" ]; then + _err "$msg" + return 1 + fi + logout +} + +dns_netcup_rm() { + login + fulldomain=$1 + txtvalue=$2 + tld="" + domain="" + exit=0 + i=20 + while [ "$i" -gt 0 ]; + do + tmp=$(echo "$fulldomain" | cut -d'.' -f$i) + if [ "$tmp" != "" ]; then + if [ "$tld" = "" ]; then + tld=$tmp + else + domain=$tmp + exit=$i + break; + fi + fi + i=$((i - 1)) + done + inc="" + i=1 + while [ "$i" -lt "$exit" ]; + do + if [ "$((exit-1))" = "$i" ]; then + inc="$inc$i" + break; + else + if [ "$inc" = "" ]; then + inc="$i," + else + inc="$inc$i," + fi + fi + i=$((i + 1)) + done + tmp=$(echo "$fulldomain" | cut -d'.' -f$inc) + doma="$domain.$tld" + rec=$(getRecords "$doma") + ids=$(echo "$rec" | jq -r ".[]|select(.destination==\"$txtvalue\")|.id") + msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$doma\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"$ids\", \"hostname\": \"$tmp\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"TRUE\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") + _debug "$msg" + if [ "$(echo "$msg" | jq -r .status)" != "success" ]; then + _err "$msg" + return 1 + fi + logout +} + +login() { + tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") + sid=$(echo "$tmp" | jq -r .responsedata.apisessionid) + _debug "$tmp" + if [ "$(echo "$tmp" | jq -r .status)" != "success" ]; then + _err "$tmp" + return 1 + fi +} +logout() { + tmp=$(_post "{\"action\": \"logout\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") + _debug "$tmp" + if [ "$(echo "$tmp" | jq -r .status)" != "success" ]; then + _err "$tmp" + return 1 + fi +} +getRecords() { + tmp2=$(_post "{\"action\": \"infoDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\", \"domainname\": \"$1\"}}" "$end" "" "POST") + xxd=$(echo "$tmp2" | jq -r ".responsedata.dnsrecords" | tr '[' ' ' | tr ']' ' ') + xcd=$(echo "$xxd" | sed 's/}\s{/},{/g') + echo "[ $xcd ]" + _debug "$tmp2" + if [ "$(echo "$tmp2" | jq -r .status)" != "success" ]; then + _err "$tmp2" + return 1 + fi +} From 3cd5b9ca2ed24ce74d5f81ef300879e7c24a0bff Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 15 May 2018 13:21:25 +0200 Subject: [PATCH 02/59] added netcup dns api --- dnsapi/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dnsapi/README.md b/dnsapi/README.md index ef6c9d0..ed16536 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -876,6 +876,22 @@ acme.sh --issue --dns dns_tele3 -d example.com -d *.example.com ``` The TELE3_Key and TELE3_Secret will be saved in ~/.acme.sh/account.conf and will be reused when needed. +## 47. Use netcup DNS API to automatically issue cert + +First you need to login to your CCP account to get your API Key and API Password. +This script requires ``jq`` +``` +export NC_Apikey="" +export NC_Apipw="" +export NC_CID="" +``` + +Now, let's issue a cert: +``` +acme.sh --issue --dns dns_netcup -d example.com -d www.example.com +``` + +The `NC_Apikey`,`NC_Apipw` and `NC_CID` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. # Use custom API If your API is not supported yet, you can write your own DNS API. From f3a622d1a747f2460ea3ec231e14461e8a15049c Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 15 May 2018 13:22:55 +0200 Subject: [PATCH 03/59] added netcup dns api --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f395e49..18b878d 100644 --- a/README.md +++ b/README.md @@ -320,6 +320,7 @@ You don't have to do anything manually! 1. Loopia.se API 1. acme-dns (https://github.com/joohoi/acme-dns) 1. TELE3 (https://www.tele3.cz) +1. netcup DNS API (https://www.netcup.de) And: From 6a4aad1aa8287c3362b566d7216ea92416f2e7d9 Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 15 May 2018 14:38:29 +0200 Subject: [PATCH 04/59] replaced increment/decrement with _math function --- dnsapi/dns_netcup.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 7a8002a..2e31e13 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -36,7 +36,7 @@ dns_netcup_add() { break; fi fi - i=$((i - 1)) + i=$(_math "$i" - 1) done inc="" i=1 @@ -52,7 +52,7 @@ dns_netcup_add() { inc="$inc$i," fi fi - i=$((i + 1)) + i=$(_math "$i" + 1) done tmp=$(echo "$fulldomain" | cut -d'.' -f$inc) @@ -85,7 +85,7 @@ dns_netcup_rm() { break; fi fi - i=$((i - 1)) + i=$(_math "$i" - 1) done inc="" i=1 @@ -101,7 +101,7 @@ dns_netcup_rm() { inc="$inc$i," fi fi - i=$((i + 1)) + i=$(_math "$i" + 1) done tmp=$(echo "$fulldomain" | cut -d'.' -f$inc) doma="$domain.$tld" From ca1d62bec07ef4233383d9652a6a8ce6f2e509b5 Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 15 May 2018 16:21:57 +0200 Subject: [PATCH 05/59] removed jq dependencies --- dnsapi/dns_netcup.sh | 47 ++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 2e31e13..7e52dd9 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -#Requirments: jq + #developed by linux-insideDE NC_Apikey="${NC_Apikey:-$(_readaccountconf_mutable NC_Apikey)}" @@ -58,7 +58,7 @@ dns_netcup_add() { tmp=$(echo "$fulldomain" | cut -d'.' -f$inc) msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain.$tld\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"\", \"hostname\": \"$tmp\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"false\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") _debug "$msg" - if [ "$(echo "$msg" | jq -r .status)" != "success" ]; then + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then _err "$msg" return 1 fi @@ -106,10 +106,29 @@ dns_netcup_rm() { tmp=$(echo "$fulldomain" | cut -d'.' -f$inc) doma="$domain.$tld" rec=$(getRecords "$doma") - ids=$(echo "$rec" | jq -r ".[]|select(.destination==\"$txtvalue\")|.id") + + ida=0000 + idv=0001 + ids=0000000000 + i=1 + while [ "$i" -ne 0 ]; + do + specrec=$(_getfield "$rec" "$i" ";") + idv="$ida" + ida=$(_getfield "$specrec" "1" "," | sed 's/\"id\":\"//g' | sed 's/\"//g') + txtv=$(_getfield "$specrec" "5" "," | sed 's/\"destination\":\"//g' | sed 's/\"//g') + i=$(_math "$i" + 1) + if [ "$txtvalue" = "$txtv" ]; then + i=0 + ids="$ida" + fi + if [ "$ida" = "$idv" ]; then + i=0 + fi + done msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$doma\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"$ids\", \"hostname\": \"$tmp\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"TRUE\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") _debug "$msg" - if [ "$(echo "$msg" | jq -r .status)" != "success" ]; then + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then _err "$msg" return 1 fi @@ -117,30 +136,28 @@ dns_netcup_rm() { } login() { - tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") - sid=$(echo "$tmp" | jq -r .responsedata.apisessionid) + tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") + sid=$(_getfield "$tmp" "8" | sed s/\"responsedata\":\{\"apisessionid\":\"//g | sed 's/\"\}\}//g') _debug "$tmp" - if [ "$(echo "$tmp" | jq -r .status)" != "success" ]; then - _err "$tmp" + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" return 1 fi } logout() { tmp=$(_post "{\"action\": \"logout\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") _debug "$tmp" - if [ "$(echo "$tmp" | jq -r .status)" != "success" ]; then - _err "$tmp" + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" return 1 fi } getRecords() { tmp2=$(_post "{\"action\": \"infoDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\", \"domainname\": \"$1\"}}" "$end" "" "POST") - xxd=$(echo "$tmp2" | jq -r ".responsedata.dnsrecords" | tr '[' ' ' | tr ']' ' ') - xcd=$(echo "$xxd" | sed 's/}\s{/},{/g') - echo "[ $xcd ]" + echo $(echo "$tmp2" | sed 's/\[//g' | sed 's/\]//g' | sed 's/{\"serverrequestid\".*\"dnsrecords\"://g' | sed 's/},{/};{/g' | sed 's/{//g' | sed 's/}//g') _debug "$tmp2" - if [ "$(echo "$tmp2" | jq -r .status)" != "success" ]; then - _err "$tmp2" + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" return 1 fi } From ed2ba6bc3aa88fa1d9ba8761ea4b92c3939441c4 Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 15 May 2018 16:22:40 +0200 Subject: [PATCH 06/59] removed jq dependencies --- dnsapi/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index ed16536..cc2f476 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -879,7 +879,6 @@ The TELE3_Key and TELE3_Secret will be saved in ~/.acme.sh/account.conf and will ## 47. Use netcup DNS API to automatically issue cert First you need to login to your CCP account to get your API Key and API Password. -This script requires ``jq`` ``` export NC_Apikey="" export NC_Apipw="" From 4715a1a5e0d6a1a6c0c2d462cba0f01a37389d88 Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Wed, 16 May 2018 22:07:44 +0200 Subject: [PATCH 07/59] satisfy shellcheck --- dnsapi/dns_netcup.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 7e52dd9..755d22b 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -1,6 +1,4 @@ #!/usr/bin/env sh - - #developed by linux-insideDE NC_Apikey="${NC_Apikey:-$(_readaccountconf_mutable NC_Apikey)}" @@ -154,7 +152,8 @@ logout() { } getRecords() { tmp2=$(_post "{\"action\": \"infoDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\", \"domainname\": \"$1\"}}" "$end" "" "POST") - echo $(echo "$tmp2" | sed 's/\[//g' | sed 's/\]//g' | sed 's/{\"serverrequestid\".*\"dnsrecords\"://g' | sed 's/},{/};{/g' | sed 's/{//g' | sed 's/}//g') + out=$(echo "$tmp2" | sed 's/\[//g' | sed 's/\]//g' | sed 's/{\"serverrequestid\".*\"dnsrecords\"://g' | sed 's/},{/};{/g' | sed 's/{//g' | sed 's/}//g') + echo "$out" _debug "$tmp2" if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then _err "$msg" From 48e8022095a9bd993ed0633066fd7a65d51a0bd8 Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 29 May 2018 16:23:28 +0200 Subject: [PATCH 08/59] improved handling for third level domains --- dnsapi/dns_netcup.sh | 131 +++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 81 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 755d22b..00edb5b 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -18,48 +18,33 @@ dns_netcup_add() { _saveaccountconf_mutable NC_CID "$NC_CID" fulldomain=$1 txtvalue=$2 - tld="" domain="" - exit=0 - i=20 - while [ "$i" -gt 0 ]; - do - tmp=$(echo "$fulldomain" | cut -d'.' -f$i) - if [ "$tmp" != "" ]; then - if [ "$tld" = "" ]; then - tld=$tmp - else - domain=$tmp - exit=$i - break; - fi - fi - i=$(_math "$i" - 1) - done - inc="" - i=1 - while [ "$i" -lt "$exit" ]; + exit=$(echo "$fulldomain" | tr -dc '.' | wc -c) + exit=$(_math "$exit" + 1) + i=$exit + + while [ "$exit" -gt 0 ] do - if [ "$((exit-1))" = "$i" ]; then - inc="$inc$i" - break; + tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") + if [ "$(_math "$i" - "$exit")" -eq 0 ]; then + domain="$tmp" else - if [ "$inc" = "" ]; then - inc="$i," - else - inc="$inc$i," - fi - fi - i=$(_math "$i" + 1) + domain="$tmp.$domain" + fi + if [ "$(_math "$i" - "$exit")" -ge 1 ]; then + msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"false\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") + _debug "$msg" + if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" + return 1 + else + break; + fi + fi + fi + exit=$(_math "$exit" - 1) done - - tmp=$(echo "$fulldomain" | cut -d'.' -f$inc) - msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain.$tld\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"\", \"hostname\": \"$tmp\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"false\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") - _debug "$msg" - if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then - _err "$msg" - return 1 - fi logout } @@ -67,43 +52,36 @@ dns_netcup_rm() { login fulldomain=$1 txtvalue=$2 - tld="" + domain="" - exit=0 - i=20 - while [ "$i" -gt 0 ]; - do - tmp=$(echo "$fulldomain" | cut -d'.' -f$i) - if [ "$tmp" != "" ]; then - if [ "$tld" = "" ]; then - tld=$tmp - else - domain=$tmp - exit=$i - break; - fi - fi - i=$(_math "$i" - 1) - done - inc="" - i=1 - while [ "$i" -lt "$exit" ]; + exit=$(echo "$fulldomain" | tr -dc '.' | wc -c) + exit=$(_math "$exit" + 1) + i=$exit + rec="" + + while [ "$exit" -gt 0 ] do - if [ "$((exit-1))" = "$i" ]; then - inc="$inc$i" - break; + tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") + if [ "$(_math "$i" - "$exit")" -eq 0 ]; then + domain="$tmp" else - if [ "$inc" = "" ]; then - inc="$i," - else - inc="$inc$i," + domain="$tmp.$domain" + fi + if [ "$(_math "$i" - "$exit")" -ge 1 ]; then + msg=$(_post "{\"action\": \"infoDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\", \"domainname\": \"$domain\"}}" "$end" "" "POST") + rec=$(echo "$msg" | sed 's/\[//g' | sed 's/\]//g' | sed 's/{\"serverrequestid\".*\"dnsrecords\"://g' | sed 's/},{/};{/g' | sed 's/{//g' | sed 's/}//g') + _debug "$msg" + if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" + return 1 + else + break; + fi fi fi - i=$(_math "$i" + 1) + exit=$(_math "$exit" - 1) done - tmp=$(echo "$fulldomain" | cut -d'.' -f$inc) - doma="$domain.$tld" - rec=$(getRecords "$doma") ida=0000 idv=0001 @@ -123,8 +101,9 @@ dns_netcup_rm() { if [ "$ida" = "$idv" ]; then i=0 fi - done - msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$doma\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"$ids\", \"hostname\": \"$tmp\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"TRUE\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") + done + + msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"$ids\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"TRUE\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") _debug "$msg" if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then _err "$msg" @@ -150,13 +129,3 @@ logout() { return 1 fi } -getRecords() { - tmp2=$(_post "{\"action\": \"infoDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\", \"domainname\": \"$1\"}}" "$end" "" "POST") - out=$(echo "$tmp2" | sed 's/\[//g' | sed 's/\]//g' | sed 's/{\"serverrequestid\".*\"dnsrecords\"://g' | sed 's/},{/};{/g' | sed 's/{//g' | sed 's/}//g') - echo "$out" - _debug "$tmp2" - if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then - _err "$msg" - return 1 - fi -} From c7b904501c7ecc3054cee92937733d45647e3690 Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 29 May 2018 16:56:07 +0200 Subject: [PATCH 09/59] make shfmt happy --- dnsapi/dns_netcup.sh | 52 ++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 00edb5b..59e9270 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -13,18 +13,18 @@ dns_netcup_add() { _err "No Credentials given" return 1 fi - _saveaccountconf_mutable NC_Apikey "$NC_Apikey" - _saveaccountconf_mutable NC_Apipw "$NC_Apipw" - _saveaccountconf_mutable NC_CID "$NC_CID" + _saveaccountconf_mutable NC_Apikey "$NC_Apikey" + _saveaccountconf_mutable NC_Apipw "$NC_Apipw" + _saveaccountconf_mutable NC_CID "$NC_CID" fulldomain=$1 txtvalue=$2 domain="" exit=$(echo "$fulldomain" | tr -dc '.' | wc -c) exit=$(_math "$exit" + 1) i=$exit - - while [ "$exit" -gt 0 ] - do + + while + [ "$exit" -gt 0 ]; do tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") if [ "$(_math "$i" - "$exit")" -eq 0 ]; then domain="$tmp" @@ -34,13 +34,13 @@ dns_netcup_add() { if [ "$(_math "$i" - "$exit")" -ge 1 ]; then msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"false\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") _debug "$msg" - if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then + if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then _err "$msg" return 1 else - break; - fi + break + fi fi fi exit=$(_math "$exit" - 1) @@ -52,57 +52,57 @@ dns_netcup_rm() { login fulldomain=$1 txtvalue=$2 - + domain="" exit=$(echo "$fulldomain" | tr -dc '.' | wc -c) exit=$(_math "$exit" + 1) i=$exit rec="" - - while [ "$exit" -gt 0 ] - do + + while + [ "$exit" -gt 0 ]; do tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") if [ "$(_math "$i" - "$exit")" -eq 0 ]; then domain="$tmp" else domain="$tmp.$domain" fi - if [ "$(_math "$i" - "$exit")" -ge 1 ]; then + if [ "$(_math "$i" - "$exit")" -ge 1 ]; then msg=$(_post "{\"action\": \"infoDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\", \"domainname\": \"$domain\"}}" "$end" "" "POST") rec=$(echo "$msg" | sed 's/\[//g' | sed 's/\]//g' | sed 's/{\"serverrequestid\".*\"dnsrecords\"://g' | sed 's/},{/};{/g' | sed 's/{//g' | sed 's/}//g') - _debug "$msg" - if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then + _debug "$msg" + if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then _err "$msg" return 1 else - break; - fi + break + fi fi fi exit=$(_math "$exit" - 1) done - + ida=0000 idv=0001 - ids=0000000000 + ids=0000000000 i=1 - while [ "$i" -ne 0 ]; - do + while + [ "$i" -ne 0 ]; do specrec=$(_getfield "$rec" "$i" ";") idv="$ida" ida=$(_getfield "$specrec" "1" "," | sed 's/\"id\":\"//g' | sed 's/\"//g') - txtv=$(_getfield "$specrec" "5" "," | sed 's/\"destination\":\"//g' | sed 's/\"//g') + txtv=$(_getfield "$specrec" "5" "," | sed 's/\"destination\":\"//g' | sed 's/\"//g') i=$(_math "$i" + 1) if [ "$txtvalue" = "$txtv" ]; then i=0 ids="$ida" - fi + fi if [ "$ida" = "$idv" ]; then i=0 fi done - + msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"$ids\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"TRUE\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") _debug "$msg" if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then @@ -113,7 +113,7 @@ dns_netcup_rm() { } login() { - tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") + tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") sid=$(_getfield "$tmp" "8" | sed s/\"responsedata\":\{\"apisessionid\":\"//g | sed 's/\"\}\}//g') _debug "$tmp" if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then From 69b780ee321c15dd5e8348766389a140277d9871 Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 29 May 2018 17:24:53 +0200 Subject: [PATCH 10/59] Update dns_netcup.sh --- dnsapi/dns_netcup.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 59e9270..573550e 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -102,7 +102,6 @@ dns_netcup_rm() { i=0 fi done - msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"$ids\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"TRUE\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") _debug "$msg" if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then From 8d230dd798f2b25cfa37761ebc20591f57ebad1c Mon Sep 17 00:00:00 2001 From: Old?ich Jedli?ka Date: Tue, 24 Jul 2018 15:39:48 +0200 Subject: [PATCH 11/59] Added dns_lexicon_rm command. Remove created TXT record when finished. Works with lexicon version 2.3.0 and later. --- dnsapi/dns_lexicon.sh | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index c09f16f..9c0f986 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -7,15 +7,7 @@ lexicon_cmd="lexicon" wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api" -######## Public functions ##################### - -#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_lexicon_add() { - fulldomain=$1 - txtvalue=$2 - - domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999) - +_initLexicon() { if ! _exists "$lexicon_cmd"; then _err "Please install $lexicon_cmd first: $wiki" return 1 @@ -66,13 +58,36 @@ dns_lexicon_add() { eval export "$Lx_domaintoken" _saveaccountconf "$Lx_domaintoken" "$Lx_domaintoken_v" fi +} + +######## Public functions ##################### + +#Usage: dns_lexicon_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_lexicon_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _initLexicon; then + return 1 + fi + + domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999) $lexicon_cmd "$PROVIDER" create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" } -#fulldomain +#Usage: dns_lexicon_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_lexicon_rm() { fulldomain=$1 + txtvalue=$2 + + if ! _initLexicon; then + return 1 + fi + + domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999) + + $lexicon_cmd "$PROVIDER" delete "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" } From 0366e8758cb908eb1224fd346b06d3973611799b Mon Sep 17 00:00:00 2001 From: Old?ich Jedli?ka Date: Tue, 24 Jul 2018 22:14:39 +0200 Subject: [PATCH 12/59] Added reading of stored config. --- dnsapi/dns_lexicon.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index 9c0f986..4ec1631 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -7,12 +7,13 @@ lexicon_cmd="lexicon" wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api" -_initLexicon() { +_lexicon_init() { if ! _exists "$lexicon_cmd"; then _err "Please install $lexicon_cmd first: $wiki" return 1 fi + PROVIDER="${PROVIDER:-$(_readdomainconf PROVIDER)}" if [ -z "$PROVIDER" ]; then PROVIDER="" _err "Please define env PROVIDER first: $wiki" @@ -25,38 +26,42 @@ _initLexicon() { # e.g. busybox-ash does not know [:upper:] # shellcheck disable=SC2018,SC2019 Lx_name=$(echo LEXICON_"${PROVIDER}"_USERNAME | tr 'a-z' 'A-Z') + eval $Lx_name="\${$Lx_name:-$(_readaccountconf_mutable $Lx_name)}" Lx_name_v=$(eval echo \$"$Lx_name") _secure_debug "$Lx_name" "$Lx_name_v" if [ "$Lx_name_v" ]; then - _saveaccountconf "$Lx_name" "$Lx_name_v" + _saveaccountconf_mutable "$Lx_name" "$Lx_name_v" eval export "$Lx_name" fi # shellcheck disable=SC2018,SC2019 Lx_token=$(echo LEXICON_"${PROVIDER}"_TOKEN | tr 'a-z' 'A-Z') + eval $Lx_token="\${$Lx_token:-$(_readaccountconf_mutable $Lx_token)}" Lx_token_v=$(eval echo \$"$Lx_token") _secure_debug "$Lx_token" "$Lx_token_v" if [ "$Lx_token_v" ]; then - _saveaccountconf "$Lx_token" "$Lx_token_v" + _saveaccountconf_mutable "$Lx_token" "$Lx_token_v" eval export "$Lx_token" fi # shellcheck disable=SC2018,SC2019 Lx_password=$(echo LEXICON_"${PROVIDER}"_PASSWORD | tr 'a-z' 'A-Z') + eval $Lx_password="\${$Lx_password:-$(_readaccountconf_mutable $Lx_password)}" Lx_password_v=$(eval echo \$"$Lx_password") _secure_debug "$Lx_password" "$Lx_password_v" if [ "$Lx_password_v" ]; then - _saveaccountconf "$Lx_password" "$Lx_password_v" + _saveaccountconf_mutable "$Lx_password" "$Lx_password_v" eval export "$Lx_password" fi # shellcheck disable=SC2018,SC2019 Lx_domaintoken=$(echo LEXICON_"${PROVIDER}"_DOMAINTOKEN | tr 'a-z' 'A-Z') + eval $Lx_domaintoken="\${$Lx_domaintoken:-$(_readaccountconf_mutable $Lx_domaintoken)}" Lx_domaintoken_v=$(eval echo \$"$Lx_domaintoken") _secure_debug "$Lx_domaintoken" "$Lx_domaintoken_v" if [ "$Lx_domaintoken_v" ]; then + _saveaccountconf_mutable "$Lx_domaintoken" "$Lx_domaintoken_v" eval export "$Lx_domaintoken" - _saveaccountconf "$Lx_domaintoken" "$Lx_domaintoken_v" fi } @@ -67,7 +72,7 @@ dns_lexicon_add() { fulldomain=$1 txtvalue=$2 - if ! _initLexicon; then + if ! _lexicon_init; then return 1 fi @@ -82,7 +87,7 @@ dns_lexicon_rm() { fulldomain=$1 txtvalue=$2 - if ! _initLexicon; then + if ! _lexicon_init; then return 1 fi From 436940285594dd9397161d5ca16f6e3973b4312c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Old=C5=99ich=20Jedli=C4=8Dka?= Date: Wed, 25 Jul 2018 10:40:57 +0200 Subject: [PATCH 13/59] Cleaned-up shellcheck warnings. --- dnsapi/dns_lexicon.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index 4ec1631..ab180fb 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -26,7 +26,7 @@ _lexicon_init() { # e.g. busybox-ash does not know [:upper:] # shellcheck disable=SC2018,SC2019 Lx_name=$(echo LEXICON_"${PROVIDER}"_USERNAME | tr 'a-z' 'A-Z') - eval $Lx_name="\${$Lx_name:-$(_readaccountconf_mutable $Lx_name)}" + eval "$Lx_name=\${$Lx_name:-$(_readaccountconf_mutable "$Lx_name")}" Lx_name_v=$(eval echo \$"$Lx_name") _secure_debug "$Lx_name" "$Lx_name_v" if [ "$Lx_name_v" ]; then @@ -36,7 +36,7 @@ _lexicon_init() { # shellcheck disable=SC2018,SC2019 Lx_token=$(echo LEXICON_"${PROVIDER}"_TOKEN | tr 'a-z' 'A-Z') - eval $Lx_token="\${$Lx_token:-$(_readaccountconf_mutable $Lx_token)}" + eval "$Lx_token=\${$Lx_token:-$(_readaccountconf_mutable "$Lx_token")}" Lx_token_v=$(eval echo \$"$Lx_token") _secure_debug "$Lx_token" "$Lx_token_v" if [ "$Lx_token_v" ]; then @@ -46,7 +46,7 @@ _lexicon_init() { # shellcheck disable=SC2018,SC2019 Lx_password=$(echo LEXICON_"${PROVIDER}"_PASSWORD | tr 'a-z' 'A-Z') - eval $Lx_password="\${$Lx_password:-$(_readaccountconf_mutable $Lx_password)}" + eval "$Lx_password=\${$Lx_password:-$(_readaccountconf_mutable "$Lx_password")}" Lx_password_v=$(eval echo \$"$Lx_password") _secure_debug "$Lx_password" "$Lx_password_v" if [ "$Lx_password_v" ]; then @@ -56,7 +56,7 @@ _lexicon_init() { # shellcheck disable=SC2018,SC2019 Lx_domaintoken=$(echo LEXICON_"${PROVIDER}"_DOMAINTOKEN | tr 'a-z' 'A-Z') - eval $Lx_domaintoken="\${$Lx_domaintoken:-$(_readaccountconf_mutable $Lx_domaintoken)}" + eval "$Lx_domaintoken=\${$Lx_domaintoken:-$(_readaccountconf_mutable "$Lx_domaintoken")}" Lx_domaintoken_v=$(eval echo \$"$Lx_domaintoken") _secure_debug "$Lx_domaintoken" "$Lx_domaintoken_v" if [ "$Lx_domaintoken_v" ]; then From d3c9d0b331b2c49327e5a4c6d3d54839e69aecd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Thu, 26 Jul 2018 19:59:15 +0200 Subject: [PATCH 14/59] Fix inwx account without Mobile TAN --- dnsapi/dns_inwx.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index cd5af91..f4590cf 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -158,7 +158,8 @@ _inwx_login() { export _H1 #https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71 - if _contains "$response" "tfa"; then + if _contains "$response" "code1000" \ + && _contains "$response" "tfaGOOGLE-AUTH"; then if [ -z "$INWX_Shared_Secret" ]; then _err "Mobile TAN detected." _err "Please define a shared secret." From 63134fafece3f9ffb5092b2d897e38366072d64d Mon Sep 17 00:00:00 2001 From: little-fat Date: Thu, 2 Aug 2018 20:57:27 +0800 Subject: [PATCH 15/59] Fix key leakage in SSH deploy log --- deploy/ssh.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index a68da35..9cb0af9 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -11,7 +11,7 @@ # # Only a username is required. All others are optional. # -# The following examples are for QNAP NAS running QTS 4.2 +# The following examples are for QNAP NAS running QTS 4.2 # export DEPLOY_SSH_CMD="" # defaults to ssh # export DEPLOY_SSH_USER="admin" # required # export DEPLOY_SSH_SERVER="qnap" # defaults to domain name @@ -101,7 +101,7 @@ ssh_deploy() { fi # CERTFILE is optional. - # If provided then private key will be copied or appended to provided filename. + # If provided then certificate will be copied or appended to provided filename. if [ -n "$DEPLOY_SSH_CERTFILE" ]; then Le_Deploy_ssh_certfile="$DEPLOY_SSH_CERTFILE" _savedomainconf Le_Deploy_ssh_certfile "$Le_Deploy_ssh_certfile" @@ -190,7 +190,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _info "Backup directories erased after 180 days." fi - _debug "Remote commands to execute: $_cmdstr" + _secure_debug "Remote commands to execute: " "$_cmdstr" _info "Submitting sequence of commands to remote server by ssh" # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 From 4fbd21da5788ce48874b483aaa57700a4520ea7f Mon Sep 17 00:00:00 2001 From: Gunnar Liljas Date: Tue, 7 Aug 2018 13:35:08 +0200 Subject: [PATCH 16/59] Spelling --- dnsapi/dns_aws.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 8ce7c34..2ad3c81 100755 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -29,7 +29,7 @@ dns_aws_add() { if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then AWS_ACCESS_KEY_ID="" AWS_SECRET_ACCESS_KEY="" - _err "You don't specify aws route53 api key id and and api key secret yet." + _err "You haven't specifed the aws route53 api key id and and api key secret yet." _err "Please create your key and try again. see $(__green $AWS_WIKI)" return 1 fi @@ -62,7 +62,7 @@ dns_aws_add() { fi if [ "$_resource_record" ] && _contains "$response" "$txtvalue"; then - _info "The txt record already exists, skip" + _info "The TXT record already exists. Skipping." return 0 fi @@ -71,7 +71,7 @@ dns_aws_add() { _aws_tmpl_xml="UPSERT$fulldomainTXT300$_resource_record\"$txtvalue\"" if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then - _info "txt record updated success." + _info "TXT record updated successfully." return 0 fi @@ -99,7 +99,7 @@ dns_aws_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - _info "Geting existing records for $fulldomain" + _info "Getting existing records for $fulldomain" if ! aws_rest GET "2013-04-01$_domain_id/rrset" "name=$fulldomain&type=TXT"; then return 1 fi @@ -108,14 +108,14 @@ dns_aws_rm() { _resource_record="$(echo "$response" | sed 's//"/g' | tr '"' "\n" | grep "$fulldomain." | _egrep_o "" | sed "s///" | sed "s###")" _debug "_resource_record" "$_resource_record" else - _debug "no records exists, skip" + _debug "no records exist, skip" return 0 fi _aws_tmpl_xml="DELETE$_resource_record$fulldomain.TXT300" if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then - _info "txt record deleted success." + _info "TXT record deleted successfully." return 0 fi @@ -163,7 +163,7 @@ _get_root() { _domain=$h return 0 fi - _err "Can not find domain id: $h" + _err "Can't find domain with id: $h" return 1 fi fi From 22cd408efbcbacb866987b866cdadc5c49f870e1 Mon Sep 17 00:00:00 2001 From: Hitoshi Date: Sun, 12 Aug 2018 18:15:20 +0800 Subject: [PATCH 17/59] add dns api support for dnspod.com --- README.md | 1 + dnsapi/README.md | 19 +++++- dnsapi/dns_dpi.sh | 161 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+), 1 deletion(-) create mode 100755 dnsapi/dns_dpi.sh diff --git a/README.md b/README.md index c8bebc6..e7c292c 100644 --- a/README.md +++ b/README.md @@ -321,6 +321,7 @@ You don't have to do anything manually! 1. acme-dns (https://github.com/joohoi/acme-dns) 1. TELE3 (https://www.tele3.cz) 1. EUSERV.EU (https://www.euserv.eu) +1. DNSPod.com API (https://www.dnspod.com) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index 1f394f9..3fa0ab3 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -897,6 +897,23 @@ acme.sh --issue --dns dns_euserv -d example.com -d *.example.com --insecure The `EUSERV_Username` and `EUSERV_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. Please report any issues to https://github.com/initit/acme.sh or to + +## 48. Use DNSPod.com domain API to automatically issue cert + +First you need to get your API Key and ID by this [get-the-user-token](https://www.dnspod.com/docs/info.html#get-the-user-token). + +``` +export DPI_Id="1234" +export DPI_Key="sADDsdasdgdsf" +``` + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_dpi -d example.com -d www.example.com +``` + +The `DPI_Id` and `DPI_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. @@ -917,4 +934,4 @@ See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide # Use lexicon DNS API -https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api \ No newline at end of file +https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api diff --git a/dnsapi/dns_dpi.sh b/dnsapi/dns_dpi.sh new file mode 100755 index 0000000..831150a --- /dev/null +++ b/dnsapi/dns_dpi.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env sh + +# Dnspod.com Domain api +# +#DPI_Id="1234" +# +#DPI_Key="sADDsdasdgdsf" + +REST_API="https://api.dnspod.com" + +######## Public functions ##################### + +#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_dpi_add() { + fulldomain=$1 + txtvalue=$2 + + DPI_Id="${DPI_Id:-$(_readaccountconf_mutable DPI_Id)}" + DPI_Key="${DPI_Key:-$(_readaccountconf_mutable DPI_Key)}" + if [ -z "$DPI_Id" ] || [ -z "$DPI_Key" ]; then + DPI_Id="" + DPI_Key="" + _err "You don't specify dnspod api key and key id yet." + _err "Please create you key and try again." + return 1 + fi + + #save the api key and email to the account conf file. + _saveaccountconf_mutable DPI_Id "$DPI_Id" + _saveaccountconf_mutable DPI_Key "$DPI_Key" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + add_record "$_domain" "$_sub_domain" "$txtvalue" + +} + +#fulldomain txtvalue +dns_dpi_rm() { + fulldomain=$1 + txtvalue=$2 + + DPI_Id="${DPI_Id:-$(_readaccountconf_mutable DPI_Id)}" + DPI_Key="${DPI_Key:-$(_readaccountconf_mutable DPI_Key)}" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + if ! _rest POST "Record.List" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain"; then + _err "Record.Lis error." + return 1 + fi + + if _contains "$response" 'No records'; then + _info "Don't need to remove." + return 0 + fi + + record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'"$txtvalue"'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \") + _debug record_id "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id." + return 1 + fi + + if ! _rest POST "Record.Remove" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then + _err "Record.Remove error." + return 1 + fi + + _contains "$response" "Action completed successful" + +} + +#add the txt record. +#usage: root sub txtvalue +add_record() { + root=$1 + sub=$2 + txtvalue=$3 + fulldomain="$sub.$root" + + _info "Adding record" + + if ! _rest POST "Record.Create" "user_token=$DPI_Id,$DPI_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain&record_type=TXT&value=$txtvalue&record_line=default"; then + return 1 + fi + + _contains "$response" "Action completed successful" || _contains "$response" "Domain record already exists" +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=sdjkglgdfewsdfg +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if ! _rest POST "Domain.Info" "user_token=$DPI_Id,$DPI_Key&format=json&domain=$h"; then + return 1 + fi + + if _contains "$response" "Action completed successful"; then + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") + _debug _domain_id "$_domain_id" + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _debug _sub_domain "$_sub_domain" + _domain="$h" + _debug _domain "$_domain" + return 0 + fi + return 1 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +#Usage: method URI data +_rest() { + m="$1" + ep="$2" + data="$3" + _debug "$ep" + url="$REST_API/$ep" + + _debug url "$url" + + if [ "$m" = "GET" ]; then + response="$(_get "$url" | tr -d '\r')" + else + _debug2 data "$data" + response="$(_post "$data" "$url" | tr -d '\r')" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} From 7aeb113c62dee96e259229028ed349828d982dac Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 14 Aug 2018 09:53:13 +0200 Subject: [PATCH 18/59] createDomainKey: fix exitcode for creating new key when running acme.sh headless (without terminal) to create a new key createDomainKey returns a non-zero exit-code. explicitly returning zero avoids this. --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index 32219d9..6eee183 100755 --- a/acme.sh +++ b/acme.sh @@ -1327,6 +1327,7 @@ createDomainKey() { if _createkey "$_cdl" "$CERT_KEY_PATH"; then _savedomainconf Le_Keylength "$_cdl" _info "The domain key is here: $(__green $CERT_KEY_PATH)" + return 0 fi else if [ "$IS_RENEW" ]; then From 0a3ac1f5c3f1ac55ad210344a02ad79a4a9abd50 Mon Sep 17 00:00:00 2001 From: Janos Lenart Date: Fri, 25 May 2018 18:56:07 +0100 Subject: [PATCH 19/59] Added support for Google Cloud DNS API (dns_gcloud) --- README.md | 1 + dnsapi/README.md | 21 ++++++ dnsapi/dns_gcloud.sh | 167 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100755 dnsapi/dns_gcloud.sh diff --git a/README.md b/README.md index c8bebc6..07fbc84 100644 --- a/README.md +++ b/README.md @@ -274,6 +274,7 @@ You don't have to do anything manually! ### Currently acme.sh supports: +1. Google Cloud DNS API 1. CloudFlare.com API 1. DNSPod.cn API 1. CloudXNS.com API diff --git a/dnsapi/README.md b/dnsapi/README.md index 1f394f9..b5fff91 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -4,6 +4,27 @@ If your dns provider doesn't provide api access, you can use our dns alias mode: https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode +## 1. Use Google Cloud DNS API to automatically issue cert + +First you need to authenticate to gcloud. + +``` +gcloud init +``` + +**The `dns_gcloud` script uses the active gcloud configuration and credentials.** +There is no logic inside `dns_gcloud` to override the project and other settings. +If needed, create additional [gcloud configurations](https://cloud.google.com/sdk/gcloud/reference/topic/configurations). +You can change the configuration being used without *activating* it; simply set the `CLOUDSDK_ACTIVE_CONFIG_NAME` environment variable. + +To issue a certificate you can: +``` +export CLOUDSDK_ACTIVE_CONFIG_NAME=default # see the note above +acme.sh --issue --dns dns_gcloud -d example.com -d '*.example.com' +``` + +`dns_gcloud` also supports [DNS alias mode](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode). + ## 1. Use CloudFlare domain API to automatically issue cert First you need to login to your CloudFlare account to get your API key. diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh new file mode 100755 index 0000000..5fbd2b6 --- /dev/null +++ b/dnsapi/dns_gcloud.sh @@ -0,0 +1,167 @@ +#!/usr/bin/env sh + +# Author: Janos Lenart + +######## Public functions ##################### + +# Usage: dns_gcloud_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_gcloud_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using gcloud" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _dns_gcloud_find_zone || return $? + + # Add an extra RR + _dns_gcloud_start_tr || return $? + _dns_gcloud_get_rrdatas || return $? + echo "$rrdatas" | _dns_gcloud_remove_rrs || return $? + echo -e "$rrdatas\n\"$txtvalue\"" | grep -v '^$' | _dns_gcloud_add_rrs || return $? + _dns_gcloud_execute_tr || return $? + + _info "$fulldomain record added" +} + +# Usage: dns_gcloud_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +# Remove the txt record after validation. +dns_gcloud_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using gcloud" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _dns_gcloud_find_zone || return $? + + # Remove one RR + _dns_gcloud_start_tr || return $? + _dns_gcloud_get_rrdatas || return $? + echo "$rrdatas" | _dns_gcloud_remove_rrs || return $? + echo "$rrdatas" | fgrep -v "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $? + _dns_gcloud_execute_tr || return $? + + _info "$fulldomain record added" +} + +#################### Private functions below ################################## + +_dns_gcloud_start_tr() { + if ! trd=`mktemp -d`; then + _err "_dns_gcloud_start_tr: failed to create temporary directory" + return 1 + fi + tr="$trd/tr.yaml" + _debug tr "$tr" + + if ! gcloud dns record-sets transaction start \ + --transaction-file="$tr" \ + --zone="$managedZone"; then + rm -r "$trd" + _err "_dns_gcloud_start_tr: failed to execute transaction" + return 1 + fi +} + +_dns_gcloud_execute_tr() { + if ! gcloud dns record-sets transaction execute \ + --transaction-file="$tr" \ + --zone="$managedZone"; then + _debug tr "`cat \"$tr\"`" + rm -r "$trd" + _err "_dns_gcloud_execute_tr: failed to execute transaction" + return 1 + fi + rm -r "$trd" + + for i in `seq 1 120`; do + if gcloud dns record-sets changes list \ + --zone=lenart \ + --filter='status != done' \ + | grep -q '.*'; then + _info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ..." + sleep 5 + else + return 0 + fi + done + + _err "_dns_gcloud_execute_tr: transaction is still pending after 10 minutes" + rm -r "$trd" + return 1 +} + +_dns_gcloud_remove_rrs() { + if ! xargs --no-run-if-empty gcloud dns record-sets transaction remove \ + --name="$fulldomain." \ + --ttl="$ttl" \ + --type=TXT \ + --zone="$managedZone" \ + --transaction-file="$tr"; then + _debug tr "`cat \"$tr\"`" + rm -r "$trd" + _err "_dns_gcloud_remove_rrs: failed to remove RRs" + return 1 + fi +} + +_dns_gcloud_add_rrs() { + ttl=60 + if ! xargs --no-run-if-empty gcloud dns record-sets transaction add \ + --name="$fulldomain." \ + --ttl="$ttl" \ + --type=TXT \ + --zone="$managedZone" \ + --transaction-file="$tr"; then + _debug tr "`cat \"$tr\"`" + rm -r "$trd" + _err "_dns_gcloud_add_rrs: failed to add RRs" + return 1 + fi +} + +_dns_gcloud_find_zone() { + # Prepare a filter that matches zones that are suiteable for this entry. + # For example, _acme-challenge.something.domain.com might need to go into something.domain.com or domain.com; + # this function finds the longest postfix that has a managed zone. + part="$fulldomain" + filter="dnsName=( " + while [ "$part" != "" ]; do + filter="$filter$part. " + part="`echo \"$part\" | sed 's/[^.]*\.*//'`" + done + filter="$filter)" + _debug filter "$filter" + + # List domains and find the longest match (in case of some levels of delegation) + if ! match=$(gcloud dns managed-zones list \ + --format="value(name, dnsName)" \ + --filter="$filter" \ + | while read dnsName name; do + echo -e "${#dnsName}\t$dnsName\t$name" + done \ + | sort -n -r | head -n1 | 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 + + dnsName=$(echo "$match" | cut -f2) + _debug dnsName "$dnsName" + managedZone=$(echo "$match" | cut -f1) + _debug managedZone "$managedZone" +} + +_dns_gcloud_get_rrdatas() { + if ! rrdatas=$(gcloud dns record-sets list \ + --zone="$managedZone" \ + --name="$fulldomain." \ + --type=TXT \ + --format="value(ttl,rrdatas)"); then + _err "_dns_gcloud_get_rrdatas: Failed to list record-sets" + rm -r "$trd" + return 1 + fi + ttl=$(echo "$rrdatas" | cut -f1) + rrdatas=$(echo "$rrdatas" | cut -f2 | sed 's/","/"\n"/g') +} From 167758003c3f04f2b849f4e330490b2c40e24251 Mon Sep 17 00:00:00 2001 From: Janos Lenart Date: Fri, 25 May 2018 19:22:40 +0100 Subject: [PATCH 20/59] Fixed shfmt (dns_gcloud) --- dnsapi/dns_gcloud.sh | 74 ++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index 5fbd2b6..9246618 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -18,7 +18,7 @@ dns_gcloud_add() { _dns_gcloud_start_tr || return $? _dns_gcloud_get_rrdatas || return $? echo "$rrdatas" | _dns_gcloud_remove_rrs || return $? - echo -e "$rrdatas\n\"$txtvalue\"" | grep -v '^$' | _dns_gcloud_add_rrs || return $? + printf "%s\n%s\n" "$rrdatas" "\"$txtvalue\"" | grep -v '^$' | _dns_gcloud_add_rrs || return $? _dns_gcloud_execute_tr || return $? _info "$fulldomain record added" @@ -39,7 +39,7 @@ dns_gcloud_rm() { _dns_gcloud_start_tr || return $? _dns_gcloud_get_rrdatas || return $? echo "$rrdatas" | _dns_gcloud_remove_rrs || return $? - echo "$rrdatas" | fgrep -v "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $? + echo "$rrdatas" | grep -F -v "\"$txtvalue\"" | _dns_gcloud_add_rrs || return $? _dns_gcloud_execute_tr || return $? _info "$fulldomain record added" @@ -48,7 +48,7 @@ dns_gcloud_rm() { #################### Private functions below ################################## _dns_gcloud_start_tr() { - if ! trd=`mktemp -d`; then + if ! trd=$(mktemp -d); then _err "_dns_gcloud_start_tr: failed to create temporary directory" return 1 fi @@ -56,8 +56,8 @@ _dns_gcloud_start_tr() { _debug tr "$tr" if ! gcloud dns record-sets transaction start \ - --transaction-file="$tr" \ - --zone="$managedZone"; then + --transaction-file="$tr" \ + --zone="$managedZone"; then rm -r "$trd" _err "_dns_gcloud_start_tr: failed to execute transaction" return 1 @@ -66,22 +66,22 @@ _dns_gcloud_start_tr() { _dns_gcloud_execute_tr() { if ! gcloud dns record-sets transaction execute \ - --transaction-file="$tr" \ - --zone="$managedZone"; then - _debug tr "`cat \"$tr\"`" + --transaction-file="$tr" \ + --zone="$managedZone"; then + _debug tr "$(cat "$tr")" rm -r "$trd" _err "_dns_gcloud_execute_tr: failed to execute transaction" return 1 fi rm -r "$trd" - for i in `seq 1 120`; do + for i in $(seq 1 120); do if gcloud dns record-sets changes list \ - --zone=lenart \ - --filter='status != done' \ - | grep -q '.*'; then - _info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ..." - sleep 5 + --zone=lenart \ + --filter='status != done' \ + | grep -q '^.*'; then + _info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ($i/120)..." + sleep 5 else return 0 fi @@ -94,12 +94,12 @@ _dns_gcloud_execute_tr() { _dns_gcloud_remove_rrs() { if ! xargs --no-run-if-empty gcloud dns record-sets transaction remove \ - --name="$fulldomain." \ - --ttl="$ttl" \ - --type=TXT \ - --zone="$managedZone" \ - --transaction-file="$tr"; then - _debug tr "`cat \"$tr\"`" + --name="$fulldomain." \ + --ttl="$ttl" \ + --type=TXT \ + --zone="$managedZone" \ + --transaction-file="$tr"; then + _debug tr "$(cat "$tr")" rm -r "$trd" _err "_dns_gcloud_remove_rrs: failed to remove RRs" return 1 @@ -109,12 +109,12 @@ _dns_gcloud_remove_rrs() { _dns_gcloud_add_rrs() { ttl=60 if ! xargs --no-run-if-empty gcloud dns record-sets transaction add \ - --name="$fulldomain." \ - --ttl="$ttl" \ - --type=TXT \ - --zone="$managedZone" \ - --transaction-file="$tr"; then - _debug tr "`cat \"$tr\"`" + --name="$fulldomain." \ + --ttl="$ttl" \ + --type=TXT \ + --zone="$managedZone" \ + --transaction-file="$tr"; then + _debug tr "$(cat "$tr")" rm -r "$trd" _err "_dns_gcloud_add_rrs: failed to add RRs" return 1 @@ -129,19 +129,19 @@ _dns_gcloud_find_zone() { filter="dnsName=( " while [ "$part" != "" ]; do filter="$filter$part. " - part="`echo \"$part\" | sed 's/[^.]*\.*//'`" + part="$(echo "$part" | sed 's/[^.]*\.*//')" done filter="$filter)" _debug filter "$filter" # List domains and find the longest match (in case of some levels of delegation) if ! match=$(gcloud dns managed-zones list \ - --format="value(name, dnsName)" \ - --filter="$filter" \ - | while read dnsName name; do - echo -e "${#dnsName}\t$dnsName\t$name" - done \ - | sort -n -r | head -n1 | cut -f2,3 | grep '.*'); then + --format="value(name, dnsName)" \ + --filter="$filter" \ + | while read -r dnsName name; do + printf "%s\t%s\t%s\n" "${#dnsName}" "$dnsName" "$name" + done \ + | sort -n -r | head -n1 | 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 @@ -154,10 +154,10 @@ _dns_gcloud_find_zone() { _dns_gcloud_get_rrdatas() { if ! rrdatas=$(gcloud dns record-sets list \ - --zone="$managedZone" \ - --name="$fulldomain." \ - --type=TXT \ - --format="value(ttl,rrdatas)"); then + --zone="$managedZone" \ + --name="$fulldomain." \ + --type=TXT \ + --format="value(ttl,rrdatas)"); then _err "_dns_gcloud_get_rrdatas: Failed to list record-sets" rm -r "$trd" return 1 From 1d4dec551068bd5b5fefc2f2b9258204305dc37c Mon Sep 17 00:00:00 2001 From: Janos Lenart Date: Sat, 26 May 2018 12:48:55 +0100 Subject: [PATCH 21/59] Moved dns_gcloud to 47. --- README.md | 2 +- dnsapi/README.md | 46 ++++++++++++++++++++++++---------------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 07fbc84..cf29d76 100644 --- a/README.md +++ b/README.md @@ -274,7 +274,6 @@ You don't have to do anything manually! ### Currently acme.sh supports: -1. Google Cloud DNS API 1. CloudFlare.com API 1. DNSPod.cn API 1. CloudXNS.com API @@ -322,6 +321,7 @@ You don't have to do anything manually! 1. acme-dns (https://github.com/joohoi/acme-dns) 1. TELE3 (https://www.tele3.cz) 1. EUSERV.EU (https://www.euserv.eu) +1. Google Cloud DNS API And: diff --git a/dnsapi/README.md b/dnsapi/README.md index b5fff91..31c99e8 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -4,27 +4,6 @@ If your dns provider doesn't provide api access, you can use our dns alias mode: https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode -## 1. Use Google Cloud DNS API to automatically issue cert - -First you need to authenticate to gcloud. - -``` -gcloud init -``` - -**The `dns_gcloud` script uses the active gcloud configuration and credentials.** -There is no logic inside `dns_gcloud` to override the project and other settings. -If needed, create additional [gcloud configurations](https://cloud.google.com/sdk/gcloud/reference/topic/configurations). -You can change the configuration being used without *activating* it; simply set the `CLOUDSDK_ACTIVE_CONFIG_NAME` environment variable. - -To issue a certificate you can: -``` -export CLOUDSDK_ACTIVE_CONFIG_NAME=default # see the note above -acme.sh --issue --dns dns_gcloud -d example.com -d '*.example.com' -``` - -`dns_gcloud` also supports [DNS alias mode](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode). - ## 1. Use CloudFlare domain API to automatically issue cert First you need to login to your CloudFlare account to get your API key. @@ -897,6 +876,7 @@ acme.sh --issue --dns dns_tele3 -d example.com -d *.example.com ``` The TELE3_Key and TELE3_Secret will be saved in ~/.acme.sh/account.conf and will be reused when needed. +<<<<<<< HEAD ## 47. Use Euserv.eu API First you need to login to your euserv.eu account and activate your API Administration (API Verwaltung). @@ -918,6 +898,28 @@ acme.sh --issue --dns dns_euserv -d example.com -d *.example.com --insecure The `EUSERV_Username` and `EUSERV_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. Please report any issues to https://github.com/initit/acme.sh or to + +## 48. Use Google Cloud DNS API to automatically issue cert + +First you need to authenticate to gcloud. + +``` +gcloud init +``` + +**The `dns_gcloud` script uses the active gcloud configuration and credentials.** +There is no logic inside `dns_gcloud` to override the project and other settings. +If needed, create additional [gcloud configurations](https://cloud.google.com/sdk/gcloud/reference/topic/configurations). +You can change the configuration being used without *activating* it; simply set the `CLOUDSDK_ACTIVE_CONFIG_NAME` environment variable. + +To issue a certificate you can: +``` +export CLOUDSDK_ACTIVE_CONFIG_NAME=default # see the note above +acme.sh --issue --dns dns_gcloud -d example.com -d '*.example.com' +``` + +`dns_gcloud` also supports [DNS alias mode](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode). + # Use custom API If your API is not supported yet, you can write your own DNS API. @@ -938,4 +940,4 @@ See: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide # Use lexicon DNS API -https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api \ No newline at end of file +https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api From 441f8f3ce83e10bbf69a30a4d25c821d65e174b1 Mon Sep 17 00:00:00 2001 From: Janos Lenart Date: Wed, 15 Aug 2018 12:01:43 +0100 Subject: [PATCH 22/59] Replied to PR comments --- dnsapi/dns_gcloud.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_gcloud.sh b/dnsapi/dns_gcloud.sh index 9246618..99fbf41 100755 --- a/dnsapi/dns_gcloud.sh +++ b/dnsapi/dns_gcloud.sh @@ -77,7 +77,7 @@ _dns_gcloud_execute_tr() { for i in $(seq 1 120); do if gcloud dns record-sets changes list \ - --zone=lenart \ + --zone="$managedZone" \ --filter='status != done' \ | grep -q '^.*'; then _info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ($i/120)..." @@ -141,7 +141,7 @@ _dns_gcloud_find_zone() { | while read -r dnsName name; do printf "%s\t%s\t%s\n" "${#dnsName}" "$dnsName" "$name" done \ - | sort -n -r | head -n1 | 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 From 9e96a9317235ce3c775a048db2a78ec6f418fe2c Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Wed, 15 Aug 2018 18:36:24 +0200 Subject: [PATCH 23/59] Updated README with Gitlab help --- deploy/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/deploy/README.md b/deploy/README.md index 181989d..5c03ce6 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -275,3 +275,24 @@ acme.sh --deploy -d haproxy.example.com --deploy-hook haproxy ``` The path for the PEM file will be stored with the domain configuration and will be available when renewing, so that deploy will happen automatically when renewed. + +## 11. Deploy your cert to Gitlab pages + +You must define the API key and the informations for the project and Gitlab page you are updating the certificate for. + +```sh +# The token can be created in your user settings under "Access Tokens" +export GITLAB_TOKEN="xxxxxxxxxxx" + +# The project ID is displayed on the home page of the project +export GITLAB_PROJECT_ID=12345678 + +# The domain must match the one defined for the Gitlab page, without "https://" +export GITLAB_DOMAIN="www.mydomain.com" +``` + +You can then deploy the certificate as follows + +```sh +acme.sh --deploy -d www.mydomain.com --deploy-hook gitlab +``` \ No newline at end of file From d06eea53ef08c68340fb48590779f48df98716f7 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Wed, 15 Aug 2018 18:36:34 +0200 Subject: [PATCH 24/59] Add deploy plugin for Gitlab pages --- deploy/gitlab.sh | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 deploy/gitlab.sh diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh new file mode 100644 index 0000000..5bc53e8 --- /dev/null +++ b/deploy/gitlab.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env sh + +# Script to deploy certificate to a Gitlab hosted page + +# The following variables exported from environment will be used. +# If not set then values previously saved in domain.conf file are used. + +# All the variables are required + +# export GITLAB_TOKEN="xxxxxxx" +# export GITLAB_PROJECT_ID=012345 +# export GITLAB_DOMAIN="mydomain.com" + +gitlab_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" + + if [ -z "$GITLAB_TOKEN" ]; then + if [ -z "$Le_Deploy_gitlab_token" ]; then + _err "GITLAB_TOKEN not defined." + return 1 + fi + else + Le_Deploy_gitlab_token="$GITLAB_TOKEN" + _savedomainconf Le_Deploy_gitlab_token "$Le_Deploy_gitlab_token" + fi + + if [ -z "$GITLAB_PROJECT_ID" ]; then + if [ -z "$Le_Deploy_gitlab_project_id" ]; then + _err "GITLAB_PROJECT_ID not defined." + return 1 + fi + else + Le_Deploy_gitlab_project_id="$GITLAB_PROJECT_ID" + _savedomainconf Le_Deploy_gitlab_project_id "$Le_Deploy_gitlab_project_id" + fi + + if [ -z "$GITLAB_DOMAIN" ]; then + if [ -z "$Le_Deploy_gitlab_domain" ]; then + _err "GITLAB_DOMAIN not defined." + return 1 + fi + else + Le_Deploy_gitlab_domain="$GITLAB_DOMAIN" + _savedomainconf Le_Deploy_gitlab_domain "$Le_Deploy_gitlab_domain" + fi + + curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain > /dev/null && exit 0 + + # Exit curl status code if curl didn't work + exit $? +} From 0575eb671a8506d69eb81946d45e385732c6e8a7 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Wed, 15 Aug 2018 18:44:24 +0200 Subject: [PATCH 25/59] Fix double quote around URL --- deploy/gitlab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index 5bc53e8..9502da7 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -54,7 +54,7 @@ gitlab_deploy() { _savedomainconf Le_Deploy_gitlab_domain "$Le_Deploy_gitlab_domain" fi - curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain > /dev/null && exit 0 + curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" > /dev/null && exit 0 # Exit curl status code if curl didn't work exit $? From 6d8292cdd8fe98a5f3d61072f1d8a53f8ceb2768 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Wed, 15 Aug 2018 19:00:08 +0200 Subject: [PATCH 26/59] Syntax fix --- deploy/gitlab.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index 9502da7..6c1d0f4 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -32,7 +32,7 @@ gitlab_deploy() { else Le_Deploy_gitlab_token="$GITLAB_TOKEN" _savedomainconf Le_Deploy_gitlab_token "$Le_Deploy_gitlab_token" - fi + fi if [ -z "$GITLAB_PROJECT_ID" ]; then if [ -z "$Le_Deploy_gitlab_project_id" ]; then @@ -42,7 +42,7 @@ gitlab_deploy() { else Le_Deploy_gitlab_project_id="$GITLAB_PROJECT_ID" _savedomainconf Le_Deploy_gitlab_project_id "$Le_Deploy_gitlab_project_id" - fi + fi if [ -z "$GITLAB_DOMAIN" ]; then if [ -z "$Le_Deploy_gitlab_domain" ]; then @@ -52,9 +52,9 @@ gitlab_deploy() { else Le_Deploy_gitlab_domain="$GITLAB_DOMAIN" _savedomainconf Le_Deploy_gitlab_domain "$Le_Deploy_gitlab_domain" - fi + fi - curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" > /dev/null && exit 0 + curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" >/dev/null && exit 0 # Exit curl status code if curl didn't work exit $? From 75dd0a770f060eccb13f7ec449a6cc1cf1fba006 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Wed, 15 Aug 2018 19:10:31 +0200 Subject: [PATCH 27/59] Fix Syntax --- deploy/gitlab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index 6c1d0f4..174b226 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -54,7 +54,7 @@ gitlab_deploy() { _savedomainconf Le_Deploy_gitlab_domain "$Le_Deploy_gitlab_domain" fi - curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" >/dev/null && exit 0 + curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" >/dev/null && exit 0 # Exit curl status code if curl didn't work exit $? From b401dbbf65f9f671f3c4e66bd4aa75c8abbdf133 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Wed, 15 Aug 2018 19:17:24 +0200 Subject: [PATCH 28/59] Fix Syntax --- deploy/gitlab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index 174b226..e0222be 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -55,7 +55,7 @@ gitlab_deploy() { fi curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" >/dev/null && exit 0 - + # Exit curl status code if curl didn't work exit $? } From 8113548920c4b3fdeee4ecdc3959d40d48410fd7 Mon Sep 17 00:00:00 2001 From: Aarup Date: Tue, 21 Aug 2018 11:44:36 +0200 Subject: [PATCH 29/59] Update dns api to support v2 wildcard cert #1261 --- dnsapi/dns_unoeuro.sh | 62 ++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/dnsapi/dns_unoeuro.sh b/dnsapi/dns_unoeuro.sh index a3803a2..8be1542 100644 --- a/dnsapi/dns_unoeuro.sh +++ b/dnsapi/dns_unoeuro.sh @@ -50,35 +50,18 @@ dns_unoeuro_add() { _err "Error" return 1 fi + _info "Adding record" - if ! _contains "$response" "$_sub_domain" >/dev/null; then - _info "Adding record" - - if _uno_rest POST "my/products/$h/dns/records" "{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":120}"; then - if _contains "$response" "\"status\": 200" >/dev/null; then - _info "Added, OK" - return 0 - else - _err "Add txt record error." - return 1 - fi - fi - _err "Add txt record error." - else - _info "Updating record" - record_line_number=$(echo "$response" | grep -n "$_sub_domain" | cut -d : -f 1) - record_line_number=$(_math "$record_line_number" - 1) - record_id=$(echo "$response" | _head_n "$record_line_number" | _tail_n 1 1 | _egrep_o "[0-9]{1,}") - _debug "record_id" "$record_id" - - _uno_rest PUT "my/products/$h/dns/records/$record_id" "{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":120}" + if _uno_rest POST "my/products/$h/dns/records" "{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":120}"; then if _contains "$response" "\"status\": 200" >/dev/null; then - _info "Updated, OK" + _info "Added, OK" return 0 + else + _err "Add txt record error." + return 1 fi - _err "Update error" - return 1 fi + _err "Add txt record error." } #fulldomain txtvalue @@ -122,23 +105,24 @@ dns_unoeuro_rm() { if ! _contains "$response" "$_sub_domain"; then _info "Don't need to remove." else - record_line_number=$(echo "$response" | grep -n "$_sub_domain" | cut -d : -f 1) - record_line_number=$(_math "$record_line_number" - 1) - record_id=$(echo "$response" | _head_n "$record_line_number" | _tail_n 1 1 | _egrep_o "[0-9]{1,}") - _debug "record_id" "$record_id" - - if [ -z "$record_id" ]; then - _err "Can not get record id to remove." - return 1 - fi + for record_line_number in $(echo "$response" | grep -n "$_sub_domain" | cut -d : -f 1); do + record_line_number=$(_math "$record_line_number" - 1) + _debug "record_line_number" "$record_line_number" + record_id=$(echo "$response" | _head_n "$record_line_number" | _tail_n 1 1 | _egrep_o "[0-9]{1,}") + _debug "record_id" "$record_id" + + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi - if ! _uno_rest DELETE "my/products/$h/dns/records/$record_id"; then - _err "Delete record error." - return 1 - fi - _contains "$response" "\"status\": 200" + if ! _uno_rest DELETE "my/products/$h/dns/records/$record_id"; then + _err "Delete record error." + return 1 + fi + _contains "$response" "\"status\": 200" + done fi - } #################### Private functions below ################################## From b23718f3ad8b7a5defc0fd67bbcf20f1ec9d1613 Mon Sep 17 00:00:00 2001 From: Jens Reimann Date: Tue, 21 Aug 2018 11:01:47 +0200 Subject: [PATCH 30/59] Add support for additional Lexicon options --- dnsapi/dns_lexicon.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index ab180fb..f6f5446 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -78,7 +78,11 @@ dns_lexicon_add() { domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999) - $lexicon_cmd "$PROVIDER" create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" + _secure_debug LEXICON_OPTS "$LEXICON_OPTS" + _savedomainconf LEXICON_OPTS "$LEXICON_OPTS" + + # shellcheck disable=SC2086 + $lexicon_cmd "$PROVIDER" $LEXICON_OPTS create "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" } @@ -93,6 +97,7 @@ dns_lexicon_rm() { domain=$(printf "%s" "$fulldomain" | cut -d . -f 2-999) - $lexicon_cmd "$PROVIDER" delete "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" + # shellcheck disable=SC2086 + $lexicon_cmd "$PROVIDER" $LEXICON_OPTS delete "${domain}" TXT --name="_acme-challenge.${domain}." --content="${txtvalue}" } From 8b6986ba18367103d1efe32fed9961ccae40ac3a Mon Sep 17 00:00:00 2001 From: Aarup Date: Tue, 21 Aug 2018 12:32:30 +0200 Subject: [PATCH 31/59] Fix file formatting --- dnsapi/dns_unoeuro.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_unoeuro.sh b/dnsapi/dns_unoeuro.sh index 8be1542..9132f13 100644 --- a/dnsapi/dns_unoeuro.sh +++ b/dnsapi/dns_unoeuro.sh @@ -61,7 +61,6 @@ dns_unoeuro_add() { return 1 fi fi - _err "Add txt record error." } #fulldomain txtvalue @@ -121,7 +120,7 @@ dns_unoeuro_rm() { return 1 fi _contains "$response" "\"status\": 200" - done + done fi } From c205777542ea8acf4ca9f36e5a55dc22c76b9515 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Tue, 21 Aug 2018 16:18:00 +0200 Subject: [PATCH 32/59] Better integration with acme.sh utils --- deploy/gitlab.sh | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index e0222be..a95983a 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/env sh -x # Script to deploy certificate to a Gitlab hosted page @@ -54,8 +54,29 @@ gitlab_deploy() { _savedomainconf Le_Deploy_gitlab_domain "$Le_Deploy_gitlab_domain" fi - curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" >/dev/null && exit 0 + #curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" >/dev/null && exit 0 + + string_fullchain=$( _url_encode < $_cfullchain ) + string_key=$( _url_encode < $_ckey ) + + body="certificate=$string_fullchain&key=$string_key" + + export _H1="PRIVATE-TOKEN: $Le_Deploy_gitlab_token" - # Exit curl status code if curl didn't work - exit $? + gitlab_url="https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" + + _response=$( _post "$body" "$gitlab_url" 0 PUT | _dbase64 "multiline" ) + + error_response="error" + + if test "${_response#*$error_response}" != "$_response"; then + _err "Error in deploying certificate:" + _err "$_response" + return 1 + fi + + _debug response "$_response" + _info "Certificate successfully deployed" + + return 0 } From f1b0dd7836021db95470cc1d2269182edf35d0e1 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Tue, 21 Aug 2018 16:22:08 +0200 Subject: [PATCH 33/59] Fix Syntax --- deploy/gitlab.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index a95983a..1ec617b 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh -x +#!/usr/bin/env sh # Script to deploy certificate to a Gitlab hosted page @@ -56,19 +56,19 @@ gitlab_deploy() { #curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" >/dev/null && exit 0 - string_fullchain=$( _url_encode < $_cfullchain ) - string_key=$( _url_encode < $_ckey ) + string_fullchain=$(_url_encode < $_cfullchain) + string_key=$(_url_encode < $_ckey) body="certificate=$string_fullchain&key=$string_key" - + export _H1="PRIVATE-TOKEN: $Le_Deploy_gitlab_token" gitlab_url="https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" - - _response=$( _post "$body" "$gitlab_url" 0 PUT | _dbase64 "multiline" ) + + _response=$(_post "$body" "$gitlab_url" 0 PUT | _dbase64 "multiline") error_response="error" - + if test "${_response#*$error_response}" != "$_response"; then _err "Error in deploying certificate:" _err "$_response" From 5a326b82bdb8569cb6c7980a5fcca85ec2791048 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Tue, 21 Aug 2018 16:24:57 +0200 Subject: [PATCH 34/59] Fix Syntax --- deploy/gitlab.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index 1ec617b..0d41ab2 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -56,8 +56,8 @@ gitlab_deploy() { #curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" >/dev/null && exit 0 - string_fullchain=$(_url_encode < $_cfullchain) - string_key=$(_url_encode < $_ckey) + string_fullchain=$(_url_encode <$_cfullchain) + string_key=$(_url_encode <$_ckey) body="certificate=$string_fullchain&key=$string_key" From bbf2a15f27acbce9f9a375f13a592b0ecb14e468 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Tue, 21 Aug 2018 16:30:33 +0200 Subject: [PATCH 35/59] Fix Syntax --- deploy/gitlab.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index 0d41ab2..ece31c9 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -54,8 +54,6 @@ gitlab_deploy() { _savedomainconf Le_Deploy_gitlab_domain "$Le_Deploy_gitlab_domain" fi - #curl -s --fail --request PUT --header "PRIVATE-TOKEN: $Le_Deploy_gitlab_token" --form "certificate=@$_cfullchain" --form "key=@$_ckey" "https://gitlab.com/api/v4/projects/$Le_Deploy_gitlab_project_id/pages/domains/$Le_Deploy_gitlab_domain" >/dev/null && exit 0 - string_fullchain=$(_url_encode <$_cfullchain) string_key=$(_url_encode <$_ckey) From e3c7fc8077aeb84c386da549dac035de855cab6c Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Tue, 21 Aug 2018 16:35:39 +0200 Subject: [PATCH 36/59] Fix Syntax --- deploy/gitlab.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index ece31c9..66bb4eb 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -56,7 +56,7 @@ gitlab_deploy() { string_fullchain=$(_url_encode <$_cfullchain) string_key=$(_url_encode <$_ckey) - + body="certificate=$string_fullchain&key=$string_key" export _H1="PRIVATE-TOKEN: $Le_Deploy_gitlab_token" From 8d6443b25da55693d4ff716b6ce76e849ae17c4d Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Tue, 21 Aug 2018 16:41:45 +0200 Subject: [PATCH 37/59] Fix Syntax --- deploy/gitlab.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/gitlab.sh b/deploy/gitlab.sh index 66bb4eb..ba2d312 100644 --- a/deploy/gitlab.sh +++ b/deploy/gitlab.sh @@ -54,8 +54,8 @@ gitlab_deploy() { _savedomainconf Le_Deploy_gitlab_domain "$Le_Deploy_gitlab_domain" fi - string_fullchain=$(_url_encode <$_cfullchain) - string_key=$(_url_encode <$_ckey) + string_fullchain=$(_url_encode <"$_cfullchain") + string_key=$(_url_encode <"$_ckey") body="certificate=$string_fullchain&key=$string_key" From 840b3a34cba3602e49a14dded23e2664a31fc277 Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 21 Aug 2018 21:47:40 +0200 Subject: [PATCH 38/59] changed some chars --- dnsapi/dns_netcup.sh | 214 +++++++++++++++++++++---------------------- 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 573550e..2dfbdab 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -8,123 +8,123 @@ end="https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON" client="" dns_netcup_add() { - login - if [ "$NC_Apikey" = "" ] || [ "$NC_Apipw" = "" ] || [ "$NC_CID" = "" ]; then - _err "No Credentials given" - return 1 - fi - _saveaccountconf_mutable NC_Apikey "$NC_Apikey" - _saveaccountconf_mutable NC_Apipw "$NC_Apipw" - _saveaccountconf_mutable NC_CID "$NC_CID" - fulldomain=$1 - txtvalue=$2 - domain="" - exit=$(echo "$fulldomain" | tr -dc '.' | wc -c) - exit=$(_math "$exit" + 1) - i=$exit + login + if [ "$NC_Apikey" = "" ] || [ "$NC_Apipw" = "" ] || [ "$NC_CID" = "" ]; then + _err "No Credentials given" + return 1 + fi + _saveaccountconf_mutable NC_Apikey "$NC_Apikey" + _saveaccountconf_mutable NC_Apipw "$NC_Apipw" + _saveaccountconf_mutable NC_CID "$NC_CID" + fulldomain=$1 + txtvalue=$2 + domain="" + exit=$(echo "$fulldomain" | tr -dc '.' | wc -c) + exit=$(_math "$exit" + 1) + i=$exit - while - [ "$exit" -gt 0 ]; do - tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") - if [ "$(_math "$i" - "$exit")" -eq 0 ]; then - domain="$tmp" - else - domain="$tmp.$domain" - fi - if [ "$(_math "$i" - "$exit")" -ge 1 ]; then - msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"false\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") - _debug "$msg" - if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then - if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then - _err "$msg" - return 1 - else - break - fi - fi - fi - exit=$(_math "$exit" - 1) - done - logout + while + [ "$exit" -gt 0 ]; do + tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") + if [ "$(_math "$i" - "$exit")" -eq 0 ]; then + domain="$tmp" + else + domain="$tmp.$domain" + fi + if [ "$(_math "$i" - "$exit")" -ge 1 ]; then + msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"false\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") + _debug "$msg" + if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" + return 1 + else + break + fi + fi + fi + exit=$(_math "$exit" - 1) + done + logout } dns_netcup_rm() { - login - fulldomain=$1 - txtvalue=$2 + login + fulldomain=$1 + txtvalue=$2 - domain="" - exit=$(echo "$fulldomain" | tr -dc '.' | wc -c) - exit=$(_math "$exit" + 1) - i=$exit - rec="" + domain="" + exit=$(echo "$fulldomain" | tr -dc '.' | wc -c) + exit=$(_math "$exit" + 1) + i=$exit + rec="" - while - [ "$exit" -gt 0 ]; do - tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") - if [ "$(_math "$i" - "$exit")" -eq 0 ]; then - domain="$tmp" - else - domain="$tmp.$domain" - fi - if [ "$(_math "$i" - "$exit")" -ge 1 ]; then - msg=$(_post "{\"action\": \"infoDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\", \"domainname\": \"$domain\"}}" "$end" "" "POST") - rec=$(echo "$msg" | sed 's/\[//g' | sed 's/\]//g' | sed 's/{\"serverrequestid\".*\"dnsrecords\"://g' | sed 's/},{/};{/g' | sed 's/{//g' | sed 's/}//g') - _debug "$msg" - if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then - if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then - _err "$msg" - return 1 - else - break - fi - fi - fi - exit=$(_math "$exit" - 1) - done + while + [ "$exit" -gt 0 ]; do + tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") + if [ "$(_math "$i" - "$exit")" -eq 0 ]; then + domain="$tmp" + else + domain="$tmp.$domain" + fi + if [ "$(_math "$i" - "$exit")" -ge 1 ]; then + msg=$(_post "{\"action\": \"infoDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\", \"domainname\": \"$domain\"}}" "$end" "" "POST") + rec=$(echo "$msg" | sed 's/\[//g' | sed 's/\]//g' | sed 's/{\"serverrequestid\".*\"dnsrecords\"://g' | sed 's/},{/};{/g' | sed 's/{//g' | sed 's/}//g') + _debug "$msg" + if [ "$(_getfield "$msg" "5" | sed 's/"statuscode"://g')" != 5028 ]; then + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" + return 1 + else + break + fi + fi + fi + exit=$(_math "$exit" - 1) + done - ida=0000 - idv=0001 - ids=0000000000 - i=1 - while - [ "$i" -ne 0 ]; do - specrec=$(_getfield "$rec" "$i" ";") - idv="$ida" - ida=$(_getfield "$specrec" "1" "," | sed 's/\"id\":\"//g' | sed 's/\"//g') - txtv=$(_getfield "$specrec" "5" "," | sed 's/\"destination\":\"//g' | sed 's/\"//g') - i=$(_math "$i" + 1) - if [ "$txtvalue" = "$txtv" ]; then - i=0 - ids="$ida" - fi - if [ "$ida" = "$idv" ]; then - i=0 - fi - done - msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"$ids\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"TRUE\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") - _debug "$msg" - if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then - _err "$msg" - return 1 - fi - logout + ida=0000 + idv=0001 + ids=0000000000 + i=1 + while + [ "$i" -ne 0 ]; do + specrec=$(_getfield "$rec" "$i" ";") + idv="$ida" + ida=$(_getfield "$specrec" "1" "," | sed 's/\"id\":\"//g' | sed 's/\"//g') + txtv=$(_getfield "$specrec" "5" "," | sed 's/\"destination\":\"//g' | sed 's/\"//g') + i=$(_math "$i" + 1) + if [ "$txtvalue" = "$txtv" ]; then + i=0 + ids="$ida" + fi + if [ "$ida" = "$idv" ]; then + i=0 + fi + done + msg=$(_post "{\"action\": \"updateDnsRecords\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\",\"clientrequestid\": \"$client\" , \"domainname\": \"$domain\", \"dnsrecordset\": { \"dnsrecords\": [ {\"id\": \"$ids\", \"hostname\": \"$fulldomain.\", \"type\": \"TXT\", \"priority\": \"\", \"destination\": \"$txtvalue\", \"deleterecord\": \"TRUE\", \"state\": \"yes\"} ]}}}" "$end" "" "POST") + _debug "$msg" + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" + return 1 + fi + logout } login() { - tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") - sid=$(_getfield "$tmp" "8" | sed s/\"responsedata\":\{\"apisessionid\":\"//g | sed 's/\"\}\}//g') - _debug "$tmp" - if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then - _err "$msg" - return 1 - fi + tmp=$(_post "{\"action\": \"login\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apipassword\": \"$NC_Apipw\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") + sid=$(_getfield "$tmp" "8" | sed s/\"responsedata\":\{\"apisessionid\":\"//g | sed 's/\"\}\}//g') + _debug "$tmp" + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" + return 1 + fi } logout() { - tmp=$(_post "{\"action\": \"logout\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") - _debug "$tmp" - if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then - _err "$msg" - return 1 - fi + tmp=$(_post "{\"action\": \"logout\", \"param\": {\"apikey\": \"$NC_Apikey\", \"apisessionid\": \"$sid\", \"customernumber\": \"$NC_CID\"}}" "$end" "" "POST") + _debug "$tmp" + if [ "$(_getfield "$msg" "4" | sed s/\"status\":\"//g | sed s/\"//g)" != "success" ]; then + _err "$msg" + return 1 + fi } From 4fffb3c8161358b1bdf9e570bedba4fb3c010803 Mon Sep 17 00:00:00 2001 From: linux-insideDE <39219399+linux-insideDE@users.noreply.github.com> Date: Tue, 21 Aug 2018 21:55:44 +0200 Subject: [PATCH 39/59] make shfmt happy --- dnsapi/dns_netcup.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_netcup.sh b/dnsapi/dns_netcup.sh index 2dfbdab..2273eb7 100644 --- a/dnsapi/dns_netcup.sh +++ b/dnsapi/dns_netcup.sh @@ -24,7 +24,8 @@ dns_netcup_add() { i=$exit while - [ "$exit" -gt 0 ]; do + [ "$exit" -gt 0 ] + do tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") if [ "$(_math "$i" - "$exit")" -eq 0 ]; then domain="$tmp" @@ -60,7 +61,8 @@ dns_netcup_rm() { rec="" while - [ "$exit" -gt 0 ]; do + [ "$exit" -gt 0 ] + do tmp=$(echo "$fulldomain" | cut -d'.' -f"$exit") if [ "$(_math "$i" - "$exit")" -eq 0 ]; then domain="$tmp" @@ -88,7 +90,8 @@ dns_netcup_rm() { ids=0000000000 i=1 while - [ "$i" -ne 0 ]; do + [ "$i" -ne 0 ] + do specrec=$(_getfield "$rec" "$i" ";") idv="$ida" ida=$(_getfield "$specrec" "1" "," | sed 's/\"id\":\"//g' | sed 's/\"//g') From 2e74df2583cf2a28a74251a8f0c25d5e55d1a170 Mon Sep 17 00:00:00 2001 From: KUDO Takashi Date: Mon, 30 Jul 2018 19:41:11 +0900 Subject: [PATCH 40/59] Add support ConoHa DNS API --- README.md | 1 + dnsapi/README.md | 19 +++- dnsapi/dns_conoha.sh | 255 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 274 insertions(+), 1 deletion(-) create mode 100755 dnsapi/dns_conoha.sh diff --git a/README.md b/README.md index ada8273..d247707 100644 --- a/README.md +++ b/README.md @@ -323,6 +323,7 @@ You don't have to do anything manually! 1. EUSERV.EU (https://www.euserv.eu) 1. DNSPod.com API (https://www.dnspod.com) 1. Google Cloud DNS API +1. ConoHa (https://www.conoha.jp) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index 8322679..15c5026 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -876,7 +876,6 @@ acme.sh --issue --dns dns_tele3 -d example.com -d *.example.com ``` The TELE3_Key and TELE3_Secret will be saved in ~/.acme.sh/account.conf and will be reused when needed. -<<<<<<< HEAD ## 47. Use Euserv.eu API First you need to login to your euserv.eu account and activate your API Administration (API Verwaltung). @@ -936,6 +935,24 @@ acme.sh --issue --dns dns_gcloud -d example.com -d '*.example.com' `dns_gcloud` also supports [DNS alias mode](https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode). +## 50. Use ConoHa API + +First you need to login to your ConoHa account to get your API credentials. + +``` +export CONOHA_Username="xxxxxx" +export CONOHA_Password="xxxxxx" +export CONOHA_TenantId="xxxxxx" +export CONOHA_IdentityServiceApi="https://identity.xxxx.conoha.io/v2.0" +``` + +To issue a cert: +``` +acme.sh --issue --dns dns_conoha -d example.com -d www.example.com +``` + +The `CONOHA_Username`, `CONOHA_Password`, `CONOHA_TenantId` and `CONOHA_IdentityServiceApi` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + ======= # Use custom API diff --git a/dnsapi/dns_conoha.sh b/dnsapi/dns_conoha.sh new file mode 100755 index 0000000..f9e4ac1 --- /dev/null +++ b/dnsapi/dns_conoha.sh @@ -0,0 +1,255 @@ +#!/usr/bin/env sh + +CONOHA_DNS_EP_PREFIX_REGEXP="https://dns-service\." + +######## Public functions ##################### + +#Usage: dns_conoha_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_conoha_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using conoha" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _debug "Check uesrname and password" + CONOHA_Username="${CONOHA_Username:-$(_readaccountconf_mutable CONOHA_Username)}" + CONOHA_Password="${CONOHA_Password:-$(_readaccountconf_mutable CONOHA_Password)}" + CONOHA_TenantId="${CONOHA_TenantId:-$(_readaccountconf_mutable CONOHA_TenantId)}" + CONOHA_IdentityServiceApi="${CONOHA_IdentityServiceApi:-$(_readaccountconf_mutable CONOHA_IdentityServiceApi)}" + if [ -z "$CONOHA_Username" ] || [ -z "$CONOHA_Password" ] || [ -z "$CONOHA_TenantId" ] || [ -z "$CONOHA_IdentityServiceApi" ]; then + CONOHA_Username="" + CONOHA_Password="" + CONOHA_TenantId="" + CONOHA_IdentityServiceApi="" + _err "You didn't specify a conoha api username and password yet." + _err "Please create the user and try again." + return 1 + fi + + _saveaccountconf_mutable CONOHA_Username "$CONOHA_Username" + _saveaccountconf_mutable CONOHA_Password "$CONOHA_Password" + _saveaccountconf_mutable CONOHA_TenantId "$CONOHA_TenantId" + _saveaccountconf_mutable CONOHA_IdentityServiceApi "$CONOHA_IdentityServiceApi" + + if set -- $(_conoha_get_accesstoken "$CONOHA_IdentityServiceApi/tokens" "$CONOHA_Username" "$CONOHA_Password" "$CONOHA_TenantId"); then + accesstoken=$1 + CONOHA_Api=$2 + else + return 1 + fi + #return 1 #XXX + + _debug "First detect the root zone" + if ! _get_root "$fulldomain" "$CONOHA_Api" "$accesstoken"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + #return 1 #XXX + + _info "Adding record" + body="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"data\":\"$txtvalue\",\"ttl\":60}" + if _conoha_rest POST "$CONOHA_Api/v1/domains/$_domain_id/records" "$body" "$accesstoken"; then + if _contains "$response" '"data":"'"$txtvalue"'"'; then + _info "Added, OK" + return 0 + else + _err "Add txt record error." + return 1 + fi + fi + + _err "Add txt record error." + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_conoha_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using conoha" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + _debug "Check uesrname and password" + CONOHA_Username="${CONOHA_Username:-$(_readaccountconf_mutable CONOHA_Username)}" + CONOHA_Password="${CONOHA_Password:-$(_readaccountconf_mutable CONOHA_Password)}" + CONOHA_TenantId="${CONOHA_TenantId:-$(_readaccountconf_mutable CONOHA_TenantId)}" + CONOHA_IdentityServiceApi="${CONOHA_IdentityServiceApi:-$(_readaccountconf_mutable CONOHA_IdentityServiceApi)}" + if [ -z "$CONOHA_Username" ] || [ -z "$CONOHA_Password" ] || [ -z "$CONOHA_TenantId" ] || [ -z "$CONOHA_IdentityServiceApi" ]; then + CONOHA_Username="" + CONOHA_Password="" + CONOHA_TenantId="" + CONOHA_IdentityServiceApi="" + _err "You didn't specify a conoha api username and password yet." + _err "Please create the user and try again." + return 1 + fi + + _saveaccountconf_mutable CONOHA_Username "$CONOHA_Username" + _saveaccountconf_mutable CONOHA_Password "$CONOHA_Password" + _saveaccountconf_mutable CONOHA_TenantId "$CONOHA_TenantId" + _saveaccountconf_mutable CONOHA_IdentityServiceApi "$CONOHA_IdentityServiceApi" + + if set -- $(_conoha_get_accesstoken "$CONOHA_IdentityServiceApi/tokens" "$CONOHA_Username" "$CONOHA_Password" "$CONOHA_TenantId"); then + accesstoken=$1 + CONOHA_Api=$2 + else + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain" "$CONOHA_Api" "$accesstoken"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + if ! _conoha_rest GET "$CONOHA_Api/v1/domains/$_domain_id/records" "" "$accesstoken"; then + _err "Error" + return 1 + fi + + record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' | + grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" | + _head_n 1 | cut -d : -f 2 | tr -d \") + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + _debug record_id "$record_id" + + _info "Removing the txt record" + if ! _conoha_rest DELETE "$CONOHA_Api/v1/domains/$_domain_id/records/$record_id" "" "$accesstoken"; then + _err "Delete record error." + return 1 + fi + + return 0 +} + +#################### Private functions below ################################## + +_conoha_rest() { + m="$1" + ep="$2" + data="$3" + accesstoken="$4" + + export _H1="Accept: application/json" + export _H2="Content-Type: application/json" + if [ -n "$accesstoken" ]; then + export _H3="X-Auth-Token: $accesstoken" + fi + + _debug "$ep" + if [ "$m" != "GET" ]; then + _secure_debug2 data "$data" + response="$(_post "$data" "$ep" "" "$m")" + else + response="$(_get "$ep")" + fi + _ret="$?" + _secure_debug2 response "$response" + if [ "$_ret" != "0" ]; then + _err "error $ep" + return 1 + fi + + response="$(printf "%s" "$response" | _normalizeJson)" + return 0 +} + +_conoha_get_accesstoken() { + ep="$1" + username="$2" + password="$3" + tenantId="$4" + + accesstoken="$(_readaccountconf_mutable conoha_accesstoken)" + expires="$(_readaccountconf_mutable conoha_tokenvalidto)" + CONOHA_Api="$(_readaccountconf_mutable conoha_dns_ep)" + + # can we reuse the access token? + if [ -n "$accesstoken" ] && [ -n "$expires" ] && [ -n "$CONOHA_Api" ]; then + utc_date="$(_utc_date | sed "s/ /T/")" + if expr "$utc_date" "<" "$expires" >/dev/null; then + # access token is still valid - reuse it + _debug "reusing access token" + printf "%s\n%s" "$accesstoken" "$CONOHA_Api" + return 0 + else + _debug "access token expired" + fi + fi + _debug "getting new access token" + + body="$(printf '{"auth":{"passwordCredentials":{"username":"%s","password":"%s"},"tenantId":"%s"}}' "$username" "$password" "$tenantId")" + if ! _conoha_rest POST "$ep" "$body" ""; then + _err error "$response" + return 1 + fi + accesstoken=$(printf "%s" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + expires=$(printf "%s" "$response" | _egrep_o "\"expires\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2-4 | tr -d \" | tr -d Z) #expect UTC + if [ -z "$accesstoken" ] || [ -z "$expires" ]; then + _err "no acccess token received. Check your Conoha settings see $WIKI" + return 1 + fi + _saveaccountconf_mutable conoha_accesstoken "$accesstoken" + _saveaccountconf_mutable conoha_tokenvalidto "$expires" + + CONOHA_Api=$(printf "%s" "$response" | _egrep_o 'publicURL":"'"$CONOHA_DNS_EP_PREFIX_REGEXP"'[^"]*"' | _head_n 1 | cut -d : -f 2-3 | tr -d \") + if [ -z "$CONOHA_Api" ]; then + _err "failed to get conoha dns endpoint url" + return 1 + fi + _saveaccountconf_mutable conoha_dns_ep "$CONOHA_Api" + + printf "%s\n%s" "$accesstoken" "$CONOHA_Api" + return 0 +} + +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=sdjkglgdfewsdfg +_get_root() { + domain="$1" + ep="$2" + accesstoken="$3" + i=2 + p=1 + 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 ! _conoha_rest GET "$ep/v1/domains?name=$h" "" "$accesstoken"; then + return 1 + fi + + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} From 72a7f932c65c4fd2c889fd3220081bb2b005cf34 Mon Sep 17 00:00:00 2001 From: KUDO Takashi Date: Mon, 30 Jul 2018 22:03:14 +0900 Subject: [PATCH 41/59] fix indent --- dnsapi/dns_conoha.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_conoha.sh b/dnsapi/dns_conoha.sh index f9e4ac1..c573d17 100755 --- a/dnsapi/dns_conoha.sh +++ b/dnsapi/dns_conoha.sh @@ -117,9 +117,9 @@ dns_conoha_rm() { return 1 fi - record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' | - grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" | - _head_n 1 | cut -d : -f 2 | tr -d \") + record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' \ + | grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" \ + | _head_n 1 | cut -d : -f 2 | tr -d \") if [ -z "$record_id" ]; then _err "Can not get record id to remove." return 1 @@ -147,7 +147,7 @@ _conoha_rest() { export _H2="Content-Type: application/json" if [ -n "$accesstoken" ]; then export _H3="X-Auth-Token: $accesstoken" - fi + fi _debug "$ep" if [ "$m" != "GET" ]; then From a35d27166941762aa819da21f6c7452b6e2dd178 Mon Sep 17 00:00:00 2001 From: KUDO Takashi Date: Mon, 30 Jul 2018 22:15:57 +0900 Subject: [PATCH 42/59] cleanup --- dnsapi/dns_conoha.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dnsapi/dns_conoha.sh b/dnsapi/dns_conoha.sh index c573d17..694665b 100755 --- a/dnsapi/dns_conoha.sh +++ b/dnsapi/dns_conoha.sh @@ -38,7 +38,6 @@ dns_conoha_add() { else return 1 fi - #return 1 #XXX _debug "First detect the root zone" if ! _get_root "$fulldomain" "$CONOHA_Api" "$accesstoken"; then @@ -48,7 +47,6 @@ dns_conoha_add() { _debug _domain_id "$_domain_id" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - #return 1 #XXX _info "Adding record" body="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"data\":\"$txtvalue\",\"ttl\":60}" @@ -176,7 +174,7 @@ _conoha_get_accesstoken() { accesstoken="$(_readaccountconf_mutable conoha_accesstoken)" expires="$(_readaccountconf_mutable conoha_tokenvalidto)" CONOHA_Api="$(_readaccountconf_mutable conoha_dns_ep)" - + # can we reuse the access token? if [ -n "$accesstoken" ] && [ -n "$expires" ] && [ -n "$CONOHA_Api" ]; then utc_date="$(_utc_date | sed "s/ /T/")" From 73d04b976ee638479e9dff65da43450a17a7858b Mon Sep 17 00:00:00 2001 From: KUDO Takashi Date: Mon, 30 Jul 2018 22:50:47 +0900 Subject: [PATCH 43/59] avoid "SC2046: Quote this to prevent word splitting." Travis CI error. --- dnsapi/dns_conoha.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_conoha.sh b/dnsapi/dns_conoha.sh index 694665b..d3bee13 100755 --- a/dnsapi/dns_conoha.sh +++ b/dnsapi/dns_conoha.sh @@ -32,9 +32,9 @@ dns_conoha_add() { _saveaccountconf_mutable CONOHA_TenantId "$CONOHA_TenantId" _saveaccountconf_mutable CONOHA_IdentityServiceApi "$CONOHA_IdentityServiceApi" - if set -- $(_conoha_get_accesstoken "$CONOHA_IdentityServiceApi/tokens" "$CONOHA_Username" "$CONOHA_Password" "$CONOHA_TenantId"); then - accesstoken=$1 - CONOHA_Api=$2 + if token="$(_conoha_get_accesstoken "$CONOHA_IdentityServiceApi/tokens" "$CONOHA_Username" "$CONOHA_Password" "$CONOHA_TenantId")"; then + accesstoken="$(printf "%s" "$token" | sed -n 1p)" + CONOHA_Api="$(printf "%s" "$token" | sed -n 2p)" else return 1 fi @@ -93,9 +93,9 @@ dns_conoha_rm() { _saveaccountconf_mutable CONOHA_TenantId "$CONOHA_TenantId" _saveaccountconf_mutable CONOHA_IdentityServiceApi "$CONOHA_IdentityServiceApi" - if set -- $(_conoha_get_accesstoken "$CONOHA_IdentityServiceApi/tokens" "$CONOHA_Username" "$CONOHA_Password" "$CONOHA_TenantId"); then - accesstoken=$1 - CONOHA_Api=$2 + if token="$(_conoha_get_accesstoken "$CONOHA_IdentityServiceApi/tokens" "$CONOHA_Username" "$CONOHA_Password" "$CONOHA_TenantId")"; then + accesstoken="$(printf "%s" "$token" | sed -n 1p)" + CONOHA_Api="$(printf "%s" "$token" | sed -n 2p)" else return 1 fi @@ -181,7 +181,7 @@ _conoha_get_accesstoken() { if expr "$utc_date" "<" "$expires" >/dev/null; then # access token is still valid - reuse it _debug "reusing access token" - printf "%s\n%s" "$accesstoken" "$CONOHA_Api" + printf "%s\n%s\n" "$accesstoken" "$CONOHA_Api" return 0 else _debug "access token expired" @@ -210,7 +210,7 @@ _conoha_get_accesstoken() { fi _saveaccountconf_mutable conoha_dns_ep "$CONOHA_Api" - printf "%s\n%s" "$accesstoken" "$CONOHA_Api" + printf "%s\n%s\n" "$accesstoken" "$CONOHA_Api" return 0 } From 68a290c34752c2aa0b913332467b7a5f2c001111 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Wed, 22 Aug 2018 19:08:33 +0200 Subject: [PATCH 44/59] revert dns_inwx.sh to dev --- dnsapi/dns_inwx.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index f4590cf..cd5af91 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -158,8 +158,7 @@ _inwx_login() { export _H1 #https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71 - if _contains "$response" "code1000" \ - && _contains "$response" "tfaGOOGLE-AUTH"; then + if _contains "$response" "tfa"; then if [ -z "$INWX_Shared_Secret" ]; then _err "Mobile TAN detected." _err "Please define a shared secret." From 1756bbff84e204bef1edaa953d2ffb0c04c9008b Mon Sep 17 00:00:00 2001 From: Herman Sletteng Date: Tue, 15 May 2018 11:31:43 +0200 Subject: [PATCH 45/59] DNS plugin for Danish service gratisdns.dk Currently only supports primary domains. My use case does not involve secondary domains so I'm not sure how it behaves, and cannot test it. Might be as simple as turning all "primary"-references into a variable that's either "primary" or "secondary", and make an extra check for this in _get_domain... Cookie handling heavily inspired by freedns plugin, including caching the cookie in the config file, so we can rm without re-authenticating --- README.md | 1 + dnsapi/README.md | 20 ++++++ dnsapi/dns_gdnsdk.sh | 168 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100755 dnsapi/dns_gdnsdk.sh diff --git a/README.md b/README.md index 0ba5eeb..904a478 100644 --- a/README.md +++ b/README.md @@ -325,6 +325,7 @@ You don't have to do anything manually! 1. Google Cloud DNS API 1. ConoHa (https://www.conoha.jp) 1. netcup DNS API (https://www.netcup.de) +1. GratisDNS.dk (https://gratisdns.dk) And: diff --git a/dnsapi/README.md b/dnsapi/README.md index 47862d6..891417f 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -970,6 +970,26 @@ acme.sh --issue --dns dns_netcup -d example.com -d www.example.com The `NC_Apikey`,`NC_Apipw` and `NC_CID` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 52. Use GratisDNS.dk + +GratisDNS.dk (https://gratisdns.dj/) does not provide an API to update DNS records (other than IPv4 and IPv6 +dynamic DNS addresses). The acme.sh plugin therefore retrieves and updates domain TXT records by logging +into the GratisDNS website to read the HTML and posting updates as HTTP. The plugin needs to know your +userid and password for the GratisDNS website. + +```sh +export GDNSDK_Username="..." +export GDNSDK_Password="..." +``` +The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + + +Now you can issue a certificate. + +```sh +acme.sh --issue --dns dns_gdnsdk -d example.com -d *.example.com +``` + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_gdnsdk.sh b/dnsapi/dns_gdnsdk.sh new file mode 100755 index 0000000..05a4c9f --- /dev/null +++ b/dnsapi/dns_gdnsdk.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env sh +#Author: Herman Sletteng +#Report Bugs here: https://github.com/loial/acme.sh +# +# +# Note, gratisdns requires a login first, so the script needs to handle +# temporary cookies. Since acme.sh _get/_post currently don't directly support +# cookies, I've defined wrapper functions _myget/_mypost to set the headers + +GDNSDK_API="https://admin.gratisdns.com" +######## Public functions ##################### +#Usage: dns_gdnsdk_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_gdnsdk_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using gratisdns.dk" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + if ! _gratisdns_login; then + _err "Login failed!" + return 1 + fi + #finding domain zone + if ! _get_domain; then + _err "No matching root domain for $fulldomain found" + return 1 + fi + # adding entry + _info "Adding the entry" + _mypost "action=dns_primary_record_added_txt&user_domain=$_domain&name=$fulldomain&txtdata=$txtvalue&ttl=1" + if _successful_update; then return 0; fi + _err "Couldn't create entry!" + return 1 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_gdnsdk_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using gratisdns.dk" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + if ! _gratisdns_login; then + _err "Login failed!" + return 1 + fi + if ! _get_domain; then + _err "No matching root domain for $fulldomain found" + return 1 + fi + _findentry "$fulldomain" "$txtvalue" + if [ -z "$_id" ]; then + _info "Entry doesn't exist, nothing to delete" + return 0 + fi + _debug "Deleting record..." + _mypost "action=dns_primary_delete_txt&user_domain=$_domain&id=$_id" + # removing entry + + if _successful_update; then return 0; fi + _err "Couldn't delete entry!" + return 1 +} + +#################### Private functions below ################################## + +_checkcredentials() { + GDNSDK_Username="${GDNSDK_Username:-$(_readaccountconf_mutable GDNSDK_Username)}" + GDNSDK_Password="${GDNSDK_Password:-$(_readaccountconf_mutable GDNSDK_Password)}" + + if [ -z "$GDNSDK_Username" ] || [ -z "$GDNSDK_Password" ]; then + GDNSDK_Username="" + GDNSDK_Password="" + _err "You haven't specified gratisdns.dk username and password yet." + _err "Please add credentials and try again." + return 1 + fi + #save the credentials to the account conf file. + _saveaccountconf_mutable GDNSDK_Username "$GDNSDK_Username" + _saveaccountconf_mutable GDNSDK_Password "$GDNSDK_Password" + return 0 +} + +_checkcookie() { + GDNSDK_Cookie="${GDNSDK_Cookie:-$(_readaccountconf_mutable GDNSDK_Cookie)}" + if [ -z "$GDNSDK_Cookie" ]; then + _debug "No cached cookie found" + return 1 + fi + _myget "action=" + if (echo "$_result" | grep -q "logmeout"); then + _debug "Cached cookie still valid" + return 0 + fi + _debug "Cached cookie no longer valid" + GDNSDK_Cookie="" + _saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie" + return 1 +} + +_gratisdns_login() { + if ! _checkcredentials; then return 1; fi + + if _checkcookie; then + _debug "Already logged in" + return 0 + fi + _debug "Logging into GratisDNS with user $GDNSDK_Username" + + if ! _mypost "login=$GDNSDK_Username&password=$GDNSDK_Password&action=logmein"; then + _err "GratisDNS login failed for user $GDNSDK_Username bad RC from _post" + return 1 + fi + + GDNSDK_Cookie="$(grep -A 15 '302 Found' "$HTTP_HEADER" | _egrep_o 'Cookie: [^;]*' | _head_n 1 | cut -d ' ' -f2)" + + if [ -z "$GDNSDK_Cookie" ]; then + _err "GratisDNS login failed for user $GDNSDK_Username. Check $HTTP_HEADER file" + return 1 + fi + export GDNSDK_Cookie + _saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie" + return 0 +} + +_myget() { + #Adds cookie to request + export _H1="Cookie: $GDNSDK_Cookie" + _result=$(_get "$GDNSDK_API?$1") +} +_mypost() { + #Adds cookie to request + export _H1="Cookie: $GDNSDK_Cookie" + _result=$(_post "$1" "$GDNSDK_API") +} + +_get_domain() { + _myget 'action=dns_primarydns' + _domains=$(echo "$_result" | grep -o -P ' domain="\K([[:alnum:].-_]+)') + if [ -z "$_domains" ]; then + _err "Primary domain list not found!" + return 1 + fi + for _domain in $_domains; do + if (_endswith "$fulldomain" "$_domain"); then + _debug "Root domain: $_domain" + return 0 + fi + done + return 1 +} + +_successful_update() { + if (echo "$_result" | grep -q 'table-success'); then return 0; fi + return 1 +} + +_findentry() { + #returns id of dns entry, if it exists + _myget "action=dns_primary_changeDNSsetup&user_domain=$_domain" + _id=$(echo "$_result" | grep -o -P "$1\s*$2.*?id=\K(\d*)") + if [ -n "$_id" ]; then + _debug "Entry found with _id=$_id" + return 0 + fi + return 1 +} From 1f25b4a8a94ad14999fd19b87a29ea3d4383c237 Mon Sep 17 00:00:00 2001 From: Herman Sletteng Date: Fri, 24 Aug 2018 00:18:04 +0200 Subject: [PATCH 46/59] Replacing "grep -o -P" with "_egrep_o" and sed --- dnsapi/dns_gdnsdk.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_gdnsdk.sh b/dnsapi/dns_gdnsdk.sh index 05a4c9f..7dc7894 100755 --- a/dnsapi/dns_gdnsdk.sh +++ b/dnsapi/dns_gdnsdk.sh @@ -137,7 +137,7 @@ _mypost() { _get_domain() { _myget 'action=dns_primarydns' - _domains=$(echo "$_result" | grep -o -P ' domain="\K([[:alnum:].-_]+)') + _domains=$(echo "$_result" | _egrep_o ' domain="[[:alnum:].-_]+' | sed 's/^.*"//') if [ -z "$_domains" ]; then _err "Primary domain list not found!" return 1 @@ -159,7 +159,7 @@ _successful_update() { _findentry() { #returns id of dns entry, if it exists _myget "action=dns_primary_changeDNSsetup&user_domain=$_domain" - _id=$(echo "$_result" | grep -o -P "$1\s*$2.*?id=\K(\d*)") + _id=$(echo "$_result" | _egrep_o "$1\s*$2[^?]*[^&]*&id=[^&]*" | sed 's/^.*=//') if [ -n "$_id" ]; then _debug "Entry found with _id=$_id" return 0 From 12c900ea7d4f4da4de856611f5955bad23e8db25 Mon Sep 17 00:00:00 2001 From: Herman Sletteng Date: Wed, 29 Aug 2018 00:44:34 +0200 Subject: [PATCH 47/59] Gratisdns.dk: Fix typo in url, also added note recommending --dnssleep 300 --- dnsapi/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 891417f..c8207b9 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -972,7 +972,7 @@ The `NC_Apikey`,`NC_Apipw` and `NC_CID` will be saved in `~/.acme.sh/account.con ## 52. Use GratisDNS.dk -GratisDNS.dk (https://gratisdns.dj/) does not provide an API to update DNS records (other than IPv4 and IPv6 +GratisDNS.dk (https://gratisdns.dk/) does not provide an API to update DNS records (other than IPv4 and IPv6 dynamic DNS addresses). The acme.sh plugin therefore retrieves and updates domain TXT records by logging into the GratisDNS website to read the HTML and posting updates as HTTP. The plugin needs to know your userid and password for the GratisDNS website. @@ -986,8 +986,11 @@ The username and password will be saved in `~/.acme.sh/account.conf` and will be Now you can issue a certificate. +Note: It usually takes a few minutes (usually 3-4 minutes) before the changes propagates to gratisdns.dk nameservers (ns3.gratisdns.dk often are slow), +and in rare cases I have seen over 5 minutes before google DNS catches it. Therefor a DNS sleep of at least 300 seconds are recommended- + ```sh -acme.sh --issue --dns dns_gdnsdk -d example.com -d *.example.com +acme.sh --issue --dns dns_gdnsdk --dnssleep 300 -d example.com -d *.example.com ``` # Use custom API From 0d03309c2f17bd5ed8e73a1425c956b4cc422a24 Mon Sep 17 00:00:00 2001 From: LLeny Date: Sun, 2 Sep 2018 21:25:44 +0800 Subject: [PATCH 48/59] Namecheap initial --- dnsapi/dns_namecheap.sh | 233 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100755 dnsapi/dns_namecheap.sh diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh new file mode 100755 index 0000000..67aa3ac --- /dev/null +++ b/dnsapi/dns_namecheap.sh @@ -0,0 +1,233 @@ +#!/usr/bin/env sh + +# Namecheap API +# https://www.namecheap.com/support/api/intro.aspx +# +# Requires Namecheap API key set in NAMECHEAP_API_KEY and NAMECHEAP_USERNAME set as environment variable +# +######## Public functions ##################### + +NAMECHEAP_API="https://api.sandbox.namecheap.com/xml.response" + +#Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_namecheap_add() { + fulldomain=$1 + txtvalue=$2 + + if ! _namecheap_check_config; then + _err "$error" + return 1 + fi + + _namecheap_set_publicip + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + _debug domain "$_domain" + _debug sub_domain "$_sub_domain" + + _set_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue" +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_namecheap_rm() { + fulldomain=$1 + txtvalue=$2 + + _namecheap_set_publicip + + if ! _namecheap_check_config; then + _err "$error" + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + _debug domain "$_domain" + _debug sub_domain "$_sub_domain" + + _del_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue" + +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +_get_root() { + domain=$1 + + if ! _namecheap_post "namecheap.domains.getList"; then + _err "$error" + return 1 + fi + + i=2 + p=1 + + 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 + _debug "$h not found" + else + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain="$h" + return 0 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +_namecheap_set_publicip() { + _publicip="$(_get https://ifconfig.co/ip)" +} + +_namecheap_post() { + command=$1 + data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}" + + response="$(_post "$data" "$NAMECHEAP_API" "" "POST")" + _debug2 response "$response" + + if _contains "$response" "Status=\"ERROR\"" >/dev/null; then + error=$(echo "$response" | _egrep_o ">.*<\\/Error>" | cut -d '<' -f 1 | tr -d '>') + _err "error $error" + return 1 + fi + + return 0 +} + + +_namecheap_parse_host() { + _host=$1 + +#HostID UniqueID of the host records +#Name The domain or subdomain for which host record is set +#Type The type of host record that is set +#Address The value that is set for the host record (IP address for A record, URL for URL redirects, etc.) +#MXPref MXPreference number +#TTL TTL value for the host record + + _debug _host "$_host" + + _hostid=$(echo "$_host" | _egrep_o 'HostId=".*"' | cut -d '"' -f 2) + _hostname=$(echo "$_host" | _egrep_o 'Name=".*"' | cut -d '"' -f 2) + _hosttype=$(echo "$_host" | _egrep_o 'Type=".*"' | cut -d '"' -f 2) + _hostaddress=$(echo "$_host" | _egrep_o 'Address=".*"' | cut -d '"' -f 2) + _hostmxpref=$(echo "$_host" | _egrep_o 'MXPref=".*"' | cut -d '"' -f 2) + _hostttl=$(echo "$_host" | _egrep_o 'TTL=".*"' | cut -d '"' -f 2) + + _debug hostid "$_hostid" + _debug hostname "$_hostname" + _debug hosttype "$_hosttype" + _debug hostaddress "$_hostaddress" + _debug hostmxpref "$_hostmxpref" + _debug hostttl "$_hostttl" + +} + +_namecheap_check_config() { + + if [ -z "$NAMECHEAP_API_KEY" ]; then + _err "No API key specified for Namecheap API." + _err "Create your key and export it as NAMECHEAP_API_KEY" + return 1 + fi + + if [ -z "$NAMECHEAP_USERNAME" ]; then + _err "No username key specified for Namecheap API." + _err "Create your key and export it as NAMECHEAP_USERNAME" + return 1 + fi + + _saveaccountconf NAMECHEAP_API_KEY "$NAMECHEAP_API_KEY" + _saveaccountconf NAMECHEAP_USERNAME "$NAMECHEAP_USERNAME" + + return 0 +} + +_set_namecheap_TXT() { + subdomain=$2 + txt=$3 + tld=$(echo "$1" | cut -d '.' -f 2) + sld=$(echo "$1" | cut -d '.' -f 1) + request="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld" + + if ! _namecheap_post "$request"; then + _err "$error" + return 1 + fi + + hosts=$(echo "$response" | _egrep_o '') + _debug hosts "$hosts" + + if [ -z "$hosts" ]; then + _error "Hosts not found" + return 1 + fi + + i=0 + found=0 + + while read host; do + + if _contains "$host" " Date: Wed, 5 Sep 2018 21:29:42 +0800 Subject: [PATCH 49/59] WIP --- dnsapi/dns_namecheap.sh | 78 +++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 67aa3ac..89aeddd 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -19,7 +19,9 @@ dns_namecheap_add() { return 1 fi - _namecheap_set_publicip + if ! _namecheap_set_publicip; then + return 1 + fi _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -40,8 +42,10 @@ dns_namecheap_add() { dns_namecheap_rm() { fulldomain=$1 txtvalue=$2 - - _namecheap_set_publicip + + if ! _namecheap_set_publicip; then + return 1 + fi if ! _namecheap_check_config; then _err "$error" @@ -102,7 +106,35 @@ _get_root() { } _namecheap_set_publicip() { - _publicip="$(_get https://ifconfig.co/ip)" + + if [ -z "$NAMECHEAP_SOURCEIP" ]; then + _err "No Source IP specified for Namecheap API." + _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" + return 1 + else + _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP" + _debug sourceip "$NAMECHEAP_SOURCEIP" + + ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*') + + _debug2 ip "$ip" + _debug2 addr "$addr" + + if [ -n "$ip" ]; then + _publicip="$ip" + elif [ -n "$addr" ]; then + _publicip=$(_get "$addr") + else + _err "No Source IP specified for Namecheap API." + _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" + return 1 + fi + fi + + _debug publicip "$_publicip" + + return 0 } _namecheap_post() { @@ -124,14 +156,6 @@ _namecheap_post() { _namecheap_parse_host() { _host=$1 - -#HostID UniqueID of the host records -#Name The domain or subdomain for which host record is set -#Type The type of host record that is set -#Address The value that is set for the host record (IP address for A record, URL for URL redirects, etc.) -#MXPref MXPreference number -#TTL TTL value for the host record - _debug _host "$_host" _hostid=$(echo "$_host" | _egrep_o 'HostId=".*"' | cut -d '"' -f 2) @@ -190,38 +214,35 @@ _set_namecheap_TXT() { return 1 fi - i=0 + _namecheap_reset_hostList found=0 - while read host; do + while read -r host; do if _contains "$host" " Date: Fri, 7 Sep 2018 20:52:10 +0800 Subject: [PATCH 50/59] Usage --- dnsapi/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dnsapi/README.md b/dnsapi/README.md index 891417f..48b0489 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -990,6 +990,27 @@ Now you can issue a certificate. acme.sh --issue --dns dns_gdnsdk -d example.com -d *.example.com ``` +## 53. Use Namecheap + +You will need your namecheap username, API KEY (https://www.namecheap.com/support/api/intro.aspx) and your external IP address (or an URL to get it), this IP will need to be whitelisted at Namecheap. +Due to Namecheap's AP limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise. + +```sh +export NAMECHEAP_USERNAME="..." +export NAMECHEAP_API_KEY="..." +export NAMECHEAP_SOURCEIP="..." +``` + +NAMECHEAP_SOURCEIP can either be an IP address (e.g. 145.34.23.54) or an URL to provide it (e.g. https://ifconfig.co/ip). + +The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + +Now you can issue a certificate. + +```sh +acme.sh --issue --dns dns_namecheap -d example.com -d *.example.com +``` + # Use custom API If your API is not supported yet, you can write your own DNS API. From dc0dd6588c7172892e87c91af57efda1fffad447 Mon Sep 17 00:00:00 2001 From: LLeny Date: Fri, 7 Sep 2018 20:52:34 +0800 Subject: [PATCH 51/59] Support list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 904a478..b9a5cc5 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,7 @@ You don't have to do anything manually! 1. ConoHa (https://www.conoha.jp) 1. netcup DNS API (https://www.netcup.de) 1. GratisDNS.dk (https://gratisdns.dk) +1. Namecheap API (https://www.namecheap.com/) And: From 8868783476809bf647fbd0c9efbba866306fe660 Mon Sep 17 00:00:00 2001 From: LLeny Date: Fri, 7 Sep 2018 20:52:49 +0800 Subject: [PATCH 52/59] Staging --- dnsapi/dns_namecheap.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 89aeddd..73ed865 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -7,7 +7,11 @@ # ######## Public functions ##################### -NAMECHEAP_API="https://api.sandbox.namecheap.com/xml.response" +if [ "$STAGE" -eq 1 ]; then + NAMECHEAP_API="https://api.sandbox.namecheap.com/xml.response" +else + NAMECHEAP_API="https://api.namecheap.com/xml.response" +fi #Usage: dns_namecheap_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_namecheap_add() { From b859dd660c5b6c718fd71c595d3a1c1eb1e8bedd Mon Sep 17 00:00:00 2001 From: LLeny Date: Fri, 7 Sep 2018 20:53:21 +0800 Subject: [PATCH 53/59] dns_rm support --- dnsapi/dns_namecheap.sh | 80 +++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 19 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 73ed865..0bf49e5 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -129,7 +129,7 @@ _namecheap_set_publicip() { _publicip="$ip" elif [ -n "$addr" ]; then _publicip=$(_get "$addr") - else + else _err "No Source IP specified for Namecheap API." _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" return 1 @@ -162,12 +162,12 @@ _namecheap_parse_host() { _host=$1 _debug _host "$_host" - _hostid=$(echo "$_host" | _egrep_o 'HostId=".*"' | cut -d '"' -f 2) - _hostname=$(echo "$_host" | _egrep_o 'Name=".*"' | cut -d '"' -f 2) - _hosttype=$(echo "$_host" | _egrep_o 'Type=".*"' | cut -d '"' -f 2) - _hostaddress=$(echo "$_host" | _egrep_o 'Address=".*"' | cut -d '"' -f 2) - _hostmxpref=$(echo "$_host" | _egrep_o 'MXPref=".*"' | cut -d '"' -f 2) - _hostttl=$(echo "$_host" | _egrep_o 'TTL=".*"' | cut -d '"' -f 2) + _hostid=$(echo "$_host" | _egrep_o '\sHostId="[^"]*' | cut -d '"' -f 2) + _hostname=$(echo "$_host" | _egrep_o '\sName="[^"]*' | cut -d '"' -f 2) + _hosttype=$(echo "$_host" | _egrep_o '\sType="[^"]*' | cut -d '"' -f 2) + _hostaddress=$(echo "$_host" | _egrep_o '\sAddress="[^"]*' | cut -d '"' -f 2) + _hostmxpref=$(echo "$_host" | _egrep_o '\sMXPref="[^"]*' | cut -d '"' -f 2) + _hostttl=$(echo "$_host" | _egrep_o '\sTTL="[^"]*' | cut -d '"' -f 2) _debug hostid "$_hostid" _debug hostname "$_hostname" @@ -210,7 +210,7 @@ _set_namecheap_TXT() { return 1 fi - hosts=$(echo "$response" | _egrep_o '') + hosts=$(echo "$response" | _egrep_o ']*') _debug hosts "$hosts" if [ -z "$hosts" ]; then @@ -219,29 +219,72 @@ _set_namecheap_TXT() { fi _namecheap_reset_hostList - found=0 while read -r host; do - if _contains "$host" "]*') + _debug hosts "$hosts" + + if [ -z "$hosts" ]; then + _error "Hosts not found" + return 1 + fi + + _namecheap_reset_hostList + + found=0 - if [ "$_hosttype" = "TXT" ] && [ "$_hostname" = "$subdomain" ]; then - _namecheap_add_host "$_hostname" "$_hosttype" "$txt" "$_hostmxpref" "$_hostttl" - found=1 + while read -r host; do + if _contains "$host" " Date: Sat, 8 Sep 2018 07:05:44 +0800 Subject: [PATCH 54/59] README fixes --- dnsapi/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 48b0489..1421cc2 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -993,7 +993,7 @@ acme.sh --issue --dns dns_gdnsdk -d example.com -d *.example.com ## 53. Use Namecheap You will need your namecheap username, API KEY (https://www.namecheap.com/support/api/intro.aspx) and your external IP address (or an URL to get it), this IP will need to be whitelisted at Namecheap. -Due to Namecheap's AP limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise. +Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise. ```sh export NAMECHEAP_USERNAME="..." @@ -1001,7 +1001,7 @@ export NAMECHEAP_API_KEY="..." export NAMECHEAP_SOURCEIP="..." ``` -NAMECHEAP_SOURCEIP can either be an IP address (e.g. 145.34.23.54) or an URL to provide it (e.g. https://ifconfig.co/ip). +NAMECHEAP_SOURCEIP can either be an IP address or an URL to provide it (e.g. https://ifconfig.co/ip). The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed. From 30ee00ff50fca9345110c69c0cd4b9827f96f65d Mon Sep 17 00:00:00 2001 From: LLeny Date: Sat, 8 Sep 2018 07:06:16 +0800 Subject: [PATCH 55/59] RM TXT check --- dnsapi/dns_namecheap.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 0bf49e5..9cf6fb1 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -270,8 +270,7 @@ _del_namecheap_TXT() { while read -r host; do if _contains "$host" " Date: Sat, 8 Sep 2018 07:06:35 +0800 Subject: [PATCH 56/59] NC API warning --- dnsapi/dns_namecheap.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 9cf6fb1..a368608 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -3,8 +3,9 @@ # Namecheap API # https://www.namecheap.com/support/api/intro.aspx # -# Requires Namecheap API key set in NAMECHEAP_API_KEY and NAMECHEAP_USERNAME set as environment variable -# +# Requires Namecheap API key set in NAMECHEAP_API_KEY, NAMECHEAP_SOURCEIP and NAMECHEAP_USERNAME set as environment variable +# Due to Namecheap's API limitation all the records of your domain will be read and re applied, make sure to have a backup of your records you could apply if any issue would arise. + ######## Public functions ##################### if [ "$STAGE" -eq 1 ]; then From 697e694de692b04531db2bc7e309c1afbe5e2616 Mon Sep 17 00:00:00 2001 From: LLeny Date: Sat, 8 Sep 2018 07:28:56 +0800 Subject: [PATCH 57/59] Indentation --- dnsapi/dns_namecheap.sh | 48 ++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index a368608..9ace134 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -20,12 +20,12 @@ dns_namecheap_add() { txtvalue=$2 if ! _namecheap_check_config; then - _err "$error" - return 1 + _err "$error" + return 1 fi if ! _namecheap_set_publicip; then - return 1 + return 1 fi _debug "First detect the root zone" @@ -49,12 +49,12 @@ dns_namecheap_rm() { txtvalue=$2 if ! _namecheap_set_publicip; then - return 1 + return 1 fi if ! _namecheap_check_config; then - _err "$error" - return 1 + _err "$error" + return 1 fi _debug "First detect the root zone" @@ -81,8 +81,8 @@ _get_root() { domain=$1 if ! _namecheap_post "namecheap.domains.getList"; then - _err "$error" - return 1 + _err "$error" + return 1 fi i=2 @@ -117,7 +117,7 @@ _namecheap_set_publicip() { _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" return 1 else - _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP" + _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP" _debug sourceip "$NAMECHEAP_SOURCEIP" ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') @@ -207,16 +207,16 @@ _set_namecheap_TXT() { request="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld" if ! _namecheap_post "$request"; then - _err "$error" - return 1 + _err "$error" + return 1 fi hosts=$(echo "$response" | _egrep_o ']*') _debug hosts "$hosts" if [ -z "$hosts" ]; then - _error "Hosts not found" - return 1 + _error "Hosts not found" + return 1 fi _namecheap_reset_hostList @@ -237,8 +237,8 @@ EOT request="namecheap.domains.dns.setHosts&SLD=${sld}&TLD=${tld}${_hostrequest}" if ! _namecheap_post "$request"; then - _err "$error" - return 1 + _err "$error" + return 1 fi return 0 @@ -252,16 +252,16 @@ _del_namecheap_TXT() { request="namecheap.domains.dns.getHosts&SLD=$sld&TLD=$tld" if ! _namecheap_post "$request"; then - _err "$error" - return 1 + _err "$error" + return 1 fi hosts=$(echo "$response" | _egrep_o ']*') _debug hosts "$hosts" if [ -z "$hosts" ]; then - _error "Hosts not found" - return 1 + _error "Hosts not found" + return 1 fi _namecheap_reset_hostList @@ -271,9 +271,9 @@ _del_namecheap_TXT() { while read -r host; do if _contains "$host" " Date: Sat, 8 Sep 2018 08:06:35 +0800 Subject: [PATCH 58/59] shfmt --- dnsapi/dns_namecheap.sh | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/dnsapi/dns_namecheap.sh b/dnsapi/dns_namecheap.sh index 9ace134..7089c2d 100755 --- a/dnsapi/dns_namecheap.sh +++ b/dnsapi/dns_namecheap.sh @@ -47,7 +47,7 @@ dns_namecheap_add() { dns_namecheap_rm() { fulldomain=$1 txtvalue=$2 - + if ! _namecheap_set_publicip; then return 1 fi @@ -69,7 +69,6 @@ dns_namecheap_rm() { _debug sub_domain "$_sub_domain" _del_namecheap_TXT "$_domain" "$_sub_domain" "$txtvalue" - } #################### Private functions below ################################## @@ -89,7 +88,7 @@ _get_root() { p=1 while true; do - + h=$(printf "%s" "$domain" | cut -d . -f $i-100) _debug h "$h" if [ -z "$h" ]; then @@ -111,7 +110,7 @@ _get_root() { } _namecheap_set_publicip() { - + if [ -z "$NAMECHEAP_SOURCEIP" ]; then _err "No Source IP specified for Namecheap API." _err "Use your public ip address or an url to retrieve it (e.g. https://ipconfig.co/ip) and export it as NAMECHEAP_SOURCEIP" @@ -119,13 +118,13 @@ _namecheap_set_publicip() { else _saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP" _debug sourceip "$NAMECHEAP_SOURCEIP" - + ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*') - + _debug2 ip "$ip" _debug2 addr "$addr" - + if [ -n "$ip" ]; then _publicip="$ip" elif [ -n "$addr" ]; then @@ -136,16 +135,16 @@ _namecheap_set_publicip() { return 1 fi fi - + _debug publicip "$_publicip" - + return 0 } _namecheap_post() { command=$1 data="ApiUser=${NAMECHEAP_USERNAME}&ApiKey=${NAMECHEAP_API_KEY}&ClientIp=${_publicip}&UserName=${NAMECHEAP_USERNAME}&Command=${command}" - + response="$(_post "$data" "$NAMECHEAP_API" "" "POST")" _debug2 response "$response" @@ -158,7 +157,6 @@ _namecheap_post() { return 0 } - _namecheap_parse_host() { _host=$1 _debug _host "$_host" @@ -176,7 +174,6 @@ _namecheap_parse_host() { _debug hostaddress "$_hostaddress" _debug hostmxpref "$_hostmxpref" _debug hostttl "$_hostttl" - } _namecheap_check_config() { @@ -273,7 +270,7 @@ _del_namecheap_TXT() { _namecheap_parse_host "$host" if [ "$_hosttype" = "TXT" ] && [ "$_hostname" = "$subdomain" ] && [ "$_hostaddress" = "$txt" ]; then _debug "TXT entry found" - found=1 + found=1 else _namecheap_add_host "$_hostname" "$_hosttype" "$_hostaddress" "$_hostmxpref" "$_hostttl" fi From 80b40c02b453538191f66d6d44aefbf7aed4b850 Mon Sep 17 00:00:00 2001 From: Christian Brandel Date: Mon, 10 Sep 2018 01:24:20 +0200 Subject: [PATCH 59/59] use perl instead of iconv, if iconv is not available --- deploy/fritzbox.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/deploy/fritzbox.sh b/deploy/fritzbox.sh index 943b198..21ea6cf 100644 --- a/deploy/fritzbox.sh +++ b/deploy/fritzbox.sh @@ -28,8 +28,10 @@ fritzbox_deploy() { _debug _cfullchain "$_cfullchain" if ! _exists iconv; then - _err "iconv not found" - return 1 + if ! _exists perl; then + _err "iconv or perl not found" + return 1 + fi fi _fritzbox_username="${DEPLOY_FRITZBOX_USERNAME}" @@ -61,7 +63,11 @@ fritzbox_deploy() { _info "Log in to the FRITZ!Box" _fritzbox_challenge="$(_get "${_fritzbox_url}/login_sid.lua" | sed -e 's/^.*//' -e 's/<\/Challenge>.*$//')" - _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | md5sum | awk '{print $1}')" + if _exists iconv; then + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | md5sum | awk '{print $1}')" + else + _fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | perl -p -e 'use Encode qw/encode/; print encode("UTF-16LE","$_"); $_="";' | md5sum | awk '{print $1}')" + fi _fritzbox_sid="$(_get "${_fritzbox_url}/login_sid.lua?sid=0000000000000000&username=${_fritzbox_username}&response=${_fritzbox_challenge}-${_fritzbox_hash}" | sed -e 's/^.*//' -e 's/<\/SID>.*$//')" if [ -z "${_fritzbox_sid}" ] || [ "${_fritzbox_sid}" = "0000000000000000" ]; then