Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

caddytls: Allow disabling storage cleaning, avoids writing two files #6593

Merged
merged 1 commit into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion caddyconfig/httpcaddyfile/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ func init() {
RegisterGlobalOption("fallback_sni", parseOptSingleString)
RegisterGlobalOption("order", parseOptOrder)
RegisterGlobalOption("storage", parseOptStorage)
RegisterGlobalOption("storage_clean_interval", parseOptDuration)
RegisterGlobalOption("storage_check", parseStorageCheck)
RegisterGlobalOption("storage_clean_interval", parseStorageCleanInterval)
RegisterGlobalOption("renew_interval", parseOptDuration)
RegisterGlobalOption("ocsp_interval", parseOptDuration)
RegisterGlobalOption("acme_ca", parseOptSingleString)
Expand Down Expand Up @@ -189,6 +190,40 @@ func parseOptStorage(d *caddyfile.Dispenser, _ any) (any, error) {
return storage, nil
}

func parseStorageCheck(d *caddyfile.Dispenser, _ any) (any, error) {
d.Next() // consume option name
if !d.Next() {
return "", d.ArgErr()
}
val := d.Val()
if d.Next() {
return "", d.ArgErr()
}
if val != "off" {
return "", d.Errf("storage_check must be 'off'")
}
return val, nil
}

func parseStorageCleanInterval(d *caddyfile.Dispenser, _ any) (any, error) {
d.Next() // consume option name
if !d.Next() {
return "", d.ArgErr()
}
val := d.Val()
if d.Next() {
return "", d.ArgErr()
}
if val == "off" {
return false, nil
}
dur, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.Errf("failed to parse storage_clean_interval, must be a duration or 'off' %w", err)
}
return caddy.Duration(dur), nil
}

func parseOptDuration(d *caddyfile.Dispenser, _ any) (any, error) {
if !d.Next() { // consume option name
return nil, d.ArgErr()
Expand Down
10 changes: 10 additions & 0 deletions caddyconfig/httpcaddyfile/tlsapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,16 @@ func (st ServerType) buildTLSApp(
tlsApp.Automation.OnDemand = onDemand
}

// if the storage clean interval is a boolean, then it's "off" to disable cleaning
if sc, ok := options["storage_check"].(string); ok && sc == "off" {
tlsApp.DisableStorageCheck = true
}

// if the storage clean interval is a boolean, then it's "off" to disable cleaning
if sci, ok := options["storage_clean_interval"].(bool); ok && !sci {
tlsApp.DisableStorageClean = true
}

// set the storage clean interval if configured
if storageCleanInterval, ok := options["storage_clean_interval"].(caddy.Duration); ok {
if tlsApp.Automation == nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
storage file_system {
root /data
}
storage_check off
storage_clean_interval off
acme_ca https://example.com
acme_ca_root /path/to/ca.crt
ocsp_stapling off
Expand Down Expand Up @@ -73,7 +75,9 @@
}
}
},
"disable_ocsp_stapling": true
"disable_ocsp_stapling": true,
"disable_storage_check": true,
"disable_storage_clean": true
}
}
}
17 changes: 16 additions & 1 deletion modules/caddytls/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ type TLS struct {
// EXPERIMENTAL. Subject to change.
DisableStorageCheck bool `json:"disable_storage_check,omitempty"`

// Disables the automatic cleanup of the storage backend.
// This is useful when TLS is not being used to store certificates
// and the user wants run their server in a read-only mode.
//
// Storage cleaning creates two files: instance.uuid and last_clean.json.
// The instance.uuid file is used to identify the instance of Caddy
// in a cluster. The last_clean.json file is used to store the last
// time the storage was cleaned.
// EXPERIMENTAL. Subject to change.
DisableStorageClean bool `json:"disable_storage_clean,omitempty"`

certificateLoaders []CertificateLoader
automateNames []string
ctx caddy.Context
Expand Down Expand Up @@ -328,7 +339,11 @@ func (t *TLS) Start() error {
return fmt.Errorf("automate: managing %v: %v", t.automateNames, err)
}

t.keepStorageClean()
if !t.DisableStorageClean {
// start the storage cleaner goroutine and ticker,
// which cleans out expired certificates and more
t.keepStorageClean()
}

return nil
}
Expand Down
Loading