Skip to content

Commit 3ea9f24

Browse files
committed
erserver: use dev-cert SSL cert if CertBus is not configured
1 parent 66c4452 commit 3ea9f24

1 file changed

Lines changed: 65 additions & 5 deletions

File tree

pkg/erserver/serve.go

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package erserver
44
import (
55
"context"
66
"crypto/tls"
7+
"errors"
78
"fmt"
89
"log"
910
"net/http"
@@ -27,12 +28,67 @@ import (
2728
"github.com/function61/gokit/taskrunner"
2829
)
2930

31+
const (
32+
ConfigDir = "/etc/edgerouter"
33+
LocalDevCertfilePath = "/etc/edgerouter/dev-cert.pem" // used when CertBus not configured
34+
)
35+
36+
type GetCertificateFn func(*tls.ClientHelloInfo) (*tls.Certificate, error)
37+
3038
func Serve(ctx context.Context, logger *log.Logger) error {
3139
logl := logex.Levels(logger)
3240

3341
metrics := initMetrics()
3442

35-
certBus, err := makeCertBus(ctx, logex.Prefix("certbus", logger))
43+
waitAlreadyDoneFIXMENOTNEEDEDLONG := false
44+
45+
tasksCtx, tasksCancel := context.WithCancel(ctx)
46+
tasks := taskrunner.New(tasksCtx, logger)
47+
defer func() {
48+
// this defer is only needed for early exits to stop certbus sync task. if we exit from happy
49+
// path at bottom of this fn, this is not needed (but does not hurt to run twice)
50+
51+
if waitAlreadyDoneFIXMENOTNEEDEDLONG {
52+
return
53+
}
54+
55+
// this currently has a bug which is fixed when we can update to new gokit
56+
if err := tasks.Wait(); err != nil {
57+
logl.Error.Printf("taskrunner early-exit Wait(): %v", err)
58+
}
59+
}()
60+
defer tasksCancel()
61+
62+
getCertificateFn, err := func() (GetCertificateFn, error) {
63+
if os.Getenv("CERTBUS_CLIENT_PRIVKEY") != "" {
64+
certBus, err := makeCertBus(ctx, logex.Prefix("certbus", logger))
65+
if err != nil {
66+
return nil, err
67+
}
68+
69+
tasks.Start("certbus sync", func(ctx context.Context) error { return certBus.Synchronizer(ctx) })
70+
71+
return certBus.GetCertificateAdapter(), nil
72+
} else {
73+
logl.Info.Printf("CertBus not configured - assuming local dev-server & using %s", LocalDevCertfilePath)
74+
75+
// this is expected to be configured with mkcert or similar
76+
keyPair, err := tls.LoadX509KeyPair(LocalDevCertfilePath, LocalDevCertfilePath)
77+
if err != nil {
78+
if errors.Is(err, os.ErrNotExist) {
79+
return nil, fmt.Errorf(
80+
"certificate not found - run '$ %s setup-devcerts' first: %w",
81+
os.Args[0],
82+
err)
83+
} else {
84+
return nil, err
85+
}
86+
}
87+
88+
// we're assuming the user only needs one hostname or that it's a wildcard certificate
89+
return alwaysReturnSameCertificate(&keyPair), nil
90+
}
91+
}()
3692
if err != nil {
3793
return err
3894
}
@@ -148,7 +204,6 @@ func Serve(ctx context.Context, logger *log.Logger) error {
148204

149205
configUpdated := make(chan *frontendMatchers, 1)
150206

151-
tasks := taskrunner.New(ctx, logger)
152207
tasks.Start("listener :443", func(ctx context.Context) error {
153208
srv := &http.Server{
154209
Addr: ":443",
@@ -160,7 +215,7 @@ func Serve(ctx context.Context, logger *log.Logger) error {
160215
//nolint:gosec // rationale above
161216
TLSConfig: &tls.Config{
162217
// MinVersion: ... // purposefully unset to follow Go stdlib MinVersion
163-
GetCertificate: certBus.GetCertificateAdapter(),
218+
GetCertificate: getCertificateFn,
164219
},
165220
Handler: serveRequestWithMetricsCapture,
166221
}
@@ -177,8 +232,6 @@ func Serve(ctx context.Context, logger *log.Logger) error {
177232
return cancelableServer(ctx, srv, srv.ListenAndServe)
178233
})
179234

180-
tasks.Start("certbus sync", func(ctx context.Context) error { return certBus.Synchronizer(ctx) })
181-
182235
tasks.Start("configsyncscheduler", func(ctx context.Context) error {
183236
return scheduledSync(
184237
ctx,
@@ -192,6 +245,7 @@ func Serve(ctx context.Context, logger *log.Logger) error {
192245
for {
193246
select {
194247
case err := <-tasks.Done():
248+
waitAlreadyDoneFIXMENOTNEEDEDLONG = true
195249
return err
196250
case config := <-configUpdated:
197251
currentConfig.Store(config)
@@ -303,6 +357,12 @@ func makeCertBus(ctx context.Context, logger *log.Logger) (*certbus.App, error)
303357
return certBus, nil
304358
}
305359

360+
func alwaysReturnSameCertificate(keyPair *tls.Certificate) GetCertificateFn {
361+
return func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
362+
return keyPair, nil
363+
}
364+
}
365+
306366
type atomicConfig struct {
307367
atomic.Value // stores *frontendMatchers
308368
}

0 commit comments

Comments
 (0)