fix(server/embed): enforce non-empty client TLS if scheme is https/unixs

Signed-off-by: Gyuho Lee <gyuhox@gmail.com>
This commit is contained in:
Gyuho Lee
2024-06-17 18:21:38 +08:00
parent debc8fb00b
commit a657f069a1
3 changed files with 44 additions and 9 deletions

View File

@ -822,6 +822,24 @@ func (e *Etcd) pickGRPCGatewayServeContext(splitHTTP bool) *serveCtx {
panic("Expect at least one context able to serve grpc") 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) { func (e *Etcd) serveMetrics() (err error) {
if e.cfg.Metrics == "extensive" { if e.cfg.Metrics == "extensive" {
grpc_prometheus.EnableHandlingTimeHistogram() grpc_prometheus.EnableHandlingTimeHistogram()
@ -833,14 +851,7 @@ func (e *Etcd) serveMetrics() (err error) {
etcdhttp.HandleHealth(e.cfg.logger, metricsMux, e.Server) etcdhttp.HandleHealth(e.cfg.logger, metricsMux, e.Server)
for _, murl := range e.cfg.ListenMetricsUrls { for _, murl := range e.cfg.ListenMetricsUrls {
tlsInfo := &e.cfg.ClientTLSInfo ml, err := e.createMetricsListener(murl)
if murl.Scheme == "http" {
tlsInfo = nil
}
ml, err := transport.NewListenerWithOpts(murl.Host, murl.Scheme,
transport.WithTLSInfo(tlsInfo),
transport.WithSocketOpts(&e.cfg.SocketOpts),
)
if err != nil { if err != nil {
return err return err
} }

24
server/embed/etcd_test.go Normal file
View File

@ -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)
}
}

View File

@ -238,7 +238,7 @@ Profiling and Monitoring:
--metrics 'basic' --metrics 'basic'
Set level of detail for exported metrics, specify 'extensive' to include server side grpc histogram metrics. Set level of detail for exported metrics, specify 'extensive' to include server side grpc histogram metrics.
--listen-metrics-urls '' --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: Logging:
--logger 'zap' --logger 'zap'