]> git.street.me.uk Git - andy/dehydrated.git/commitdiff
initial support for configuration on per-certificate base (#105)
authorLukas Schauer <lukas@schauer.so>
Thu, 26 May 2016 15:09:07 +0000 (17:09 +0200)
committerLukas Schauer <lukas@schauer.so>
Thu, 26 May 2016 15:11:42 +0000 (17:11 +0200)
CHANGELOG
docs/per-certificate-config.md [new file with mode: 0644]
letsencrypt.sh

index c752901dca587f4c8ff141d00019cc0dee3c2a3f..4bde97192cdb29d6e46d824cc935c19ce37ddafe 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,7 @@ This file contains a log of major changes in letsencrypt.sh
 
 ## Added
 - Added option to add CSR-flag indicating OCSP stapling to be mandatory
+- Initial support for configuration on per-certificate base
 
 ## [0.2.0] - 2016-05-22
 ### Changed
diff --git a/docs/per-certificate-config.md b/docs/per-certificate-config.md
new file mode 100644 (file)
index 0000000..4862a4e
--- /dev/null
@@ -0,0 +1,18 @@
+# Config on per-certificate base
+
+letsencrypt.sh allows a few configuration variables to be set on a per-certificate base.
+
+To use this feature create a `config` file in the certificates output directory (e.g. `certs/example.org/config`).
+
+Currently supported options:
+
+- PRIVATE_KEY_RENEW
+- KEY_ALGO
+- KEYSIZE
+- OCSP_MUST_STAPLE
+- CHALLENGETYPE
+- HOOK
+- HOOK_CHAIN
+- WELLKNOWN
+- OPENSSL_CNF
+- RENEW_DAYS
index 9529c80c2ef4b179e5d64fb622024cb556d28324..6c595ead91c797201bc878a4516bb03f0d76975d 100755 (executable)
@@ -35,6 +35,7 @@ check_dependencies() {
   _sed "" < /dev/null > /dev/null 2>&1 || _exiterr "This script requires sed with support for extended (modern) regular expressions."
   command -v grep > /dev/null 2>&1 || _exiterr "This script requires grep."
   _mktemp -u > /dev/null 2>&1 || _exiterr "This script requires mktemp."
+  diff -v > /dev/null || _exiterr "This script requires diff."
 
   # curl returns with an error code in some ancient versions so we have to catch that
   set +e
@@ -46,6 +47,44 @@ check_dependencies() {
   fi
 }
 
+store_configvars() {
+  __KEY_ALGO="${KEY_ALGO}"
+  __OCSP_MUST_STAPLE="${OCSP_MUST_STAPLE}"
+  __PRIVATE_KEY_RENEW="${PRIVATE_KEY_RENEW}"
+  __KEYSIZE="${KEYSIZE}"
+  __CHALLENGETYPE="${CHALLENGETYPE}"
+  __HOOK="${HOOK}"
+  __WELLKNOWN="${WELLKNOWN}"
+  __HOOK_CHAIN="${HOOK_CHAIN}"
+  __OPENSSL_CNF="${OPENSSL_CNF}"
+  __RENEW_DAYS="${RENEW_DAYS}"
+}
+
+reset_configvars() {
+  KEY_ALGO="${__KEY_ALGO}"
+  OCSP_MUST_STAPLE="${__OCSP_MUST_STAPLE}"
+  PRIVATE_KEY_RENEW="${__PRIVATE_KEY_RENEW}"
+  KEYSIZE="${__KEYSIZE}"
+  CHALLENGETYPE="${__CHALLENGETYPE}"
+  HOOK="${__HOOK}"
+  WELLKNOWN="${__WELLKNOWN}"
+  HOOK_CHAIN="${__HOOK_CHAIN}"
+  OPENSSL_CNF="${__OPENSSL_CNF}"
+  RENEW_DAYS="${__RENEW_DAYS}"
+}
+
+# verify configuration values
+verify_config() {
+  [[ "${CHALLENGETYPE}" =~ (http-01|dns-01) ]] || _exiterr "Unknown challenge type ${CHALLENGETYPE}... can not continue."
+  if [[ "${CHALLENGETYPE}" = "dns-01" ]] && [[ -z "${HOOK}" ]]; then
+    _exiterr "Challenge type dns-01 needs a hook script for deployment... can not continue."
+  fi
+  if [[ "${CHALLENGETYPE}" = "http-01" && ! -d "${WELLKNOWN}" ]]; then
+    _exiterr "WELLKNOWN directory doesn't exist, please create ${WELLKNOWN} and set appropriate permissions."
+  fi
+  [[ "${KEY_ALGO}" =~ ^(rsa|prime256v1|secp384r1)$ ]] || _exiterr "Unknown public key algorithm ${KEY_ALGO}... can not continue."
+}
+
 # Setup default config values, search for and load configuration files
 load_config() {
   # Check for config in various locations
@@ -131,11 +170,8 @@ load_config() {
   [[ -n "${PARAM_KEY_ALGO:-}" ]] && KEY_ALGO="${PARAM_KEY_ALGO}"
   [[ -n "${PARAM_OCSP_MUST_STAPLE:-}" ]] && OCSP_MUST_STAPLE="${PARAM_OCSP_MUST_STAPLE}"
 
-  [[ "${CHALLENGETYPE}" =~ (http-01|dns-01) ]] || _exiterr "Unknown challenge type ${CHALLENGETYPE}... can not continue."
-  if [[ "${CHALLENGETYPE}" = "dns-01" ]] && [[ -z "${HOOK}" ]]; then
-   _exiterr "Challenge type dns-01 needs a hook script for deployment... can not continue."
-  fi
-  [[ "${KEY_ALGO}" =~ ^(rsa|prime256v1|secp384r1)$ ]] || _exiterr "Unknown public key algorithm ${KEY_ALGO}... can not continue."
+  verify_config
+  store_configvars
 }
 
 # Initialize system
@@ -196,9 +232,6 @@ init_system() {
     fi
   fi
 
-  if [[ "${CHALLENGETYPE}" = "http-01" && ! -d "${WELLKNOWN}" ]]; then
-      _exiterr "WELLKNOWN directory doesn't exist, please create ${WELLKNOWN} and set appropriate permissions."
-  fi
 }
 
 # Different sed version for different os types...
@@ -592,6 +625,7 @@ command_sign_domains() {
   ORIGIFS="${IFS}"
   IFS=$'\n'
   for line in $(<"${DOMAINS_TXT}" tr -d '\r' | tr '[:upper:]' '[:lower:]' | _sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*$//g' -e 's/[[:space:]]+/ /g' | (grep -vE '^(#|$)' || true)); do
+    reset_configvars
     IFS="${ORIGIFS}"
     domain="$(printf '%s\n' "${line}" | cut -d' ' -f1)"
     morenames="$(printf '%s\n' "${line}" | cut -s -d' ' -f2-)"
@@ -605,6 +639,40 @@ command_sign_domains() {
       echo "Processing ${domain} with alternative names: ${morenames}"
     fi
 
+    # read cert config
+    # for now this loads the certificate specific config in a subshell and parses a diff of set variables.
+    # we could just source the config file but i decided to go this way to protect people from accidentally overriding
+    # variables used internally by this script itself.
+    if [ -f "${CERTDIR}/${domain}/config" ]; then
+      echo " + Using certificate specific config file!"
+      ORIGIFS="${IFS}"
+      IFS=$'\n'
+      for cfgline in $(
+        beforevars="$(_mktemp)"
+        aftervars="$(_mktemp)"
+        set > "${beforevars}"
+        # shellcheck disable=SC1090
+        . "${CERTDIR}/${domain}/config"
+        set > "${aftervars}"
+        diff -u "${beforevars}" "${aftervars}" | grep -E '^\+[^+]'
+        rm "${beforevars}"
+        rm "${aftervars}"
+      ); do
+        config_var="$(echo "${cfgline:1}" | cut -d'=' -f1)"
+        config_value="$(echo "${cfgline:1}" | cut -d'=' -f2-)"
+        case "${config_var}" in
+          KEY_ALGO|OCSP_MUST_STAPLE|PRIVATE_KEY_RENEW|KEYSIZE|CHALLENGETYPE|HOOK|WELLKNOWN|HOOK_CHAIN|OPENSSL_CNF|RENEW_DAYS)
+            echo "   + ${config_var} = ${config_value}"
+            declare -- "${config_var}=${config_value}"
+            ;;
+          _) ;;
+          *) echo "   ! Setting ${config_var} on a per-certificate base is not (yet) supported"
+        esac
+      done
+      IFS="${ORIGIFS}"
+    fi
+    verify_config
+
     if [[ -e "${cert}" ]]; then
       printf " + Checking domain name(s) of existing cert..."