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: Add option to configure certificate lifetime #6253

Merged
merged 4 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions caddyconfig/httpcaddyfile/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func init() {
RegisterGlobalOption("auto_https", parseOptAutoHTTPS)
RegisterGlobalOption("servers", parseServerOptions)
RegisterGlobalOption("ocsp_stapling", parseOCSPStaplingOptions)
RegisterGlobalOption("cert_lifetime", parseOptDuration)
RegisterGlobalOption("log", parseLogOptions)
RegisterGlobalOption("preferred_chains", parseOptPreferredChains)
RegisterGlobalOption("persist_config", parseOptPersistConfig)
Expand Down
5 changes: 5 additions & 0 deletions caddyconfig/httpcaddyfile/tlsapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ func fillInGlobalACMEDefaults(issuer certmagic.Issuer, options map[string]any) e
globalACMEDNS := options["acme_dns"]
globalACMEEAB := options["acme_eab"]
globalPreferredChains := options["preferred_chains"]
globalCertLifetime := options["cert_lifetime"]

if globalEmail != nil && acmeIssuer.Email == "" {
acmeIssuer.Email = globalEmail.(string)
Expand All @@ -479,6 +480,10 @@ func fillInGlobalACMEDefaults(issuer certmagic.Issuer, options map[string]any) e
if globalPreferredChains != nil && acmeIssuer.PreferredChains == nil {
acmeIssuer.PreferredChains = globalPreferredChains.(*caddytls.ChainPreference)
}

if globalCertLifetime != nil && acmeIssuer.CertificateLifetime == 0 {
acmeIssuer.CertificateLifetime = globalCertLifetime.(caddy.Duration)
}
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/Masterminds/sprig/v3 v3.2.3
github.com/alecthomas/chroma/v2 v2.13.0
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
github.com/caddyserver/certmagic v0.20.1-0.20240412214119-167015dd6570
github.com/caddyserver/certmagic v0.20.1-0.20240419174353-855d4670a49d
github.com/caddyserver/zerossl v0.1.2
github.com/dustin/go-humanize v1.0.1
github.com/go-chi/chi/v5 v5.0.12
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/caddyserver/certmagic v0.20.1-0.20240412214119-167015dd6570 h1:SsAXjoQx2wOmLl6mEwJEwh7wwys2hb/l/mhtmxA3wts=
github.com/caddyserver/certmagic v0.20.1-0.20240412214119-167015dd6570/go.mod h1:e1NhB1rF5KZnAuAX6oSyhE7sg1Ru5bWgggw5RtauhEY=
github.com/caddyserver/certmagic v0.20.1-0.20240418194233-27ab129028e1 h1:jyf7BgZCwGqrqjv2+wOX662oZr9QqeSjzwA9bCG+paM=
github.com/caddyserver/certmagic v0.20.1-0.20240418194233-27ab129028e1/go.mod h1:e1NhB1rF5KZnAuAX6oSyhE7sg1Ru5bWgggw5RtauhEY=
github.com/caddyserver/certmagic v0.20.1-0.20240419174353-855d4670a49d h1:fi1dMdHOoyWHXpxpCbaB+H4xdAgQcBP2AXSqpXVpIcg=
github.com/caddyserver/certmagic v0.20.1-0.20240419174353-855d4670a49d/go.mod h1:e1NhB1rF5KZnAuAX6oSyhE7sg1Ru5bWgggw5RtauhEY=
github.com/caddyserver/zerossl v0.1.2 h1:tlEu1VzWGoqcCpivs9liKAKhfpJWYJkHEMmlxRbVAxE=
github.com/caddyserver/zerossl v0.1.2/go.mod h1:wtiJEHbdvunr40ZzhXlnIkOB8Xj4eKtBKizCcZitJiQ=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
Expand Down
22 changes: 22 additions & 0 deletions modules/caddytls/acmeissuer.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ type ACMEIssuer struct {
// will be selected.
PreferredChains *ChainPreference `json:"preferred_chains,omitempty"`

// The validity period to ask the CA to issue a certificate for.
// Default: 0 (don't ask a custom lifetime to the CA)
// This value is used to compute the "notAfter" field of the ACME order,
// therefore the system must have a reasonably synchronized clock.
// Important : Let's Encrypt and ZeroSSL don't allow custom
// validity period and will refuse to issue a certicate if this is set.
// For CAs that support it, there are often limits
// on the allowed validity periods. Please refer to your CA documentation.
clauverjat marked this conversation as resolved.
Show resolved Hide resolved
CertificateLifetime caddy.Duration `json:"certificate_lifetime,omitempty"`

rootPool *x509.CertPool
logger *zap.Logger

Expand Down Expand Up @@ -178,6 +188,7 @@ func (iss *ACMEIssuer) makeIssuerTemplate() (certmagic.ACMEIssuer, error) {
CertObtainTimeout: time.Duration(iss.ACMETimeout),
TrustedRoots: iss.rootPool,
ExternalAccount: iss.ExternalAccount,
NotAfter: time.Duration(iss.CertificateLifetime),
Logger: iss.logger,
}

Expand Down Expand Up @@ -349,6 +360,17 @@ func (iss *ACMEIssuer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {

for d.NextBlock(0) {
switch d.Val() {
case "lifetime":
var lifetimeStr string
if !d.AllArgs(&lifetimeStr) {
return d.ArgErr()
}
lifetime, err := caddy.ParseDuration(lifetimeStr)
if err != nil {
return d.Errf("invalid lifetime %s: %v", lifetimeStr, err)
}
// TODO: Add check that valid lifetime must be >= 0
clauverjat marked this conversation as resolved.
Show resolved Hide resolved
iss.CertificateLifetime = caddy.Duration(lifetime)
case "dir":
if iss.CA != "" {
return d.Errf("directory is already specified: %s", iss.CA)
Expand Down
Loading