@marcel91200 / caddy Mirror · read-only / commits / 19f36667
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 14, 05:15 UTC

tls: Clean up expired OCSP staples and certificates

Matthew Holt committed Sep 17, 2019 at 16:00 UTC 19f36667f75491f101b28b558551fc9639006f79
3 files changed +77 -5
go.mod
+1 -1
@@ -18,7 +18,7 @@ require (
18 github.com/klauspost/compress v1.7.1-0.20190613161414-0b31f265a57b
19 github.com/klauspost/cpuid v1.2.1
20 github.com/lucas-clemente/quic-go v0.7.1-0.20190908032346-fc962d18373a
21 - github.com/mholt/certmagic v0.7.1
21 + github.com/mholt/certmagic v0.7.2
22 github.com/muhammadmuzzammil1998/jsonc v0.0.0-20190902132743-e4903c4dea48
23 github.com/rs/cors v1.6.0
24 github.com/russross/blackfriday/v2 v2.0.1
go.sum
+2 -2
@@ -158,8 +158,8 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
158 github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
159 github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
160 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
161 -github.com/mholt/certmagic v0.7.1 h1:nbSSVwvlDE3+vttD/RBikBIkxrlKVkIQOz449gCrG5Q=
162 -github.com/mholt/certmagic v0.7.1/go.mod h1:hqHzDsY32TwZpj/KswVylheSISjquF/eOVOaJTYV15w=
161 +github.com/mholt/certmagic v0.7.2 h1:i4FRZyM33Ke6UdTrq69hLSRq1xvqS83JQTkzzUWtuF4=
162 +github.com/mholt/certmagic v0.7.2/go.mod h1:hqHzDsY32TwZpj/KswVylheSISjquF/eOVOaJTYV15w=
163 github.com/miekg/dns v1.1.15 h1:CSSIDtllwGLMoA6zjdKnaE6Tx6eVUxQ29LUgGetiDCI=
164 github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
165 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
modules/caddytls/tls.go
+74 -2
@@ -18,7 +18,9 @@ import (
18 "crypto/tls"
19 "encoding/json"
20 "fmt"
21 + "log"
22 "net/http"
23 + "sync"
24 "time"
25
26 "github.com/caddyserver/caddy/v2"
@@ -40,6 +42,8 @@ type TLS struct {
42 certificateLoaders []CertificateLoader
43 certCache *certmagic.Cache
44 ctx caddy.Context
45 + storageCleanTicker *time.Ticker
46 + storageCleanStop chan struct{}
47 }
48
49 // CaddyModule returns the Caddy module information.
@@ -121,6 +125,9 @@ func (t *TLS) Provision(ctx caddy.Context) error {
125 }
126 }
127
128 + t.storageCleanTicker = time.NewTicker(storageCleanInterval)
129 + t.storageCleanStop = make(chan struct{})
130 +
131 return nil
132 }
133
@@ -140,16 +147,25 @@ func (t *TLS) Start() error {
147 }
148 t.Certificates = nil // allow GC to deallocate
149
150 + t.keepStorageClean()
151 +
152 return nil
153 }
154
155 // Stop stops the TLS module and cleans up any allocations.
156 func (t *TLS) Stop() error {
157 + // stop the certificate cache
158 if t.certCache != nil {
149 - // TODO: ensure locks are cleaned up too... maybe in certmagic though
159 t.certCache.Stop()
160 }
161 +
162 + // stop the session ticket rotation goroutine
163 t.SessionTickets.stop()
164 +
165 + // stop the storage cleaner goroutine and ticker
166 + close(t.storageCleanStop)
167 + t.storageCleanTicker.Stop()
168 +
169 return nil
170 }
171
@@ -200,12 +216,60 @@ func (t *TLS) getAutomationPolicyForName(name string) AutomationPolicy {
216 return AutomationPolicy{Management: new(ACMEManagerMaker)}
217 }
218
203 -// CertificatesForSAN returns the list of all certificates in
219 +// AllMatchingCertificates returns the list of all certificates in
220 // the cache which could be used to satisfy the given SAN.
221 func (t *TLS) AllMatchingCertificates(san string) []certmagic.Certificate {
222 return t.certCache.AllMatchingCertificates(san)
223 }
224
225 +// keepStorageClean immediately cleans up all known storage units
226 +// if it was not recently done, and starts a goroutine that runs
227 +// the operation at every tick from t.storageCleanTicker.
228 +func (t *TLS) keepStorageClean() {
229 + go func() {
230 + for {
231 + select {
232 + case <-t.storageCleanStop:
233 + return
234 + case <-t.storageCleanTicker.C:
235 + t.cleanStorageUnits()
236 + }
237 + }
238 + }()
239 + t.cleanStorageUnits()
240 +}
241 +
242 +func (t *TLS) cleanStorageUnits() {
243 + storageCleanMu.Lock()
244 + defer storageCleanMu.Unlock()
245 +
246 + if !storageClean.IsZero() && time.Since(storageClean) < storageCleanInterval {
247 + return
248 + }
249 +
250 + options := certmagic.CleanStorageOptions{
251 + OCSPStaples: true,
252 + ExpiredCerts: true,
253 + ExpiredCertGracePeriod: 24 * time.Hour * 14,
254 + }
255 +
256 + // start with the default storage
257 + certmagic.CleanStorage(t.ctx.Storage(), options)
258 +
259 + // then clean each storage defined in ACME automation policies
260 + for _, ap := range t.Automation.Policies {
261 + if acmeMgmt, ok := ap.Management.(ACMEManagerMaker); ok {
262 + if acmeMgmt.storage != nil {
263 + certmagic.CleanStorage(acmeMgmt.storage, options)
264 + }
265 + }
266 + }
267 +
268 + storageClean = time.Now()
269 +
270 + log.Println("[INFO] tls: Cleaned up storage unit(s)")
271 +}
272 +
273 // CertificateLoader is a type that can load certificates.
274 // Certificates can optionally be associated with tags.
275 type CertificateLoader interface {
@@ -301,4 +365,12 @@ var (
365 }
366 )
367
368 +// Variables related to storage cleaning.
369 +var (
370 + storageCleanInterval = 12 * time.Hour
371 +
372 + storageClean time.Time
373 + storageCleanMu sync.Mutex
374 +)
375 +
376 const automateKey = "automate"