Your message dated Tue, 03 Jun 2025 07:49:53 +0000 with message-id <E1uMMPB-004Itq-38@respighi.debian.org> and subject line unblock dehydrated has caused the Debian Bug report #1107165, regarding unblock: dehydrated/0.7.2-1 to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact owner@bugs.debian.org immediately.) -- 1107165: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1107165 Debian Bug Tracking System Contact owner@bugs.debian.org with problems
--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: unblock: dehydrated/0.7.2-1
- From: Mattia Rizzolo <mattia@debian.org>
- Date: Mon, 2 Jun 2025 17:08:57 +0200
- Message-id: <[🔎] aD2-iZm0NjT66x6n@mapreri.org>
Package: release.debian.org Severity: normal X-Debbugs-Cc: dehydrated@packages.debian.org Control: affects -1 + src:dehydrated User: release.debian.org@packages.debian.org Usertags: unblock Please unblock package dehydrated [ Reason ] A couple of weeks ago upstream released 0.7.2. The changes are pretty minimal, and they include stuff that might be relevant to the trixie release cycle (i.e., the openssl warning coming from 3.2+ which is in trixie) Also, the certificate profiles that is part of the updated ACME protocol (https://letsencrypt.org/2025/01/09/acme-profiles/) [ Impact ] Overall, these are pretty much all new features, and nothing would break if this unblock request is not approved. [ Tests ] Nothing manual, but I ran it on a few of my servers to verify everything that used to work still works. [ Risks ] The risks are low if nothing else because the changes are easily audited. I attached also a diffoscope of the .deb package, as that shows a more correct diff, since most of the big changes from this release were already included in the previous version via patches. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing unblock dehydrated/0.7.2-1 -- regards, Mattia Rizzolo GPG Key: 66AE 2B4A FCCF 3F52 DA18 4D18 4B04 3FCD B944 4540 .''`. More about me: https://mapreri.org : :' : Launchpad user: https://launchpad.net/~mapreri `. `'` Debian QA page: https://qa.debian.org/developer.php?login=mattia `-diffstat for dehydrated-0.7.1 dehydrated-0.7.2 CHANGELOG | 12 README.md | 10 debian/changelog | 10 debian/control | 2 debian/copyright | 2 debian/patches/0002-added-note-about-dehydrated-irc-channel.patch | 26 - debian/patches/0002-only-validate-existance-of-wellknown-directory-or-ho.patch | 36 ++ debian/patches/0003-improve-man-page-based-on-feedback-from-debian-l10n-.patch | 66 ---- debian/patches/0004-Replace-all-escaped-slashes-in-json-strings-closes-8.patch | 27 - debian/patches/0004-small-addition-to-0.7.2-changelog.patch | 24 + debian/patches/0005-fix-zsh-compatibility-fixes-896.patch | 25 - debian/patches/0006-Ignore-output-of-openssl-req-verify.patch | 27 - debian/patches/series | 7 dehydrated | 136 ++++++++-- docs/examples/config | 15 - docs/man/dehydrated.1 | 12 16 files changed, 225 insertions(+), 212 deletions(-) diff -Nru dehydrated-0.7.1/CHANGELOG dehydrated-0.7.2/CHANGELOG --- dehydrated-0.7.1/CHANGELOG 2022-10-31 15:12:38.000000000 +0100 +++ dehydrated-0.7.2/CHANGELOG 2025-05-18 01:34:32.000000000 +0200 @@ -1,6 +1,18 @@ # Change Log This file contains a log of major changes in dehydrated +## [0.7.2] - 2025-05-18 +## Added +- Implemented support for certificate profile selection +- Added a configuration parameter to allow for timeouts during order processing (`ORDER_TIMEOUT`, defaults to 0 = no timeout) +- Allowed for automatic deletion of old files (`AUTO_CLEANUP_DELETE`, disabled by default) + +## Changed +- Renew certificates with 32 days remaining (instead of 30) to avoid issues with monthly cronjobs (`RENEW_DAYS=32`) + +## Fixed +- Changed behaviour of `openssl req` stdin handling to fix compatibility with OpenSSL version 3.2+ + ## [0.7.1] - 2022-10-31 ## Changed - `--force` no longer forces domain name revalidation by default, a new argument `--force-validation` has been added for that diff -Nru dehydrated-0.7.1/debian/changelog dehydrated-0.7.2/debian/changelog --- dehydrated-0.7.1/debian/changelog 2024-07-27 08:13:05.000000000 +0200 +++ dehydrated-0.7.2/debian/changelog 2025-06-02 16:50:35.000000000 +0200 @@ -1,3 +1,13 @@ +dehydrated (0.7.2-1) unstable; urgency=medium + + * New upstream release 0.7.2. + * Update copyright. + * Drop all patches applied upstream. + * Add patches from upstream after the 0.7.2 release. + * Bump Standards-Version to 4.7.2, no changes needed. + + -- Mattia Rizzolo <mattia@debian.org> Mon, 02 Jun 2025 16:50:35 +0200 + dehydrated (0.7.1-1) unstable; urgency=medium * New upstream release 0.7.1. Closes: #1023655 diff -Nru dehydrated-0.7.1/debian/control dehydrated-0.7.2/debian/control --- dehydrated-0.7.1/debian/control 2024-07-27 08:13:05.000000000 +0200 +++ dehydrated-0.7.2/debian/control 2025-06-02 16:50:35.000000000 +0200 @@ -10,7 +10,7 @@ debhelper-compat (= 13), dh-apache2, dh-exec, -Standards-Version: 4.7.0 +Standards-Version: 4.7.2 Rules-Requires-Root: no Vcs-Git: https://salsa.debian.org/letsencrypt-team/dehydrated.git Vcs-Browser: https://salsa.debian.org/letsencrypt-team/dehydrated diff -Nru dehydrated-0.7.1/debian/copyright dehydrated-0.7.2/debian/copyright --- dehydrated-0.7.1/debian/copyright 2024-07-27 08:08:39.000000000 +0200 +++ dehydrated-0.7.2/debian/copyright 2025-06-02 16:50:35.000000000 +0200 @@ -9,7 +9,7 @@ Files: debian/* Copyright: 2016 Daniel Beyer <dabe@deb.ymc.ch> - 2016-2024 Mattia Rizzolo <mattia@debian.org> + 2016-2025 Mattia Rizzolo <mattia@debian.org> License: Expat License: Expat diff -Nru dehydrated-0.7.1/debian/patches/0002-added-note-about-dehydrated-irc-channel.patch dehydrated-0.7.2/debian/patches/0002-added-note-about-dehydrated-irc-channel.patch --- dehydrated-0.7.1/debian/patches/0002-added-note-about-dehydrated-irc-channel.patch 2024-07-27 08:11:37.000000000 +0200 +++ dehydrated-0.7.2/debian/patches/0002-added-note-about-dehydrated-irc-channel.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,26 +0,0 @@ -From 5c4adf6baa9f65d86298d438d53bad308ddd1a60 Mon Sep 17 00:00:00 2001 -From: Lukas Schauer <lukas@schauer.dev> -Date: Mon, 31 Oct 2022 15:46:28 +0100 -Subject: [PATCH 2/6] added note about dehydrated irc channel - ---- - README.md | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/README.md b/README.md -index c03f147..7db9880 100644 ---- a/README.md -+++ b/README.md -@@ -86,3 +86,9 @@ Parameters: - --challenge (-t) http-01|dns-01|tls-alpn-01 Which challenge should be used? Currently http-01, dns-01, and tls-alpn-01 are supported - --algo (-a) rsa|prime256v1|secp384r1 Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1 - ``` -+ -+## Chat -+ -+Dehydrated has an official IRC-channel `#dehydrated` on libera.chat that can be used for general discussion and suggestions. -+ -+The channel can also be accessed with Matrix using the official libera.chat bridge at `#dehydrated:libera.chat`. --- -2.45.2 - diff -Nru dehydrated-0.7.1/debian/patches/0002-only-validate-existance-of-wellknown-directory-or-ho.patch dehydrated-0.7.2/debian/patches/0002-only-validate-existance-of-wellknown-directory-or-ho.patch --- dehydrated-0.7.1/debian/patches/0002-only-validate-existance-of-wellknown-directory-or-ho.patch 1970-01-01 01:00:00.000000000 +0100 +++ dehydrated-0.7.2/debian/patches/0002-only-validate-existance-of-wellknown-directory-or-ho.patch 2025-06-02 16:50:35.000000000 +0200 @@ -0,0 +1,36 @@ +From 3a71a7ad9472aa625a22d9fba3d89d9dc5ec391c Mon Sep 17 00:00:00 2001 +From: Lukas Schauer <lukas@schauer.dev> +Date: Sun, 18 May 2025 02:06:53 +0200 +Subject: [PATCH 2/4] only validate existance of wellknown directory or hook + script when actually necessary (fixes #965) + +--- + dehydrated | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/dehydrated b/dehydrated +index 0416cb7..ab25633 100755 +--- a/dehydrated ++++ b/dehydrated +@@ -326,11 +326,13 @@ hookscript_bricker_hook() { + # verify configuration values + verify_config() { + [[ "${CHALLENGETYPE}" == "http-01" || "${CHALLENGETYPE}" == "dns-01" || "${CHALLENGETYPE}" == "tls-alpn-01" ]] || _exiterr "Unknown challenge type ${CHALLENGETYPE}... cannot continue." +- if [[ "${CHALLENGETYPE}" = "dns-01" ]] && [[ -z "${HOOK}" ]]; then +- _exiterr "Challenge type dns-01 needs a hook script for deployment... cannot continue." +- fi +- if [[ "${CHALLENGETYPE}" = "http-01" && ! -d "${WELLKNOWN}" && ! "${COMMAND:-}" = "register" ]]; then +- _exiterr "WELLKNOWN directory doesn't exist, please create ${WELLKNOWN} and set appropriate permissions." ++ if [[ "${COMMAND:-}" =~ sign_domains|sign_csr ]]; then ++ if [[ "${CHALLENGETYPE}" = "dns-01" ]] && [[ -z "${HOOK}" ]]; then ++ _exiterr "Challenge type dns-01 needs a hook script for deployment... cannot continue." ++ fi ++ if [[ "${CHALLENGETYPE}" = "http-01" ]] && [[ ! -d "${WELLKNOWN}" ]]; then ++ _exiterr "WELLKNOWN directory doesn't exist, please create ${WELLKNOWN} and set appropriate permissions." ++ fi + fi + [[ "${KEY_ALGO}" == "rsa" || "${KEY_ALGO}" == "prime256v1" || "${KEY_ALGO}" == "secp384r1" || "${KEY_ALGO}" == "secp521r1" ]] || _exiterr "Unknown public key algorithm ${KEY_ALGO}... cannot continue." + if [[ -n "${IP_VERSION}" ]]; then +-- +2.49.0 + diff -Nru dehydrated-0.7.1/debian/patches/0003-improve-man-page-based-on-feedback-from-debian-l10n-.patch dehydrated-0.7.2/debian/patches/0003-improve-man-page-based-on-feedback-from-debian-l10n-.patch --- dehydrated-0.7.1/debian/patches/0003-improve-man-page-based-on-feedback-from-debian-l10n-.patch 2024-07-27 08:11:37.000000000 +0200 +++ dehydrated-0.7.2/debian/patches/0003-improve-man-page-based-on-feedback-from-debian-l10n-.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,66 +0,0 @@ -From fa68ad8b2302e893e2ce9d4b4cd3a87a00021f1c Mon Sep 17 00:00:00 2001 -From: Daniel Molkentin <daniel@molkentin.de> -Date: Thu, 12 May 2022 11:41:13 +0200 -Subject: [PATCH 3/6] improve man page based on feedback from - debian-l10n-english (fixes #873, closes #875) - -Also propagate changes to dehydrated help and README.md ---- - README.md | 2 +- - dehydrated | 2 +- - docs/man/dehydrated.1 | 6 +++--- - 3 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/README.md b/README.md -index 7db9880..c9e532d 100644 ---- a/README.md -+++ b/README.md -@@ -71,7 +71,7 @@ Parameters: - --ca url/preset Use specified CA URL or preset - --alias certalias Use specified name for certificate directory (and per-certificate config) instead of the primary domain (only used if --domain is specified) - --keep-going (-g) Keep going after encountering an error while creating/renewing multiple certificates in cron mode -- --force (-x) Force renew of certificate even if it is longer valid than value in RENEW_DAYS -+ --force (-x) Force certificate renewal even if it is not due to expire within RENEW_DAYS - --force-validation Force revalidation of domain names (used in combination with --force) - --no-lock (-n) Don't use lockfile (potentially dangerous!) - --lock-suffix example.com Suffix lockfile name with a string (useful for with -d) -diff --git a/dehydrated b/dehydrated -index 2befdfb..791fe41 100755 ---- a/dehydrated -+++ b/dehydrated -@@ -2262,7 +2262,7 @@ main() { - ;; - - # PARAM_Usage: --force (-x) -- # PARAM_Description: Force renew of certificate even if it is longer valid than value in RENEW_DAYS -+ # PARAM_Description: Force certificate renewal even if it is not due to expire within RENEW_DAYS - --force|-x) - PARAM_FORCE="yes" - ;; -diff --git a/docs/man/dehydrated.1 b/docs/man/dehydrated.1 -index d866fec..1dadc69 100644 ---- a/docs/man/dehydrated.1 -+++ b/docs/man/dehydrated.1 -@@ -20,8 +20,8 @@ Dehydrated will notify if no account is configured. Run with \fB--register - - Next, all domain names must be provided in domains.txt. The format is line - based: If the file contains two lines "example.com" and "example.net", --Dehydrated will request two certificate, one for "example.com" and the other --for "example.net". A single line while "example.com example.net" will request a -+dehydrated will request two certificate, one for "example.com" and the other -+for "example.net". A single line containing "example.com example.net" will request a - single certificate valid for both "example.net" and "example.com" through the \fISubject - Alternative Name\fR (SAN) field. - -@@ -106,7 +106,7 @@ Keep going after encountering an error while creating/renewing multiple - certificates in cron mode - .TP - .BR \-\-force ", " \-x --Force renew of certificate even if it is longer valid than value in RENEW_DAYS -+Force certificate renewal even if it is not due to expire within RENEW_DAYS - .TP - .BR \-\-no\-lock ", " \-n - Don't use lockfile (potentially dangerous!) --- -2.45.2 - diff -Nru dehydrated-0.7.1/debian/patches/0004-Replace-all-escaped-slashes-in-json-strings-closes-8.patch dehydrated-0.7.2/debian/patches/0004-Replace-all-escaped-slashes-in-json-strings-closes-8.patch --- dehydrated-0.7.1/debian/patches/0004-Replace-all-escaped-slashes-in-json-strings-closes-8.patch 2024-07-27 08:11:37.000000000 +0200 +++ dehydrated-0.7.2/debian/patches/0004-Replace-all-escaped-slashes-in-json-strings-closes-8.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,27 +0,0 @@ -From 67b111a7b09374182bbba2bf3feecbbd549c0df2 Mon Sep 17 00:00:00 2001 -From: Alexander Sulfrian <asulfrian@zedat.fu-berlin.de> -Date: Fri, 4 Feb 2022 20:34:22 +0100 -Subject: [PATCH 4/6] Replace all escaped slashes in json strings (closes #866) - -${var/pattern/string} will only replace the first occurence. We should -use ${var//pattern/string} to replace all escaped slashes. ---- - dehydrated | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dehydrated b/dehydrated -index 791fe41..c11d7d0 100755 ---- a/dehydrated -+++ b/dehydrated -@@ -217,7 +217,7 @@ jsonsh() { - '[') parse_array "$jpath" ;; - # At this point, the only valid single-character tokens are digits. - ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; -- *) value="${token/\\\///}" -+ *) value="${token//\\\///}" - # replace solidus ("\/") in json strings with normalized value: "/" - ;; - esac --- -2.45.2 - diff -Nru dehydrated-0.7.1/debian/patches/0004-small-addition-to-0.7.2-changelog.patch dehydrated-0.7.2/debian/patches/0004-small-addition-to-0.7.2-changelog.patch --- dehydrated-0.7.1/debian/patches/0004-small-addition-to-0.7.2-changelog.patch 1970-01-01 01:00:00.000000000 +0100 +++ dehydrated-0.7.2/debian/patches/0004-small-addition-to-0.7.2-changelog.patch 2025-06-02 16:50:35.000000000 +0200 @@ -0,0 +1,24 @@ +From 9cfcd66f156f75f130a065164b1a27e87e9246c2 Mon Sep 17 00:00:00 2001 +From: Lukas Schauer <lukas@schauer.dev> +Date: Sun, 18 May 2025 02:28:57 +0200 +Subject: [PATCH 4/4] small addition to 0.7.2 changelog + +--- + CHANGELOG | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/CHANGELOG b/CHANGELOG +index d16be92..4c5e516 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -10,6 +10,7 @@ This file contains a log of major changes in dehydrated + - Implemented support for certificate profile selection + - Added a configuration parameter to allow for timeouts during order processing (`ORDER_TIMEOUT`, defaults to 0 = no timeout) + - Allowed for automatic deletion of old files (`AUTO_CLEANUP_DELETE`, disabled by default) ++- Added CA presets for Google Trust Services (prod: google, test: google-test) + + ## Changed + - Renew certificates with 32 days remaining (instead of 30) to avoid issues with monthly cronjobs (`RENEW_DAYS=32`) +-- +2.49.0 + diff -Nru dehydrated-0.7.1/debian/patches/0005-fix-zsh-compatibility-fixes-896.patch dehydrated-0.7.2/debian/patches/0005-fix-zsh-compatibility-fixes-896.patch --- dehydrated-0.7.1/debian/patches/0005-fix-zsh-compatibility-fixes-896.patch 2024-07-27 08:11:37.000000000 +0200 +++ dehydrated-0.7.2/debian/patches/0005-fix-zsh-compatibility-fixes-896.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,25 +0,0 @@ -From e3ef43c816f73d443f32410862d9253d35cf3f99 Mon Sep 17 00:00:00 2001 -From: Lukas Schauer <lukas@schauer.dev> -Date: Mon, 16 Jan 2023 22:41:05 +0100 -Subject: [PATCH 5/6] fix zsh compatibility (fixes #896) - ---- - dehydrated | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dehydrated b/dehydrated -index c11d7d0..a2bff40 100755 ---- a/dehydrated -+++ b/dehydrated -@@ -143,7 +143,7 @@ jsonsh() { - - # Force zsh to expand $A into multiple words - local is_wordsplit_disabled -- is_wordsplit_disabled="$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')" -+ is_wordsplit_disabled="$(unsetopt 2>/dev/null | grep -c '^shwordsplit$' || true)" - if [ "${is_wordsplit_disabled}" != "0" ]; then setopt shwordsplit; fi - $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | grep -Ev "^$SPACE$" - if [ "${is_wordsplit_disabled}" != "0" ]; then unsetopt shwordsplit; fi --- -2.45.2 - diff -Nru dehydrated-0.7.1/debian/patches/0006-Ignore-output-of-openssl-req-verify.patch dehydrated-0.7.2/debian/patches/0006-Ignore-output-of-openssl-req-verify.patch --- dehydrated-0.7.1/debian/patches/0006-Ignore-output-of-openssl-req-verify.patch 2024-07-27 08:11:37.000000000 +0200 +++ dehydrated-0.7.2/debian/patches/0006-Ignore-output-of-openssl-req-verify.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,27 +0,0 @@ -From 4fd777e87e589652b1127b79ac6688ed7cb151fe Mon Sep 17 00:00:00 2001 -From: Wilfried Teiken <wteiken@teiken.org> -Date: Sun, 3 Dec 2023 15:07:01 -0500 -Subject: [PATCH 6/6] Ignore output of 'openssl req -verify'. - -Newer versions of openssl seem to send the verify outout to stdout instead of -stderr in the past. Ignore that output when retrieving altnames. ---- - dehydrated | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dehydrated b/dehydrated -index a2bff40..a15fb04 100755 ---- a/dehydrated -+++ b/dehydrated -@@ -1011,7 +1011,7 @@ signed_request() { - extract_altnames() { - csr="${1}" # the CSR itself (not a file) - -- if ! <<<"${csr}" "${OPENSSL}" req -verify -noout 2>/dev/null; then -+ if ! <<<"${csr}" "${OPENSSL}" req -verify -noout >/dev/null 2>&1; then - _exiterr "Certificate signing request isn't valid" - fi - --- -2.45.2 - diff -Nru dehydrated-0.7.1/debian/patches/series dehydrated-0.7.2/debian/patches/series --- dehydrated-0.7.1/debian/patches/series 2024-07-27 08:12:22.000000000 +0200 +++ dehydrated-0.7.2/debian/patches/series 2025-06-02 16:50:35.000000000 +0200 @@ -1,5 +1,2 @@ -0002-added-note-about-dehydrated-irc-channel.patch -0003-improve-man-page-based-on-feedback-from-debian-l10n-.patch -0004-Replace-all-escaped-slashes-in-json-strings-closes-8.patch -0005-fix-zsh-compatibility-fixes-896.patch -0006-Ignore-output-of-openssl-req-verify.patch +0002-only-validate-existance-of-wellknown-directory-or-ho.patch +0004-small-addition-to-0.7.2-changelog.patch diff -Nru dehydrated-0.7.1/dehydrated dehydrated-0.7.2/dehydrated --- dehydrated-0.7.1/dehydrated 2022-10-31 15:12:38.000000000 +0100 +++ dehydrated-0.7.2/dehydrated 2025-05-18 01:34:32.000000000 +0200 @@ -17,7 +17,7 @@ exec 3>&- exec 4>&- -VERSION="0.7.1" +VERSION="0.7.2" # Find directory in which this script is stored by traversing all symbolic links SOURCE="${0}" @@ -143,7 +143,7 @@ # Force zsh to expand $A into multiple words local is_wordsplit_disabled - is_wordsplit_disabled="$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')" + is_wordsplit_disabled="$(unsetopt 2>/dev/null | grep -c '^shwordsplit$' || true)" if [ "${is_wordsplit_disabled}" != "0" ]; then setopt shwordsplit; fi $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | grep -Ev "^$SPACE$" if [ "${is_wordsplit_disabled}" != "0" ]; then unsetopt shwordsplit; fi @@ -217,7 +217,7 @@ '[') parse_array "$jpath" ;; # At this point, the only valid single-character tokens are digits. ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;; - *) value="${token/\\\///}" + *) value="${token//\\\///}" # replace solidus ("\/") in json strings with normalized value: "/" ;; esac @@ -291,6 +291,8 @@ __OPENSSL_CNF="${OPENSSL_CNF}" __RENEW_DAYS="${RENEW_DAYS}" __IP_VERSION="${IP_VERSION}" + __ACME_PROFILE="${ACME_PROFILE}" + __ORDER_TIMEOUT=${ORDER_TIMEOUT} } reset_configvars() { @@ -309,6 +311,8 @@ OPENSSL_CNF="${__OPENSSL_CNF}" RENEW_DAYS="${__RENEW_DAYS}" IP_VERSION="${__IP_VERSION}" + ACME_PROFILE="${__ACME_PROFILE}" + ORDER_TIMEOUT=${__ORDER_TIMEOUT} } hookscript_bricker_hook() { @@ -334,6 +338,7 @@ fi [[ "${API}" == "auto" || "${API}" == "1" || "${API}" == "2" ]] || _exiterr "Unsupported API version defined in config: ${API}" [[ "${OCSP_DAYS}" =~ ^[0-9]+$ ]] || _exiterr "OCSP_DAYS must be a number" + [[ "${ORDER_TIMEOUT}" =~ ^[0-9]+$ ]] || _exiterr "ORDER_TIMEOUT must be a number" } # Setup default config values, search for and load configuration files @@ -355,6 +360,8 @@ CA_LETSENCRYPT_TEST="https://acme-staging-v02.api.letsencrypt.org/directory" CA_BUYPASS="https://api.buypass.com/acme/directory" CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" + CA_GOOGLE="https://dv.acme-v02.api.pki.goog/directory" + CA_GOOGLE_TEST="https://dv.acme-v02.test-api.pki.goog/directory" # Default values CA="letsencrypt" @@ -372,7 +379,7 @@ HOOK= PREFERRED_CHAIN= HOOK_CHAIN="no" - RENEW_DAYS="30" + RENEW_DAYS="32" KEYSIZE="4096" WELLKNOWN= PRIVATE_KEY_RENEW="yes" @@ -388,9 +395,12 @@ IP_VERSION= CHAINCACHE= AUTO_CLEANUP="no" + AUTO_CLEANUP_DELETE="no" DEHYDRATED_USER= DEHYDRATED_GROUP= API="auto" + ACME_PROFILE="" + ORDER_TIMEOUT=0 if [[ -z "${CONFIG:-}" ]]; then echo "#" >&2 @@ -481,6 +491,10 @@ CA="${CA_BUYPASS}" elif [ "${CA}" = "buypass-test" ]; then CA="${CA_BUYPASS_TEST}" + elif [ "${CA}" = "google" ]; then + CA="${CA_GOOGLE}" + elif [ "${CA}" = "google-test" ]; then + CA="${CA_GOOGLE_TEST}" fi if [[ -z "${OLDCA}" ]] && [[ "${CA}" = "https://acme-v02.api.letsencrypt.org/directory" ]]; then @@ -544,6 +558,8 @@ [[ -n "${PARAM_KEY_ALGO:-}" ]] && KEY_ALGO="${PARAM_KEY_ALGO}" [[ -n "${PARAM_OCSP_MUST_STAPLE:-}" ]] && OCSP_MUST_STAPLE="${PARAM_OCSP_MUST_STAPLE}" [[ -n "${PARAM_IP_VERSION:-}" ]] && IP_VERSION="${PARAM_IP_VERSION}" + [[ -n "${PARAM_ACME_PROFILE:-}" ]] && ACME_PROFILE="${PARAM_ACME_PROFILE}" + [[ -n "${PARAM_ORDER_TIMEOUT:-}" ]] && ORDER_TIMEOUT="${PARAM_ORDER_TIMEOUT}" if [ "${PARAM_FORCE_VALIDATION:-no}" = "yes" ] && [ "${PARAM_FORCE:-no}" = "no" ]; then _exiterr "Argument --force-validation can only be used in combination with --force (-x)" @@ -587,6 +603,10 @@ _exiterr "Problem retrieving ACME/CA-URLs, check if your configured CA points to the directory entrypoint." # Since reg URI is missing from directory we will assume it is the same as CA_NEW_REG without the new part CA_REG=${CA_NEW_REG/new-reg/reg} + + if [[ -n "${ACME_PROFILE}" ]]; then + _exiterr "ACME profiles are not supported in ACME v1." + fi else CA_NEW_ORDER="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newOrder)" && CA_NEW_NONCE="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newNonce)" && @@ -595,6 +615,35 @@ CA_REQUIRES_EAB="$(printf "%s" "${CA_DIRECTORY}" | get_json_bool_value -p '"meta","externalAccountRequired"' || echo false)" && CA_REVOKE_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value revokeCert)" || _exiterr "Problem retrieving ACME/CA-URLs, check if your configured CA points to the directory entrypoint." + + # Checking ACME profile + if [[ -n "${ACME_PROFILE}" ]]; then + # Extract available profiles from CA directory + declare -A available_profiles=() + while IFS=$'\t' read -r path value; do + if [[ "${value}" =~ ^\"([^\"]+)\"$ ]]; then + value=${BASH_REMATCH[1]} + fi + if [[ "${path}" =~ ^\[\"([^\"]+)\"\]$ ]]; then + available_profiles[${BASH_REMATCH[1]}]=$value + fi + done <<< "$(printf "%s" "${CA_DIRECTORY}" | get_json_dict_value -p '"meta","profiles"' 2>/dev/null)" + if [[ ${#available_profiles[@]} -eq 0 ]]; then + _exiterr "ACME profile not supported by this CA" + fi + + # Check if the requested profile is available + found_profile="no" + for profile in "${!available_profiles[@]}"; do + if [[ "${profile}" == "${ACME_PROFILE}" ]]; then + found_profile="yes" + break + fi + done + if [[ "${found_profile}" == "no" ]]; then + _exiterr "ACME profile '${ACME_PROFILE}' not found, available profiles:$(for key in "${!available_profiles[@]}"; do printf "\n %s: %s" "${key}" "${available_profiles[$key]}"; done)" + fi + fi fi # Export some environment variables to be used in hook script @@ -703,6 +752,14 @@ fi fi + # Google special sauce + if [[ "${CA}" = "${CA_GOOGLE}" ]]; then + if [[ -z "${CONTACT_EMAIL}" ]] || [[ -z "${EAB_KID:-}" ]] || [[ -z "${EAB_HMAC_KEY:-}" ]]; then + echo "Google requires contact email, EAB_KID and EAB_HMAC_KEY to be manually configured (see https://cloud.google.com/certificate-manager/docs/public-ca-tutorial)" + FAILED=true + fi + fi + # Check if external account is required if [[ "${FAILED}" = "false" ]]; then if [[ "${CA_REQUIRES_EAB}" = "true" ]]; then @@ -1009,13 +1066,13 @@ # Extracts all subject names from a CSR # Outputs either the CN, or the SANs, one per line extract_altnames() { - csr="${1}" # the CSR itself (not a file) + csrfile="${1}" # path to CSR file - if ! <<<"${csr}" "${OPENSSL}" req -verify -noout 2>/dev/null; then + if ! "${OPENSSL}" req -in "${csrfile}" -verify -noout >/dev/null; then _exiterr "Certificate signing request isn't valid" fi - reqtext="$( <<<"${csr}" "${OPENSSL}" req -noout -text )" + reqtext="$("${OPENSSL}" req -in "${csrfile}" -noout -text)" if <<<"${reqtext}" grep -q '^[[:space:]]*X509v3 Subject Alternative Name:[[:space:]]*$'; then # SANs used, extract these altnames="$( <<<"${reqtext}" awk '/X509v3 Subject Alternative Name:/{print;getline;print;}' | tail -n1 )" @@ -1043,7 +1100,7 @@ # Create certificate for domain(s) and outputs it FD 3 sign_csr() { - csr="${1}" # the CSR itself (not a file) + csrfile="${1}" # path to CSR file if { true >&3; } 2>/dev/null; then : # fd 3 looks OK @@ -1082,7 +1139,12 @@ challenge_identifiers="[${challenge_identifiers%, }]" echo " + Requesting new certificate order from CA..." - order_location="$(signed_request "${CA_NEW_ORDER}" '{"identifiers": '"${challenge_identifiers}"'}' 4>&1 | grep -i ^Location: | cut -d':' -f2- | tr -d ' \t\r\n')" + local order_payload='{"identifiers": '"${challenge_identifiers}" + if [[ -n "${ACME_PROFILE}" ]]; then + order_payload="${order_payload}"',"profile":"'"${ACME_PROFILE}"'"' + fi + order_payload="${order_payload}"'}' + order_location="$(signed_request "${CA_NEW_ORDER}" "${order_payload}" 4>&1 | grep -i ^Location: | cut -d':' -f2- | tr -d ' \t\r\n')" result="$(signed_request "${order_location}" "" | jsonsh)" order_authorizations="$(echo "${result}" | get_json_array_values authorizations)" @@ -1268,25 +1330,30 @@ # Finally request certificate from the acme-server and store it in cert-${timestamp}.pem and link from cert.pem echo " + Requesting certificate..." - csr64="$( <<<"${csr}" "${OPENSSL}" req -config "${OPENSSL_CNF}" -outform DER | urlbase64)" + csr64="$("${OPENSSL}" req -in "${csrfile}" -config "${OPENSSL_CNF}" -outform DER | urlbase64)" if [[ ${API} -eq 1 ]]; then crt64="$(signed_request "${CA_NEW_CERT}" '{"resource": "new-cert", "csr": "'"${csr64}"'"}' | "${OPENSSL}" base64 -e)" crt="$( printf -- '-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n' "${crt64}" )" else result="$(signed_request "${finalize}" '{"csr": "'"${csr64}"'"}' | jsonsh)" + waited=0 while :; do orderstatus="$(echo "${result}" | get_json_string_value status)" case "${orderstatus}" in "processing" | "pending") + if [ ${ORDER_TIMEOUT} -gt 0 ] && [ ${waited} -gt ${ORDER_TIMEOUT} ]; then + _exiterr "Timed out waiting for processing of order (still ${orderstatus})" + fi echo " + Order is ${orderstatus}..." sleep 2; + waited=$((waited+2)) ;; "valid") break; ;; *) - _exiterr "Order in status ${orderstatus}" + _exiterr "Order has invalid/unknown status: ${orderstatus}" ;; esac result="$(signed_request "${order_location}" "" | jsonsh)" @@ -1510,7 +1577,7 @@ crt_path="${certdir}/cert-${timestamp}.pem" # shellcheck disable=SC2086 - sign_csr "$(< "${certdir}/cert-${timestamp}.csr")" ${altnames} 3>"${crt_path}" + sign_csr "${certdir}/cert-${timestamp}.csr" ${altnames} 3>"${crt_path}" # Create fullchain.pem echo " + Creating fullchain.pem..." @@ -1775,7 +1842,7 @@ # All settings that are allowed here should also be stored and # restored in store_configvars() and reset_configvars() case "${config_var}" in - KEY_ALGO|OCSP_MUST_STAPLE|OCSP_FETCH|OCSP_DAYS|PRIVATE_KEY_RENEW|PRIVATE_KEY_ROLLOVER|KEYSIZE|CHALLENGETYPE|HOOK|PREFERRED_CHAIN|WELLKNOWN|HOOK_CHAIN|OPENSSL_CNF|RENEW_DAYS) + KEY_ALGO|OCSP_MUST_STAPLE|OCSP_FETCH|OCSP_DAYS|PRIVATE_KEY_RENEW|PRIVATE_KEY_ROLLOVER|KEYSIZE|CHALLENGETYPE|HOOK|PREFERRED_CHAIN|WELLKNOWN|HOOK_CHAIN|OPENSSL_CNF|RENEW_DAYS|ACME_PROFILE|ORDER_TIMEOUT) echo " + ${config_var} = ${config_value}" declare -- "${config_var}=${config_value}" ;; @@ -1792,16 +1859,18 @@ skip="no" # Allow for external CSR generation - local csr="" + local csrfile="" if [[ -n "${HOOK}" ]]; then csr="$("${HOOK}" "generate_csr" "${domain}" "${certdir}" "${domain} ${morenames}")" || _exiterr 'generate_csr hook returned with non-zero exit code' if grep -qE "\-----BEGIN (NEW )?CERTIFICATE REQUEST-----" <<< "${csr}"; then - altnames="$(extract_altnames "${csr}")" + csrfile="$(_mktemp)" + cat > "${csrfile}" <<< "${csr}" + altnames="$(extract_altnames "${csrfile}")" domain="$(cut -d' ' -f1 <<< "${altnames}")" morenames="$(cut -s -d' ' -f2- <<< "${altnames}")" echo " + Using CSR from hook script (real names: ${altnames})" else - csr="" + csrfile="" fi fi @@ -1851,7 +1920,10 @@ # Sign certificate for this domain if [[ ! "${skip}" = "yes" ]]; then update_ocsp="yes" - [[ -z "${csr}" ]] || printf "%s" "${csr}" > "${certdir}/cert-${timestamp}.csr" + if [[ -n "${csrfile}" ]]; then + cat "${csrfile}" > "${certdir}/cert-${timestamp}.csr" + rm "${csrfile}" + fi # shellcheck disable=SC2086 if [[ "${PARAM_KEEP_GOING:-}" = "yes" ]]; then skip_exit_hook=yes @@ -1895,8 +1967,8 @@ [[ -n "${HOOK}" ]] && ("${HOOK}" "exit_hook" || echo 'exit_hook returned with non-zero exit code!' >&2) if [[ "${AUTO_CLEANUP}" == "yes" ]]; then - echo "+ Running automatic cleanup" - command_cleanup noinit + echo " + Running automatic cleanup" + PARAM_CLEANUPDELETE="${AUTO_CLEANUP_DELETE:-no}" command_cleanup noinit | _sed 's/^/ + /g' fi exit "${exit_with_errorcode}" @@ -1912,19 +1984,18 @@ exec 3>&1 1>&2 # load csr - csrfile="${1}" + local csrfile="${1}" if [ ! -r "${csrfile}" ]; then _exiterr "Could not read certificate signing request ${csrfile}" fi - csr="$(cat "${csrfile}")" # extract names - altnames="$(extract_altnames "${csr}")" + altnames="$(extract_altnames "${csrfile}")" # gen cert certfile="$(_mktemp)" # shellcheck disable=SC2086 - sign_csr "${csr}" ${altnames} 3> "${certfile}" + sign_csr "${csrfile}" ${altnames} 3> "${certfile}" # print cert echo "# CERT #" >&3 @@ -2262,7 +2333,7 @@ ;; # PARAM_Usage: --force (-x) - # PARAM_Description: Force renew of certificate even if it is longer valid than value in RENEW_DAYS + # PARAM_Description: Force certificate renewal even if it is not due to expire within RENEW_DAYS --force|-x) PARAM_FORCE="yes" ;; @@ -2364,6 +2435,23 @@ check_parameters "${1:-}" PARAM_KEY_ALGO="${1}" ;; + + # PARAM_Usage: --acme-profile profile_name + # PARAM_Description: Use specified ACME profile + --acme-profile) + shift 1 + check_parameters "${1:-}" + PARAM_ACME_PROFILE="${1}" + ;; + + # PARAM_Usage: --order-timeout seconds + # PARAM_Description: Amount of seconds to wait for processing of order until erroring out + --order-timeout) + shift 1 + check_parameters "${1:-}" + PARAM_ORDER_TIMEOUT=${1} + ;; + *) echo "Unknown parameter detected: ${1}" >&2 echo >&2 diff -Nru dehydrated-0.7.1/docs/examples/config dehydrated-0.7.2/docs/examples/config --- dehydrated-0.7.1/docs/examples/config 2022-10-31 15:12:38.000000000 +0100 +++ dehydrated-0.7.2/docs/examples/config 2025-05-18 01:34:32.000000000 +0200 @@ -22,7 +22,7 @@ #IP_VERSION= # URL to certificate authority or internal preset -# Presets: letsencrypt, letsencrypt-test, zerossl, buypass, buypass-test +# Presets: letsencrypt, letsencrypt-test, zerossl, buypass, buypass-test, google, google-test # default: letsencrypt #CA="letsencrypt" @@ -92,8 +92,8 @@ # Chain clean_challenge|deploy_challenge arguments together into one hook call per certificate (default: no) #HOOK_CHAIN="no" -# Minimum days before expiration to automatically renew certificate (default: 30) -#RENEW_DAYS="30" +# Minimum days before expiration to automatically renew certificate (default: 32) +#RENEW_DAYS="32" # Regenerate private keys instead of just signing new certificates on renewal (default: yes) #PRIVATE_KEY_RENEW="yes" @@ -125,8 +125,17 @@ # Automatic cleanup (default: no) #AUTO_CLEANUP="no" +# Delete files during automatic cleanup instead of moving to archive (default: no) +#AUTO_CLEANUP_DELETE="no" + # ACME API version (default: auto) #API=auto # Preferred issuer chain (default: <unset> -> uses default chain) #PREFERRED_CHAIN= + +# Request certificate with specific profile (default: <unset>) +#ACME_PROFILE= + +# Amount of seconds to wait for processing of order until erroring out (default: 0 => no timeout) +#ORDER_TIMEOUT=0 diff -Nru dehydrated-0.7.1/docs/man/dehydrated.1 dehydrated-0.7.2/docs/man/dehydrated.1 --- dehydrated-0.7.1/docs/man/dehydrated.1 2022-10-31 15:12:38.000000000 +0100 +++ dehydrated-0.7.2/docs/man/dehydrated.1 2025-05-18 01:34:32.000000000 +0200 @@ -20,13 +20,13 @@ Next, all domain names must be provided in domains.txt. The format is line based: If the file contains two lines "example.com" and "example.net", -Dehydrated will request two certificate, one for "example.com" and the other -for "example.net". A single line while "example.com example.net" will request a +dehydrated will request two certificate, one for "example.com" and the other +for "example.net". A single line containing "example.com example.net" will request a single certificate valid for both "example.net" and "example.com" through the \fISubject Alternative Name\fR (SAN) field. For the next step, one way of verifying domain name ownership needs to be -configured. Dehydrated implements \fIhttp-01\fR and \fIdns-01\fR verification. +configured. Dehydrated implements \fIhttp-01\fR and \fIdns-01\fR verification. The \fIhttp-01\fR verification provides proof of ownership by providing a challenge token. In order to do that, the directory referenced in the @@ -106,7 +106,7 @@ certificates in cron mode .TP .BR \-\-force ", " \-x -Force renew of certificate even if it is longer valid than value in RENEW_DAYS +Force certificate renewal even if it is not due to expire within RENEW_DAYS .TP .BR \-\-no\-lock ", " \-n Don't use lockfile (potentially dangerous!) @@ -139,7 +139,7 @@ The program exits 0 if everything was fine, 1 if an error occurred. .SH BUGS Please report any bugs that you may encounter at the project web site -.UR https://github.com/lukas2511/dehydrated/issues +.UR https://github.com/dehydrated-io/dehydrated/issues .UE . .SH AUTHOR Dehydrated was written by Lukas Schauer. This man page was contributed by @@ -151,5 +151,5 @@ .SH SEE ALSO Full documentation along with configuration examples are provided in the \fIdocs\fR directory of the distribution, or at -.UR https://github.com/lukas2511/dehydrated/tree/master/docs +.UR https://github.com/dehydrated-io/dehydrated/tree/master/docs .UE . diff -Nru dehydrated-0.7.1/README.md dehydrated-0.7.2/README.md --- dehydrated-0.7.1/README.md 2022-10-31 15:12:38.000000000 +0100 +++ dehydrated-0.7.2/README.md 2025-05-18 01:34:32.000000000 +0200 @@ -71,7 +71,7 @@ --ca url/preset Use specified CA URL or preset --alias certalias Use specified name for certificate directory (and per-certificate config) instead of the primary domain (only used if --domain is specified) --keep-going (-g) Keep going after encountering an error while creating/renewing multiple certificates in cron mode - --force (-x) Force renew of certificate even if it is longer valid than value in RENEW_DAYS + --force (-x) Force certificate renewal even if it is not due to expire within RENEW_DAYS --force-validation Force revalidation of domain names (used in combination with --force) --no-lock (-n) Don't use lockfile (potentially dangerous!) --lock-suffix example.com Suffix lockfile name with a string (useful for with -d) @@ -85,4 +85,12 @@ --alpn alpn-certs/directory Output alpn verification certificates into the specified directory --challenge (-t) http-01|dns-01|tls-alpn-01 Which challenge should be used? Currently http-01, dns-01, and tls-alpn-01 are supported --algo (-a) rsa|prime256v1|secp384r1 Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1 + --acme-profile profile_name Use specified ACME profile + --order-timeout seconds Amount of seconds to wait for processing of order until erroring out ``` + +## Chat + +Dehydrated has an official IRC-channel `#dehydrated` on libera.chat that can be used for general discussion and suggestions. + +The channel can also be accessed with Matrix using the official libera.chat bridge at `#dehydrated:libera.chat`.--- dehydrated_0.7.1-1_all.deb +++ dehydrated_0.7.2-1_all.deb ├── file list │ @@ -1,3 +1,3 @@ │ --rw-r--r-- 0 0 0 4 2024-07-27 06:13:05.000000 debian-binary │ --rw-r--r-- 0 0 0 1420 2024-07-27 06:13:05.000000 control.tar.xz │ --rw-r--r-- 0 0 0 118924 2024-07-27 06:13:05.000000 data.tar.xz │ +-rw-r--r-- 0 0 0 4 2025-06-02 14:50:35.000000 debian-binary │ +-rw-r--r-- 0 0 0 1420 2025-06-02 14:50:35.000000 control.tar.xz │ +-rw-r--r-- 0 0 0 120076 2025-06-02 14:50:35.000000 data.tar.xz ├── control.tar.xz │ ├── control.tar │ │ ├── file list │ │ │ @@ -1,4 +1,4 @@ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./ │ │ │ --rw-r--r-- 0 root (0) root (0) 23 2024-07-27 06:13:05.000000 ./conffiles │ │ │ --rw-r--r-- 0 root (0) root (0) 799 2024-07-27 06:13:05.000000 ./control │ │ │ --rw-r--r-- 0 root (0) root (0) 1666 2024-07-27 06:13:05.000000 ./md5sums │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./ │ │ │ +-rw-r--r-- 0 root (0) root (0) 23 2025-06-02 14:50:35.000000 ./conffiles │ │ │ +-rw-r--r-- 0 root (0) root (0) 799 2025-06-02 14:50:35.000000 ./control │ │ │ +-rw-r--r-- 0 root (0) root (0) 1666 2025-06-02 14:50:35.000000 ./md5sums │ │ ├── ./control │ │ │ @@ -1,12 +1,12 @@ │ │ │ Package: dehydrated │ │ │ -Version: 0.7.1-1 │ │ │ +Version: 0.7.2-1 │ │ │ Architecture: all │ │ │ Maintainer: Debian Let's Encrypt Team <team+letsencrypt@tracker.debian.org> │ │ │ -Installed-Size: 239 │ │ │ +Installed-Size: 244 │ │ │ Depends: ca-certificates, curl, openssl │ │ │ Section: misc │ │ │ Priority: optional │ │ │ Multi-Arch: foreign │ │ │ Homepage: https://dehydrated.io │ │ │ Description: ACME client implemented in Bash │ │ │ The dehydrated ACME client allows signing certificates with an │ │ ├── ./md5sums │ │ │ ├── ./md5sums │ │ │ │┄ Files differ ├── data.tar.xz │ ├── data.tar │ │ ├── file list │ │ │ @@ -1,41 +1,41 @@ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./etc/ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./etc/dehydrated/ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./etc/dehydrated/conf.d/ │ │ │ --rw-r--r-- 0 root (0) root (0) 762 2024-07-27 06:13:05.000000 ./etc/dehydrated/config │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/bin/ │ │ │ --rwxr-xr-x 0 root (0) root (0) 88977 2024-07-27 06:13:05.000000 ./usr/bin/dehydrated │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/share/ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/share/doc/ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/share/doc/dehydrated/ │ │ │ --rw-r--r-- 0 root (0) root (0) 2668 2024-07-27 06:08:25.000000 ./usr/share/doc/dehydrated/README.Debian │ │ │ --rw-r--r-- 0 root (0) root (0) 2512 2024-07-27 06:13:05.000000 ./usr/share/doc/dehydrated/README.md.gz │ │ │ --rw-r--r-- 0 root (0) root (0) 907 2024-07-27 06:13:05.000000 ./usr/share/doc/dehydrated/changelog.Debian.gz │ │ │ --rw-r--r-- 0 root (0) root (0) 2818 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/changelog.gz │ │ │ --rw-r--r-- 0 root (0) root (0) 1465 2024-07-27 06:08:39.000000 ./usr/share/doc/dehydrated/copyright │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/share/doc/dehydrated/docs/ │ │ │ --rw-r--r-- 0 root (0) root (0) 1709 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/acme-v1.md │ │ │ --rw-r--r-- 0 root (0) root (0) 1895 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/dns-verification.md │ │ │ --rw-r--r-- 0 root (0) root (0) 3525 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/domains_txt.md │ │ │ --rw-r--r-- 0 root (0) root (0) 174 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/ecc.md │ │ │ --rw-r--r-- 0 root (0) root (0) 2892 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/hook_chain.md │ │ │ --rw-r--r-- 0 root (0) root (0) 76482 2024-07-27 06:13:05.000000 ./usr/share/doc/dehydrated/docs/logo.png │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/share/doc/dehydrated/docs/man/ │ │ │ --rw-r--r-- 0 root (0) root (0) 2486 2024-07-27 06:13:05.000000 ./usr/share/doc/dehydrated/docs/man/dehydrated.1.gz │ │ │ --rw-r--r-- 0 root (0) root (0) 744 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/per-certificate-config.md │ │ │ --rw-r--r-- 0 root (0) root (0) 546 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/staging.md │ │ │ --rw-r--r-- 0 root (0) root (0) 1850 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/tls-alpn.md.gz │ │ │ --rw-r--r-- 0 root (0) root (0) 3549 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/troubleshooting.md │ │ │ --rw-r--r-- 0 root (0) root (0) 2677 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/docs/wellknown.md │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/share/doc/dehydrated/examples/ │ │ │ --rw-r--r-- 0 root (0) root (0) 4770 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/examples/config │ │ │ --rw-r--r-- 0 root (0) root (0) 1846 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/examples/domains.txt │ │ │ --rwxr-xr-x 0 root (0) root (0) 7745 2022-10-31 14:12:38.000000 ./usr/share/doc/dehydrated/examples/hook.sh │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/share/man/ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./usr/share/man/man1/ │ │ │ --rw-r--r-- 0 root (0) root (0) 2486 2024-07-27 06:13:05.000000 ./usr/share/man/man1/dehydrated.1.gz │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./var/ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./var/lib/ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./var/lib/dehydrated/ │ │ │ -drwxr-xr-x 0 root (0) root (0) 0 2024-07-27 06:13:05.000000 ./var/lib/dehydrated/acme-challenges/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./etc/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./etc/dehydrated/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./etc/dehydrated/conf.d/ │ │ │ +-rw-r--r-- 0 root (0) root (0) 762 2025-06-02 14:50:35.000000 ./etc/dehydrated/config │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/bin/ │ │ │ +-rwxr-xr-x 0 root (0) root (0) 92503 2025-06-02 14:50:35.000000 ./usr/bin/dehydrated │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/share/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/share/doc/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/share/doc/dehydrated/ │ │ │ +-rw-r--r-- 0 root (0) root (0) 2668 2025-06-02 14:50:35.000000 ./usr/share/doc/dehydrated/README.Debian │ │ │ +-rw-r--r-- 0 root (0) root (0) 2578 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/README.md.gz │ │ │ +-rw-r--r-- 0 root (0) root (0) 942 2025-06-02 14:50:35.000000 ./usr/share/doc/dehydrated/changelog.Debian.gz │ │ │ +-rw-r--r-- 0 root (0) root (0) 3074 2025-06-02 14:50:35.000000 ./usr/share/doc/dehydrated/changelog.gz │ │ │ +-rw-r--r-- 0 root (0) root (0) 1465 2025-06-02 14:50:35.000000 ./usr/share/doc/dehydrated/copyright │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/share/doc/dehydrated/docs/ │ │ │ +-rw-r--r-- 0 root (0) root (0) 1709 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/acme-v1.md │ │ │ +-rw-r--r-- 0 root (0) root (0) 1895 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/dns-verification.md │ │ │ +-rw-r--r-- 0 root (0) root (0) 3525 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/domains_txt.md │ │ │ +-rw-r--r-- 0 root (0) root (0) 174 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/ecc.md │ │ │ +-rw-r--r-- 0 root (0) root (0) 2892 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/hook_chain.md │ │ │ +-rw-r--r-- 0 root (0) root (0) 76482 2025-06-02 14:50:35.000000 ./usr/share/doc/dehydrated/docs/logo.png │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/share/doc/dehydrated/docs/man/ │ │ │ +-rw-r--r-- 0 root (0) root (0) 2482 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/man/dehydrated.1.gz │ │ │ +-rw-r--r-- 0 root (0) root (0) 744 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/per-certificate-config.md │ │ │ +-rw-r--r-- 0 root (0) root (0) 546 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/staging.md │ │ │ +-rw-r--r-- 0 root (0) root (0) 1850 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/tls-alpn.md.gz │ │ │ +-rw-r--r-- 0 root (0) root (0) 3549 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/troubleshooting.md │ │ │ +-rw-r--r-- 0 root (0) root (0) 2677 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/docs/wellknown.md │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/share/doc/dehydrated/examples/ │ │ │ +-rw-r--r-- 0 root (0) root (0) 5096 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/examples/config │ │ │ +-rw-r--r-- 0 root (0) root (0) 1846 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/examples/domains.txt │ │ │ +-rwxr-xr-x 0 root (0) root (0) 7745 2025-05-17 23:34:32.000000 ./usr/share/doc/dehydrated/examples/hook.sh │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/share/man/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./usr/share/man/man1/ │ │ │ +-rw-r--r-- 0 root (0) root (0) 2482 2025-06-02 14:50:35.000000 ./usr/share/man/man1/dehydrated.1.gz │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./var/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./var/lib/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./var/lib/dehydrated/ │ │ │ +drwxr-xr-x 0 root (0) root (0) 0 2025-06-02 14:50:35.000000 ./var/lib/dehydrated/acme-challenges/ │ │ ├── ./usr/bin/dehydrated │ │ │ @@ -13,15 +13,15 @@ │ │ │ │ │ │ umask 077 # paranoid umask, we're creating private keys │ │ │ │ │ │ # Close weird external file descriptors │ │ │ exec 3>&- │ │ │ exec 4>&- │ │ │ │ │ │ -VERSION="0.7.1" │ │ │ +VERSION="0.7.2" │ │ │ │ │ │ # Find directory in which this script is stored by traversing all symbolic links │ │ │ SOURCE="${0}" │ │ │ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink │ │ │ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" │ │ │ SOURCE="$(readlink "$SOURCE")" │ │ │ [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located │ │ │ @@ -287,14 +287,16 @@ │ │ │ __HOOK="${HOOK}" │ │ │ __PREFERRED_CHAIN="${PREFERRED_CHAIN}" │ │ │ __WELLKNOWN="${WELLKNOWN}" │ │ │ __HOOK_CHAIN="${HOOK_CHAIN}" │ │ │ __OPENSSL_CNF="${OPENSSL_CNF}" │ │ │ __RENEW_DAYS="${RENEW_DAYS}" │ │ │ __IP_VERSION="${IP_VERSION}" │ │ │ + __ACME_PROFILE="${ACME_PROFILE}" │ │ │ + __ORDER_TIMEOUT=${ORDER_TIMEOUT} │ │ │ } │ │ │ │ │ │ reset_configvars() { │ │ │ KEY_ALGO="${__KEY_ALGO}" │ │ │ OCSP_MUST_STAPLE="${__OCSP_MUST_STAPLE}" │ │ │ OCSP_FETCH="${__OCSP_FETCH}" │ │ │ OCSP_DAYS="${__OCSP_DAYS}" │ │ │ @@ -305,39 +307,44 @@ │ │ │ HOOK="${__HOOK}" │ │ │ PREFERRED_CHAIN="${__PREFERRED_CHAIN}" │ │ │ WELLKNOWN="${__WELLKNOWN}" │ │ │ HOOK_CHAIN="${__HOOK_CHAIN}" │ │ │ OPENSSL_CNF="${__OPENSSL_CNF}" │ │ │ RENEW_DAYS="${__RENEW_DAYS}" │ │ │ IP_VERSION="${__IP_VERSION}" │ │ │ + ACME_PROFILE="${__ACME_PROFILE}" │ │ │ + ORDER_TIMEOUT=${__ORDER_TIMEOUT} │ │ │ } │ │ │ │ │ │ hookscript_bricker_hook() { │ │ │ # Hook scripts should ignore any hooks they don't know. │ │ │ # Calling a random hook to make this clear to the hook script authors... │ │ │ if [[ -n "${HOOK}" ]]; then │ │ │ "${HOOK}" "this_hookscript_is_broken__dehydrated_is_working_fine__please_ignore_unknown_hooks_in_your_script" || _exiterr "Please check your hook script, it should exit cleanly without doing anything on unknown/new hooks." │ │ │ fi │ │ │ } │ │ │ │ │ │ # verify configuration values │ │ │ verify_config() { │ │ │ [[ "${CHALLENGETYPE}" == "http-01" || "${CHALLENGETYPE}" == "dns-01" || "${CHALLENGETYPE}" == "tls-alpn-01" ]] || _exiterr "Unknown challenge type ${CHALLENGETYPE}... cannot continue." │ │ │ - if [[ "${CHALLENGETYPE}" = "dns-01" ]] && [[ -z "${HOOK}" ]]; then │ │ │ - _exiterr "Challenge type dns-01 needs a hook script for deployment... cannot continue." │ │ │ - fi │ │ │ - if [[ "${CHALLENGETYPE}" = "http-01" && ! -d "${WELLKNOWN}" && ! "${COMMAND:-}" = "register" ]]; then │ │ │ - _exiterr "WELLKNOWN directory doesn't exist, please create ${WELLKNOWN} and set appropriate permissions." │ │ │ + if [[ "${COMMAND:-}" =~ sign_domains|sign_csr ]]; then │ │ │ + if [[ "${CHALLENGETYPE}" = "dns-01" ]] && [[ -z "${HOOK}" ]]; then │ │ │ + _exiterr "Challenge type dns-01 needs a hook script for deployment... cannot continue." │ │ │ + fi │ │ │ + if [[ "${CHALLENGETYPE}" = "http-01" ]] && [[ ! -d "${WELLKNOWN}" ]]; then │ │ │ + _exiterr "WELLKNOWN directory doesn't exist, please create ${WELLKNOWN} and set appropriate permissions." │ │ │ + fi │ │ │ fi │ │ │ [[ "${KEY_ALGO}" == "rsa" || "${KEY_ALGO}" == "prime256v1" || "${KEY_ALGO}" == "secp384r1" || "${KEY_ALGO}" == "secp521r1" ]] || _exiterr "Unknown public key algorithm ${KEY_ALGO}... cannot continue." │ │ │ if [[ -n "${IP_VERSION}" ]]; then │ │ │ [[ "${IP_VERSION}" = "4" || "${IP_VERSION}" = "6" ]] || _exiterr "Unknown IP version ${IP_VERSION}... cannot continue." │ │ │ fi │ │ │ [[ "${API}" == "auto" || "${API}" == "1" || "${API}" == "2" ]] || _exiterr "Unsupported API version defined in config: ${API}" │ │ │ [[ "${OCSP_DAYS}" =~ ^[0-9]+$ ]] || _exiterr "OCSP_DAYS must be a number" │ │ │ + [[ "${ORDER_TIMEOUT}" =~ ^[0-9]+$ ]] || _exiterr "ORDER_TIMEOUT must be a number" │ │ │ } │ │ │ │ │ │ # Setup default config values, search for and load configuration files │ │ │ load_config() { │ │ │ # Check for config in various locations │ │ │ if [[ -z "${CONFIG:-}" ]]; then │ │ │ for check_config in "/etc/dehydrated" "/usr/local/etc/dehydrated" "${PWD}" "${SCRIPTDIR}"; do │ │ │ @@ -351,14 +358,16 @@ │ │ │ │ │ │ # Preset │ │ │ CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" │ │ │ CA_LETSENCRYPT="https://acme-v02.api.letsencrypt.org/directory" │ │ │ CA_LETSENCRYPT_TEST="https://acme-staging-v02.api.letsencrypt.org/directory" │ │ │ CA_BUYPASS="https://api.buypass.com/acme/directory" │ │ │ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" │ │ │ + CA_GOOGLE="https://dv.acme-v02.api.pki.goog/directory" │ │ │ + CA_GOOGLE_TEST="https://dv.acme-v02.test-api.pki.goog/directory" │ │ │ │ │ │ # Default values │ │ │ CA="letsencrypt" │ │ │ OLDCA= │ │ │ CERTDIR= │ │ │ ALPNCERTDIR= │ │ │ ACCOUNTDIR= │ │ │ @@ -368,15 +377,15 @@ │ │ │ CONFIG_D= │ │ │ CURL_OPTS= │ │ │ DOMAINS_D= │ │ │ DOMAINS_TXT= │ │ │ HOOK= │ │ │ PREFERRED_CHAIN= │ │ │ HOOK_CHAIN="no" │ │ │ - RENEW_DAYS="30" │ │ │ + RENEW_DAYS="32" │ │ │ KEYSIZE="4096" │ │ │ WELLKNOWN= │ │ │ PRIVATE_KEY_RENEW="yes" │ │ │ PRIVATE_KEY_ROLLOVER="no" │ │ │ KEY_ALGO=secp384r1 │ │ │ OPENSSL=openssl │ │ │ OPENSSL_CNF= │ │ │ @@ -384,17 +393,20 @@ │ │ │ LOCKFILE= │ │ │ OCSP_MUST_STAPLE="no" │ │ │ OCSP_FETCH="no" │ │ │ OCSP_DAYS=5 │ │ │ IP_VERSION= │ │ │ CHAINCACHE= │ │ │ AUTO_CLEANUP="no" │ │ │ + AUTO_CLEANUP_DELETE="no" │ │ │ DEHYDRATED_USER= │ │ │ DEHYDRATED_GROUP= │ │ │ API="auto" │ │ │ + ACME_PROFILE="" │ │ │ + ORDER_TIMEOUT=0 │ │ │ │ │ │ if [[ -z "${CONFIG:-}" ]]; then │ │ │ echo "#" >&2 │ │ │ echo "# !! WARNING !! No main config file found, using default config!" >&2 │ │ │ echo "#" >&2 │ │ │ elif [[ -f "${CONFIG}" ]]; then │ │ │ echo "# INFO: Using main config file ${CONFIG}" │ │ │ @@ -477,14 +489,18 @@ │ │ │ CA="${CA_LETSENCRYPT_TEST}" │ │ │ elif [ "${CA}" = "zerossl" ]; then │ │ │ CA="${CA_ZEROSSL}" │ │ │ elif [ "${CA}" = "buypass" ]; then │ │ │ CA="${CA_BUYPASS}" │ │ │ elif [ "${CA}" = "buypass-test" ]; then │ │ │ CA="${CA_BUYPASS_TEST}" │ │ │ + elif [ "${CA}" = "google" ]; then │ │ │ + CA="${CA_GOOGLE}" │ │ │ + elif [ "${CA}" = "google-test" ]; then │ │ │ + CA="${CA_GOOGLE_TEST}" │ │ │ fi │ │ │ │ │ │ if [[ -z "${OLDCA}" ]] && [[ "${CA}" = "https://acme-v02.api.letsencrypt.org/directory" ]]; then │ │ │ OLDCA="https://acme-v01.api.letsencrypt.org/directory" │ │ │ fi │ │ │ │ │ │ # Create new account directory or symlink to account directory from old CA │ │ │ @@ -540,14 +556,16 @@ │ │ │ [[ -n "${PARAM_PREFERRED_CHAIN:-}" ]] && PREFERRED_CHAIN="${PARAM_PREFERRED_CHAIN}" │ │ │ [[ -n "${PARAM_CERTDIR:-}" ]] && CERTDIR="${PARAM_CERTDIR}" │ │ │ [[ -n "${PARAM_ALPNCERTDIR:-}" ]] && ALPNCERTDIR="${PARAM_ALPNCERTDIR}" │ │ │ [[ -n "${PARAM_CHALLENGETYPE:-}" ]] && CHALLENGETYPE="${PARAM_CHALLENGETYPE}" │ │ │ [[ -n "${PARAM_KEY_ALGO:-}" ]] && KEY_ALGO="${PARAM_KEY_ALGO}" │ │ │ [[ -n "${PARAM_OCSP_MUST_STAPLE:-}" ]] && OCSP_MUST_STAPLE="${PARAM_OCSP_MUST_STAPLE}" │ │ │ [[ -n "${PARAM_IP_VERSION:-}" ]] && IP_VERSION="${PARAM_IP_VERSION}" │ │ │ + [[ -n "${PARAM_ACME_PROFILE:-}" ]] && ACME_PROFILE="${PARAM_ACME_PROFILE}" │ │ │ + [[ -n "${PARAM_ORDER_TIMEOUT:-}" ]] && ORDER_TIMEOUT="${PARAM_ORDER_TIMEOUT}" │ │ │ │ │ │ if [ "${PARAM_FORCE_VALIDATION:-no}" = "yes" ] && [ "${PARAM_FORCE:-no}" = "no" ]; then │ │ │ _exiterr "Argument --force-validation can only be used in combination with --force (-x)" │ │ │ fi │ │ │ │ │ │ if [ ! "${1:-}" = "noverify" ]; then │ │ │ verify_config │ │ │ @@ -583,22 +601,55 @@ │ │ │ CA_NEW_REG="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-reg)" && │ │ │ CA_TERMS="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value terms-of-service)" && │ │ │ CA_REQUIRES_EAB="false" && │ │ │ CA_REVOKE_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value revoke-cert)" || │ │ │ _exiterr "Problem retrieving ACME/CA-URLs, check if your configured CA points to the directory entrypoint." │ │ │ # Since reg URI is missing from directory we will assume it is the same as CA_NEW_REG without the new part │ │ │ CA_REG=${CA_NEW_REG/new-reg/reg} │ │ │ + │ │ │ + if [[ -n "${ACME_PROFILE}" ]]; then │ │ │ + _exiterr "ACME profiles are not supported in ACME v1." │ │ │ + fi │ │ │ else │ │ │ CA_NEW_ORDER="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newOrder)" && │ │ │ CA_NEW_NONCE="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newNonce)" && │ │ │ CA_NEW_ACCOUNT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newAccount)" && │ │ │ CA_TERMS="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value -p '"meta","termsOfService"')" && │ │ │ CA_REQUIRES_EAB="$(printf "%s" "${CA_DIRECTORY}" | get_json_bool_value -p '"meta","externalAccountRequired"' || echo false)" && │ │ │ CA_REVOKE_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value revokeCert)" || │ │ │ _exiterr "Problem retrieving ACME/CA-URLs, check if your configured CA points to the directory entrypoint." │ │ │ + │ │ │ + # Checking ACME profile │ │ │ + if [[ -n "${ACME_PROFILE}" ]]; then │ │ │ + # Extract available profiles from CA directory │ │ │ + declare -A available_profiles=() │ │ │ + while IFS=$'\t' read -r path value; do │ │ │ + if [[ "${value}" =~ ^\"([^\"]+)\"$ ]]; then │ │ │ + value=${BASH_REMATCH[1]} │ │ │ + fi │ │ │ + if [[ "${path}" =~ ^\[\"([^\"]+)\"\]$ ]]; then │ │ │ + available_profiles[${BASH_REMATCH[1]}]=$value │ │ │ + fi │ │ │ + done <<< "$(printf "%s" "${CA_DIRECTORY}" | get_json_dict_value -p '"meta","profiles"' 2>/dev/null)" │ │ │ + if [[ ${#available_profiles[@]} -eq 0 ]]; then │ │ │ + _exiterr "ACME profile not supported by this CA" │ │ │ + fi │ │ │ + │ │ │ + # Check if the requested profile is available │ │ │ + found_profile="no" │ │ │ + for profile in "${!available_profiles[@]}"; do │ │ │ + if [[ "${profile}" == "${ACME_PROFILE}" ]]; then │ │ │ + found_profile="yes" │ │ │ + break │ │ │ + fi │ │ │ + done │ │ │ + if [[ "${found_profile}" == "no" ]]; then │ │ │ + _exiterr "ACME profile '${ACME_PROFILE}' not found, available profiles:$(for key in "${!available_profiles[@]}"; do printf "\n %s: %s" "${key}" "${available_profiles[$key]}"; done)" │ │ │ + fi │ │ │ + fi │ │ │ fi │ │ │ │ │ │ # Export some environment variables to be used in hook script │ │ │ export WELLKNOWN BASEDIR CERTDIR ALPNCERTDIR CONFIG COMMAND │ │ │ │ │ │ # Checking for private key ... │ │ │ register_new_key="no" │ │ │ @@ -699,14 +750,22 @@ │ │ │ echo "${zeroapi}" │ │ │ FAILED=true │ │ │ fi │ │ │ fi │ │ │ fi │ │ │ fi │ │ │ │ │ │ + # Google special sauce │ │ │ + if [[ "${CA}" = "${CA_GOOGLE}" ]]; then │ │ │ + if [[ -z "${CONTACT_EMAIL}" ]] || [[ -z "${EAB_KID:-}" ]] || [[ -z "${EAB_HMAC_KEY:-}" ]]; then │ │ │ + echo "Google requires contact email, EAB_KID and EAB_HMAC_KEY to be manually configured (see https://cloud.google.com/certificate-manager/docs/public-ca-tutorial)" │ │ │ + FAILED=true │ │ │ + fi │ │ │ + fi │ │ │ + │ │ │ # Check if external account is required │ │ │ if [[ "${FAILED}" = "false" ]]; then │ │ │ if [[ "${CA_REQUIRES_EAB}" = "true" ]]; then │ │ │ if [[ -z "${EAB_KID:-}" ]] || [[ -z "${EAB_HMAC_KEY:-}" ]]; then │ │ │ FAILED=true │ │ │ echo "This CA requires an external account but no EAB_KID/EAB_HMAC_KEY has been configured" │ │ │ fi │ │ │ @@ -1005,21 +1064,21 @@ │ │ │ printf "%s" "${output}" │ │ │ fi │ │ │ } │ │ │ │ │ │ # Extracts all subject names from a CSR │ │ │ # Outputs either the CN, or the SANs, one per line │ │ │ extract_altnames() { │ │ │ - csr="${1}" # the CSR itself (not a file) │ │ │ + csrfile="${1}" # path to CSR file │ │ │ │ │ │ - if ! <<<"${csr}" "${OPENSSL}" req -verify -noout >/dev/null 2>&1; then │ │ │ + if ! "${OPENSSL}" req -in "${csrfile}" -verify -noout >/dev/null; then │ │ │ _exiterr "Certificate signing request isn't valid" │ │ │ fi │ │ │ │ │ │ - reqtext="$( <<<"${csr}" "${OPENSSL}" req -noout -text )" │ │ │ + reqtext="$("${OPENSSL}" req -in "${csrfile}" -noout -text)" │ │ │ if <<<"${reqtext}" grep -q '^[[:space:]]*X509v3 Subject Alternative Name:[[:space:]]*$'; then │ │ │ # SANs used, extract these │ │ │ altnames="$( <<<"${reqtext}" awk '/X509v3 Subject Alternative Name:/{print;getline;print;}' | tail -n1 )" │ │ │ # split to one per line: │ │ │ # shellcheck disable=SC1003 │ │ │ altnames="$( <<<"${altnames}" _sed -e 's/^[[:space:]]*//; s/, /\'$'\n''/g' )" │ │ │ # we can only get DNS/IP: ones signed │ │ │ @@ -1039,15 +1098,15 @@ │ │ │ # Get last issuer CN in certificate chain │ │ │ get_last_cn() { │ │ │ <<<"${1}" _sed 'H;/-----BEGIN CERTIFICATE-----/h;$!d;x' | "${OPENSSL}" x509 -noout -issuer | head -n1 | _sed -e 's/.*[ /]CN ?= ?([^/,]*).*/\1/' │ │ │ } │ │ │ │ │ │ # Create certificate for domain(s) and outputs it FD 3 │ │ │ sign_csr() { │ │ │ - csr="${1}" # the CSR itself (not a file) │ │ │ + csrfile="${1}" # path to CSR file │ │ │ │ │ │ if { true >&3; } 2>/dev/null; then │ │ │ : # fd 3 looks OK │ │ │ else │ │ │ _exiterr "sign_csr: FD 3 not open" │ │ │ fi │ │ │ │ │ │ @@ -1078,15 +1137,20 @@ │ │ │ else │ │ │ challenge_identifiers+="$(printf '{"type": "dns", "value": "%s"}, ' "${altname}")" │ │ │ fi │ │ │ done │ │ │ challenge_identifiers="[${challenge_identifiers%, }]" │ │ │ │ │ │ echo " + Requesting new certificate order from CA..." │ │ │ - order_location="$(signed_request "${CA_NEW_ORDER}" '{"identifiers": '"${challenge_identifiers}"'}' 4>&1 | grep -i ^Location: | cut -d':' -f2- | tr -d ' \t\r\n')" │ │ │ + local order_payload='{"identifiers": '"${challenge_identifiers}" │ │ │ + if [[ -n "${ACME_PROFILE}" ]]; then │ │ │ + order_payload="${order_payload}"',"profile":"'"${ACME_PROFILE}"'"' │ │ │ + fi │ │ │ + order_payload="${order_payload}"'}' │ │ │ + order_location="$(signed_request "${CA_NEW_ORDER}" "${order_payload}" 4>&1 | grep -i ^Location: | cut -d':' -f2- | tr -d ' \t\r\n')" │ │ │ result="$(signed_request "${order_location}" "" | jsonsh)" │ │ │ │ │ │ order_authorizations="$(echo "${result}" | get_json_array_values authorizations)" │ │ │ finalize="$(echo "${result}" | get_json_string_value finalize)" │ │ │ │ │ │ local idx=0 │ │ │ for uri in ${order_authorizations}; do │ │ │ @@ -1264,33 +1328,38 @@ │ │ │ echo " + Challenge validation has failed :(" │ │ │ _exiterr "Challenge is invalid! (returned: ${reqstatus}) (result: ${result})" │ │ │ fi │ │ │ fi │ │ │ │ │ │ # Finally request certificate from the acme-server and store it in cert-${timestamp}.pem and link from cert.pem │ │ │ echo " + Requesting certificate..." │ │ │ - csr64="$( <<<"${csr}" "${OPENSSL}" req -config "${OPENSSL_CNF}" -outform DER | urlbase64)" │ │ │ + csr64="$("${OPENSSL}" req -in "${csrfile}" -config "${OPENSSL_CNF}" -outform DER | urlbase64)" │ │ │ if [[ ${API} -eq 1 ]]; then │ │ │ crt64="$(signed_request "${CA_NEW_CERT}" '{"resource": "new-cert", "csr": "'"${csr64}"'"}' | "${OPENSSL}" base64 -e)" │ │ │ crt="$( printf -- '-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n' "${crt64}" )" │ │ │ else │ │ │ result="$(signed_request "${finalize}" '{"csr": "'"${csr64}"'"}' | jsonsh)" │ │ │ + waited=0 │ │ │ while :; do │ │ │ orderstatus="$(echo "${result}" | get_json_string_value status)" │ │ │ case "${orderstatus}" │ │ │ in │ │ │ "processing" | "pending") │ │ │ + if [ ${ORDER_TIMEOUT} -gt 0 ] && [ ${waited} -gt ${ORDER_TIMEOUT} ]; then │ │ │ + _exiterr "Timed out waiting for processing of order (still ${orderstatus})" │ │ │ + fi │ │ │ echo " + Order is ${orderstatus}..." │ │ │ sleep 2; │ │ │ + waited=$((waited+2)) │ │ │ ;; │ │ │ "valid") │ │ │ break; │ │ │ ;; │ │ │ *) │ │ │ - _exiterr "Order in status ${orderstatus}" │ │ │ + _exiterr "Order has invalid/unknown status: ${orderstatus}" │ │ │ ;; │ │ │ esac │ │ │ result="$(signed_request "${order_location}" "" | jsonsh)" │ │ │ done │ │ │ │ │ │ resheaders="$(_mktemp)" │ │ │ certificate="$(echo "${result}" | get_json_string_value certificate)" │ │ │ @@ -1506,15 +1575,15 @@ │ │ │ fi │ │ │ "${OPENSSL}" req -new -sha256 -key "${certdir}/${privkey}" -out "${certdir}/cert-${timestamp}.csr" -subj "${SUBJ}" -reqexts SAN -config "${tmp_openssl_cnf}" │ │ │ rm -f "${tmp_openssl_cnf}" │ │ │ fi │ │ │ │ │ │ crt_path="${certdir}/cert-${timestamp}.pem" │ │ │ # shellcheck disable=SC2086 │ │ │ - sign_csr "$(< "${certdir}/cert-${timestamp}.csr")" ${altnames} 3>"${crt_path}" │ │ │ + sign_csr "${certdir}/cert-${timestamp}.csr" ${altnames} 3>"${crt_path}" │ │ │ │ │ │ # Create fullchain.pem │ │ │ echo " + Creating fullchain.pem..." │ │ │ if [[ ${API} -eq 1 ]]; then │ │ │ cat "${crt_path}" > "${certdir}/fullchain-${timestamp}.pem" │ │ │ local issuer_hash │ │ │ issuer_hash="$(get_issuer_hash "${crt_path}")" │ │ │ @@ -1771,15 +1840,15 @@ │ │ │ rm "${aftervars}" │ │ │ ); do │ │ │ config_var="$(echo "${cfgline:1}" | cut -d'=' -f1)" │ │ │ config_value="$(echo "${cfgline:1}" | cut -d'=' -f2- | tr -d "'")" │ │ │ # All settings that are allowed here should also be stored and │ │ │ # restored in store_configvars() and reset_configvars() │ │ │ case "${config_var}" in │ │ │ - KEY_ALGO|OCSP_MUST_STAPLE|OCSP_FETCH|OCSP_DAYS|PRIVATE_KEY_RENEW|PRIVATE_KEY_ROLLOVER|KEYSIZE|CHALLENGETYPE|HOOK|PREFERRED_CHAIN|WELLKNOWN|HOOK_CHAIN|OPENSSL_CNF|RENEW_DAYS) │ │ │ + KEY_ALGO|OCSP_MUST_STAPLE|OCSP_FETCH|OCSP_DAYS|PRIVATE_KEY_RENEW|PRIVATE_KEY_ROLLOVER|KEYSIZE|CHALLENGETYPE|HOOK|PREFERRED_CHAIN|WELLKNOWN|HOOK_CHAIN|OPENSSL_CNF|RENEW_DAYS|ACME_PROFILE|ORDER_TIMEOUT) │ │ │ echo " + ${config_var} = ${config_value}" │ │ │ declare -- "${config_var}=${config_value}" │ │ │ ;; │ │ │ _) ;; │ │ │ *) echo " ! Setting ${config_var} on a per-certificate base is not (yet) supported" >&2 │ │ │ esac │ │ │ done │ │ │ @@ -1788,24 +1857,26 @@ │ │ │ verify_config │ │ │ hookscript_bricker_hook │ │ │ export WELLKNOWN CHALLENGETYPE KEY_ALGO PRIVATE_KEY_ROLLOVER │ │ │ │ │ │ skip="no" │ │ │ │ │ │ # Allow for external CSR generation │ │ │ - local csr="" │ │ │ + local csrfile="" │ │ │ if [[ -n "${HOOK}" ]]; then │ │ │ csr="$("${HOOK}" "generate_csr" "${domain}" "${certdir}" "${domain} ${morenames}")" || _exiterr 'generate_csr hook returned with non-zero exit code' │ │ │ if grep -qE "\-----BEGIN (NEW )?CERTIFICATE REQUEST-----" <<< "${csr}"; then │ │ │ - altnames="$(extract_altnames "${csr}")" │ │ │ + csrfile="$(_mktemp)" │ │ │ + cat > "${csrfile}" <<< "${csr}" │ │ │ + altnames="$(extract_altnames "${csrfile}")" │ │ │ domain="$(cut -d' ' -f1 <<< "${altnames}")" │ │ │ morenames="$(cut -s -d' ' -f2- <<< "${altnames}")" │ │ │ echo " + Using CSR from hook script (real names: ${altnames})" │ │ │ else │ │ │ - csr="" │ │ │ + csrfile="" │ │ │ fi │ │ │ fi │ │ │ │ │ │ # Check domain names of existing certificate │ │ │ if [[ -e "${cert}" && "${force_renew}" = "no" ]]; then │ │ │ printf " + Checking domain name(s) of existing cert..." │ │ │ │ │ │ @@ -1847,15 +1918,18 @@ │ │ │ │ │ │ local update_ocsp │ │ │ update_ocsp="no" │ │ │ │ │ │ # Sign certificate for this domain │ │ │ if [[ ! "${skip}" = "yes" ]]; then │ │ │ update_ocsp="yes" │ │ │ - [[ -z "${csr}" ]] || printf "%s" "${csr}" > "${certdir}/cert-${timestamp}.csr" │ │ │ + if [[ -n "${csrfile}" ]]; then │ │ │ + cat "${csrfile}" > "${certdir}/cert-${timestamp}.csr" │ │ │ + rm "${csrfile}" │ │ │ + fi │ │ │ # shellcheck disable=SC2086 │ │ │ if [[ "${PARAM_KEEP_GOING:-}" = "yes" ]]; then │ │ │ skip_exit_hook=yes │ │ │ sign_domain "${certdir}" "${timestamp}" "${domain}" ${morenames} & │ │ │ wait $! || exit_with_errorcode=1 │ │ │ skip_exit_hook=no │ │ │ else │ │ │ @@ -1891,16 +1965,16 @@ │ │ │ reset_configvars │ │ │ │ │ │ # remove temporary domains.txt file if used │ │ │ [[ -n "${PARAM_DOMAIN:-}" ]] && rm -f "${DOMAINS_TXT}" │ │ │ │ │ │ [[ -n "${HOOK}" ]] && ("${HOOK}" "exit_hook" || echo 'exit_hook returned with non-zero exit code!' >&2) │ │ │ if [[ "${AUTO_CLEANUP}" == "yes" ]]; then │ │ │ - echo "+ Running automatic cleanup" │ │ │ - command_cleanup noinit │ │ │ + echo " + Running automatic cleanup" │ │ │ + PARAM_CLEANUPDELETE="${AUTO_CLEANUP_DELETE:-no}" command_cleanup noinit | _sed 's/^/ + /g' │ │ │ fi │ │ │ │ │ │ exit "${exit_with_errorcode}" │ │ │ } │ │ │ │ │ │ # Usage: --signcsr (-s) path/to/csr.pem │ │ │ # Description: Sign a given CSR, output CRT on stdout (advanced usage) │ │ │ @@ -1908,27 +1982,26 @@ │ │ │ init_system │ │ │ │ │ │ # redirect stdout to stderr │ │ │ # leave stdout over at fd 3 to output the cert │ │ │ exec 3>&1 1>&2 │ │ │ │ │ │ # load csr │ │ │ - csrfile="${1}" │ │ │ + local csrfile="${1}" │ │ │ if [ ! -r "${csrfile}" ]; then │ │ │ _exiterr "Could not read certificate signing request ${csrfile}" │ │ │ fi │ │ │ - csr="$(cat "${csrfile}")" │ │ │ │ │ │ # extract names │ │ │ - altnames="$(extract_altnames "${csr}")" │ │ │ + altnames="$(extract_altnames "${csrfile}")" │ │ │ │ │ │ # gen cert │ │ │ certfile="$(_mktemp)" │ │ │ # shellcheck disable=SC2086 │ │ │ - sign_csr "${csr}" ${altnames} 3> "${certfile}" │ │ │ + sign_csr "${csrfile}" ${altnames} 3> "${certfile}" │ │ │ │ │ │ # print cert │ │ │ echo "# CERT #" >&3 │ │ │ cat "${certfile}" >&3 │ │ │ echo >&3 │ │ │ │ │ │ # print chain │ │ │ @@ -2360,14 +2433,31 @@ │ │ │ # PARAM_Usage: --algo (-a) rsa|prime256v1|secp384r1 │ │ │ # PARAM_Description: Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1 │ │ │ --algo|-a) │ │ │ shift 1 │ │ │ check_parameters "${1:-}" │ │ │ PARAM_KEY_ALGO="${1}" │ │ │ ;; │ │ │ + │ │ │ + # PARAM_Usage: --acme-profile profile_name │ │ │ + # PARAM_Description: Use specified ACME profile │ │ │ + --acme-profile) │ │ │ + shift 1 │ │ │ + check_parameters "${1:-}" │ │ │ + PARAM_ACME_PROFILE="${1}" │ │ │ + ;; │ │ │ + │ │ │ + # PARAM_Usage: --order-timeout seconds │ │ │ + # PARAM_Description: Amount of seconds to wait for processing of order until erroring out │ │ │ + --order-timeout) │ │ │ + shift 1 │ │ │ + check_parameters "${1:-}" │ │ │ + PARAM_ORDER_TIMEOUT=${1} │ │ │ + ;; │ │ │ + │ │ │ *) │ │ │ echo "Unknown parameter detected: ${1}" >&2 │ │ │ echo >&2 │ │ │ command_help >&2 │ │ │ exit 1 │ │ │ ;; │ │ │ esac │ │ ├── ./usr/share/doc/dehydrated/README.md.gz │ │ │ ├── README.md │ │ │ │ @@ -81,14 +81,16 @@ │ │ │ │ --config (-f) path/to/config Use specified config file │ │ │ │ --hook (-k) path/to/hook.sh Use specified script for hooks │ │ │ │ --preferred-chain issuer-cn Use alternative certificate chain identified by issuer CN │ │ │ │ --out (-o) certs/directory Output certificates into the specified directory │ │ │ │ --alpn alpn-certs/directory Output alpn verification certificates into the specified directory │ │ │ │ --challenge (-t) http-01|dns-01|tls-alpn-01 Which challenge should be used? Currently http-01, dns-01, and tls-alpn-01 are supported │ │ │ │ --algo (-a) rsa|prime256v1|secp384r1 Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1 │ │ │ │ + --acme-profile profile_name Use specified ACME profile │ │ │ │ + --order-timeout seconds Amount of seconds to wait for processing of order until erroring out │ │ │ │ ``` │ │ │ │ │ │ │ │ ## Chat │ │ │ │ │ │ │ │ Dehydrated has an official IRC-channel `#dehydrated` on libera.chat that can be used for general discussion and suggestions. │ │ │ │ │ │ │ │ The channel can also be accessed with Matrix using the official libera.chat bridge at `#dehydrated:libera.chat`. │ │ ├── ./usr/share/doc/dehydrated/changelog.Debian.gz │ │ │ ├── changelog.Debian │ │ │ │ @@ -1,7 +1,17 @@ │ │ │ │ +dehydrated (0.7.2-1) unstable; urgency=medium │ │ │ │ + │ │ │ │ + * New upstream release 0.7.2. │ │ │ │ + * Update copyright. │ │ │ │ + * Drop all patches applied upstream. │ │ │ │ + * Add patches from upstream after the 0.7.2 release. │ │ │ │ + * Bump Standards-Version to 4.7.2, no changes needed. │ │ │ │ + │ │ │ │ + -- Mattia Rizzolo <mattia@debian.org> Mon, 02 Jun 2025 16:50:35 +0200 │ │ │ │ + │ │ │ │ dehydrated (0.7.1-1) unstable; urgency=medium │ │ │ │ │ │ │ │ * New upstream release 0.7.1. Closes: #1023655 │ │ │ │ * Update watch file. │ │ │ │ Thanks to Beat Bolli <me+dev@drbeat.li> for the patch │ │ │ │ * Update copyright. │ │ │ │ * Remove all patches applied upstream. │ │ ├── ./usr/share/doc/dehydrated/changelog.gz │ │ │ ├── changelog │ │ │ │ @@ -1,10 +1,23 @@ │ │ │ │ # Change Log │ │ │ │ This file contains a log of major changes in dehydrated │ │ │ │ │ │ │ │ +## [0.7.2] - 2025-05-18 │ │ │ │ +## Added │ │ │ │ +- Implemented support for certificate profile selection │ │ │ │ +- Added a configuration parameter to allow for timeouts during order processing (`ORDER_TIMEOUT`, defaults to 0 = no timeout) │ │ │ │ +- Allowed for automatic deletion of old files (`AUTO_CLEANUP_DELETE`, disabled by default) │ │ │ │ +- Added CA presets for Google Trust Services (prod: google, test: google-test) │ │ │ │ + │ │ │ │ +## Changed │ │ │ │ +- Renew certificates with 32 days remaining (instead of 30) to avoid issues with monthly cronjobs (`RENEW_DAYS=32`) │ │ │ │ + │ │ │ │ +## Fixed │ │ │ │ +- Changed behaviour of `openssl req` stdin handling to fix compatibility with OpenSSL version 3.2+ │ │ │ │ + │ │ │ │ ## [0.7.1] - 2022-10-31 │ │ │ │ ## Changed │ │ │ │ - `--force` no longer forces domain name revalidation by default, a new argument `--force-validation` has been added for that │ │ │ │ - Added support for EC secp521r1 algorithm (works with e.g. zerossl) │ │ │ │ - `EC PARAMETERS` are no longer written to privkey.pem (didn't seem necessary and was causing issues with various software) │ │ │ │ │ │ │ │ ## Fixed │ │ ├── ./usr/share/doc/dehydrated/copyright │ │ │ @@ -5,15 +5,15 @@ │ │ │ │ │ │ Files: * │ │ │ Copyright: 2015-2021 Lukas Schauer │ │ │ License: Expat │ │ │ │ │ │ Files: debian/* │ │ │ Copyright: 2016 Daniel Beyer <dabe@deb.ymc.ch> │ │ │ - 2016-2024 Mattia Rizzolo <mattia@debian.org> │ │ │ + 2016-2025 Mattia Rizzolo <mattia@debian.org> │ │ │ License: Expat │ │ │ │ │ │ License: Expat │ │ │ Permission is hereby granted, free of charge, to any person obtaining a copy │ │ │ of this software and associated documentation files (the "Software"), to deal │ │ │ in the Software without restriction, including without limitation the rights │ │ │ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell │ │ ├── ./usr/share/doc/dehydrated/docs/logo.png │ │ │ ├── sng │ │ │ │ @@ -16,37 +16,37 @@ │ │ │ │ } │ │ │ │ bKGD {red: 255; green: 255; blue: 255;} │ │ │ │ pHYs {xpixels: 5487; ypixels: 5487; per: meter;} # (139 dpi) │ │ │ │ private orNT { │ │ │ │ base64 1; │ │ │ │ } │ │ │ │ tIME { │ │ │ │ - # 27 Jul 2024 06:13:05 GMT │ │ │ │ - year: 2024 │ │ │ │ - month: 7 │ │ │ │ - day: 27 │ │ │ │ - hour: 6 │ │ │ │ - minute: 13 │ │ │ │ - second: 5 │ │ │ │ + # 2 Jun 2025 14:50:35 GMT │ │ │ │ + year: 2025 │ │ │ │ + month: 6 │ │ │ │ + day: 2 │ │ │ │ + hour: 14 │ │ │ │ + minute: 50 │ │ │ │ + second: 35 │ │ │ │ } │ │ │ │ zTXt { │ │ │ │ keyword: "Raw profile type icc"; │ │ │ │ text: "\nicc\n 672\n000002a06c636d73043000006d6e74725247422058595a2007e5000b0001001200080025\n616373704150504c0000000000000000000000000000000000000000000000000000f6d6\n000100000000d32d6c636d73000000000000000000000000000000000000000000000000\n00000000000000000000000000000000000000000000000d646573630000012000000040\n63707274000001600000003677747074000001980000001463686164000001ac0000002c\n7258595a000001d8000000146258595a000001ec000000146758595a0000020000000014\n725452430000021400000020675452430000021400000020625452430000021400000020\n6368726d0000023400000024646d6e640000025800000024646d64640000027c00000024\n6d6c756300000000000000010000000c656e5553000000240000001c00470049004d0050\n0020006200750069006c0074002d0069006e002000730052004700426d6c756300000000\n000000010000000c656e55530000001a0000001c005000750062006c0069006300200044\n006f006d00610069006e000058595a20000000000000f6d6000100000000d32d73663332\n0000000000010c42000005defffff325000007930000fd90fffffba1fffffda2000003dc\n0000c06e58595a200000000000006fa0000038f50000039058595a20000000000000249f\n00000f840000b6c458595a2000000000000062970000b787000018d97061726100000000\n00030000000266660000f2a700000d59000013d000000a5b6368726d0000000000030000\n0000a3d70000547c00004ccd0000999a0000266700000f5c6d6c75630000000000000001\n0000000c656e5553000000080000001c00470049004d00506d6c75630000000000000001\n0000000c656e5553000000080000001c0073005200470042\n"; │ │ │ │ } │ │ │ │ zTXt { │ │ │ │ keyword: "Raw profile type xmp"; │ │ │ │ text: "\nxmp\n 3332\n3c3f787061636b657420626567696e3d22efbbbf222069643d2257354d304d7043656869\n487a7265537a4e54637a6b633964223f3e0a3c783a786d706d65746120786d6c6e733a78\n3d2261646f62653a6e733a6d6574612f2220783a786d70746b3d22584d5020436f726520\n342e342e302d4578697632223e0a203c7264663a52444620786d6c6e733a7264663d2268\n7474703a2f2f7777772e77332e6f72672f313939392f30322f32322d7264662d73796e74\n61782d6e7323223e0a20203c7264663a4465736372697074696f6e207264663a61626f75\n743d22220a20202020786d6c6e733a786d704d4d3d22687474703a2f2f6e732e61646f62\n652e636f6d2f7861702f312e302f6d6d2f220a20202020786d6c6e733a73744576743d22\n687474703a2f2f6e732e61646f62652e636f6d2f7861702f312e302f73547970652f5265\n736f757263654576656e7423220a20202020786d6c6e733a64633d22687474703a2f2f70\n75726c2e6f72672f64632f656c656d656e74732f312e312f220a20202020786d6c6e733a\n47494d503d22687474703a2f2f7777772e67696d702e6f72672f786d702f220a20202020\n786d6c6e733a746966663d22687474703a2f2f6e732e61646f62652e636f6d2f74696666\n2f312e302f220a20202020786d6c6e733a786d703d22687474703a2f2f6e732e61646f62\n652e636f6d2f7861702f312e302f220a202020786d704d4d3a446f63756d656e7449443d\n2267696d703a646f6369643a67696d703a30643137303065362d653962652d346238302d\n613733642d646563313266373034613536220a202020786d704d4d3a496e7374616e6365\n49443d22786d702e6969643a33643638633035372d333334612d343361642d616438362d\n363965623030303830646162220a202020786d704d4d3a4f726967696e616c446f63756d\n656e7449443d22786d702e6469643a64343637313964362d343264302d343534322d3931\n30342d303362616638313161376533220a20202064633a466f726d61743d22696d616765\n2f706e67220a20202047494d503a4150493d22322e30220a20202047494d503a506c6174\n666f726d3d224c696e7578220a20202047494d503a54696d655374616d703d2231363335\n373930323333313237323434220a20202047494d503a56657273696f6e3d22322e31302e\n3238220a202020746966663a4f7269656e746174696f6e3d2231220a202020786d703a43\n726561746f72546f6f6c3d2247494d5020322e3130223e0a2020203c786d704d4d3a4869\n73746f72793e0a202020203c7264663a5365713e0a20202020203c7264663a6c690a2020\n2020202073744576743a616374696f6e3d227361766564220a2020202020207374457674\n3a6368616e6765643d222f220a20202020202073744576743a696e7374616e636549443d\n22786d702e6969643a61643862333566332d333134332d346239312d383631372d346138\n396162633864376662220a20202020202073744576743a736f6674776172654167656e74\n3d2247696d7020322e313020284c696e757829220a20202020202073744576743a776865\n6e3d22323032312d31312d30315431393a31303a33332b30313a3030222f3e0a20202020\n3c2f7264663a5365713e0a2020203c2f786d704d4d3a486973746f72793e0a20203c2f72\n64663a4465736372697074696f6e3e0a203c2f7264663a5244463e0a3c2f783a786d706d\n6574613e0a20202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n2020202020202020202020202020202020202020202020202020202020202020200a2020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n20202020202020202020202020202020202020202020202020200a202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020200a20202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n2020202020202020202020200a2020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n20202020200a202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020200a20\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n2020202020202020202020202020202020202020202020202020200a2020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n20202020202020202020202020202020202020200a202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020200a20202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n2020202020200a2020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n20202020202020202020202020202020202020202020202020202020202020202020200a\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020200a20202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n2020202020202020202020202020202020202020200a2020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n20202020202020202020202020200a202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020200a20202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n0a2020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n20202020202020202020202020202020202020202020202020202020200a202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020200a20202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n2020202020202020202020202020200a2020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n202020202020202020202020202020202020202020202020202020202020202020202020\n20202020202020200a202020202020202020202020202020202020202020202020202020\n0a3c3f787061636b657420656e643d2277223f3e\n"; │ │ │ │ } │ │ │ │ tEXt { │ │ │ │ keyword: "date:create"; │ │ │ │ - text: "2024-07-27T06:13:05-00:00"; │ │ │ │ + text: "2025-06-02T14:50:35-00:00"; │ │ │ │ } │ │ │ │ tEXt { │ │ │ │ keyword: "date:modify"; │ │ │ │ - text: "2024-07-27T06:13:05-00:00"; │ │ │ │ + text: "2025-06-02T14:50:35-00:00"; │ │ │ │ } │ │ │ │ tEXt { │ │ │ │ keyword: "exif:BitsPerSample"; │ │ │ │ text: "8, 8, 8"; │ │ │ │ } │ │ │ │ tEXt { │ │ │ │ keyword: "exif:ColorSpace"; │ │ ├── ./usr/share/doc/dehydrated/docs/man/dehydrated.1.gz │ │ │ ├── dehydrated.1 │ │ │ │ @@ -22,15 +22,15 @@ │ │ │ │ based: If the file contains two lines "example.com" and "example.net", │ │ │ │ dehydrated will request two certificate, one for "example.com" and the other │ │ │ │ for "example.net". A single line containing "example.com example.net" will request a │ │ │ │ single certificate valid for both "example.net" and "example.com" through the \fISubject │ │ │ │ Alternative Name\fR (SAN) field. │ │ │ │ │ │ │ │ For the next step, one way of verifying domain name ownership needs to be │ │ │ │ -configured. Dehydrated implements \fIhttp-01\fR and \fIdns-01\fR verification. │ │ │ │ +configured. Dehydrated implements \fIhttp-01\fR and \fIdns-01\fR verification. │ │ │ │ │ │ │ │ The \fIhttp-01\fR verification provides proof of ownership by providing a │ │ │ │ challenge token. In order to do that, the directory referenced in the │ │ │ │ \fIWELLKNOWN\fR config variable needs to be exposed at │ │ │ │ \fIhttp://{domain}/.well-known/acme-challenge/\fR, where {domain} is every │ │ │ │ domain name specified in \fIdomains.txt\fR. Dehydrated does not provide its │ │ │ │ own challenge responder, but relies on an existing web server to provide the │ │ │ │ @@ -135,21 +135,21 @@ │ │ │ │ .BR \-\-algo ", " \-a " " \fI[rsa|prime256v1|secp384r1]\fR │ │ │ │ Which public key algorithm should be used? Supported: rsa, prime256v1 and │ │ │ │ secp384r1 │ │ │ │ .SH DIAGNOSTICS │ │ │ │ The program exits 0 if everything was fine, 1 if an error occurred. │ │ │ │ .SH BUGS │ │ │ │ Please report any bugs that you may encounter at the project web site │ │ │ │ -.UR https://github.com/lukas2511/dehydrated/issues │ │ │ │ +.UR https://github.com/dehydrated-io/dehydrated/issues │ │ │ │ .UE . │ │ │ │ .SH AUTHOR │ │ │ │ Dehydrated was written by Lukas Schauer. This man page was contributed by │ │ │ │ Daniel Molkentin. │ │ │ │ .SH COPYRIGHT │ │ │ │ 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 │ │ │ │ Full documentation along with configuration examples are provided in the \fIdocs\fR │ │ │ │ directory of the distribution, or at │ │ │ │ -.UR https://github.com/lukas2511/dehydrated/tree/master/docs │ │ │ │ +.UR https://github.com/dehydrated-io/dehydrated/tree/master/docs │ │ │ │ .UE . │ │ ├── ./usr/share/doc/dehydrated/examples/config │ │ │ @@ -18,15 +18,15 @@ │ │ │ │ │ │ # Resolve names to addresses of IP version only. (curl) │ │ │ # supported values: 4, 6 │ │ │ # default: <unset> │ │ │ #IP_VERSION= │ │ │ │ │ │ # URL to certificate authority or internal preset │ │ │ -# Presets: letsencrypt, letsencrypt-test, zerossl, buypass, buypass-test │ │ │ +# Presets: letsencrypt, letsencrypt-test, zerossl, buypass, buypass-test, google, google-test │ │ │ # default: letsencrypt │ │ │ #CA="letsencrypt" │ │ │ │ │ │ # 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. │ │ │ @@ -88,16 +88,16 @@ │ │ │ # BASEDIR and WELLKNOWN variables are exported and can be used in an external program │ │ │ # default: <unset> │ │ │ #HOOK= │ │ │ │ │ │ # Chain clean_challenge|deploy_challenge arguments together into one hook call per certificate (default: no) │ │ │ #HOOK_CHAIN="no" │ │ │ │ │ │ -# Minimum days before expiration to automatically renew certificate (default: 30) │ │ │ -#RENEW_DAYS="30" │ │ │ +# Minimum days before expiration to automatically renew certificate (default: 32) │ │ │ +#RENEW_DAYS="32" │ │ │ │ │ │ # Regenerate private keys instead of just signing new certificates on renewal (default: yes) │ │ │ #PRIVATE_KEY_RENEW="yes" │ │ │ │ │ │ # Create an extra private key for rollover (default: no) │ │ │ #PRIVATE_KEY_ROLLOVER="no" │ │ │ │ │ │ @@ -121,12 +121,21 @@ │ │ │ │ │ │ # Issuer chain cache directory (default: $BASEDIR/chains) │ │ │ #CHAINCACHE="${BASEDIR}/chains" │ │ │ │ │ │ # Automatic cleanup (default: no) │ │ │ #AUTO_CLEANUP="no" │ │ │ │ │ │ +# Delete files during automatic cleanup instead of moving to archive (default: no) │ │ │ +#AUTO_CLEANUP_DELETE="no" │ │ │ + │ │ │ # ACME API version (default: auto) │ │ │ #API=auto │ │ │ │ │ │ # Preferred issuer chain (default: <unset> -> uses default chain) │ │ │ #PREFERRED_CHAIN= │ │ │ + │ │ │ +# Request certificate with specific profile (default: <unset>) │ │ │ +#ACME_PROFILE= │ │ │ + │ │ │ +# Amount of seconds to wait for processing of order until erroring out (default: 0 => no timeout) │ │ │ +#ORDER_TIMEOUT=0 │ │ ├── ./usr/share/man/man1/dehydrated.1.gz │ │ │ ├── dehydrated.1 │ │ │ │ @@ -22,15 +22,15 @@ │ │ │ │ based: If the file contains two lines "example.com" and "example.net", │ │ │ │ dehydrated will request two certificate, one for "example.com" and the other │ │ │ │ for "example.net". A single line containing "example.com example.net" will request a │ │ │ │ single certificate valid for both "example.net" and "example.com" through the \fISubject │ │ │ │ Alternative Name\fR (SAN) field. │ │ │ │ │ │ │ │ For the next step, one way of verifying domain name ownership needs to be │ │ │ │ -configured. Dehydrated implements \fIhttp-01\fR and \fIdns-01\fR verification. │ │ │ │ +configured. Dehydrated implements \fIhttp-01\fR and \fIdns-01\fR verification. │ │ │ │ │ │ │ │ The \fIhttp-01\fR verification provides proof of ownership by providing a │ │ │ │ challenge token. In order to do that, the directory referenced in the │ │ │ │ \fIWELLKNOWN\fR config variable needs to be exposed at │ │ │ │ \fIhttp://{domain}/.well-known/acme-challenge/\fR, where {domain} is every │ │ │ │ domain name specified in \fIdomains.txt\fR. Dehydrated does not provide its │ │ │ │ own challenge responder, but relies on an existing web server to provide the │ │ │ │ @@ -135,21 +135,21 @@ │ │ │ │ .BR \-\-algo ", " \-a " " \fI[rsa|prime256v1|secp384r1]\fR │ │ │ │ Which public key algorithm should be used? Supported: rsa, prime256v1 and │ │ │ │ secp384r1 │ │ │ │ .SH DIAGNOSTICS │ │ │ │ The program exits 0 if everything was fine, 1 if an error occurred. │ │ │ │ .SH BUGS │ │ │ │ Please report any bugs that you may encounter at the project web site │ │ │ │ -.UR https://github.com/lukas2511/dehydrated/issues │ │ │ │ +.UR https://github.com/dehydrated-io/dehydrated/issues │ │ │ │ .UE . │ │ │ │ .SH AUTHOR │ │ │ │ Dehydrated was written by Lukas Schauer. This man page was contributed by │ │ │ │ Daniel Molkentin. │ │ │ │ .SH COPYRIGHT │ │ │ │ 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 │ │ │ │ Full documentation along with configuration examples are provided in the \fIdocs\fR │ │ │ │ directory of the distribution, or at │ │ │ │ -.UR https://github.com/lukas2511/dehydrated/tree/master/docs │ │ │ │ +.UR https://github.com/dehydrated-io/dehydrated/tree/master/docs │ │ │ │ .UE .Attachment: signature.asc
Description: PGP signature
--- End Message ---
--- Begin Message ---
- To: 1107165-done@bugs.debian.org
- Subject: unblock dehydrated
- From: Sebastian Ramacher <sramacher@respighi.debian.org>
- Date: Tue, 03 Jun 2025 07:49:53 +0000
- Message-id: <E1uMMPB-004Itq-38@respighi.debian.org>
Unblocked.
--- End Message ---