Skip to content

Commit 929d0e5

Browse files
authored
caddyfile: Add renewal_window_ratio global option and tls subdirective (#7473)
* caddyfile: Add renewal_window_ratio global option Adds support for configuring the TLS certificate renewal window ratio directly in the Caddyfile global options block. This allows users to customize when certificates should be renewed without needing to use JSON configuration. Example usage: { renewal_window_ratio 0.1666 } Fixes #7467 * caddyfile: Add renewal_window_ratio to tls directive and tests Adds support for renewal_window_ratio in the tls directive (not just global options) and adds caddyfile adapt tests for both the global option and tls directive. * fix: inherit global renewal_window_ratio in site policies * fix: correct test expected output for policy consolidation * fix: properly inherit global renewal_window_ratio without removing other code
1 parent 6718bd4 commit 929d0e5

File tree

5 files changed

+160
-1
lines changed

5 files changed

+160
-1
lines changed

caddyconfig/httpcaddyfile/builtins.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ func parseBind(h Helper) ([]ConfigValue, error) {
113113
// issuer <module_name> [...]
114114
// get_certificate <module_name> [...]
115115
// insecure_secrets_log <log_file>
116+
// renewal_window_ratio <ratio>
116117
// }
117118
func parseTLS(h Helper) ([]ConfigValue, error) {
118119
h.Next() // consume directive name
@@ -129,6 +130,7 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
129130
var onDemand bool
130131
var reusePrivateKeys bool
131132
var forceAutomate bool
133+
var renewalWindowRatio float64
132134

133135
// Track which DNS challenge options are set
134136
var dnsOptionsSet []string
@@ -473,6 +475,20 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
473475
}
474476
cp.InsecureSecretsLog = h.Val()
475477

478+
case "renewal_window_ratio":
479+
arg := h.RemainingArgs()
480+
if len(arg) != 1 {
481+
return nil, h.ArgErr()
482+
}
483+
ratio, err := strconv.ParseFloat(arg[0], 64)
484+
if err != nil {
485+
return nil, h.Errf("parsing renewal_window_ratio: %v", err)
486+
}
487+
if ratio <= 0 || ratio >= 1 {
488+
return nil, h.Errf("renewal_window_ratio must be between 0 and 1 (exclusive)")
489+
}
490+
renewalWindowRatio = ratio
491+
476492
default:
477493
return nil, h.Errf("unknown subdirective: %s", h.Val())
478494
}
@@ -597,6 +613,14 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
597613
})
598614
}
599615

616+
// renewal window ratio
617+
if renewalWindowRatio > 0 {
618+
configVals = append(configVals, ConfigValue{
619+
Class: "tls.renewal_window_ratio",
620+
Value: renewalWindowRatio,
621+
})
622+
}
623+
600624
// if enabled, the names in the site addresses will be
601625
// added to the automation policies
602626
if forceAutomate {

caddyconfig/httpcaddyfile/options.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ func init() {
6565
RegisterGlobalOption("persist_config", parseOptPersistConfig)
6666
RegisterGlobalOption("dns", parseOptDNS)
6767
RegisterGlobalOption("ech", parseOptECH)
68+
RegisterGlobalOption("renewal_window_ratio", parseOptRenewalWindowRatio)
6869
}
6970

7071
func parseOptTrue(d *caddyfile.Dispenser, _ any) (any, error) { return true, nil }
@@ -624,3 +625,22 @@ func parseOptECH(d *caddyfile.Dispenser, _ any) (any, error) {
624625

625626
return ech, nil
626627
}
628+
629+
func parseOptRenewalWindowRatio(d *caddyfile.Dispenser, _ any) (any, error) {
630+
d.Next() // consume option name
631+
if !d.Next() {
632+
return 0, d.ArgErr()
633+
}
634+
val := d.Val()
635+
ratio, err := strconv.ParseFloat(val, 64)
636+
if err != nil {
637+
return 0, d.Errf("parsing renewal_window_ratio: %v", err)
638+
}
639+
if ratio <= 0 || ratio >= 1 {
640+
return 0, d.Errf("renewal_window_ratio must be between 0 and 1 (exclusive)")
641+
}
642+
if d.Next() {
643+
return 0, d.ArgErr()
644+
}
645+
return ratio, nil
646+
}

caddyconfig/httpcaddyfile/tlsapp.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ func (st ServerType) buildTLSApp(
143143
ap.KeyType = keyTypeVals[0].Value.(string)
144144
}
145145

146+
if renewalWindowRatioVals, ok := sblock.pile["tls.renewal_window_ratio"]; ok {
147+
ap.RenewalWindowRatio = renewalWindowRatioVals[0].Value.(float64)
148+
} else if globalRenewalWindowRatio, ok := options["renewal_window_ratio"]; ok {
149+
ap.RenewalWindowRatio = globalRenewalWindowRatio.(float64)
150+
}
151+
146152
// certificate issuers
147153
if issuerVals, ok := sblock.pile["tls.cert_issuer"]; ok {
148154
var issuers []certmagic.Issuer
@@ -607,7 +613,8 @@ func newBaseAutomationPolicy(
607613
_, hasLocalCerts := options["local_certs"]
608614
keyType, hasKeyType := options["key_type"]
609615
ocspStapling, hasOCSPStapling := options["ocsp_stapling"]
610-
hasGlobalAutomationOpts := hasIssuers || hasLocalCerts || hasKeyType || hasOCSPStapling
616+
renewalWindowRatio, hasRenewalWindowRatio := options["renewal_window_ratio"]
617+
hasGlobalAutomationOpts := hasIssuers || hasLocalCerts || hasKeyType || hasOCSPStapling || hasRenewalWindowRatio
611618

612619
globalACMECA := options["acme_ca"]
613620
globalACMECARoot := options["acme_ca_root"]
@@ -654,6 +661,10 @@ func newBaseAutomationPolicy(
654661
ap.OCSPOverrides = ocspConfig.ResponderOverrides
655662
}
656663

664+
if hasRenewalWindowRatio {
665+
ap.RenewalWindowRatio = renewalWindowRatio.(float64)
666+
}
667+
657668
return ap, nil
658669
}
659670

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
renewal_window_ratio 0.1666
3+
}
4+
5+
example.com {
6+
}
7+
----------
8+
{
9+
"apps": {
10+
"http": {
11+
"servers": {
12+
"srv0": {
13+
"listen": [
14+
":443"
15+
],
16+
"routes": [
17+
{
18+
"match": [
19+
{
20+
"host": [
21+
"example.com"
22+
]
23+
}
24+
],
25+
"terminal": true
26+
}
27+
]
28+
}
29+
}
30+
},
31+
"tls": {
32+
"automation": {
33+
"policies": [
34+
{
35+
"renewal_window_ratio": 0.1666
36+
}
37+
]
38+
}
39+
}
40+
}
41+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
renewal_window_ratio 0.1666
3+
}
4+
5+
a.example.com {
6+
tls {
7+
renewal_window_ratio 0.25
8+
}
9+
}
10+
11+
b.example.com {
12+
}
13+
----------
14+
{
15+
"apps": {
16+
"http": {
17+
"servers": {
18+
"srv0": {
19+
"listen": [
20+
":443"
21+
],
22+
"routes": [
23+
{
24+
"match": [
25+
{
26+
"host": [
27+
"a.example.com"
28+
]
29+
}
30+
],
31+
"terminal": true
32+
},
33+
{
34+
"match": [
35+
{
36+
"host": [
37+
"b.example.com"
38+
]
39+
}
40+
],
41+
"terminal": true
42+
}
43+
]
44+
}
45+
}
46+
},
47+
"tls": {
48+
"automation": {
49+
"policies": [
50+
{
51+
"subjects": [
52+
"a.example.com"
53+
],
54+
"renewal_window_ratio": 0.25
55+
},
56+
{
57+
"renewal_window_ratio": 0.1666
58+
}
59+
]
60+
}
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)