nixos/acme: default to dynamic renewal days (#479209)

This commit is contained in:
Franz Pletz
2026-03-22 11:36:48 +00:00
committed by GitHub
2 changed files with 56 additions and 17 deletions
@@ -225,6 +225,15 @@ See <https://github.com/NixOS/nixpkgs/issues/481673>.
- Wine has been updated to the 11.0 branch. Please check the [upstream announcement](https://gitlab.winehq.org/wine/wine/-/releases/wine-11.0) for more details.
- `security.acme` now defaults to a dynamic renewal duration, if
[security.acme.defaults.validMinDays](#opt-security.acme.defaults.validMinDays)
remains unset. This accomodates certificates with different ACME profile:
- For certificates with a total validity at or above 10 days renewal will happen
after two thirds of the lifetime has passed (e.g. a certificate valid for 90
days renews once the validity falls below 30 days)
- For shortlived certificates with a total validty below 10 days renewal
will happen after half of the total lifetime has passed
- Cinnamon has been updated to 6.6, please check the [upstream announcement](https://www.linuxmint.com/rel_zena_whatsnew.php) for more details.
- Budgie has been updated to 10.10, please check the [upstream announcement](https://buddiesofbudgie.org/blog/budgie-10-10-released) for more details.
+47 -17
View File
@@ -523,20 +523,42 @@ let
[[ -e $pem ]]
expiration_line="$(
set -euxo pipefail
openssl x509 -noout -enddate <"$pem" \
| grep notAfter \
| sed -e 's/^notAfter=//'
)"
[[ -n "$expiration_line" ]]
# Read certificate valid duration
not_before=$(openssl x509 -in "$pem" -noout -startdate | cut -d= -f2)
not_after=$(openssl x509 -in "$pem" -noout -enddate | cut -d= -f2)
expiration_date="$(date -d "$expiration_line" +%s)"
now="$(date +%s)"
expiration_s=$((expiration_date - now))
expiration_days=$((expiration_s / (3600 * 24))) # rounds down
# Convert timestamp to seconds since epoch
not_before_epoch=$(date -d "$not_before" +%s)
not_after_epoch=$(date -d "$not_after" +%s)
now_epoch=$(date +%s)
[[ $expiration_days -gt ${toString data.validMinDays} ]]
# Determine total and remaining duration
total_duration=$((not_after_epoch - not_before_epoch))
remaining_duration=$((not_after_epoch - now_epoch))
${
if (data.validMinDays != null) then
''
# Convert to days and round down
total_days=$((total_duration / 86400))
remaining_days=$((remaining_duration / 86400))
[[ $remaining_days -gt ${toString data.validMinDays} ]]
''
else
''
# Recreate --dynamic logic from lego
if (( total_duration < 864000 )); then
# 1/2 for shortlived certificates with total lifetime < 10 days
threshold=$(( total_duration / 2))
else
# 1/3 for longer validity durations with total lifetime >= 10 days
threshold=$(( total_duration / 3))
fi
[[ $remaining_duration -gt $threshold ]]
''
}
}
echo '${domainHash}' > domainhash.txt
@@ -548,9 +570,11 @@ let
# Even if a cert is not expired, it may be revoked by the CA.
# Try to renew, and silently fail if the cert is not expired.
# Avoids #85794 and resolves #129838
if ! lego ${renewOpts} --days ${toString data.validMinDays}; then
if ! lego ${renewOpts} ${
if data.validMinDays != null then "--days ${toString data.validMinDays}" else "--dynamic"
}; then
if is_expiration_skippable out/full.pem; then
echo 1>&2 "nixos-acme: Ignoring failed renewal because expiration isn't within the coming ${toString data.validMinDays} days"
echo 1>&2 "nixos-acme: Ignoring failed renewal because expiration isn't due yet"
else
# High number to avoid Systemd reserved codes.
exit 11
@@ -626,9 +650,15 @@ let
options = {
validMinDays = lib.mkOption {
type = lib.types.int;
inherit (defaultAndText "validMinDays" 30) default defaultText;
description = "Minimum remaining validity before renewal in days.";
type = lib.types.nullOr lib.types.int;
default = null;
description = ''
Minimum remaining validity before renewal in days.
If unset, the renewal time is calculated dynamically:
- for regular certificates, renewal occurs when less than one-third of the lifetime remains
- for short-lived certificates, renewal occurs when less than half of the lifetime remains
'';
};
renewInterval = lib.mkOption {