caddytls: Allow missing ECH meta file

This commit is contained in:
Matthew Holt 2025-04-18 12:20:21 -06:00
parent 1bfa111552
commit 3f19f937f8
No known key found for this signature in database
GPG Key ID: 2A349DD577D586A5

View File

@ -278,7 +278,7 @@ func (t *TLS) publishECHConfigs() error {
// if all the (inner) domains have had this ECH config list published
// by this publisher, then try the next publication config
if len(serverNamesSet) == 0 {
logger.Debug("ECH config list already published by publisher for associated domains",
logger.Debug("ECH config list already published by publisher for associated domains (or no domains to publish for)",
zap.Uint8s("config_ids", configIDs),
zap.String("publisher", publisherKey))
continue
@ -299,7 +299,7 @@ func (t *TLS) publishECHConfigs() error {
err := publisher.PublishECHConfigList(t.ctx, dnsNamesToPublish, echCfgListBin)
if err == nil {
t.logger.Info("published ECH configuration list",
zap.Strings("domains", publication.Domains),
zap.Strings("domains", dnsNamesToPublish),
zap.Uint8s("config_ids", configIDs),
zap.Error(err))
// update publication history, so that we don't unnecessarily republish every time
@ -389,27 +389,33 @@ func loadECHConfig(ctx caddy.Context, configID string) (echConfig, error) {
return echConfig{}, nil
}
metaBytes, err := storage.Load(ctx, metaKey)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
logger.Warn("ECH config metadata file missing; will recreate at next publication",
zap.String("config_id", configID),
zap.Error(err))
} else if err != nil {
delErr := storage.Delete(ctx, cfgIDKey)
if delErr != nil {
return echConfig{}, fmt.Errorf("error loading ECH metadata (%v) and cleaning up parent storage key %s: %v", err, cfgIDKey, delErr)
return echConfig{}, fmt.Errorf("error loading ECH config metadata (%v) and cleaning up parent storage key %s: %v", err, cfgIDKey, delErr)
}
logger.Warn("could not load ECH metadata; deleted its config folder",
logger.Warn("could not load ECH config metadata; deleted its folder",
zap.String("config_id", configID),
zap.Error(err))
return echConfig{}, nil
}
var meta echConfigMeta
if err := json.Unmarshal(metaBytes, &meta); err != nil {
// even though it's just metadata, reset the whole config since we can't reliably maintain it
delErr := storage.Delete(ctx, cfgIDKey)
if delErr != nil {
return echConfig{}, fmt.Errorf("error decoding ECH metadata (%v) and cleaning up parent storage key %s: %v", err, cfgIDKey, delErr)
if len(metaBytes) > 0 {
if err := json.Unmarshal(metaBytes, &meta); err != nil {
// even though it's just metadata, reset the whole config since we can't reliably maintain it
delErr := storage.Delete(ctx, cfgIDKey)
if delErr != nil {
return echConfig{}, fmt.Errorf("error decoding ECH metadata (%v) and cleaning up parent storage key %s: %v", err, cfgIDKey, delErr)
}
logger.Warn("could not JSON-decode ECH metadata; deleted its config folder",
zap.String("config_id", configID),
zap.Error(err))
return echConfig{}, nil
}
logger.Warn("could not JSON-decode ECH metadata; deleted its config folder",
zap.String("config_id", configID),
zap.Error(err))
return echConfig{}, nil
}
cfg.privKeyBin = privKeyBytes
@ -700,7 +706,7 @@ nextName:
// HTTPS and SVCB RRs: RFC 9460 (https://www.rfc-editor.org/rfc/rfc9460)
Scheme: "https",
Name: relName,
TTL: 1 * time.Minute, // TODO: for testing only
TTL: 5 * time.Minute, // TODO: low hard-coded value only temporary; change to a higher value once more field-tested and key rotation is implemented
Priority: 2, // allows a manual override with priority 1
Target: ".",
Params: params,