Skip to content

Commit 2b0e0a9

Browse files
authored
nixos/h2o: disable OCSP stapling w/ Let’s Encrypt (support sunset) (#393765)
2 parents d417129 + 7c8b3c8 commit 2b0e0a9

File tree

1 file changed

+45
-34
lines changed

1 file changed

+45
-34
lines changed

nixos/modules/services/web-servers/h2o/default.nix

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ let
5252

5353
# Attrset with the ACME certificate names split by whether or not they depend
5454
# on H2O serving challenges.
55-
certNames =
55+
acmeCertNames =
5656
let
5757
partition =
5858
acc: vhostSettings:
@@ -67,14 +67,14 @@ let
6767
else
6868
acc;
6969

70-
certNames' = lib.lists.foldl partition {
70+
certNames = lib.lists.foldl partition {
7171
dependent = [ ];
7272
independent = [ ];
7373
} acmeEnabledHostsConfigs;
7474
in
75-
certNames'
75+
certNames
7676
// {
77-
all = certNames'.dependent ++ certNames'.independent;
77+
all = certNames.dependent ++ certNames.independent;
7878
};
7979

8080
mozTLSRecs =
@@ -115,7 +115,7 @@ let
115115

116116
names = getNames name value;
117117

118-
acmeSettings = lib.optionalAttrs (builtins.elem names.cert certNames.dependent) (
118+
acmeSettings = lib.optionalAttrs (builtins.elem names.cert acmeCertNames.dependent) (
119119
let
120120
acmePort = 80;
121121
acmeChallengePath = "/.well-known/acme-challenge";
@@ -165,25 +165,34 @@ let
165165

166166
hasTLSRecommendations = tlsRecommendations != null && mozTLSRecs != null;
167167

168-
# NOTE: Let’s Encrypt has sunset OCSP stapling. Mozilla’s
169-
# ssl-config-generator is at present still recommending this setting, but
170-
# this module will skip setting a stapling value as Let’s Encrypt +
171-
# ACME is the most likely use case.
172-
#
173-
# See: https://github.com/mozilla/ssl-config-generator/issues/323
174-
tlsRecAttrs = lib.optionalAttrs hasTLSRecommendations (
175-
let
176-
recs = mozTLSRecs.${tlsRecommendations};
177-
in
178-
{
179-
min-version = builtins.head recs.tls_versions;
180-
cipher-preference = "server";
181-
"cipher-suite-tls1.3" = recs.ciphersuites;
182-
}
183-
// lib.optionalAttrs (recs.ciphers.openssl != [ ]) {
184-
cipher-suite = lib.concatStringsSep ":" recs.ciphers.openssl;
168+
# ATTENTION: Let’s Encrypt has sunset OCSP stapling.
169+
tlsRecAttrs =
170+
# If using ACME, this module will disable H2O’s default OCSP
171+
# stapling.
172+
#
173+
# See: https://letsencrypt.org/2024/12/05/ending-ocsp/
174+
lib.optionalAttrs (builtins.elem names.cert acmeCertNames.all) {
175+
ocsp-update-interval = 0;
185176
}
186-
);
177+
# Mozilla’s ssl-config-generator is at present still
178+
# recommending this setting as well, but this module will
179+
# skip setting a stapling value as Let’s Encrypt + ACME is
180+
# the most likely use case.
181+
#
182+
# See: https://github.com/mozilla/ssl-config-generator/issues/323
183+
// lib.optionalAttrs hasTLSRecommendations (
184+
let
185+
recs = mozTLSRecs.${tlsRecommendations};
186+
in
187+
{
188+
min-version = builtins.head recs.tls_versions;
189+
cipher-preference = "server";
190+
"cipher-suite-tls1.3" = recs.ciphersuites;
191+
}
192+
// lib.optionalAttrs (recs.ciphers.openssl != [ ]) {
193+
cipher-suite = lib.concatStringsSep ":" recs.ciphers.openssl;
194+
}
195+
);
187196

188197
headerRecAttrs =
189198
lib.optionalAttrs
@@ -220,7 +229,7 @@ let
220229
let
221230
identity =
222231
value.tls.identity
223-
++ lib.optional (builtins.elem names.cert certNames.all) {
232+
++ lib.optional (builtins.elem names.cert acmeCertNames.all) {
224233
key-file = "${certs.${names.cert}.directory}/key.pem";
225234
certificate-file = "${certs.${names.cert}.directory}/fullchain.pem";
226235
};
@@ -402,9 +411,9 @@ in
402411
groups = config.users.groups;
403412
services = [
404413
config.systemd.services.h2o
405-
] ++ lib.optional (certNames.all != [ ]) config.systemd.services.h2o-config-reload;
414+
] ++ lib.optional (acmeCertNames.all != [ ]) config.systemd.services.h2o-config-reload;
406415
}
407-
) certNames.all;
416+
) acmeCertNames.all;
408417

409418
users = {
410419
users.${cfg.user} =
@@ -420,13 +429,13 @@ in
420429
systemd.services.h2o = {
421430
description = "H2O HTTP server";
422431
wantedBy = [ "multi-user.target" ];
423-
wants = lib.concatLists (map (certName: [ "acme-finished-${certName}.target" ]) certNames.all);
432+
wants = lib.concatLists (map (certName: [ "acme-finished-${certName}.target" ]) acmeCertNames.all);
424433
# Since H2O will be hosting the challenges, H2O must be started
425-
before = builtins.map (certName: "acme-${certName}.service") certNames.dependent;
434+
before = builtins.map (certName: "acme-${certName}.service") acmeCertNames.dependent;
426435
after =
427436
[ "network.target" ]
428-
++ builtins.map (certName: "acme-selfsigned-${certName}.service") certNames.all
429-
++ builtins.map (certName: "acme-${certName}.service") certNames.independent; # avoid loading self-signed key w/ real cert, or vice-versa
437+
++ builtins.map (certName: "acme-selfsigned-${certName}.service") acmeCertNames.all
438+
++ builtins.map (certName: "acme-${certName}.service") acmeCertNames.independent; # avoid loading self-signed key w/ real cert, or vice-versa
430439

431440
serviceConfig = {
432441
ExecStart = "${h2oExe} --mode 'master'";
@@ -479,15 +488,17 @@ in
479488
# of certs end-to-end.
480489
systemd.services.h2o-config-reload =
481490
let
482-
tlsTargets = map (certName: "acme-${certName}.target") certNames.all;
483-
tlsServices = map (certName: "acme-${certName}.service") certNames.all;
491+
tlsTargets = map (certName: "acme-${certName}.target") acmeCertNames.all;
492+
tlsServices = map (certName: "acme-${certName}.service") acmeCertNames.all;
484493
in
485-
mkIf (certNames.all != [ ]) {
494+
mkIf (acmeCertNames.all != [ ]) {
486495
wantedBy = tlsServices ++ [ "multi-user.target" ];
487496
before = tlsTargets;
488497
after = tlsServices;
489498
unitConfig = {
490-
ConditionPathExists = map (certName: "${certs.${certName}.directory}/fullchain.pem") certNames.all;
499+
ConditionPathExists = map (
500+
certName: "${certs.${certName}.directory}/fullchain.pem"
501+
) acmeCertNames.all;
491502
# Disable rate limiting for this since it may be triggered quickly
492503
# a bunch of times if a lot of certificates are renewed in quick
493504
# succession. The reload itself is cheap, so even doing a lot of them

0 commit comments

Comments
 (0)