Hello community, here is the log from the commit of package dehydrated for openSUSE:Factory checked in at 2018-04-27 16:09:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dehydrated (Old) and /work/SRC/openSUSE:Factory/.dehydrated.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "dehydrated" Fri Apr 27 16:09:55 2018 rev:9 rq:601882 version:0.6.2 Changes: -------- --- /work/SRC/openSUSE:Factory/dehydrated/dehydrated.changes 2018-03-16 10:45:10.736519895 +0100 +++ /work/SRC/openSUSE:Factory/.dehydrated.new/dehydrated.changes 2018-04-27 16:09:59.156830465 +0200 @@ -1,0 +2,25 @@ +Fri Apr 27 11:14:45 UTC 2018 - daniel.molkentin@suse.com + +- Update to dehydrated 0.6.2 + * removes 0001-fixed-CA-url-in-example-config.patch + * removes 0002-don-t-walk-certificate-chain-for-ACMEv2-certificate-.patch + + Added + + * New deploy_ocsp hook + * Allow account registration with custom key + + Changed + + * Don't walk certificate chain for ACMEv2 (certificate contains chain by default) + * Improved documentation on wildcards + + Fixes + + * Added workaround for compatibility with filesystem ACLs + * Close unwanted external file-descriptors + * Fixed JSON parsing on force-renewal (bsc#1091216) + * Fixed cleanup of challenge files/dns-entries on validation errors + * A few more minor fixes + +------------------------------------------------------------------- Old: ---- 0001-fixed-CA-url-in-example-config.patch 0002-don-t-walk-certificate-chain-for-ACMEv2-certificate-.patch dehydrated-0.6.1.tar.gz dehydrated-0.6.1.tar.gz.asc New: ---- dehydrated-0.6.2.tar.gz dehydrated-0.6.2.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ dehydrated.spec ++++++ --- /var/tmp/diff_new_pack.4pfter/_old 2018-04-27 16:09:59.800806848 +0200 +++ /var/tmp/diff_new_pack.4pfter/_new 2018-04-27 16:09:59.800806848 +0200 @@ -46,7 +46,7 @@ %endif Name: dehydrated -Version: 0.6.1 +Version: 0.6.2 Release: 0 Summary: A client for signing certificates with an ACME server License: MIT @@ -65,8 +65,6 @@ Source11: README.hooks Source12: %{name}-%{version}.tar.gz.asc Source13: %{name}.keyring -Patch1: 0001-fixed-CA-url-in-example-config.patch -Patch2: 0002-don-t-walk-certificate-chain-for-ACMEv2-certificate-.patch BuildRequires: %{_apache} Requires: coreutils Requires: curl @@ -184,8 +182,6 @@ %prep %setup -q -%patch1 -p1 -%patch2 -p1 cp %{SOURCE9} . cp %{SOURCE10} . ++++++ dehydrated-0.6.1.tar.gz -> dehydrated-0.6.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dehydrated-0.6.1/CHANGELOG new/dehydrated-0.6.2/CHANGELOG --- old/dehydrated-0.6.1/CHANGELOG 2018-03-13 20:57:52.000000000 +0100 +++ new/dehydrated-0.6.2/CHANGELOG 2018-04-25 23:22:40.000000000 +0200 @@ -1,6 +1,22 @@ # Change Log This file contains a log of major changes in dehydrated +## [0.6.2] - 2018-04-25 +## Added +- New deploy_ocsp hook +- Allow account registration with custom key + +## Changed +- Don't walk certificate chain for ACMEv2 (certificate contains chain by default) +- Improved documentation on wildcards + +## Fixes +- Added workaround for compatibility with filesystem ACLs +- Close unwanted external file-descriptors +- Fixed JSON parsing on force-renewal +- Fixed cleanup of challenge files/dns-entries on validation errors +- A few more minor fixes + ## [0.6.1] - 2018-03-13 ## Changed - Use new ACME v2 endpoint by default diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dehydrated-0.6.1/README.md new/dehydrated-0.6.2/README.md --- old/dehydrated-0.6.1/README.md 2018-03-13 20:57:52.000000000 +0100 +++ new/dehydrated-0.6.2/README.md 2018-04-25 23:22:40.000000000 +0200 @@ -2,20 +2,21 @@ ![](docs/logo.jpg) -This is a client for signing certificates with an ACME-server (currently only provided by Let's Encrypt) implemented as a relatively simple bash-script. -Dehydrated supports both ACME v1 and the new ACME v2 including support for wildcard certificates! +Dehydrated is a client for signing certificates with an ACME-server (e.g. Let's Encrypt) implemented as a relatively simple (zsh-compatible) bash-script. +This client supports both ACME v1 and the new ACME v2 including support for wildcard certificates! It uses the `openssl` utility for everything related to actually handling keys and certificates, so you need to have that installed. -Other dependencies are: cURL, sed, grep, mktemp (all found on almost any system, cURL being the only exception) +Other dependencies are: cURL, sed, grep, awk, mktemp (all found pre-installed on almost any system, cURL being the only exception). Current features: -- Signing of a list of domains -- Signing of a CSR -- Renewal if a certificate is about to expire or SAN (subdomains) changed +- Signing of a list of domains (including wildcard domains!) +- Signing of a custom CSR (either standalone or completely automated using hooks!) +- Renewal if a certificate is about to expire or defined set of domains changed - Certificate revocation -Please keep in mind that this software and even the acme-protocol are relatively young and may still have some unresolved issues. Feel free to report any issues you find with this script or contribute by submitting a pull request. +Please keep in mind that this software, the ACME-protocol and all supported CA servers out there are relatively young and there might be a few issues. Feel free to report any issues you find with this script or contribute by submitting a pull request, +but please check for duplicates first (feel free to comment on those to get things rolling). ## Getting started @@ -87,12 +88,12 @@ I'd really appreciate if you could [donate a bit of money](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=23P9DSJBTY7C8) so I can buy cool stuff (while still being able to afford food :D). -If you have hardware laying around that you think I'd enjoy playing with (e.g. decomissioned but still modern-ish servers, +If you have hardware laying around that you think I'd enjoy playing with (e.g. decommissioned but still modern-ish servers, 10G networking hardware, enterprise grade routers or APs, interesting ARM/MIPS boards, etc.) and that you would be willing -to ship to me please contact me at `donations@dehydrated.de` or on Twitter [@lukas2511](https://twitter.com/lukas2511). +to ship to me please contact me at `donations@dehydrated.io` or on Twitter [@lukas2511](https://twitter.com/lukas2511). -If you want your name to be added to the [donations list](https://dehydrated.de/donations.html) please add a note or send me an -email `donations@dehydrated.de`. I respect your privacy and won't publish your name without permission. +If you want your name to be added to the [donations list](https://dehydrated.io/donations.html) please add a note or send me an +email `donations@dehydrated.io`. I respect your privacy and won't publish your name without permission. Other ways of donating: - [My Amazon Wishlist](http://www.amazon.de/registry/wishlist/1TUCFJK35IO4Q) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dehydrated-0.6.1/dehydrated new/dehydrated-0.6.2/dehydrated --- old/dehydrated-0.6.1/dehydrated 2018-03-13 20:57:52.000000000 +0100 +++ new/dehydrated-0.6.2/dehydrated 2018-04-25 23:22:40.000000000 +0200 @@ -1,7 +1,7 @@ #!/usr/bin/env bash # dehydrated by lukas2511 -# Source: https://dehydrated.de +# Source: https://dehydrated.io # # This script is licensed under The MIT License (see LICENSE for more information). @@ -13,7 +13,11 @@ umask 077 # paranoid umask, we're creating private keys -VERSION="0.6.1" +# Close weird external file descriptors +exec 3>&- +exec 4>&- + +VERSION="0.6.2" # Find directory in which this script is stored by traversing all symbolic links SOURCE="${0}" @@ -324,6 +328,7 @@ echo "Using private key ${PARAM_ACCOUNT_KEY} instead of account key" ACCOUNT_KEY="${PARAM_ACCOUNT_KEY}" ACCOUNT_KEY_JSON="${PARAM_ACCOUNT_KEY}.json" + [ "${COMMAND:-}" = "register" ] && register_new_key="yes" else # Check if private account key exists, if it doesn't exist yet generate a new one (rsa key) if [[ ! -e "${ACCOUNT_KEY}" ]]; then @@ -335,7 +340,10 @@ fi echo "+ Generating account key..." - _openssl genrsa -out "${ACCOUNT_KEY}" "${KEYSIZE}" + local tmp_account_key="$(_mktemp)" + _openssl genrsa -out "${tmp_account_key}" "${KEYSIZE}" + cat "${tmp_account_key}" > "${ACCOUNT_KEY}" + rm "${tmp_account_key}" register_new_key="yes" fi fi @@ -397,10 +405,9 @@ else echo "Fetching missing account information from CA..." if [[ ${API} -eq 1 ]]; then - ACCOUNT_URL="$(signed_request "${CA_NEW_REG}" '{"resource": "new-reg", "onlyReturnExisting": true}' 4>&1 | grep ^Location: | awk '{print $2}' | tr -d '\r\n')" - ACCOUNT_INFO="$(signed_request "${ACCOUNT_URL}" '{"resource": "reg"}')" + _exiterr "This is not implemented for ACMEv1! Consider switching to ACMEv2 :)" else - ACCOUNT_URL="$(signed_request "${CA_NEW_ACCOUNT}" '{"only-return-existing": true}' 4>&1 | grep ^Location: | awk '{print $2}' | tr -d '\r\n')" + ACCOUNT_URL="$(signed_request "${CA_NEW_ACCOUNT}" '{"onlyReturnExisting": true}' 4>&1 | grep ^Location: | awk '{print $2}' | tr -d '\r\n')" ACCOUNT_INFO="$(signed_request "${ACCOUNT_URL}" '{}')" fi ACCOUNT_ID="${ACCOUNT_URL##*/}" @@ -503,14 +510,14 @@ set +e if [[ "${1}" = "head" ]]; then - statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydr4ted/${VERSION} curl/${CURL_VERSION}" -s -w "%{http_code}" -o "${tempcont}" "${2}" -I)" + statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydrated/${VERSION} curl/${CURL_VERSION}" -s -w "%{http_code}" -o "${tempcont}" "${2}" -I)" touch "${tempheaders}" curlret="${?}" elif [[ "${1}" = "get" ]]; then - statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydr4ted/${VERSION} curl/${CURL_VERSION}" -L -s -w "%{http_code}" -o "${tempcont}" -D "${tempheaders}" "${2}")" + statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydrated/${VERSION} curl/${CURL_VERSION}" -L -s -w "%{http_code}" -o "${tempcont}" -D "${tempheaders}" "${2}")" curlret="${?}" elif [[ "${1}" = "post" ]]; then - statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydr4ted/${VERSION} curl/${CURL_VERSION}" -s -w "%{http_code}" -o "${tempcont}" "${2}" -D "${tempheaders}" -H 'Content-Type: application/jose+json' -d "${3}")" + statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydrated/${VERSION} curl/${CURL_VERSION}" -s -w "%{http_code}" -o "${tempcont}" "${2}" -D "${tempheaders}" -H 'Content-Type: application/jose+json' -d "${3}")" curlret="${?}" else set -e @@ -530,10 +537,6 @@ # check for already-revoked warning elif [[ -n "${CA_REVOKE_CERT:-}" ]] && [[ "${2}" = "${CA_REVOKE_CERT:-}" ]] && [[ "${statuscode}" = "409" ]]; then grep -q "Certificate already revoked" "${tempcont}" && return - # check for redirects on license - elif [[ -n "${CA_TERMS:-}" ]] && [[ "${2}" = "${CA_TERMS:-}" ]] && [[ "${statuscode:0:1}" = "3" ]]; then - # do nothing - : else echo " + ERROR: An error occurred while sending ${1}-request to ${2} (Status ${statuscode})" >&2 echo >&2 @@ -544,7 +547,7 @@ echo >&2 # An exclusive hook for the {1}-request error might be useful (e.g., for sending an e-mail to admins) - if [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]]; then + if [[ -n "${HOOK}" ]]; then errtxt="$(cat ${tempcont})" errheaders="$(cat ${tempheaders})" "${HOOK}" "request_failure" "${statuscode}" "${errtxt}" "${1}" "${errheaders}" @@ -553,11 +556,6 @@ rm -f "${tempcont}" rm -f "${tempheaders}" - # Wait for hook script to clean the challenge if used - if [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]] && [[ -n "${challenge_token:+set}" ]]; then - "${HOOK}" "clean_challenge" '' "${challenge_token}" "${keyauth}" - fi - # remove temporary domains.txt file if used [[ -n "${PARAM_DOMAIN:-}" && -n "${DOMAINS_TXT:-}" ]] && rm "${DOMAINS_TXT}" exit 1 @@ -667,14 +665,15 @@ fi if [[ -n "${ZSH_VERSION:-}" ]]; then - local -A challenge_identifiers challenge_uris challenge_tokens authorizations keyauths deploy_args + local -A challenge_names challenge_uris challenge_tokens authorizations keyauths deploy_args else - local -a challenge_identifiers challenge_uris challenge_tokens authorizations keyauths deploy_args + local -a challenge_names challenge_uris challenge_tokens authorizations keyauths deploy_args fi # Initial step: Find which authorizations we're dealing with if [[ ${API} -eq 2 ]]; then # Request new order and store authorization URIs + local challenge_identifiers="" for altname in ${altnames}; do challenge_identifiers+="$(printf '{"type": "dns", "value": "%s"}, ' "${altname}")" done @@ -731,12 +730,12 @@ fi # Gather challenge information - challenge_identifiers[${idx}]="${identifier}" + challenge_names[${idx}]="${identifier}" challenge_tokens[${idx}]="$(echo "${challenge}" | get_json_string_value token)" if [[ ${API} -eq 2 ]]; then - challenge_uris[${idx}]="$(echo "${challenge}" | get_json_string_value url)" + challenge_uris[${idx}]="$(echo "${challenge}" | _sed 's/"validationRecord": ?\[[^]]+\]//g' | get_json_string_value url)" else - challenge_uris[${idx}]="$(echo "${challenge}" | get_json_string_value uri)" + challenge_uris[${idx}]="$(echo "${challenge}" | _sed 's/"validationRecord": ?\[[^]]+\]//g' | get_json_string_value uri)" fi # Prepare challenge tokens and deployment parameters @@ -781,7 +780,7 @@ # Validate pending challenges local idx=0 while [ ${idx} -lt ${num_pending_challenges} ]; do - echo " + Responding to challenge for ${challenge_identifiers[${idx}]} authorization..." + echo " + Responding to challenge for ${challenge_names[${idx}]} authorization..." # Ask the acme-server to verify our challenge and wait until it is no longer pending if [[ ${API} -eq 1 ]]; then @@ -800,34 +799,33 @@ [[ "${CHALLENGETYPE}" = "http-01" ]] && rm -f "${WELLKNOWN}/${challenge_tokens[${idx}]}" - # Run hook script to clean the challenge token - if [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]]; then - # shellcheck disable=SC2086 - "${HOOK}" "clean_challenge" ${deploy_args[${idx}]} - fi - idx=$((idx+1)) - if [[ "${reqstatus}" = "valid" ]]; then echo " + Challenge is valid!" else - [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]] && "${HOOK}" "invalid_challenge" "${altname}" "${result}" + [[ -n "${HOOK}" ]] && "${HOOK}" "invalid_challenge" "${altname}" "${result}" break fi + idx=$((idx+1)) done if [[ ${num_pending_challenges} -ne 0 ]]; then + echo " + Cleaning challenge tokens..." + # Clean challenge tokens using chained hook [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" = "yes" ]] && "${HOOK}" "clean_challenge" ${deploy_args[@]} # Clean remaining challenge tokens if validation has failed - if [[ "${reqstatus}" != "valid" ]]; then - if [[ "${CHALLENGETYPE}" = "http-01" ]] && [[ ${num_pending_challenges} -ne 0 ]]; then - while [ ${idx} -lt ${num_pending_challenges} ]; do - rm -f "${WELLKNOWN}/${challenge_tokens[${idx}]}" - idx=$((idx+1)) - done - fi + local idx=0 + while [ ${idx} -lt ${num_pending_challenges} ]; do + # Delete challenge file + [[ "${CHALLENGETYPE}" = "http-01" ]] && rm -f "${WELLKNOWN}/${challenge_tokens[${idx}]}" + # Clean challenge token using non-chained hook + [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]] && "${HOOK}" "clean_challenge" ${deploy_args[${idx}]} + idx=$((idx+1)) + done + if [[ "${reqstatus}" != "valid" ]]; then + echo " + Challenge validation has failed :(" _exiterr "Challenge is invalid! (returned: ${reqstatus}) (result: ${result})" fi fi @@ -934,10 +932,13 @@ if [[ ! -r "${certdir}/privkey.pem" ]] || [[ "${PRIVATE_KEY_RENEW}" = "yes" ]]; then echo " + Generating private key..." privkey="privkey-${timestamp}.pem" + local tmp_privkey="$(_mktemp)" case "${KEY_ALGO}" in - rsa) _openssl genrsa -out "${certdir}/privkey-${timestamp}.pem" "${KEYSIZE}";; - prime256v1|secp384r1) _openssl ecparam -genkey -name "${KEY_ALGO}" -out "${certdir}/privkey-${timestamp}.pem";; + rsa) _openssl genrsa -out "${tmp_privkey}" "${KEYSIZE}";; + prime256v1|secp384r1) _openssl ecparam -genkey -name "${KEY_ALGO}" -out "${tmp_privkey}";; esac + cat "${tmp_privkey}" > "${certdir}/privkey-${timestamp}.pem" + rm "${tmp_privkey}" fi # move rolloverkey into position (if any) if [[ -r "${certdir}/privkey.pem" && -r "${certdir}/privkey.roll.pem" && "${PRIVATE_KEY_RENEW}" = "yes" && "${PRIVATE_KEY_ROLLOVER}" = "yes" ]]; then @@ -990,20 +991,30 @@ # Create fullchain.pem echo " + Creating fullchain.pem..." - cat "${crt_path}" > "${certdir}/fullchain-${timestamp}.pem" - local issuer_hash - issuer_hash="$(get_issuer_hash "${crt_path}")" - if [ -e "${CHAINCACHE}/${issuer_hash}.chain" ]; then - echo " + Using cached chain!" - cat "${CHAINCACHE}/${issuer_hash}.chain" > "${certdir}/chain-${timestamp}.pem" + if [[ ${API} -eq 1 ]]; then + cat "${crt_path}" > "${certdir}/fullchain-${timestamp}.pem" + local issuer_hash + issuer_hash="$(get_issuer_hash "${crt_path}")" + if [ -e "${CHAINCACHE}/${issuer_hash}.chain" ]; then + echo " + Using cached chain!" + cat "${CHAINCACHE}/${issuer_hash}.chain" > "${certdir}/chain-${timestamp}.pem" + else + echo " + Walking chain..." + local issuer_cert_uri + issuer_cert_uri="$(get_issuer_cert_uri "${crt_path}" || echo "unknown")" + (walk_chain "${crt_path}" > "${certdir}/chain-${timestamp}.pem") || _exiterr "Walking chain has failed, your certificate has been created and can be found at ${crt_path}, the corresponding private key at ${privkey}. If you want you can manually continue on creating and linking all necessary files. If this error occurs again you should manually generate the certificate chain and place it under ${CHAINCACHE}/${issuer_hash}.chain (see ${issuer_cert_uri})" + cat "${certdir}/chain-${timestamp}.pem" > "${CHAINCACHE}/${issuer_hash}.chain" + fi + cat "${certdir}/chain-${timestamp}.pem" >> "${certdir}/fullchain-${timestamp}.pem" else - echo " + Walking chain..." - local issuer_cert_uri - issuer_cert_uri="$(get_issuer_cert_uri "${crt_path}" || echo "unknown")" - (walk_chain "${crt_path}" > "${certdir}/chain-${timestamp}.pem") || _exiterr "Walking chain has failed, your certificate has been created and can be found at ${crt_path}, the corresponding private key at ${privkey}. If you want you can manually continue on creating and linking all necessary files. If this error occurs again you should manually generate the certificate chain and place it under ${CHAINCACHE}/${issuer_hash}.chain (see ${issuer_cert_uri})" - cat "${certdir}/chain-${timestamp}.pem" > "${CHAINCACHE}/${issuer_hash}.chain" + tmpcert="$(_mktemp)" + tmpchain="$(_mktemp)" + awk '{print >out}; /----END CERTIFICATE-----/{out=tmpchain}' out="${tmpcert}" tmpchain="${tmpchain}" "${certdir}/cert-${timestamp}.pem" + mv "${certdir}/cert-${timestamp}.pem" "${certdir}/fullchain-${timestamp}.pem" + cat "${tmpcert}" > "${certdir}/cert-${timestamp}.pem" + cat "${tmpchain}" > "${certdir}/chain-${timestamp}.pem" + rm "${tmpcert}" "${tmpchain}" fi - cat "${certdir}/chain-${timestamp}.pem" >> "${certdir}/fullchain-${timestamp}.pem" # Update symlinks [[ "${privkey}" = "privkey.pem" ]] || ln -sf "privkey-${timestamp}.pem" "${certdir}/privkey.pem" @@ -1026,7 +1037,7 @@ load_config noverify echo "Dehydrated by Lukas Schauer" - echo "https://dehydrated.de" + echo "https://dehydrated.io" echo "" echo "Dehydrated version: ${VERSION}" revision="$(cd "${SCRIPTDIR}"; git rev-parse HEAD 2>/dev/null || echo "unknown")" @@ -1228,7 +1239,7 @@ local csr="" if [[ -n "${HOOK}" ]]; then csr="$("${HOOK}" "generate_csr" "${domain}" "${certdir}" "${domain} ${morenames}")" - if grep -q "\-----BEGIN CERTIFICATE REQUEST-----" <<< "${csr}"; then + if grep -qE "\-----BEGIN (NEW )?CERTIFICATE REQUEST-----" <<< "${csr}"; then altnames="$(extract_altnames "${csr}")" domain="$(cut -d' ' -f1 <<< "${altnames}")" morenames="$(cut -s -d' ' -f2- <<< "${altnames}")" @@ -1312,6 +1323,7 @@ ocsp_log="$("${OPENSSL}" ocsp -no_nonce -issuer "${chain}" -verify_other "${chain}" -cert "${cert}" -respout "${certdir}/ocsp-${ocsp_timestamp}.der" -url "${ocsp_url}" 2>&1)" || _exiterr "Error while fetching OCSP information: ${ocsp_log}" fi ln -sf "ocsp-${ocsp_timestamp}.der" "${certdir}/ocsp.der" + [[ -n "${HOOK}" ]] && altnames="${domain} ${morenames}" "${HOOK}" "deploy_ocsp" "${domain}" "${certdir}/ocsp.der" "${ocsp_timestamp}" else echo " + OSCP stapling file is still valid (skipping update)" fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dehydrated-0.6.1/docs/domains_txt.md new/dehydrated-0.6.2/docs/domains_txt.md --- old/dehydrated-0.6.1/docs/domains_txt.md 2018-03-13 20:57:52.000000000 +0100 +++ new/dehydrated-0.6.2/docs/domains_txt.md 2018-04-25 23:22:40.000000000 +0200 @@ -1,22 +1,72 @@ -### domains.txt +## domains.txt -dehydrated uses the file `domains.txt` as configuration for which certificates should be requested. +dehydrated uses the file `domains.txt` as configuration for which certificates +should be requested. The file should have the following format: ```text +example.org example.com www.example.com example.net www.example.net wiki.example.net +``` + +This states that there are the following certificates: + * `example.org` without any *alternative names* + * `example.com` with an *alternative name* of `www.example.com` + * `example.net` with the *alternative names*: `www.example.net` and + `wiki.example.net` + +### Aliases + +You can define an *alias* for your certificate which will (instead of the +primary domain) be used as the directory name under your `CERTDIR` and for a +per-certificate lookup. This is done using the `>` character. This allows +multiple certificates with identical sets of domains but different +configuration to exist. + +Here is an example of using an *alias* called `certalias` for creating the +certificate for `example.net` with *alternative names* `www.example.net` and +`wiki.example.net`. The certificate will be stored in the directory `certalias` +under your `CERTDIR`. + +```text example.net www.example.net wiki.example.net > certalias ``` -This states that there should be two certificates `example.com` and `example.net`, -with the other domains in the corresponding line being their alternative names. +### Wildcards -You can define an alias for your certificate which will (instead of the primary domain) be -used as directory name under your certdir and for a per-certificate lookup. -This allows multiple certificates with identical sets of domains but different configuration -to exist. +Support for wildcards was added by the ACME v2 protocol. + +Certificates with a wildcard domain as the first (or only) name require an +*alias* to be set. *Aliases* can't start with `*.`. + +For example to create the wildcard for `*.service.example.com` your +`domains.txt` could use the *alias* method like this: + +```text +*.service.example.com > star_service_example_com +``` + +This creates a wildcard certificate for only `*.service.example.com` and will +store it in the directory `star_service_example_com` under your `CERTDIR`. As a +note this certificate will **NOT** be valid for `service.example.com` but only +for `*.service.example.com`. So it would, for example, be valid for +`foo.service.example.com`. + + +Another way to create it is using *alternative names*. For example your +`domains.txt` could do this: + +```text +service.example.com *.service.example.com +eggs.example.com *.ham.example.com +``` -Certificates with a wildcard domain as first (or only) name require an alias to be set. -Aliases can't start with `*.`. +This creates two certificates one for `service.example.com` with an +*alternative name* of `*.service.example.com` and a second certificate for +`eggs.example.com` with an *alternative name* of `*.ham.example.com`. + +**Note:** The first certificate is valid for both `service.example.com` and for +`*.service.example.com` which can be a useful way to create wildcard +certificates. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dehydrated-0.6.1/docs/examples/config new/dehydrated-0.6.2/docs/examples/config --- old/dehydrated-0.6.1/docs/examples/config 2018-03-13 20:57:52.000000000 +0100 +++ new/dehydrated-0.6.2/docs/examples/config 2018-04-25 23:22:40.000000000 +0200 @@ -21,15 +21,15 @@ # default: <unset> #IP_VERSION= -# Path to certificate authority (default: https://acme-v01.api.letsencrypt.org/directory) -#CA="https://acme-v01.api.letsencrypt.org/directory" +# Path to certificate authority (default: https://acme-v02.api.letsencrypt.org/directory) +#CA="https://acme-v02.api.letsencrypt.org/directory" # Path to old certificate authority # Set this value to your old CA value when upgrading from ACMEv1 to ACMEv2 under a different endpoint. # If dehydrated detects an account-key for the old CA it will automatically reuse that key # instead of registering a new one. -# default: <unset> -#OLDCA= +# default: https://acme-v01.api.letsencrypt.org/directory +#OLDCA="https://acme-v01.api.letsencrypt.org/directory" # Which challenge should be used? Currently http-01 and dns-01 are supported #CHALLENGETYPE="http-01" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dehydrated-0.6.1/docs/examples/domains.txt new/dehydrated-0.6.2/docs/examples/domains.txt --- old/dehydrated-0.6.1/docs/examples/domains.txt 2018-03-13 20:57:52.000000000 +0100 +++ new/dehydrated-0.6.2/docs/examples/domains.txt 2018-04-25 23:22:40.000000000 +0200 @@ -1,2 +1,30 @@ +# Create certificate for 'example.org' with an alternative name of +# 'www.example.org'. It will be stored in the directory ${CERT_DIR}/example.org example.org www.example.org + +# Create certificate for 'example.com' with alternative names of +# 'www.example.com' & 'wiki.example.com'. It will be stored in the directory +# ${CERT_DIR}/example.com example.com www.example.com wiki.example.com + +# Using the alias 'certalias' create certificate for 'example.net' with +# alternate name 'www.example.net' and store it in the directory +# ${CERTDIR}/certalias +example.net www.example.net > certalias + +# Using the alias 'service_example_com' create a wildcard certificate for +# '*.service.example.com' and store it in the directory +# ${CERTDIR}/service_example_com +# NOTE: It is NOT a certificate for 'service.example.com' +*.service.example.com > service_example_com + +# Using the alias 'star_service_example_org' create a wildcard certificate for +# '*.service.example.org' with an alternative name of `service.example.org' +# and store it in the directory ${CERTDIR}/star_service_example_org +# NOTE: It is a certificate for 'service.example.org' +*.service.example.org service.example.org > star_service_example_org + +# Create a certificate for 'service.example.net' with an alternative name of +# '*.service.example.net' (which is a wildcard domain) and store it in the +# directory ${CERTDIR}/service.example.net +service.example.net *.service.example.net diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dehydrated-0.6.1/docs/examples/hook.sh new/dehydrated-0.6.2/docs/examples/hook.sh --- old/dehydrated-0.6.1/docs/examples/hook.sh 2018-03-13 20:57:52.000000000 +0100 +++ new/dehydrated-0.6.2/docs/examples/hook.sh 2018-04-25 23:22:40.000000000 +0200 @@ -64,6 +64,28 @@ # systemctl reload nginx } +deploy_ocsp() { + local DOMAIN="${1}" OCSPFILE="${2}" TIMESTAMP="${3}" + + # This hook is called once for each updated ocsp stapling file that has + # been produced. Here you might, for instance, copy your new ocsp stapling + # files to service-specific locations and reload the service. + # + # Parameters: + # - DOMAIN + # The primary domain name, i.e. the certificate common + # name (CN). + # - OCSPFILE + # The path of the ocsp stapling file + # - TIMESTAMP + # Timestamp when the specified ocsp stapling file was created. + + # Simple example: Copy file to nginx config + # cp "${OCSPFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl + # systemctl reload nginx +} + + unchanged_cert() { local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" @@ -116,6 +138,8 @@ # The specified reason for the error. # - REQTYPE # The kind of request that was made (GET, POST...) + # - HEADERS + # HTTP headers returned by the CA # Simple example: Send mail to root # printf "Subject: HTTP request failed failed!\n\nA http request failed with status ${STATUSCODE}!" | sendmail root @@ -161,6 +185,6 @@ } HANDLER="$1"; shift -if [[ "${HANDLER}" =~ ^(deploy_challenge|clean_challenge|deploy_cert|unchanged_cert|invalid_challenge|request_failure|generate_csr|startup_hook|exit_hook)$ ]]; then +if [[ "${HANDLER}" =~ ^(deploy_challenge|clean_challenge|deploy_cert|deploy_ocsp|unchanged_cert|invalid_challenge|request_failure|generate_csr|startup_hook|exit_hook)$ ]]; then "$HANDLER" "$@" fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dehydrated-0.6.1/docs/man/dehydrated.1 new/dehydrated-0.6.2/docs/man/dehydrated.1 --- old/dehydrated-0.6.1/docs/man/dehydrated.1 2018-03-13 20:57:52.000000000 +0100 +++ new/dehydrated-0.6.2/docs/man/dehydrated.1 2018-04-25 23:22:40.000000000 +0200 @@ -145,7 +145,7 @@ Dehydrated was written by Lukas Schauer. This man page was contributed by Daniel Molkentin. .SH COPYRIGHT -Copyright 20015-2018 by Lukas Schauer and the respective contributors. +Copyright 2015-2018 by Lukas Schauer and the respective contributors. Provided under the MIT License. See the LICENSE file that accompanies the distribution for licensing information. .SH SEE ALSO