Unverified Commit fa020b79 authored by Franz Pletz's avatar Franz Pletz Committed by GitHub
Browse files

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

parents 141ea5be 633ede5a
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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.
+49 −19
Original line number Diff line number Diff line
@@ -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" ]]

            expiration_date="$(date -d "$expiration_line" +%s)"
            now="$(date +%s)"
            expiration_s=$((expiration_date - now))
            expiration_days=$((expiration_s / (3600 * 24)))   # rounds down

            [[ $expiration_days -gt ${toString data.validMinDays} ]]
            # 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)

            # 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)

            # 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 {