From a30084dd1ecccb3912ee63a292cd71ae146c6e4b Mon Sep 17 00:00:00 2001 From: sausageroll2077 Date: Tue, 5 May 2026 17:34:14 +0200 Subject: [PATCH 1/5] added support for le shortlived profile --- .../s6-rc.d/init-certbot-config/run | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run b/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run index 5e34aaae..28473339 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run @@ -12,12 +12,13 @@ EXTRA_DOMAINS=${EXTRA_DOMAINS}\\n\ ONLY_SUBDOMAINS=${ONLY_SUBDOMAINS}\\n\ VALIDATION=${VALIDATION}\\n\ CERTPROVIDER=${CERTPROVIDER}\\n\ +CERT_PROFILE=${CERT_PROFILE}\\n\ DNSPLUGIN=${DNSPLUGIN}\\n\ EMAIL=${EMAIL}\\n\ STAGING=${STAGING}\\n" # Sanitize variables -SANED_VARS=(DNSPLUGIN EMAIL EXTRA_DOMAINS ONLY_SUBDOMAINS STAGING SUBDOMAINS URL VALIDATION CERTPROVIDER) +SANED_VARS=(DNSPLUGIN EMAIL EXTRA_DOMAINS ONLY_SUBDOMAINS STAGING SUBDOMAINS URL VALIDATION CERTPROVIDER CERT_PROFILE) for i in "${SANED_VARS[@]}"; do export echo "${i}"="${!i//\"/}" export echo "${i}"="$(echo "${!i}" | tr '[:upper:]' '[:lower:]')" @@ -80,7 +81,7 @@ if [[ -f "/config/donoteditthisfile.conf" ]]; then mv /config/donoteditthisfile.conf /config/.donoteditthisfile.conf fi if [[ ! -f "/config/.donoteditthisfile.conf" ]]; then - echo -e "ORIGURL=\"${URL}\" ORIGSUBDOMAINS=\"${SUBDOMAINS}\" ORIGONLY_SUBDOMAINS=\"${ONLY_SUBDOMAINS}\" ORIGEXTRA_DOMAINS=\"${EXTRA_DOMAINS}\" ORIGVALIDATION=\"${VALIDATION}\" ORIGDNSPLUGIN=\"${DNSPLUGIN}\" ORIGPROPAGATION=\"${PROPAGATION}\" ORIGSTAGING=\"${STAGING}\" ORIGCERTPROVIDER=\"${CERTPROVIDER}\" ORIGEMAIL=\"${EMAIL}\"" >/config/.donoteditthisfile.conf + echo -e "ORIGURL=\"${URL}\" ORIGSUBDOMAINS=\"${SUBDOMAINS}\" ORIGONLY_SUBDOMAINS=\"${ONLY_SUBDOMAINS}\" ORIGEXTRA_DOMAINS=\"${EXTRA_DOMAINS}\" ORIGVALIDATION=\"${VALIDATION}\" ORIGDNSPLUGIN=\"${DNSPLUGIN}\" ORIGPROPAGATION=\"${PROPAGATION}\" ORIGSTAGING=\"${STAGING}\" ORIGCERTPROVIDER=\"${CERTPROVIDER}\" ORIGEMAIL=\"${EMAIL}\" ORIGCERT_PROFILE=\"${CERT_PROFILE}\"" >/config/.donoteditthisfile.conf echo "Created .donoteditthisfile.conf" fi @@ -186,7 +187,8 @@ if [[ ! "${URL}" = "${ORIGURL}" ]] || [[ ! "${DNSPLUGIN}" = "${ORIGDNSPLUGIN}" ]] || [[ ! "${PROPAGATION}" = "${ORIGPROPAGATION}" ]] || [[ ! "${STAGING}" = "${ORIGSTAGING}" ]] || - [[ ! "${CERTPROVIDER}" = "${ORIGCERTPROVIDER}" ]]; then + [[ ! "${CERTPROVIDER}" = "${ORIGCERTPROVIDER}" ]] || + [[ ! "${CERT_PROFILE}" = "${ORIGCERT_PROFILE}" ]]; then echo "Different validation parameters entered than what was used before. Revoking and deleting existing certificate, and an updated one will be created" if [[ "${ORIGCERTPROVIDER}" = "zerossl" ]]; then REV_ACMESERVER=("https://acme.zerossl.com/v2/DV90") @@ -204,7 +206,7 @@ if [[ ! "${URL}" = "${ORIGURL}" ]] || fi # saving new variables -echo -e "ORIGURL=\"${URL}\" ORIGSUBDOMAINS=\"${SUBDOMAINS}\" ORIGONLY_SUBDOMAINS=\"${ONLY_SUBDOMAINS}\" ORIGEXTRA_DOMAINS=\"${EXTRA_DOMAINS}\" ORIGVALIDATION=\"${VALIDATION}\" ORIGDNSPLUGIN=\"${DNSPLUGIN}\" ORIGPROPAGATION=\"${PROPAGATION}\" ORIGSTAGING=\"${STAGING}\" ORIGCERTPROVIDER=\"${CERTPROVIDER}\" ORIGEMAIL=\"${EMAIL}\"" >/config/.donoteditthisfile.conf +echo -e "ORIGURL=\"${URL}\" ORIGSUBDOMAINS=\"${SUBDOMAINS}\" ORIGONLY_SUBDOMAINS=\"${ONLY_SUBDOMAINS}\" ORIGEXTRA_DOMAINS=\"${EXTRA_DOMAINS}\" ORIGVALIDATION=\"${VALIDATION}\" ORIGDNSPLUGIN=\"${DNSPLUGIN}\" ORIGPROPAGATION=\"${PROPAGATION}\" ORIGSTAGING=\"${STAGING}\" ORIGCERTPROVIDER=\"${CERTPROVIDER}\" ORIGEMAIL=\"${EMAIL}\" ORIGCERT_PROFILE=\"${CERT_PROFILE}\"" >/config/.donoteditthisfile.conf # Check if the cert is using the old LE root cert, revoke and regen if necessary if [[ -f "/config/keys/letsencrypt/chain.pem" ]] && { [[ "${CERTPROVIDER}" == "letsencrypt" ]] || [[ "${CERTPROVIDER}" == "" ]]; } && [[ "${STAGING}" != "true" ]] && ! openssl x509 -in /config/keys/letsencrypt/chain.pem -noout -issuer | grep -q "ISRG Root X"; then @@ -239,6 +241,21 @@ fi set_ini_value "server" "${ACMESERVER}" /config/etc/letsencrypt/cli.ini +# set certificate profile (e.g. "shortlived" for 6-day certs, "classic" for 90-day) +# Profiles are a Let's Encrypt ACME feature; ZeroSSL ignores it. +if [[ -n "${CERT_PROFILE}" ]]; then + if [[ "${CERTPROVIDER}" = "zerossl" ]]; then + echo "ZeroSSL does not support ACME profiles, ignoring CERT_PROFILE variable" + sed -i "/^preferred-profile\b/d" /config/etc/letsencrypt/cli.ini + else + echo "Requesting certificate with profile: ${CERT_PROFILE}" + set_ini_value "preferred-profile" "${CERT_PROFILE}" /config/etc/letsencrypt/cli.ini + fi +else + # remove if previously set so going back to default works + sed -i "/^preferred-profile\b/d" /config/etc/letsencrypt/cli.ini +fi + # figuring out domain only vs domain & subdomains vs subdomains only DOMAINS_ARRAY=() if [[ -z "${SUBDOMAINS}" ]] || [[ "${ONLY_SUBDOMAINS}" != true ]]; then From 828618f86bc669fe29b466d47b11a5ef736971f0 Mon Sep 17 00:00:00 2001 From: sausageroll2077 Date: Tue, 5 May 2026 18:30:22 +0200 Subject: [PATCH 2/5] Included the enviroment for cert_profile with a link to the Let's encrypt documentation for it. --- readme-vars.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/readme-vars.yml b/readme-vars.yml index 27bde094..84071236 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -32,6 +32,7 @@ opt_param_usage_include_env: true opt_param_env_vars: - {env_var: "SUBDOMAINS", env_value: "www,", desc: "Subdomains you'd like the cert to cover (comma separated, no spaces) ie. `www,ftp,cloud`. For a wildcard cert, set this *exactly* to `wildcard` (wildcard cert is available via `dns` validation only)"} - {env_var: "CERTPROVIDER", env_value: "", desc: "Optionally define the cert provider. Set to `zerossl` for ZeroSSL certs (requires existing [ZeroSSL account](https://app.zerossl.com/signup) and the e-mail address entered in `EMAIL` env var). Otherwise defaults to Let's Encrypt."} + - {env_var: "CERT_PROFILE", env_value: "", desc: "Optionally define a cert profile to use for cert generation. This is useful if you want to use a custom cert profile instead of the default one. Currently only supported for Let's Encrypt. See https://letsencrypt.org/docs/profiles/ "} - {env_var: "DNSPLUGIN", env_value: "cloudflare", desc: "Required if `VALIDATION` is set to `dns`. Options are `acmedns`, `aliyun`, `azure`, `bunny`, `cloudflare`, `cpanel`, `desec`, `digitalocean`, `directadmin`, `dnsimple`, `dnsmadeeasy`, `dnspod`, `do`, `domeneshop`, `dreamhost`, `duckdns`, `dynu`, `freedns`, `gandi`, `gehirn`, `glesys`, `godaddy`, `google`, `he`, `hetzner`, `hetzner-cloud`, `infomaniak`, `inwx`, `ionos`, `linode`, `loopia`, `luadns`, `namecheap`, `netcup`, `njalla`, `nsone`, `ovh`, `porkbun`, `rfc2136`, `route53`, `sakuracloud`, `standalone`, `transip`, and `vultr`. Also need to enter the credentials into the corresponding ini (or json for some plugins) file under `/config/dns-conf`."} - {env_var: "PROPAGATION", env_value: "", desc: "Optionally override (in seconds) the default propagation time for the dns plugins."} - {env_var: "EMAIL", env_value: "", desc: "Optional e-mail address used for cert expiration notifications (Required for ZeroSSL)."} From 295cd100dfc2b5c842067051b39d9a26a7759bc7 Mon Sep 17 00:00:00 2001 From: sausageroll2077 Date: Tue, 5 May 2026 18:34:22 +0200 Subject: [PATCH 3/5] Added change to changelog --- readme-vars.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/readme-vars.yml b/readme-vars.yml index 84071236..4713fc9f 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -220,6 +220,7 @@ init_diagram: | "swag:latest" <- Base Images # changelog changelogs: + - {date: "05.05.26:", desc: "Added support for Let's Encrypt cert profiles." } - {date: "23.01.26:", desc: "Reorder init to fix proxy conf version checks."} - {date: "21.12.25:", desc: "Add support for hetzner-cloud dns validation."} - {date: "04.11.25:", desc: "Switch default Gandi credentials from API Key to Token, allow DNS propagation time for Azure DNS plugin."} From 22bcba61509a8f4e18a32a010e8713b16448aa55 Mon Sep 17 00:00:00 2001 From: sausageroll2077 Date: Tue, 5 May 2026 19:57:20 +0200 Subject: [PATCH 4/5] Changes logic to check for old root ca. to stop constant certificate renewal. --- .../s6-overlay/s6-rc.d/init-certbot-config/run | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run b/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run index 28473339..8263b218 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run @@ -209,15 +209,12 @@ fi echo -e "ORIGURL=\"${URL}\" ORIGSUBDOMAINS=\"${SUBDOMAINS}\" ORIGONLY_SUBDOMAINS=\"${ONLY_SUBDOMAINS}\" ORIGEXTRA_DOMAINS=\"${EXTRA_DOMAINS}\" ORIGVALIDATION=\"${VALIDATION}\" ORIGDNSPLUGIN=\"${DNSPLUGIN}\" ORIGPROPAGATION=\"${PROPAGATION}\" ORIGSTAGING=\"${STAGING}\" ORIGCERTPROVIDER=\"${CERTPROVIDER}\" ORIGEMAIL=\"${EMAIL}\" ORIGCERT_PROFILE=\"${CERT_PROFILE}\"" >/config/.donoteditthisfile.conf # Check if the cert is using the old LE root cert, revoke and regen if necessary -if [[ -f "/config/keys/letsencrypt/chain.pem" ]] && { [[ "${CERTPROVIDER}" == "letsencrypt" ]] || [[ "${CERTPROVIDER}" == "" ]]; } && [[ "${STAGING}" != "true" ]] && ! openssl x509 -in /config/keys/letsencrypt/chain.pem -noout -issuer | grep -q "ISRG Root X"; then - echo "The cert seems to be using the old LE root cert, which is no longer valid. Deleting and revoking." - REV_ACMESERVER=("https://acme-v02.api.letsencrypt.org/directory") - if [[ -f /config/etc/letsencrypt/live/"${ORIGDOMAIN}"/fullchain.pem ]]; then - certbot revoke --config-dir /config/etc/letsencrypt --logs-dir /config/log/letsencrypt --work-dir /tmp/letsencrypt --config /config/etc/letsencrypt/cli.ini --non-interactive --cert-path /config/etc/letsencrypt/live/"${ORIGDOMAIN}"/fullchain.pem --server "${REV_ACMESERVER[@]}" || true - else - certbot revoke --config-dir /config/etc/letsencrypt --logs-dir /config/log/letsencrypt --work-dir /tmp/letsencrypt --config /config/etc/letsencrypt/cli.ini --non-interactive --cert-name "${ORIGDOMAIN}" --server "${REV_ACMESERVER[@]}" || true - fi - rm -rf /config/etc/letsencrypt/{accounts,archive,live,renewal} +if [[ -f "/config/keys/letsencrypt/chain.pem" ]] && \ + { [[ "${CERTPROVIDER}" == "letsencrypt" ]] || [[ "${CERTPROVIDER}" == "" ]]; } && \ + [[ "${STAGING}" != "true" ]] && \ + openssl x509 -in /config/keys/letsencrypt/chain.pem -noout -issuer | grep -q "DST Root CA X3"; then + echo "The cert is chained through the expired DST Root CA X3. Deleting and revoking to force re-issuance." + ... fi # if zerossl is selected or staging is set to true, use the relevant server From bcca92b1fd8317436687d40dfa17097aa4533372 Mon Sep 17 00:00:00 2001 From: sausageroll2077 Date: Tue, 5 May 2026 20:14:39 +0200 Subject: [PATCH 5/5] Restore revocation body in DST Root CA X3 check --- root/etc/s6-overlay/s6-rc.d/init-certbot-config/run | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run b/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run index 8263b218..dd24ba1d 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-certbot-config/run @@ -208,13 +208,19 @@ fi # saving new variables echo -e "ORIGURL=\"${URL}\" ORIGSUBDOMAINS=\"${SUBDOMAINS}\" ORIGONLY_SUBDOMAINS=\"${ONLY_SUBDOMAINS}\" ORIGEXTRA_DOMAINS=\"${EXTRA_DOMAINS}\" ORIGVALIDATION=\"${VALIDATION}\" ORIGDNSPLUGIN=\"${DNSPLUGIN}\" ORIGPROPAGATION=\"${PROPAGATION}\" ORIGSTAGING=\"${STAGING}\" ORIGCERTPROVIDER=\"${CERTPROVIDER}\" ORIGEMAIL=\"${EMAIL}\" ORIGCERT_PROFILE=\"${CERT_PROFILE}\"" >/config/.donoteditthisfile.conf -# Check if the cert is using the old LE root cert, revoke and regen if necessary +# Check if the cert is chained through the expired DST Root CA X3, revoke and regen if necessary if [[ -f "/config/keys/letsencrypt/chain.pem" ]] && \ { [[ "${CERTPROVIDER}" == "letsencrypt" ]] || [[ "${CERTPROVIDER}" == "" ]]; } && \ [[ "${STAGING}" != "true" ]] && \ openssl x509 -in /config/keys/letsencrypt/chain.pem -noout -issuer | grep -q "DST Root CA X3"; then echo "The cert is chained through the expired DST Root CA X3. Deleting and revoking to force re-issuance." - ... + REV_ACMESERVER=("https://acme-v02.api.letsencrypt.org/directory") + if [[ -f /config/etc/letsencrypt/live/"${ORIGDOMAIN}"/fullchain.pem ]]; then + certbot revoke --config-dir /config/etc/letsencrypt --logs-dir /config/log/letsencrypt --work-dir /tmp/letsencrypt --config /config/etc/letsencrypt/cli.ini --non-interactive --cert-path /config/etc/letsencrypt/live/"${ORIGDOMAIN}"/fullchain.pem --server "${REV_ACMESERVER[@]}" || true + else + certbot revoke --config-dir /config/etc/letsencrypt --logs-dir /config/log/letsencrypt --work-dir /tmp/letsencrypt --config /config/etc/letsencrypt/cli.ini --non-interactive --cert-name "${ORIGDOMAIN}" --server "${REV_ACMESERVER[@]}" || true + fi + rm -rf /config/etc/letsencrypt/{accounts,archive,live,renewal} fi # if zerossl is selected or staging is set to true, use the relevant server