From d6d11a75e63e8bf2919c82f2501e81cf18a7f8fe Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sat, 5 Dec 2015 18:07:54 +0100 Subject: [PATCH 1/9] quote output filename Shouldn't be necessary for output from `mktemp`, but better play it safe. --- letsencrypt.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/letsencrypt.sh b/letsencrypt.sh index f1e314c..55ce63d 100755 --- a/letsencrypt.sh +++ b/letsencrypt.sh @@ -43,11 +43,11 @@ hex2bin() { _request() { temperr="$(mktemp)" if [ "${1}" = "head" ]; then - curl -sSf -I "${2}" 2>${temperr} + curl -sSf -I "${2}" 2>"${temperr}" elif [ "${1}" = "get" ]; then - curl -sSf "${2}" 2>${temperr} + curl -sSf "${2}" 2>"${temperr}" elif [ "${1}" = "post" ]; then - curl -sSf "${2}" -d "${3}" 2>${temperr} + curl -sSf "${2}" -d "${3}" 2>"${temperr}" fi if [ ! -z "$(<${temperr})" ]; then echo " + ERROR: An error occured while sending ${1}-request to ${2} ($(<"${temperr}"))" >&2; exit 1; fi rm -f "${temperr}" From 2f9c639c2b678a1d75dd14bd8de622d9ebbe46ed Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sat, 5 Dec 2015 18:14:32 +0100 Subject: [PATCH 2/9] simplify check for empty file --- letsencrypt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/letsencrypt.sh b/letsencrypt.sh index 55ce63d..38bd0b6 100755 --- a/letsencrypt.sh +++ b/letsencrypt.sh @@ -49,7 +49,7 @@ _request() { elif [ "${1}" = "post" ]; then curl -sSf "${2}" -d "${3}" 2>"${temperr}" fi - if [ ! -z "$(<${temperr})" ]; then echo " + ERROR: An error occured while sending ${1}-request to ${2} ($(<"${temperr}"))" >&2; exit 1; fi + if [ -s "${temperr}" ]; then echo " + ERROR: An error occured while sending ${1}-request to ${2} ($(<"${temperr}"))" >&2; exit 1; fi rm -f "${temperr}" } From 130ea6ab690220aa0ce8b115a1ea0c17735d1219 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sat, 5 Dec 2015 18:15:11 +0100 Subject: [PATCH 3/9] rewrap line No code changes. --- letsencrypt.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/letsencrypt.sh b/letsencrypt.sh index 38bd0b6..49ccd9f 100755 --- a/letsencrypt.sh +++ b/letsencrypt.sh @@ -49,7 +49,10 @@ _request() { elif [ "${1}" = "post" ]; then curl -sSf "${2}" -d "${3}" 2>"${temperr}" fi - if [ -s "${temperr}" ]; then echo " + ERROR: An error occured while sending ${1}-request to ${2} ($(<"${temperr}"))" >&2; exit 1; fi + if [ -s "${temperr}" ]; then + echo " + ERROR: An error occured while sending ${1}-request to ${2} ($(<"${temperr}"))" >&2 + exit 1 + fi rm -f "${temperr}" } From 730930a153691c18a189d80a7f481836e37e53e4 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sat, 5 Dec 2015 18:15:38 +0100 Subject: [PATCH 4/9] also remove tempfile for curl's stderr on error --- letsencrypt.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/letsencrypt.sh b/letsencrypt.sh index 49ccd9f..f995a49 100755 --- a/letsencrypt.sh +++ b/letsencrypt.sh @@ -51,6 +51,7 @@ _request() { fi if [ -s "${temperr}" ]; then echo " + ERROR: An error occured while sending ${1}-request to ${2} ($(<"${temperr}"))" >&2 + rm -f "${temperr}" exit 1 fi rm -f "${temperr}" From 1cd81e9f037f3e06f52a42584b87539f7570a367 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sat, 5 Dec 2015 18:17:33 +0100 Subject: [PATCH 5/9] fix typo in error string --- letsencrypt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/letsencrypt.sh b/letsencrypt.sh index f995a49..90174c9 100755 --- a/letsencrypt.sh +++ b/letsencrypt.sh @@ -50,7 +50,7 @@ _request() { curl -sSf "${2}" -d "${3}" 2>"${temperr}" fi if [ -s "${temperr}" ]; then - echo " + ERROR: An error occured while sending ${1}-request to ${2} ($(<"${temperr}"))" >&2 + echo " + ERROR: An error occurred while sending ${1}-request to ${2} ($(<"${temperr}"))" >&2 rm -f "${temperr}" exit 1 fi From f11bb1db6e049c0ceea77ef325fd71ca5569ace4 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sat, 5 Dec 2015 18:23:22 +0100 Subject: [PATCH 6/9] set CA setting per default letsencrypt.sh is mainly used with letsencrypt.org. --- config.sh.example | 4 +++- letsencrypt.sh | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/config.sh.example b/config.sh.example index 9ed0e42..63d9ebc 100644 --- a/config.sh.example +++ b/config.sh.example @@ -1,2 +1,4 @@ -CA="https://acme-v01.api.letsencrypt.org" +# default values are commented + +#CA="https://acme-v01.api.letsencrypt.org" WELLKNOWN="/var/www/letsencrypt/.well-known/acme-challenge" diff --git a/letsencrypt.sh b/letsencrypt.sh index 90174c9..17f5ab3 100755 --- a/letsencrypt.sh +++ b/letsencrypt.sh @@ -4,6 +4,9 @@ set -e set -u set -o pipefail +# default config values +CA="https://acme-v01.api.letsencrypt.org" + . ./config.sh umask 077 # paranoid umask, we're creating private keys From 00a0937c1f9bef32ccbfea5c87b0edeacfa525ca Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sat, 5 Dec 2015 18:25:02 +0100 Subject: [PATCH 7/9] make license agreement configurable as LICENSE --- letsencrypt.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/letsencrypt.sh b/letsencrypt.sh index 17f5ab3..cefdb00 100755 --- a/letsencrypt.sh +++ b/letsencrypt.sh @@ -6,6 +6,7 @@ set -o pipefail # default config values CA="https://acme-v01.api.letsencrypt.org" +LICENSE="https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf" . ./config.sh @@ -168,7 +169,7 @@ thumbprint="$(printf '%s' "$(printf '%s' '{"e":"'"${pubExponent64}"'","kty":"RSA # If we generated a new private key in the step above we have to register it with the acme-server if [ "${register}" = "1" ]; then echo "+ Registering account key with letsencrypt..." - signed_request "${CA}/acme/new-reg" '{"resource": "new-reg", "agreement": "https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf"}' > /dev/null + signed_request "${CA}/acme/new-reg" '{"resource": "new-reg", "agreement": "'"$LICENSE"'"}' > /dev/null fi # Generate certificates for all domains found in domain.txt (TODO: check if certificate already exists and is about to expire) From d211fece4a03d9fa0d46bf25a9e3133d7739d967 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sat, 5 Dec 2015 18:36:34 +0100 Subject: [PATCH 8/9] use mkdir -p to create certs/$domain/ Prevents an error if running for the first time in a different directory. --- certs/.keep | 0 letsencrypt.sh | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 certs/.keep diff --git a/certs/.keep b/certs/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/letsencrypt.sh b/letsencrypt.sh index cefdb00..82a0686 100755 --- a/letsencrypt.sh +++ b/letsencrypt.sh @@ -91,7 +91,7 @@ sign_domain() { # If there is no existing certificate directory we need a new private key if [ ! -e "certs/${domain}" ]; then - mkdir "certs/${domain}" + mkdir -p "certs/${domain}" echo " + Generating private key..." openssl genrsa -out "certs/${domain}/privkey.pem" 4096 2> /dev/null > /dev/null fi From b33f1288936dd118eba6d5627da6fee20d25c960 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sun, 6 Dec 2015 01:06:17 +0100 Subject: [PATCH 9/9] add HOOK_CHALLENGE option to run a command before the reponse --- config.sh.example | 5 +++++ letsencrypt.sh | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/config.sh.example b/config.sh.example index 63d9ebc..0cf6574 100644 --- a/config.sh.example +++ b/config.sh.example @@ -2,3 +2,8 @@ #CA="https://acme-v01.api.letsencrypt.org" WELLKNOWN="/var/www/letsencrypt/.well-known/acme-challenge" + +# program called before responding to the challenge, arguments: path/to/token +# token; can be used to e.g. upload the challenge if this script doesn't run +# on the webserver +#HOOK_CHALLENGE= diff --git a/letsencrypt.sh b/letsencrypt.sh index 82a0686..8297f42 100755 --- a/letsencrypt.sh +++ b/letsencrypt.sh @@ -7,6 +7,7 @@ set -o pipefail # default config values CA="https://acme-v01.api.letsencrypt.org" LICENSE="https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf" +HOOK_CHALLENGE= . ./config.sh @@ -126,6 +127,11 @@ sign_domain() { printf '%s' "${keyauth}" > "${WELLKNOWN}/${challenge_token}" chmod a+r "${WELLKNOWN}/${challenge_token}" + # Wait for hook script to deploy the challenge if used + if [ -n "${HOOK_CHALLENGE}" ]; then + ${HOOK_CHALLENGE} "${WELLKNOWN}/${challenge_token}" "${keyauth}" + fi + # Ask the acme-server to verify our challenge and wait until it becomes valid echo " + Responding to challenge for ${altname}..." result="$(signed_request "${challenge_uri}" '{"resource": "challenge", "keyAuthorization": "'"${keyauth}"'"}')"