@marcel91200 / caddy Mirror · read-only / commits / 4a09cf0d
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 12, 20:45 UTC

caddytls: Sync distributed storage cleaning (#5940)

* caddytls: Log out remote addr to detect abuse * caddytls: Sync distributed storage cleaning * Handle errors * Update certmagic to fix tiny bug * Split off port when logging remote IP * Upgrade CertMagic

Matt Holt committed Dec 7, 2023 at 11:00 UTC 4a09cf0dc00724c3b0f76fe1ae4da887bde46240
5 files changed +36 -21
go.mod
+1 -1
@@ -7,7 +7,7 @@ require (
7 github.com/Masterminds/sprig/v3 v3.2.3
8 github.com/alecthomas/chroma/v2 v2.9.1
9 github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
10 - github.com/caddyserver/certmagic v0.19.3-0.20231030175448-e8e6167a2a51
10 + github.com/caddyserver/certmagic v0.20.0
11 github.com/dustin/go-humanize v1.0.1
12 github.com/go-chi/chi/v5 v5.0.10
13 github.com/google/cel-go v0.15.1
go.sum
+2 -4
@@ -61,10 +61,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
61 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
62 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
63 github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
64 -github.com/caddyserver/certmagic v0.19.2 h1:HZd1AKLx4592MalEGQS39DKs2ZOAJCEM/xYPMQ2/ui0=
65 -github.com/caddyserver/certmagic v0.19.2/go.mod h1:fsL01NomQ6N+kE2j37ZCnig2MFosG+MIO4ztnmG/zz8=
66 -github.com/caddyserver/certmagic v0.19.3-0.20231030175448-e8e6167a2a51 h1:9gmY8uzVBgUqJPjGBHMikvrxoyA+Ctu1u5WeVk5ktQ0=
67 -github.com/caddyserver/certmagic v0.19.3-0.20231030175448-e8e6167a2a51/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
64 +github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
65 +github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
66 github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
67 github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
68 github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
modules/caddytls/acmeissuer.go
+13 -1
@@ -16,9 +16,11 @@ package caddytls
16
17 import (
18 "context"
19 + "crypto/tls"
20 "crypto/x509"
21 "errors"
22 "fmt"
23 + "net"
24 "net/url"
25 "os"
26 "strconv"
@@ -496,7 +498,7 @@ func (iss *ACMEIssuer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
498 // to see if a certificate can be obtained for name.
499 // The certificate request should be denied if this
500 // returns an error.
499 -func onDemandAskRequest(logger *zap.Logger, ask string, name string) error {
501 +func onDemandAskRequest(ctx context.Context, logger *zap.Logger, ask string, name string) error {
502 askURL, err := url.Parse(ask)
503 if err != nil {
504 return fmt.Errorf("parsing ask URL: %v", err)
@@ -513,7 +515,17 @@ func onDemandAskRequest(logger *zap.Logger, ask string, name string) error {
515 }
516 resp.Body.Close()
517
518 + // logging out the client IP can be useful for servers that want to count
519 + // attempts from clients to detect patterns of abuse
520 + var clientIP string
521 + if hello, ok := ctx.Value(certmagic.ClientHelloInfoCtxKey).(*tls.ClientHelloInfo); ok && hello != nil {
522 + if remote := hello.Conn.RemoteAddr(); remote != nil {
523 + clientIP, _, _ = net.SplitHostPort(remote.String())
524 + }
525 + }
526 +
527 logger.Debug("response from ask endpoint",
528 + zap.String("client_ip", clientIP),
529 zap.String("domain", name),
530 zap.String("url", askURLString),
531 zap.Int("status", resp.StatusCode))
modules/caddytls/automation.go
+1 -1
@@ -256,7 +256,7 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error {
256 if tlsApp.Automation == nil || tlsApp.Automation.OnDemand == nil {
257 return nil
258 }
259 - if err := onDemandAskRequest(tlsApp.logger, tlsApp.Automation.OnDemand.Ask, name); err != nil {
259 + if err := onDemandAskRequest(ctx, tlsApp.logger, tlsApp.Automation.OnDemand.Ask, name); err != nil {
260 // distinguish true errors from denials, because it's important to elevate actual errors
261 if errors.Is(err, errAskDenied) {
262 tlsApp.logger.Debug("certificate issuance denied",
modules/caddytls/tls.go
+19 -14
@@ -551,6 +551,10 @@ func (t *TLS) cleanStorageUnits() {
551 storageCleanMu.Lock()
552 defer storageCleanMu.Unlock()
553
554 + // TODO: This check might not be needed anymore now that CertMagic syncs
555 + // and throttles storage cleaning globally across the cluster.
556 + // The original comment below might be outdated:
557 + //
558 // If storage was cleaned recently, don't do it again for now. Although the ticker
559 // calling this function drops missed ticks for us, config reloads discard the old
560 // ticker and replace it with a new one, possibly invoking a cleaning to happen again
@@ -563,21 +567,26 @@ func (t *TLS) cleanStorageUnits() {
567 return
568 }
569
570 + id, err := caddy.InstanceID()
571 + if err != nil {
572 + t.logger.Warn("unable to get instance ID; storage clean stamps will be incomplete", zap.Error(err))
573 + }
574 options := certmagic.CleanStorageOptions{
575 + Logger: t.logger,
576 + InstanceID: id.String(),
577 + Interval: t.storageCleanInterval(),
578 OCSPStaples: true,
579 ExpiredCerts: true,
580 ExpiredCertGracePeriod: 24 * time.Hour * 14,
581 }
582
572 - // avoid cleaning same storage more than once per cleaning cycle
573 - storagesCleaned := make(map[string]struct{})
574 -
583 // start with the default/global storage
576 - storage := t.ctx.Storage()
577 - storageStr := fmt.Sprintf("%v", storage)
578 - t.logger.Info("cleaning storage unit", zap.String("description", storageStr))
579 - certmagic.CleanStorage(t.ctx, storage, options)
580 - storagesCleaned[storageStr] = struct{}{}
584 + err = certmagic.CleanStorage(t.ctx, t.ctx.Storage(), options)
585 + if err != nil {
586 + // probably don't want to return early, since we should still
587 + // see if any other storages can get cleaned up
588 + t.logger.Error("could not clean default/global storage", zap.Error(err))
589 + }
590
591 // then clean each storage defined in ACME automation policies
592 if t.Automation != nil {
@@ -585,13 +594,9 @@ func (t *TLS) cleanStorageUnits() {
594 if ap.storage == nil {
595 continue
596 }
588 - storageStr := fmt.Sprintf("%v", ap.storage)
589 - if _, ok := storagesCleaned[storageStr]; ok {
590 - continue
597 + if err := certmagic.CleanStorage(t.ctx, ap.storage, options); err != nil {
598 + t.logger.Error("could not clean storage configured in automation policy", zap.Error(err))
599 }
592 - t.logger.Info("cleaning storage unit", zap.String("description", storageStr))
593 - certmagic.CleanStorage(t.ctx, ap.storage, options)
594 - storagesCleaned[storageStr] = struct{}{}
600 }
601 }
602