Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 12, 02:00 UTC
caddytls: Reorder provisioning steps (fix #6877)
Also add a quick check to allow users to load their own certs for ECH (outer) domains.
Matthew Holt committed
Mar 7, 2025 at 11:17 UTC
4ebcfed9c942c59f473f12f8108e1d0fa92e0855
1 file changed
+62
-56
modules/caddytls/tls.go
+62
-56
@@ -182,17 +182,6 @@ func (t *TLS) Provision(ctx caddy.Context) error {
182
t.dns = dnsMod
183
}
184
185
- // ECH (Encrypted ClientHello) initialization
186
- if t.EncryptedClientHello != nil {
187
- t.EncryptedClientHello.configs = make(map[string][]echConfig)
188
- outerNames, err := t.EncryptedClientHello.Provision(ctx)
189
- if err != nil {
190
- return fmt.Errorf("provisioning Encrypted ClientHello components: %v", err)
191
- }
192
- // outer names should have certificates to reduce client brittleness
193
- t.automateNames = append(t.automateNames, outerNames...)
194
- }
195
-
185
// set up a new certificate cache; this (re)loads all certificates
186
cacheOpts := certmagic.CacheOptions{
187
GetConfigForCert: func(cert certmagic.Certificate) (*certmagic.Config, error) {
@@ -243,31 +232,34 @@ func (t *TLS) Provision(ctx caddy.Context) error {
232
t.certificateLoaders = append(t.certificateLoaders, modIface.(CertificateLoader))
233
}
234
246
- // on-demand permission module
247
- if t.Automation != nil && t.Automation.OnDemand != nil && t.Automation.OnDemand.PermissionRaw != nil {
248
- if t.Automation.OnDemand.Ask != "" {
249
- return fmt.Errorf("on-demand TLS config conflict: both 'ask' endpoint and a 'permission' module are specified; 'ask' is deprecated, so use only the permission module")
250
- }
251
- val, err := ctx.LoadModule(t.Automation.OnDemand, "PermissionRaw")
252
- if err != nil {
253
- return fmt.Errorf("loading on-demand TLS permission module: %v", err)
254
- }
255
- t.Automation.OnDemand.permission = val.(OnDemandPermission)
256
- }
257
-
258
- // run replacer on ask URL (for environment variables) -- return errors to prevent surprises (#5036)
259
- if t.Automation != nil && t.Automation.OnDemand != nil && t.Automation.OnDemand.Ask != "" {
260
- t.Automation.OnDemand.Ask, err = repl.ReplaceOrErr(t.Automation.OnDemand.Ask, true, true)
235
+ // using the certificate loaders we just initialized, load
236
+ // manual/static (unmanaged) certificates - we do this in
237
+ // provision so that other apps (such as http) can know which
238
+ // certificates have been manually loaded, and also so that
239
+ // commands like validate can be a better test
240
+ certCacheMu.RLock()
241
+ magic := certmagic.New(certCache, certmagic.Config{
242
+ Storage: ctx.Storage(),
243
+ Logger: t.logger,
244
+ OnEvent: t.onEvent,
245
+ OCSP: certmagic.OCSPConfig{
246
+ DisableStapling: t.DisableOCSPStapling,
247
+ },
248
+ DisableStorageCheck: t.DisableStorageCheck,
249
+ })
250
+ certCacheMu.RUnlock()
251
+ for _, loader := range t.certificateLoaders {
252
+ certs, err := loader.LoadCertificates()
253
if err != nil {
262
- return fmt.Errorf("preparing 'ask' endpoint: %v", err)
263
- }
264
- perm := PermissionByHTTP{
265
- Endpoint: t.Automation.OnDemand.Ask,
254
+ return fmt.Errorf("loading certificates: %v", err)
255
}
267
- if err := perm.Provision(ctx); err != nil {
268
- return fmt.Errorf("provisioning 'ask' module: %v", err)
256
+ for _, cert := range certs {
257
+ hash, err := magic.CacheUnmanagedTLSCertificate(ctx, cert.Certificate, cert.Tags)
258
+ if err != nil {
259
+ return fmt.Errorf("caching unmanaged certificate: %v", err)
260
+ }
261
+ t.loaded[hash] = ""
262
}
270
- t.Automation.OnDemand.permission = perm
263
}
264
265
// automation/management policies
@@ -302,6 +294,33 @@ func (t *TLS) Provision(ctx caddy.Context) error {
294
}
295
}
296
297
+ // on-demand permission module
298
+ if t.Automation != nil && t.Automation.OnDemand != nil && t.Automation.OnDemand.PermissionRaw != nil {
299
+ if t.Automation.OnDemand.Ask != "" {
300
+ return fmt.Errorf("on-demand TLS config conflict: both 'ask' endpoint and a 'permission' module are specified; 'ask' is deprecated, so use only the permission module")
301
+ }
302
+ val, err := ctx.LoadModule(t.Automation.OnDemand, "PermissionRaw")
303
+ if err != nil {
304
+ return fmt.Errorf("loading on-demand TLS permission module: %v", err)
305
+ }
306
+ t.Automation.OnDemand.permission = val.(OnDemandPermission)
307
+ }
308
+
309
+ // run replacer on ask URL (for environment variables) -- return errors to prevent surprises (#5036)
310
+ if t.Automation != nil && t.Automation.OnDemand != nil && t.Automation.OnDemand.Ask != "" {
311
+ t.Automation.OnDemand.Ask, err = repl.ReplaceOrErr(t.Automation.OnDemand.Ask, true, true)
312
+ if err != nil {
313
+ return fmt.Errorf("preparing 'ask' endpoint: %v", err)
314
+ }
315
+ perm := PermissionByHTTP{
316
+ Endpoint: t.Automation.OnDemand.Ask,
317
+ }
318
+ if err := perm.Provision(ctx); err != nil {
319
+ return fmt.Errorf("provisioning 'ask' module: %v", err)
320
+ }
321
+ t.Automation.OnDemand.permission = perm
322
+ }
323
+
324
// session ticket ephemeral keys (STEK) service and provider
325
if t.SessionTickets != nil {
326
err := t.SessionTickets.provision(ctx)
@@ -310,32 +329,19 @@ func (t *TLS) Provision(ctx caddy.Context) error {
329
}
330
}
331
313
- // load manual/static (unmanaged) certificates - we do this in
314
- // provision so that other apps (such as http) can know which
315
- // certificates have been manually loaded, and also so that
316
- // commands like validate can be a better test
317
- certCacheMu.RLock()
318
- magic := certmagic.New(certCache, certmagic.Config{
319
- Storage: ctx.Storage(),
320
- Logger: t.logger,
321
- OnEvent: t.onEvent,
322
- OCSP: certmagic.OCSPConfig{
323
- DisableStapling: t.DisableOCSPStapling,
324
- },
325
- DisableStorageCheck: t.DisableStorageCheck,
326
- })
327
- certCacheMu.RUnlock()
328
- for _, loader := range t.certificateLoaders {
329
- certs, err := loader.LoadCertificates()
332
+ // ECH (Encrypted ClientHello) initialization
333
+ if t.EncryptedClientHello != nil {
334
+ t.EncryptedClientHello.configs = make(map[string][]echConfig)
335
+ outerNames, err := t.EncryptedClientHello.Provision(ctx)
336
if err != nil {
331
- return fmt.Errorf("loading certificates: %v", err)
337
+ return fmt.Errorf("provisioning Encrypted ClientHello components: %v", err)
338
}
333
- for _, cert := range certs {
334
- hash, err := magic.CacheUnmanagedTLSCertificate(ctx, cert.Certificate, cert.Tags)
335
- if err != nil {
336
- return fmt.Errorf("caching unmanaged certificate: %v", err)
339
+
340
+ // outer names should have certificates to reduce client brittleness
341
+ for _, outerName := range outerNames {
342
+ if !t.HasCertificateForSubject(outerName) {
343
+ t.automateNames = append(t.automateNames, outerNames...)
344
}
338
- t.loaded[hash] = ""
345
}
346
}
347