From 1699e94f0ffdd056cd58891dd43a4386b2246471 Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 14:09:58 +0100 Subject: [PATCH 01/25] Adding kong deploy script (https://getkong.org) --- deploy/kong.sh | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 deploy/kong.sh diff --git a/deploy/kong.sh b/deploy/kong.sh new file mode 100644 index 0000000..cd9de10 --- /dev/null +++ b/deploy/kong.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env sh + +# This deploy hook will deploy ssl cert on kong proxy engine based on api request_host parameter. +# Note that ssl plugin should be available on Kong instance +# The hook will match cdomain to request_host, in case of multiple domain it will always take the first +# one (acme.sh behaviour). +# If ssl config already exist it will update only cert and key not touching other parameter +# If ssl config doesn't exist it will only upload cert and key and not set other parameter +# Not that we deploy full chain +# See https://getkong.org/plugins/dynamic-ssl/ for other options +# Written by Geoffroi Genot + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +kong.sh_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + _info "Deploying certificate on Kong instance" + if [ -z "$KONG_URL" ] + then + _debug "KONG_URL Not set, using default http://localhost:8001" + KONG_URL="http://localhost:8001" + fi + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + #Get uuid linked to the domain + uuid=$( _get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' ) + if [ "$uuid" = "" ] + then + _err "Unable to get Kong uuid for domain $_cdomain" + _err "Make sure that KONG_URL is correctly configured" + _err "Make sure that a Kong api request_host match the domain" + _err "Kong url: $KONG_URL" + return 1 + fi + #Save kong url if it's succesful (First run case) + _saveaccountconf KONG_URL "$KONG_URL" + #Generate DEIM + delim="-----MultipartDelimeter$(date "+%s%N")" + nl=$( printf "\\r\\n" ) + #Set Header + _H1="Content-Type: multipart/form-data; boundary=$delim" + #Generate data for request (Multipart/form-data with mixed content) + #set name to ssl + content="--$delim${nl}Content-Disposition: form-data; name=\"name\"${nl}${nl}ssl" + #add key + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"config.key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" + #Add cert + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"config.cert\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" + #Close multipart + content="$content${nl}--$delim--${nl}" + #DEBUG + _debug header "$_H1" + _debug content "$content" + #Check if ssl plugins is aready enabled (if not => POST else => PATCH) + ssl_uuid=$(_get $KONG_URL/apis/$uuid/plugins | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' ) + _debug ssl_uuid "$ssl_uuid" + if [ "$ssl_uuid" = "" ] + then + #Post certificate to Kong + response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST" ) + else + #patch + response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH" ) + fi + if ! [ "$( echo "$response" | _egrep_o "ssl" )" = "ssl" ] + then + _err "An error occured with cert upload. Check response:" + _err "$response" + return 1 + fi + _debug response "$response" + _info "Certificate successfully deployed" +} From 07feb87deeab89fe55af42a532b463f1e3cc3ae8 Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 14:52:52 +0100 Subject: [PATCH 02/25] Travis fix --- deploy/kong.sh | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/deploy/kong.sh b/deploy/kong.sh index cd9de10..0fa726a 100644 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -20,8 +20,7 @@ kong.sh_deploy() { _cca="$4" _cfullchain="$5" _info "Deploying certificate on Kong instance" - if [ -z "$KONG_URL" ] - then + if [ -z "$KONG_URL" ]; then _debug "KONG_URL Not set, using default http://localhost:8001" KONG_URL="http://localhost:8001" fi @@ -33,9 +32,8 @@ kong.sh_deploy() { _debug _cfullchain "$_cfullchain" #Get uuid linked to the domain - uuid=$( _get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' ) - if [ "$uuid" = "" ] - then + uuid=$( _get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') + if [ "$uuid" = "" ]; then _err "Unable to get Kong uuid for domain $_cdomain" _err "Make sure that KONG_URL is correctly configured" _err "Make sure that a Kong api request_host match the domain" @@ -46,7 +44,7 @@ kong.sh_deploy() { _saveaccountconf KONG_URL "$KONG_URL" #Generate DEIM delim="-----MultipartDelimeter$(date "+%s%N")" - nl=$( printf "\\r\\n" ) + nl=$(printf "\\r\\n") #Set Header _H1="Content-Type: multipart/form-data; boundary=$delim" #Generate data for request (Multipart/form-data with mixed content) @@ -62,18 +60,17 @@ kong.sh_deploy() { _debug header "$_H1" _debug content "$content" #Check if ssl plugins is aready enabled (if not => POST else => PATCH) - ssl_uuid=$(_get $KONG_URL/apis/$uuid/plugins | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' ) + ssl_uuid=$(_get "$KONG_URL/apis/$uuid/plugins" | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') _debug ssl_uuid "$ssl_uuid" if [ "$ssl_uuid" = "" ] then #Post certificate to Kong - response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST" ) + response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST") else #patch - response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH" ) + response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH") fi - if ! [ "$( echo "$response" | _egrep_o "ssl" )" = "ssl" ] - then + if ! [ "$( echo "$response" | _egrep_o "ssl" )" = "ssl" ]; then _err "An error occured with cert upload. Check response:" _err "$response" return 1 From e2cc350fbc90c18e5574361d15ce57f600eaa42c Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 14:54:52 +0100 Subject: [PATCH 03/25] Fix function name --- deploy/kong.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/kong.sh b/deploy/kong.sh index 0fa726a..86a1835 100644 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -13,7 +13,7 @@ ######## Public functions ##################### #domain keyfile certfile cafile fullchain -kong.sh_deploy() { +kong_deploy() { _cdomain="$1" _ckey="$2" _ccert="$3" From 753d0e7df77b9dcf261da4547c679fec49df0961 Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 15:05:26 +0100 Subject: [PATCH 04/25] Syntax fix part 2 --- deploy/kong.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/deploy/kong.sh b/deploy/kong.sh index 86a1835..2eab3d4 100644 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -21,8 +21,8 @@ kong_deploy() { _cfullchain="$5" _info "Deploying certificate on Kong instance" if [ -z "$KONG_URL" ]; then - _debug "KONG_URL Not set, using default http://localhost:8001" - KONG_URL="http://localhost:8001" + _debug "KONG_URL Not set, using default http://localhost:8001" + KONG_URL="http://localhost:8001" fi _debug _cdomain "$_cdomain" @@ -32,7 +32,7 @@ kong_deploy() { _debug _cfullchain "$_cfullchain" #Get uuid linked to the domain - uuid=$( _get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') + uuid=$(_get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') if [ "$uuid" = "" ]; then _err "Unable to get Kong uuid for domain $_cdomain" _err "Make sure that KONG_URL is correctly configured" @@ -62,15 +62,14 @@ kong_deploy() { #Check if ssl plugins is aready enabled (if not => POST else => PATCH) ssl_uuid=$(_get "$KONG_URL/apis/$uuid/plugins" | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') _debug ssl_uuid "$ssl_uuid" - if [ "$ssl_uuid" = "" ] - then + if [ "$ssl_uuid" = "" ]; then #Post certificate to Kong response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST") else #patch response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH") fi - if ! [ "$( echo "$response" | _egrep_o "ssl" )" = "ssl" ]; then + if ! [ "$(echo "$response" | _egrep_o "ssl")" = "ssl" ]; then _err "An error occured with cert upload. Check response:" _err "$response" return 1 From 5fe91d65770d84e6de633384f94fcdcd5a9e6039 Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 16:17:16 +0100 Subject: [PATCH 05/25] Correction of test from comment of Neilpang + Correction of CRLF with sh not working correctly --- deploy/kong.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/deploy/kong.sh b/deploy/kong.sh index 2eab3d4..3b9c5c7 100644 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -33,7 +33,7 @@ kong_deploy() { #Get uuid linked to the domain uuid=$(_get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') - if [ "$uuid" = "" ]; then + if [ -z "$uuid" ]; then _err "Unable to get Kong uuid for domain $_cdomain" _err "Make sure that KONG_URL is correctly configured" _err "Make sure that a Kong api request_host match the domain" @@ -44,7 +44,7 @@ kong_deploy() { _saveaccountconf KONG_URL "$KONG_URL" #Generate DEIM delim="-----MultipartDelimeter$(date "+%s%N")" - nl=$(printf "\\r\\n") + nl="\015\012" #Set Header _H1="Content-Type: multipart/form-data; boundary=$delim" #Generate data for request (Multipart/form-data with mixed content) @@ -56,13 +56,15 @@ kong_deploy() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"config.cert\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" #Close multipart content="$content${nl}--$delim--${nl}" + #Convert CRLF + content=$(printf %b "$content") #DEBUG _debug header "$_H1" _debug content "$content" #Check if ssl plugins is aready enabled (if not => POST else => PATCH) ssl_uuid=$(_get "$KONG_URL/apis/$uuid/plugins" | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') _debug ssl_uuid "$ssl_uuid" - if [ "$ssl_uuid" = "" ]; then + if [ -z "$ssl_uuid" ]; then #Post certificate to Kong response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST") else From 38f2334360301396cd2baa6dd3eb899fd01cb00a Mon Sep 17 00:00:00 2001 From: Philipp Grosswiler Date: Mon, 16 Jan 2017 15:42:17 +0700 Subject: [PATCH 06/25] Added support for Linode DNS API. --- README.md | 1 + dnsapi/README.md | 19 ++++++++++++++ dnsapi/dns_linode.sh | 60 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100755 dnsapi/dns_linode.sh diff --git a/README.md b/README.md index 9b5891c..ea0e0de 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,7 @@ You don't have to do anything manually! 1. aliyun.com(阿里云) API 1. ISPConfig 3.1 API 1. Alwaysdata.com API +1. Linode.com API **More APIs coming soon...** diff --git a/dnsapi/README.md b/dnsapi/README.md index e32b465..1895d37 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -257,6 +257,25 @@ acme.sh --issue --dns dns_ad -d example.com -d www.example.com The `AD_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 14. Use Linode domain API + +You will need to install the Linode CLI and set it up accordingly. + +[https://www.linode.com/docs/platform/linode-cli](https://www.linode.com/docs/platform/linode-cli) + +Follow the installation instructions appropriate for your platform and then run the configuration. + +```linode configure +``` + +Make sure Linode CLI is working correctly before proceeding. + +Due to the reload time of any changes in the DNS records, we have to use the `dnssleep` option to wait at least 15 minutes for the changes to take effect. + +```sh +acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.com +``` + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh new file mode 100755 index 0000000..0af1ad7 --- /dev/null +++ b/dnsapi/dns_linode.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +linode_cmd="/usr/bin/linode" + +######## Public functions ##################### + +#Usage: dns_linode_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_linode_add() { + fulldomain="${1}" + txtvalue="${2}" + + _info "Using Linode" + _debug "Calling: dns_linode_add() '${fulldomain}' '${txtvalue}'" + + domain=$(printf "%s" "${fulldomain}" | cut -d . -f 3-999) + name=$(printf "%s" "${fulldomain}" | cut -d . -f 1-2) + _debug name "${name}" + _debug domain "${domain}" + + _Linode_CLI && _Linode_addTXT +} + +#Usage: dns_linode_rm _acme-challenge.www.domain.com +dns_linode_rm() { + fulldomain="${1}" + + _info "Using Linode" + _debug "Calling: dns_linode_rm() '${fulldomain}'" + + domain=$(printf "%s" "${fulldomain}" | cut -d . -f 3-999) + name=$(printf "%s" "${fulldomain}" | cut -d . -f 1-2) + _debug name "${name}" + _debug domain "${domain}" + + _Linode_CLI && _Linode_rmTXT +} + +#################### Private functions below ################################## + +_Linode_CLI() { + if [ ! -f "${linode_cmd}" ]; then + _err "Please install the Linode CLI package and set it up accordingly before using this DNS API." + return 1 + fi +} + +_Linode_addTXT() { + _debug "$linode_cmd domain record-update ${domain} TXT ${name} --target ${txtvalue}" + $linode_cmd domain record-update ${domain} TXT ${name} --target ${txtvalue} + + if [ $? -ne 0 ]; then + _debug "$linode_cmd domain record-create ${domain} TXT ${name} ${txtvalue}" + $linode_cmd domain record-create ${domain} TXT ${name} ${txtvalue} + fi +} + +_Linode_rmTXT() { + _debug "$linode_cmd domain record-delete ${domain} TXT ${name}" + $linode_cmd domain record-delete ${domain} TXT ${name} +} From 11927a768eca90138dd123391d7a55cece468b85 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 29 Jan 2017 11:47:04 +0800 Subject: [PATCH 07/25] minor, rename --- acme.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index 7ec84e6..eb3164f 100755 --- a/acme.sh +++ b/acme.sh @@ -868,7 +868,7 @@ createCSR() { } -_urlencode() { +_url_replace() { tr '/+' '_-' | tr -d '= ' } @@ -935,7 +935,7 @@ _calcjwk() { modulus=$($OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2) _debug3 modulus "$modulus" - n="$(printf "%s" "$modulus" | _h2b | _base64 | _urlencode)" + n="$(printf "%s" "$modulus" | _h2b | _base64 | _url_replace)" _debug3 n "$n" jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' @@ -990,14 +990,14 @@ _calcjwk() { x="$(printf "%s" "$pubtext" | cut -d : -f 2-"$xend")" _debug3 x "$x" - x64="$(printf "%s" "$x" | tr -d : | _h2b | _base64 | _urlencode)" + x64="$(printf "%s" "$x" | tr -d : | _h2b | _base64 | _url_replace)" _debug3 x64 "$x64" xend=$(_math "$xend" + 1) y="$(printf "%s" "$pubtext" | cut -d : -f "$xend"-10000)" _debug3 y "$y" - y64="$(printf "%s" "$y" | tr -d : | _h2b | _base64 | _urlencode)" + y64="$(printf "%s" "$y" | tr -d : | _h2b | _base64 | _url_replace)" _debug3 y64 "$y64" jwk='{"crv": "'$crv'", "kty": "EC", "x": "'$x64'", "y": "'$y64'"}' @@ -1241,7 +1241,7 @@ _send_signed_request() { return 1 fi - payload64=$(printf "%s" "$payload" | _base64 | _urlencode) + payload64=$(printf "%s" "$payload" | _base64 | _url_replace) _debug3 payload64 "$payload64" if [ -z "$_CACHED_NONCE" ]; then @@ -1267,7 +1267,7 @@ _send_signed_request() { protected="$JWK_HEADERPLACE_PART1$nonce$JWK_HEADERPLACE_PART2" _debug3 protected "$protected" - protected64="$(printf "%s" "$protected" | _base64 | _urlencode)" + protected64="$(printf "%s" "$protected" | _base64 | _url_replace)" _debug3 protected64 "$protected64" if ! _sig_t="$(printf "%s" "$protected64.$payload64" | _sign "$keyfile" "sha256")"; then @@ -1276,7 +1276,7 @@ _send_signed_request() { fi _debug3 _sig_t "$_sig_t" - sig="$(printf "%s" "$_sig_t" | _urlencode)" + sig="$(printf "%s" "$_sig_t" | _url_replace)" _debug3 sig "$sig" body="{\"header\": $JWK_HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" @@ -2005,7 +2005,7 @@ _clearupdns() { keyauthorization=$(echo "$ventry" | cut -d "$sep" -f 2) vtype=$(echo "$ventry" | cut -d "$sep" -f 4) _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5) - txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _urlencode)" + txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" _debug txt "$txt" if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then _info "$d is already verified, skip $vtype." @@ -2549,7 +2549,7 @@ issue() { if [ -z "$thumbprint" ]; then accountkey_json=$(printf "%s" "$jwk" | tr -d ' ') - thumbprint=$(printf "%s" "$accountkey_json" | _digest "sha256" | _urlencode) + thumbprint=$(printf "%s" "$accountkey_json" | _digest "sha256" | _url_replace) fi entry="$(printf "%s\n" "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" @@ -2600,7 +2600,7 @@ issue() { dnsadded='0' txtdomain="_acme-challenge.$d" _debug txtdomain "$txtdomain" - txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _urlencode)" + txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" _debug txt "$txt" d_api="$(_findHook "$d" dnsapi "$_currentRoot")" @@ -2875,7 +2875,7 @@ issue() { _clearup _info "Verify finished, start to sign." - der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _urlencode)" + der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" if ! _send_signed_request "$API/acme/new-cert" "{\"resource\": \"new-cert\", \"csr\": \"$der\"}" "needbase64"; then _err "Sign failed." @@ -3453,7 +3453,7 @@ revoke() { return 1 fi - cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _urlencode)" + cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _url_replace)" if [ -z "$cert" ]; then _err "Cert for $Le_Domain is empty found, skip." From 542d7977db1479f9383561ae1657dcfb2ecfcb2c Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 30 Jan 2017 12:07:50 +0800 Subject: [PATCH 08/25] add new _url_encode --- acme.sh | 248 ++++++++++++++++++++++++++++++++++++++++++++-- dnsapi/dns_ali.sh | 2 +- dnsapi/dns_aws.sh | 2 +- dnsapi/dns_me.sh | 2 +- 4 files changed, 242 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index eb3164f..22d4935 100755 --- a/acme.sh +++ b/acme.sh @@ -336,15 +336,245 @@ _h2b() { done } -#hex string -_hex() { - _str="$1" - _str_len=${#_str} - _h_i=1 - while [ "$_h_i" -le "$_str_len" ]; do - _str_c="$(printf "%s" "$_str" | cut -c "$_h_i")" - printf "%02x" "'$_str_c" - _h_i="$(_math "$_h_i" + 1)" +_is_solaris() { + _contains "${__OS__:=$(uname -a)}" "solaris" || _contains "${__OS__:=$(uname -a)}" "SunOS" +} + +#stdin output hexstr splited by one space +#input:"abc" +#output: " 61 62 63" +_hex_dump() { + if _is_solaris; then + od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | tr -d "\n" + else + od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | sed "s/ $//" | tr -d "\n" + fi +} + +#url encode, no-preserved chars +#A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +#41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a + +#a b c d e f g h i j k l m n o p q r s t u v w x y z +#61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a + +#0 1 2 3 4 5 6 7 8 9 - _ . ~ +#30 31 32 33 34 35 36 37 38 39 2d 5f 2e 7e + +#stdin stdout +_url_encode() { + _hex_str=$(_hex_dump) + _debug3 "_url_encode" + _debug3 "_hex_str" "$_hex_str" + for _hex_code in $_hex_str; do + #upper case + case "${_hex_code}" in + "41" ) + printf "%s" "A" + ;; + "42" ) + printf "%s" "B" + ;; + "43" ) + printf "%s" "C" + ;; + "44" ) + printf "%s" "D" + ;; + "45" ) + printf "%s" "E" + ;; + "46" ) + printf "%s" "F" + ;; + "47" ) + printf "%s" "G" + ;; + "48" ) + printf "%s" "H" + ;; + "49" ) + printf "%s" "I" + ;; + "4a" ) + printf "%s" "J" + ;; + "4b" ) + printf "%s" "K" + ;; + "4c" ) + printf "%s" "L" + ;; + "4d" ) + printf "%s" "M" + ;; + "4e" ) + printf "%s" "N" + ;; + "4f" ) + printf "%s" "O" + ;; + "50" ) + printf "%s" "P" + ;; + "51" ) + printf "%s" "Q" + ;; + "52" ) + printf "%s" "R" + ;; + "53" ) + printf "%s" "S" + ;; + "54" ) + printf "%s" "T" + ;; + "55" ) + printf "%s" "U" + ;; + "56" ) + printf "%s" "V" + ;; + "57" ) + printf "%s" "W" + ;; + "58" ) + printf "%s" "X" + ;; + "59" ) + printf "%s" "Y" + ;; + "5a" ) + printf "%s" "Z" + ;; + + #lower case + "61" ) + printf "%s" "a" + ;; + "62" ) + printf "%s" "b" + ;; + "63" ) + printf "%s" "c" + ;; + "64" ) + printf "%s" "d" + ;; + "65" ) + printf "%s" "e" + ;; + "66" ) + printf "%s" "f" + ;; + "67" ) + printf "%s" "g" + ;; + "68" ) + printf "%s" "h" + ;; + "69" ) + printf "%s" "i" + ;; + "6a" ) + printf "%s" "j" + ;; + "6b" ) + printf "%s" "k" + ;; + "6c" ) + printf "%s" "l" + ;; + "6d" ) + printf "%s" "m" + ;; + "6e" ) + printf "%s" "n" + ;; + "6f" ) + printf "%s" "o" + ;; + "70" ) + printf "%s" "p" + ;; + "71" ) + printf "%s" "q" + ;; + "72" ) + printf "%s" "r" + ;; + "73" ) + printf "%s" "s" + ;; + "74" ) + printf "%s" "t" + ;; + "75" ) + printf "%s" "u" + ;; + "76" ) + printf "%s" "v" + ;; + "77" ) + printf "%s" "w" + ;; + "78" ) + printf "%s" "x" + ;; + "79" ) + printf "%s" "y" + ;; + "7a" ) + printf "%s" "z" + ;; + #numbers + "30" ) + printf "%s" "0" + ;; + "31" ) + printf "%s" "1" + ;; + "32" ) + printf "%s" "2" + ;; + "33" ) + printf "%s" "3" + ;; + "34" ) + printf "%s" "4" + ;; + "35" ) + printf "%s" "5" + ;; + "36" ) + printf "%s" "6" + ;; + "37" ) + printf "%s" "7" + ;; + "38" ) + printf "%s" "8" + ;; + "39" ) + printf "%s" "9" + ;; + "2d" ) + printf "%s" "-" + ;; + "5f" ) + printf "%s" "_" + ;; + "2e" ) + printf "%s" "." + ;; + "7e" ) + printf "%s" "~" + ;; + #other hex + *) + printf '%%%s' "$_hex_code" + ;; + esac done } diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 98c56f8..9b6f85c 100644 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -67,7 +67,7 @@ _get_root() { } _ali_rest() { - signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(_hex "$Ali_Secret&")" | _base64) + signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | sed "s/ //g")" | _base64) signature=$(_ali_urlencode "$signature") url="$Ali_API?$query&Signature=$signature" diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 59ef618..5e7b34f 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -183,7 +183,7 @@ aws_rest() { _debug2 kSecret "$kSecret" - kSecretH="$(_hex "$kSecret")" + kSecretH="$(printf "%s" "$kSecret" | _hex_dump | sed "s/ //g")" _debug2 kSecretH "$kSecretH" kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 9fe6baf..c6bec70 100755 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -124,7 +124,7 @@ _me_rest() { _debug "$ep" cdate=$(date -u +"%a, %d %b %Y %T %Z") - hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(_hex "$ME_Secret")" hex) + hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(printf "%s" "$ME_Secret" | _hex_dump | sed "s/ //g")" hex) export _H1="x-dnsme-apiKey: $ME_Key" export _H2="x-dnsme-requestDate: $cdate" From c3b1eb0837cd5585709d32f8b337158d18bc38eb Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 30 Jan 2017 12:25:56 +0800 Subject: [PATCH 09/25] fix format --- acme.sh | 406 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 203 insertions(+), 203 deletions(-) diff --git a/acme.sh b/acme.sh index 22d4935..cf82153 100755 --- a/acme.sh +++ b/acme.sh @@ -369,211 +369,211 @@ _url_encode() { for _hex_code in $_hex_str; do #upper case case "${_hex_code}" in - "41" ) - printf "%s" "A" - ;; - "42" ) - printf "%s" "B" - ;; - "43" ) - printf "%s" "C" - ;; - "44" ) - printf "%s" "D" - ;; - "45" ) - printf "%s" "E" - ;; - "46" ) - printf "%s" "F" - ;; - "47" ) - printf "%s" "G" - ;; - "48" ) - printf "%s" "H" - ;; - "49" ) - printf "%s" "I" - ;; - "4a" ) - printf "%s" "J" - ;; - "4b" ) - printf "%s" "K" - ;; - "4c" ) - printf "%s" "L" - ;; - "4d" ) - printf "%s" "M" - ;; - "4e" ) - printf "%s" "N" - ;; - "4f" ) - printf "%s" "O" - ;; - "50" ) - printf "%s" "P" - ;; - "51" ) - printf "%s" "Q" - ;; - "52" ) - printf "%s" "R" - ;; - "53" ) - printf "%s" "S" - ;; - "54" ) - printf "%s" "T" - ;; - "55" ) - printf "%s" "U" - ;; - "56" ) - printf "%s" "V" - ;; - "57" ) - printf "%s" "W" - ;; - "58" ) - printf "%s" "X" - ;; - "59" ) - printf "%s" "Y" - ;; - "5a" ) - printf "%s" "Z" - ;; + "41") + printf "%s" "A" + ;; + "42") + printf "%s" "B" + ;; + "43") + printf "%s" "C" + ;; + "44") + printf "%s" "D" + ;; + "45") + printf "%s" "E" + ;; + "46") + printf "%s" "F" + ;; + "47") + printf "%s" "G" + ;; + "48") + printf "%s" "H" + ;; + "49") + printf "%s" "I" + ;; + "4a") + printf "%s" "J" + ;; + "4b") + printf "%s" "K" + ;; + "4c") + printf "%s" "L" + ;; + "4d") + printf "%s" "M" + ;; + "4e") + printf "%s" "N" + ;; + "4f") + printf "%s" "O" + ;; + "50") + printf "%s" "P" + ;; + "51") + printf "%s" "Q" + ;; + "52") + printf "%s" "R" + ;; + "53") + printf "%s" "S" + ;; + "54") + printf "%s" "T" + ;; + "55") + printf "%s" "U" + ;; + "56") + printf "%s" "V" + ;; + "57") + printf "%s" "W" + ;; + "58") + printf "%s" "X" + ;; + "59") + printf "%s" "Y" + ;; + "5a") + printf "%s" "Z" + ;; - #lower case - "61" ) - printf "%s" "a" - ;; - "62" ) - printf "%s" "b" - ;; - "63" ) - printf "%s" "c" - ;; - "64" ) - printf "%s" "d" - ;; - "65" ) - printf "%s" "e" - ;; - "66" ) - printf "%s" "f" - ;; - "67" ) - printf "%s" "g" - ;; - "68" ) - printf "%s" "h" - ;; - "69" ) - printf "%s" "i" - ;; - "6a" ) - printf "%s" "j" - ;; - "6b" ) - printf "%s" "k" - ;; - "6c" ) - printf "%s" "l" - ;; - "6d" ) - printf "%s" "m" - ;; - "6e" ) - printf "%s" "n" - ;; - "6f" ) - printf "%s" "o" - ;; - "70" ) - printf "%s" "p" - ;; - "71" ) - printf "%s" "q" - ;; - "72" ) - printf "%s" "r" - ;; - "73" ) - printf "%s" "s" - ;; - "74" ) - printf "%s" "t" - ;; - "75" ) - printf "%s" "u" - ;; - "76" ) - printf "%s" "v" - ;; - "77" ) - printf "%s" "w" - ;; - "78" ) - printf "%s" "x" - ;; - "79" ) - printf "%s" "y" - ;; - "7a" ) - printf "%s" "z" - ;; - #numbers - "30" ) - printf "%s" "0" - ;; - "31" ) - printf "%s" "1" - ;; - "32" ) - printf "%s" "2" - ;; - "33" ) - printf "%s" "3" - ;; - "34" ) - printf "%s" "4" - ;; - "35" ) - printf "%s" "5" - ;; - "36" ) - printf "%s" "6" - ;; - "37" ) - printf "%s" "7" - ;; - "38" ) - printf "%s" "8" - ;; - "39" ) - printf "%s" "9" - ;; - "2d" ) - printf "%s" "-" - ;; - "5f" ) - printf "%s" "_" - ;; - "2e" ) - printf "%s" "." - ;; - "7e" ) - printf "%s" "~" - ;; - #other hex + #lower case + "61") + printf "%s" "a" + ;; + "62") + printf "%s" "b" + ;; + "63") + printf "%s" "c" + ;; + "64") + printf "%s" "d" + ;; + "65") + printf "%s" "e" + ;; + "66") + printf "%s" "f" + ;; + "67") + printf "%s" "g" + ;; + "68") + printf "%s" "h" + ;; + "69") + printf "%s" "i" + ;; + "6a") + printf "%s" "j" + ;; + "6b") + printf "%s" "k" + ;; + "6c") + printf "%s" "l" + ;; + "6d") + printf "%s" "m" + ;; + "6e") + printf "%s" "n" + ;; + "6f") + printf "%s" "o" + ;; + "70") + printf "%s" "p" + ;; + "71") + printf "%s" "q" + ;; + "72") + printf "%s" "r" + ;; + "73") + printf "%s" "s" + ;; + "74") + printf "%s" "t" + ;; + "75") + printf "%s" "u" + ;; + "76") + printf "%s" "v" + ;; + "77") + printf "%s" "w" + ;; + "78") + printf "%s" "x" + ;; + "79") + printf "%s" "y" + ;; + "7a") + printf "%s" "z" + ;; + #numbers + "30") + printf "%s" "0" + ;; + "31") + printf "%s" "1" + ;; + "32") + printf "%s" "2" + ;; + "33") + printf "%s" "3" + ;; + "34") + printf "%s" "4" + ;; + "35") + printf "%s" "5" + ;; + "36") + printf "%s" "6" + ;; + "37") + printf "%s" "7" + ;; + "38") + printf "%s" "8" + ;; + "39") + printf "%s" "9" + ;; + "2d") + printf "%s" "-" + ;; + "5f") + printf "%s" "_" + ;; + "2e") + printf "%s" "." + ;; + "7e") + printf "%s" "~" + ;; + #other hex *) - printf '%%%s' "$_hex_code" - ;; + printf '%%%s' "$_hex_code" + ;; esac done } From 0899803294d2bbebda8e098b5022d3fd808049bb Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 30 Jan 2017 14:29:40 +0800 Subject: [PATCH 10/25] add my twitter --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9b5891c..7b9d002 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ It's probably the `easiest&smallest&smartest` shell script to automatically issu Wiki: https://github.com/Neilpang/acme.sh/wiki +Twitter: [@neilpangxa](https://twitter.com/neilpangxa) + + # [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E) From 59182dbc97dbbf017441a46c53f6dcac837431e6 Mon Sep 17 00:00:00 2001 From: Philipp Grosswiler Date: Tue, 31 Jan 2017 10:43:30 +0700 Subject: [PATCH 11/25] Removed Linode CLI dependency. --- dnsapi/dns_linode.sh | 176 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 152 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index 0af1ad7..e1c3220 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -1,6 +1,13 @@ #!/usr/bin/env bash -linode_cmd="/usr/bin/linode" +#Author: Philipp Grosswiler + +#How to create the Linode API key: +#Sign into your Linode account and go to this page: https://manager.linode.com/profile/api +#Then add an API key with label ACME and copy the new key. +#export LINODE_API_KEY="..." + +LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action=" ######## Public functions ##################### @@ -9,52 +16,173 @@ dns_linode_add() { fulldomain="${1}" txtvalue="${2}" + if ! _Linode_API; then + return 1 + fi + _info "Using Linode" _debug "Calling: dns_linode_add() '${fulldomain}' '${txtvalue}'" - domain=$(printf "%s" "${fulldomain}" | cut -d . -f 3-999) - name=$(printf "%s" "${fulldomain}" | cut -d . -f 1-2) - _debug name "${name}" - _debug domain "${domain}" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Domain does not exist." + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _parameters="&DomainID=$_domain_id&Type=TXT&Name=$_sub_domain&Target=$txtvalue" + + if _rest GET "domain.resource.create" "$_parameters" && [ -n "$response" ]; then + _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + _debug _resource_id "$_resource_id" + + if [ -z "$_resource_id" ]; then + _err "Error adding the domain resource." + return 1 + fi - _Linode_CLI && _Linode_addTXT + _info "Domain resource successfully added." + return 0 + fi + + return 1 } #Usage: dns_linode_rm _acme-challenge.www.domain.com dns_linode_rm() { fulldomain="${1}" + if ! _Linode_API; then + return 1 + fi + _info "Using Linode" _debug "Calling: dns_linode_rm() '${fulldomain}'" - domain=$(printf "%s" "${fulldomain}" | cut -d . -f 3-999) - name=$(printf "%s" "${fulldomain}" | cut -d . -f 1-2) - _debug name "${name}" - _debug domain "${domain}" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Domain does not exist." + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _parameters="&DomainID=$_domain_id" + + if _rest GET "domain.resource.list" "$_parameters" && [ -n "$response" ]; then + response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" + + resource="$(echo "$response" | _egrep_o "{.*\"NAME\":\s*\"$_sub_domain\".*}")" + if [ "$resource" ]; then + _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"RESOURCEID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + if [ "$_resource_id" ]; then + _debug _resource_id "$_resource_id" - _Linode_CLI && _Linode_rmTXT + _parameters="&DomainID=$_domain_id&ResourceID=$_resource_id" + + if _rest GET "domain.resource.delete" "$_parameters" && [ -n "$response" ]; then + _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + _debug _resource_id "$_resource_id" + + if [ -z "$_resource_id" ]; then + _err "Error deleting the domain resource." + return 1 + fi + + _info "Domain resource successfully deleted." + return 0 + fi + fi + + return 1 + fi + + return 0 + fi + + return 1 } #################### Private functions below ################################## -_Linode_CLI() { - if [ ! -f "${linode_cmd}" ]; then - _err "Please install the Linode CLI package and set it up accordingly before using this DNS API." +_Linode_API() { + if [ -z "$LINODE_API_KEY" ]; then + LINODE_API_KEY="" + + _err "You didn't specify the Linode API key yet." + _err "Please create your key and try again." + return 1 fi + + _saveaccountconf LINODE_API_KEY "$LINODE_API_KEY" } -_Linode_addTXT() { - _debug "$linode_cmd domain record-update ${domain} TXT ${name} --target ${txtvalue}" - $linode_cmd domain record-update ${domain} TXT ${name} --target ${txtvalue} +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=12345 +_get_root() { + domain=$1 + i=2 + p=1 + + if _rest GET "domain.list"; then + response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" + 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 [ $? -ne 0 ]; then - _debug "$linode_cmd domain record-create ${domain} TXT ${name} ${txtvalue}" - $linode_cmd domain record-create ${domain} TXT ${name} ${txtvalue} + hostedzone="$(echo "$response" | _egrep_o "{.*\"DOMAIN\":\s*\"$h\".*}")" + if [ "$hostedzone" ]; then + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"DOMAINID\":\s*[0-9]+" | _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 fi + return 1 } -_Linode_rmTXT() { - _debug "$linode_cmd domain record-delete ${domain} TXT ${name}" - $linode_cmd domain record-delete ${domain} TXT ${name} -} +#method method action data +_rest() { + mtd="$1" + ep="$2" + data="$3" + + _debug mtd "$mtd" + _debug ep "$ep" + + export _H1="Accept: application/json" + export _H2="Content-Type: application/json" + + if [ "$mtd" != "GET" ]; then + # both POST and DELETE. + _debug data "$data" + response="$(_post "$data" "$LINODE_API_URL$ep" "" "$mtd")" + else + response="$(_get "$LINODE_API_URL$ep$data")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} \ No newline at end of file From dd17ac5045a8dc7832d90644271937f4550e793e Mon Sep 17 00:00:00 2001 From: Philipp Grosswiler Date: Tue, 31 Jan 2017 10:56:34 +0700 Subject: [PATCH 12/25] Added instructions on how to get the Linode API key. --- dnsapi/README.md | 16 +++++++++------- dnsapi/dns_linode.sh | 7 +------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 1895d37..df728ac 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -259,23 +259,25 @@ when needed. ## 14. Use Linode domain API -You will need to install the Linode CLI and set it up accordingly. +First you need to login to your Linode account to get your API Key. +[https://manager.linode.com/profile/api](https://manager.linode.com/profile/api) -[https://www.linode.com/docs/platform/linode-cli](https://www.linode.com/docs/platform/linode-cli) +Then add an API key with label *ACME* and copy the new key. -Follow the installation instructions appropriate for your platform and then run the configuration. - -```linode configure +```sh +export LINODE_API_KEY="..." ``` -Make sure Linode CLI is working correctly before proceeding. - Due to the reload time of any changes in the DNS records, we have to use the `dnssleep` option to wait at least 15 minutes for the changes to take effect. +Ok, let's issue a cert now: + ```sh acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.com ``` +The `LINODE_API_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. diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index e1c3220..501a51a 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -1,12 +1,7 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh #Author: Philipp Grosswiler -#How to create the Linode API key: -#Sign into your Linode account and go to this page: https://manager.linode.com/profile/api -#Then add an API key with label ACME and copy the new key. -#export LINODE_API_KEY="..." - LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action=" ######## Public functions ##################### From bcf96608d123d2cfd0f810b0c1138e0f37a4efea Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 12:38:37 +0800 Subject: [PATCH 13/25] fix for solaris --- dnsapi/dns_cx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index 9c032fd..fa821f7 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -155,7 +155,7 @@ _get_root() { fi if _contains "$response" "$h."; then - seg=$(printf "%s\n" "$response" | _egrep_o '[^{]*"'"$h"'."[^}]*}') + seg=$(printf "%s\n" "$response" | _egrep_o '"id":[^{]*"'"$h"'."[^}]*}') _debug seg "$seg" _domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" From 646c0bfcb9290a98a8b835897114860e14376560 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 12:51:59 +0800 Subject: [PATCH 14/25] fix for solaris --- dnsapi/dns_cx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index fa821f7..2b6d569 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -82,7 +82,7 @@ existing_records() { return 1 fi - seg=$(printf "%s\n" "$response" | _egrep_o '[^{]*host":"'"$_sub_domain"'"[^}]*\}') + seg=$(printf "%s\n" "$response" | _egrep_o '"record_id":[^{]*host":"'"$_sub_domain"'"[^}]*\}') _debug seg "$seg" if [ -z "$seg" ]; then return 0 From 1c22c2f76a0a7c0b3c03c40aaba0d0c6fd7723f3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 14:04:40 +0800 Subject: [PATCH 15/25] fix for solaris --- dnsapi/dns_ali.sh | 2 +- dnsapi/dns_aws.sh | 2 +- dnsapi/dns_me.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 9b6f85c..f796f07 100644 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -67,7 +67,7 @@ _get_root() { } _ali_rest() { - signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | sed "s/ //g")" | _base64) + signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64) signature=$(_ali_urlencode "$signature") url="$Ali_API?$query&Signature=$signature" diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 5e7b34f..1308c50 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -183,7 +183,7 @@ aws_rest() { _debug2 kSecret "$kSecret" - kSecretH="$(printf "%s" "$kSecret" | _hex_dump | sed "s/ //g")" + kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")" _debug2 kSecretH "$kSecretH" kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index c6bec70..f63621d 100755 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -124,7 +124,7 @@ _me_rest() { _debug "$ep" cdate=$(date -u +"%a, %d %b %Y %T %Z") - hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(printf "%s" "$ME_Secret" | _hex_dump | sed "s/ //g")" hex) + hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(printf "%s" "$ME_Secret" | _hex_dump | tr -d " ")" hex) export _H1="x-dnsme-apiKey: $ME_Key" export _H2="x-dnsme-requestDate: $cdate" From c070407ab2dfd784f57188a2a34322aed020fc1b Mon Sep 17 00:00:00 2001 From: Philipp Grosswiler Date: Tue, 31 Jan 2017 13:38:16 +0700 Subject: [PATCH 16/25] Fixed Travis CI complaining about missing newline at end of file. --- dnsapi/dns_linode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index 501a51a..6d54e6c 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -180,4 +180,4 @@ _rest() { fi _debug2 response "$response" return 0 -} \ No newline at end of file +} From bb6326f4d423b9fe6b6677ffb058711724376fcb Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 15:57:43 +0800 Subject: [PATCH 17/25] fix for solaris --- dnsapi/dns_aws.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 1308c50..555bd70 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -93,7 +93,7 @@ _get_root() { fi if _contains "$response" "$h."; then - hostedzone="$(echo "$response" | sed 's//\n&/g' | _egrep_o ".*?$h.<.Name>.*?<.HostedZone>")" + hostedzone="$(echo "$response" | _egrep_o "[^<]*<.Id>$h.<.Name>.*<.HostedZone>")" _debug hostedzone "$hostedzone" if [ -z "$hostedzone" ]; then _err "Error, can not get hostedzone." From 5d833336d33ca82eb3f1634d83e21b8d805bf88b Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 18:41:32 +0800 Subject: [PATCH 18/25] minor --- dnsapi/dns_lua.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 47f4497..9506929 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -46,12 +46,12 @@ dns_lua_add() { return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l) + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l | tr -s " ") _debug count "$count" if [ "$count" = "0" ]; then _info "Adding record" if _LUA_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"ttl\":120}"; then - if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then + if _contains "$response" "$fulldomain"; then _info "Added" #todo: check if the record takes effect return 0 @@ -99,6 +99,7 @@ _get_root() { fi while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" if [ -z "$h" ]; then #not valid return 1 @@ -106,6 +107,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\""; then _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$h\"" | cut -d : -f 2 | cut -d , -f 1) + _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" From 05cf405cb53a2ea1bc55d29535beefaffd8dbe97 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 18:46:24 +0800 Subject: [PATCH 19/25] minor --- dnsapi/dns_lua.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 9506929..be77b9d 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -46,7 +46,7 @@ dns_lua_add() { return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l | tr -s " ") + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l | tr -d " ") _debug count "$count" if [ "$count" = "0" ]; then _info "Adding record" From 53fa16d39f314a43e60b47c923cd5d854742e539 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 18:59:00 +0800 Subject: [PATCH 20/25] minor --- dnsapi/dns_lua.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index be77b9d..211dbb0 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -46,7 +46,7 @@ dns_lua_add() { return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l | tr -d " ") + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | wc -l | tr -d " ") _debug count "$count" if [ "$count" = "0" ]; then _info "Adding record" From ab5c1b0a3a6843954ee959c4700f8e422c5b8002 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 19:03:29 +0800 Subject: [PATCH 21/25] minor --- dnsapi/dns_lua.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 211dbb0..0dd97fc 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -63,7 +63,7 @@ dns_lua_add() { _err "Add txt record error." else _info "Updating record" - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | cut -d: -f2 | cut -d, -f1) + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | _head_n 1 | cut -d: -f2 | cut -d, -f1) _debug "record_id" "$record_id" _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"ttl\":120}" From d78ba322bfbbaf93659c8b905b50431b3a7d14f4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 19:22:14 +0800 Subject: [PATCH 22/25] fix update --- dnsapi/dns_lua.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 0dd97fc..42d55e8 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -66,8 +66,8 @@ dns_lua_add() { record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | _head_n 1 | cut -d: -f2 | cut -d, -f1) _debug "record_id" "$record_id" - _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"ttl\":120}" - if [ "$?" = "0" ]; then + _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":$record_id,\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":$_domain_id,\"ttl\":120}" + if [ "$?" = "0" ] && _contains "$response" "updated_at" ; then _info "Updated!" #todo: check if the record takes effect return 0 From 5f8daeeb6d987687ac896c128c327c2096b02009 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 20:03:41 +0800 Subject: [PATCH 23/25] minor, a better hex_dump --- acme.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index cf82153..e5728b3 100755 --- a/acme.sh +++ b/acme.sh @@ -344,11 +344,7 @@ _is_solaris() { #input:"abc" #output: " 61 62 63" _hex_dump() { - if _is_solaris; then - od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | tr -d "\n" - else - od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | sed "s/ $//" | tr -d "\n" - fi + od -A n -v -t x1 | tr -d "\r\t" | tr -s " " | sed "s/ $//" | tr -d "\n" } #url encode, no-preserved chars From 1476a9ecf144b3c5a033adc533b429fe1365e9a7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 1 Feb 2017 16:12:43 +0800 Subject: [PATCH 24/25] fix format --- dnsapi/dns_lua.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 42d55e8..828e801 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -67,7 +67,7 @@ dns_lua_add() { _debug "record_id" "$record_id" _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":$record_id,\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":$_domain_id,\"ttl\":120}" - if [ "$?" = "0" ] && _contains "$response" "updated_at" ; then + if [ "$?" = "0" ] && _contains "$response" "updated_at"; then _info "Updated!" #todo: check if the record takes effect return 0 From 70b63a5ed442efe28587b8107c216db9e2965f70 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 1 Feb 2017 23:18:37 +0800 Subject: [PATCH 25/25] Create README.md --- deploy/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 deploy/README.md diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..580eaac --- /dev/null +++ b/deploy/README.md @@ -0,0 +1 @@ +#Using deploy api