Skip to content

Commit

Permalink
fix(server/embed): enforce non-empty client TLS if scheme is https/unixs
Browse files Browse the repository at this point in the history
Signed-off-by: Gyuho Lee <gyuhox@gmail.com>
  • Loading branch information
gyuho committed Jun 17, 2024
1 parent debc8fb commit a657f06
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
27 changes: 19 additions & 8 deletions server/embed/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,24 @@ func (e *Etcd) pickGRPCGatewayServeContext(splitHTTP bool) *serveCtx {
panic("Expect at least one context able to serve grpc")
}

var errMissingClientTLSInfoForMetricsURL = errors.New("client TLS key/cert (--cert-file, --key-file) must be provided for metrics url")

func (e *Etcd) createMetricsListener(murl url.URL) (net.Listener, error) {
tlsInfo := &e.cfg.ClientTLSInfo
switch murl.Scheme {
case "http":
tlsInfo = nil
case "https", "unixs":
if e.cfg.ClientTLSInfo.Empty() {
return nil, errMissingClientTLSInfoForMetricsURL
}
}
return transport.NewListenerWithOpts(murl.Host, murl.Scheme,
transport.WithTLSInfo(tlsInfo),
transport.WithSocketOpts(&e.cfg.SocketOpts),
)
}

func (e *Etcd) serveMetrics() (err error) {
if e.cfg.Metrics == "extensive" {
grpc_prometheus.EnableHandlingTimeHistogram()
Expand All @@ -833,14 +851,7 @@ func (e *Etcd) serveMetrics() (err error) {
etcdhttp.HandleHealth(e.cfg.logger, metricsMux, e.Server)

for _, murl := range e.cfg.ListenMetricsUrls {
tlsInfo := &e.cfg.ClientTLSInfo
if murl.Scheme == "http" {
tlsInfo = nil
}
ml, err := transport.NewListenerWithOpts(murl.Host, murl.Scheme,
transport.WithTLSInfo(tlsInfo),
transport.WithSocketOpts(&e.cfg.SocketOpts),
)
ml, err := e.createMetricsListener(murl)
if err != nil {
return err
}
Expand Down
24 changes: 24 additions & 0 deletions server/embed/etcd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package embed

import (
"net/url"
"testing"

"go.etcd.io/etcd/client/pkg/v3/transport"
)

func TestEmptyClientTLSInfo_createMetricsListener(t *testing.T) {
e := &Etcd{
cfg: Config{
ClientTLSInfo: transport.TLSInfo{},
},
}

murl := url.URL{
Scheme: "https",
Host: "localhost:8080",
}
if _, err := e.createMetricsListener(murl); err != errMissingClientTLSInfoForMetricsURL {
t.Fatalf("expected error %v, got %v", errMissingClientTLSInfoForMetricsURL, err)
}
}
2 changes: 1 addition & 1 deletion server/etcdmain/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ Profiling and Monitoring:
--metrics 'basic'
Set level of detail for exported metrics, specify 'extensive' to include server side grpc histogram metrics.
--listen-metrics-urls ''
List of URLs to listen on for the metrics and health endpoints.
List of URLs to listen on for the /metrics and /health endpoints. For https, the client URL TLS info is used.
Logging:
--logger 'zap'
Expand Down

0 comments on commit a657f06

Please sign in to comment.