From bfaf2a8201b83d7369772cb6f2439abe66d9342a Mon Sep 17 00:00:00 2001 From: Kyle McCullough Date: Mon, 5 Dec 2022 23:12:26 -0800 Subject: acme_server: Configurable default lifetime for issued certificates (#5232) * acme_server: add certificate lifetime configuration option Signed-off-by: Kyle McCullough * pki: allow intermediate cert lifetime to be configured Signed-off-by: Kyle McCullough Signed-off-by: Kyle McCullough --- modules/caddypki/acmeserver/acmeserver.go | 14 +++++++++++++- modules/caddypki/acmeserver/caddyfile.go | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'modules/caddypki/acmeserver') diff --git a/modules/caddypki/acmeserver/acmeserver.go b/modules/caddypki/acmeserver/acmeserver.go index 921d0b8..6ecdfdc 100644 --- a/modules/caddypki/acmeserver/acmeserver.go +++ b/modules/caddypki/acmeserver/acmeserver.go @@ -48,6 +48,9 @@ type Handler struct { // the default ID is "local". CA string `json:"ca,omitempty"` + // The lifetime for issued certificates + Lifetime caddy.Duration `json:"lifetime,omitempty"` + // The hostname or IP address by which ACME clients // will access the server. This is used to populate // the ACME directory endpoint. If not set, the Host @@ -95,6 +98,9 @@ func (ash *Handler) Provision(ctx caddy.Context) error { if ash.PathPrefix == "" { ash.PathPrefix = defaultPathPrefix } + if ash.Lifetime == 0 { + ash.Lifetime = caddy.Duration(12 * time.Hour) + } // get a reference to the configured CA appModule, err := ctx.App("pki") @@ -107,6 +113,12 @@ func (ash *Handler) Provision(ctx caddy.Context) error { return err } + // make sure leaf cert lifetime is less than the intermediate cert lifetime. this check only + // applies for caddy-managed intermediate certificates + if ca.Intermediate == nil && ash.Lifetime >= ca.IntermediateLifetime { + return fmt.Errorf("certificate lifetime (%s) should be less than intermediate certificate lifetime (%s)", time.Duration(ash.Lifetime), time.Duration(ca.IntermediateLifetime)) + } + database, err := ash.openDatabase() if err != nil { return err @@ -122,7 +134,7 @@ func (ash *Handler) Provision(ctx caddy.Context) error { Claims: &provisioner.Claims{ MinTLSDur: &provisioner.Duration{Duration: 5 * time.Minute}, MaxTLSDur: &provisioner.Duration{Duration: 24 * time.Hour * 365}, - DefaultTLSDur: &provisioner.Duration{Duration: 12 * time.Hour}, + DefaultTLSDur: &provisioner.Duration{Duration: time.Duration(ash.Lifetime)}, }, }, }, diff --git a/modules/caddypki/acmeserver/caddyfile.go b/modules/caddypki/acmeserver/caddyfile.go index fe12712..ae2d8ef 100644 --- a/modules/caddypki/acmeserver/caddyfile.go +++ b/modules/caddypki/acmeserver/caddyfile.go @@ -15,6 +15,9 @@ package acmeserver import ( + "time" + + "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" "github.com/caddyserver/caddy/v2/modules/caddypki" ) @@ -27,6 +30,7 @@ func init() { // // acme_server [] { // ca +// lifetime // } func parseACMEServer(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) { if !h.Next() { @@ -55,6 +59,21 @@ func parseACMEServer(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error ca = new(caddypki.CA) } ca.ID = acmeServer.CA + case "lifetime": + if !h.NextArg() { + return nil, h.ArgErr() + } + + dur, err := caddy.ParseDuration(h.Val()) + if err != nil { + return nil, err + } + + if d := time.Duration(ca.IntermediateLifetime); d > 0 && dur > d { + return nil, h.Errf("certificate lifetime (%s) exceeds intermediate certificate lifetime (%s)", dur, d) + } + + acmeServer.Lifetime = caddy.Duration(dur) } } } -- cgit v1.2.3