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"