mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-31 10:37:24 -04:00 
			
		
		
		
	caddytls: Don't publish ECH configs if other records don't exist
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m27s
				
			
		
			
				
	
				Tests / test (s390x on IBM Z) (push) Has been skipped
				
			
		
			
				
	
				Tests / goreleaser-check (push) Has been skipped
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m17s
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m23s
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m22s
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m14s
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m15s
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m13s
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m26s
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m13s
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m16s
				
			
		
			
				
	
				Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m13s
				
			
		
			
				
	
				Lint / lint (ubuntu-latest, linux) (push) Successful in 1m51s
				
			
		
			
				
	
				Lint / govulncheck (push) Successful in 1m7s
				
			
		
			
				
	
				Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
				
			
		
			
				
	
				Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
				
			
		
			
				
	
				Lint / lint (macos-14, mac) (push) Has been cancelled
				
			
		
			
				
	
				Lint / lint (windows-latest, windows) (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m27s
				
			Tests / test (s390x on IBM Z) (push) Has been skipped
				
			Tests / goreleaser-check (push) Has been skipped
				
			Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m17s
				
			Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m23s
				
			Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m22s
				
			Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m14s
				
			Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m15s
				
			Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m13s
				
			Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m26s
				
			Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m13s
				
			Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m16s
				
			Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m13s
				
			Lint / lint (ubuntu-latest, linux) (push) Successful in 1m51s
				
			Lint / govulncheck (push) Successful in 1m7s
				
			Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
				
			Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
				
			Lint / lint (macos-14, mac) (push) Has been cancelled
				
			Lint / lint (windows-latest, windows) (push) Has been cancelled
				
			Publishing a DNS record for a name that doesn't have any could make wildcards ineffective, which would be surprising for site owners and could lead to downtime.
This commit is contained in:
		
							parent
							
								
									2ac09fdb20
								
							
						
					
					
						commit
						1f8dab572c
					
				| @ -163,6 +163,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// trim the list of domains covered by wildcards, if configured | ||||
| 		if srv.AutoHTTPS.PreferWildcard { | ||||
| 			wildcards := make(map[string]struct{}) | ||||
| 			for d := range serverDomainSet { | ||||
| @ -184,6 +185,17 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// build the list of domains that could be used with ECH (if enabled) | ||||
| 		// so the TLS app can know to publish ECH configs for them; we do this | ||||
| 		// after trimming domains covered by wildcards because, presumably, | ||||
| 		// if the user wants to use wildcard certs, they also want to use the | ||||
| 		// wildcard for ECH, rather than individual subdomains | ||||
| 		echDomains := make([]string, 0, len(serverDomainSet)) | ||||
| 		for d := range serverDomainSet { | ||||
| 			echDomains = append(echDomains, d) | ||||
| 		} | ||||
| 		app.tlsApp.RegisterServerNames(echDomains) | ||||
| 
 | ||||
| 		// nothing more to do here if there are no domains that qualify for | ||||
| 		// automatic HTTPS and there are no explicit TLS connection policies: | ||||
| 		// if there is at least one domain but no TLS conn policy (F&&T), we'll | ||||
| @ -205,7 +217,6 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er | ||||
| 		// for all the hostnames we found, filter them so we have | ||||
| 		// a deduplicated list of names for which to obtain certs | ||||
| 		// (only if cert management not disabled for this server) | ||||
| 		var echDomains []string | ||||
| 		if srv.AutoHTTPS.DisableCerts { | ||||
| 			logger.Warn("skipping automated certificate management for server because it is disabled", zap.String("server_name", srvName)) | ||||
| 		} else { | ||||
| @ -232,14 +243,10 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er | ||||
| 					} | ||||
| 
 | ||||
| 					uniqueDomainsForCerts[d] = struct{}{} | ||||
| 					echDomains = append(echDomains, d) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// let the TLS server know we have some hostnames that could be protected behind ECH | ||||
| 		app.tlsApp.RegisterServerNames(echDomains) | ||||
| 
 | ||||
| 		// tell the server to use TLS if it is not already doing so | ||||
| 		if srv.TLSConnPolicies == nil { | ||||
| 			srv.TLSConnPolicies = caddytls.ConnectionPolicies{new(caddytls.ConnectionPolicy)} | ||||
|  | ||||
| @ -639,8 +639,16 @@ func (dnsPub *ECHDNSPublisher) PublishECHConfigList(ctx context.Context, innerNa | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		// get any existing HTTPS record for this domain, and augment | ||||
| 		// our ech SvcParamKey with any other existing SvcParams | ||||
| 		relName := libdns.RelativeName(domain+".", zone) | ||||
| 		// TODO: libdns.RelativeName should probably return "@" instead of "". (The latest commits of libdns do this, so remove this logic once upgraded.) | ||||
| 		if relName == "" { | ||||
| 			relName = "@" | ||||
| 		} | ||||
| 
 | ||||
| 		// get existing records for this domain; we need to make sure another | ||||
| 		// record exists for it so we don't accidentally trample a wildcard; we | ||||
| 		// also want to get any HTTPS record that may already exist for it so | ||||
| 		// we can augment the ech SvcParamKey with any other existing SvcParams | ||||
| 		recs, err := dnsPub.provider.GetRecords(ctx, zone) | ||||
| 		if err != nil { | ||||
| 			dnsPub.logger.Error("unable to get existing DNS records to publish ECH data to HTTPS DNS record", | ||||
| @ -648,17 +656,29 @@ func (dnsPub *ECHDNSPublisher) PublishECHConfigList(ctx context.Context, innerNa | ||||
| 				zap.Error(err)) | ||||
| 			continue | ||||
| 		} | ||||
| 		relName := libdns.RelativeName(domain+".", zone) | ||||
| 		// TODO: libdns.RelativeName should probably return "@" instead of "". | ||||
| 		if relName == "" { | ||||
| 			relName = "@" | ||||
| 		} | ||||
| 		var httpsRec libdns.Record | ||||
| 		var nameHasExistingRecord bool | ||||
| 		for _, rec := range recs { | ||||
| 			if rec.Name == relName && rec.Type == "HTTPS" && (rec.Target == "" || rec.Target == ".") { | ||||
| 				httpsRec = rec | ||||
| 			if rec.Name == relName { | ||||
| 				nameHasExistingRecord = true | ||||
| 				if rec.Type == "HTTPS" && (rec.Target == "" || rec.Target == ".") { | ||||
| 					httpsRec = rec | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if !nameHasExistingRecord { | ||||
| 			// Turns out if you publish a DNS record for a name that doesn't have any DNS record yet, | ||||
| 			// any wildcard records won't apply for the name anymore, meaning if a wildcard A/AAAA record | ||||
| 			// is used to resolve the domain to a server, publishing an HTTPS record could break resolution! | ||||
| 			// In theory, this should be a non-issue, at least for A/AAAA records, if the HTTPS record | ||||
| 			// includes ipv[4|6]hint SvcParamKeys, | ||||
| 			dnsPub.logger.Warn("domain does not have any existing records, so skipping publication of HTTPS record", | ||||
| 				zap.String("domain", domain), | ||||
| 				zap.String("relative_name", relName), | ||||
| 				zap.String("zone", zone)) | ||||
| 			continue | ||||
| 		} | ||||
| 		params := make(svcParams) | ||||
| 		if httpsRec.Value != "" { | ||||
| 			params, err = parseSvcParams(httpsRec.Value) | ||||
|  | ||||
| @ -563,7 +563,7 @@ func (t *TLS) Manage(names []string) error { | ||||
| // (keeping only the hotsname) and filters IP addresses, which can't be | ||||
| // used with ECH. | ||||
| // | ||||
| // EXPERIMENTAL: This function and its behavior are subject to change. | ||||
| // EXPERIMENTAL: This function and its semantics/behavior are subject to change. | ||||
| func (t *TLS) RegisterServerNames(dnsNames []string) { | ||||
| 	t.serverNamesMu.Lock() | ||||
| 	for _, name := range dnsNames { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user