mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-24 17:16:41 +00:00
feat(metrics): enable TLS/mTLS serving support (#1576)
* feat(config): add metrics TLS configuration Signed-off-by: Xe Iaso <me@xeiaso.net> * feat(metrics): add naive TLS serving for metrics Signed-off-by: Xe Iaso <me@xeiaso.net> * feat(metrics): import keypairreloader from a private project Signed-off-by: Xe Iaso <me@xeiaso.net> * fix(metrics): properly surface errors with the metrics server Signed-off-by: Xe Iaso <me@xeiaso.net> * feat(config): add CA certificate config value Signed-off-by: Xe Iaso <me@xeiaso.net> * feat(metrics): enable mTLS support Signed-off-by: Xe Iaso <me@xeiaso.net> * doc(default-config): document how to set up TLS and mTLS Signed-off-by: Xe Iaso <me@xeiaso.net> * doc: document metrics TLS and mTLS Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: spelling Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
+45
-3
@@ -2,11 +2,14 @@ package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/TecharoHQ/anubis/internal"
|
||||
@@ -20,10 +23,16 @@ type Server struct {
|
||||
Log *slog.Logger
|
||||
}
|
||||
|
||||
func (s *Server) Run(ctx context.Context, done func()) error {
|
||||
func (s *Server) Run(ctx context.Context, done func()) {
|
||||
defer done()
|
||||
lg := s.Log.With("subsystem", "metrics")
|
||||
|
||||
if err := s.run(ctx, lg); err != nil {
|
||||
lg.Error("can't serve metrics server", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) run(ctx context.Context, lg *slog.Logger) error {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("GET /debug/pprof/", pprof.Index)
|
||||
mux.HandleFunc("GET /debug/pprof/cmdline", pprof.Cmdline)
|
||||
@@ -62,6 +71,32 @@ func (s *Server) Run(ctx context.Context, done func()) error {
|
||||
|
||||
defer ln.Close()
|
||||
|
||||
if s.Config.TLS != nil {
|
||||
kpr, err := NewKeypairReloader(s.Config.TLS.Certificate, s.Config.TLS.Key, lg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't setup keypair reloader: %w", err)
|
||||
}
|
||||
|
||||
srv.TLSConfig = &tls.Config{
|
||||
GetCertificate: kpr.GetCertificate,
|
||||
}
|
||||
|
||||
if s.Config.TLS.CA != "" {
|
||||
caCert, err := os.ReadFile(s.Config.TLS.CA)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w %s: %w", config.ErrCantReadFile, s.Config.TLS.CA, err)
|
||||
}
|
||||
|
||||
certPool := x509.NewCertPool()
|
||||
if !certPool.AppendCertsFromPEM(caCert) {
|
||||
return fmt.Errorf("%w %s", config.ErrInvalidMetricsCACertificate, s.Config.TLS.CA)
|
||||
}
|
||||
|
||||
srv.TLSConfig.ClientCAs = certPool
|
||||
srv.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
}
|
||||
}
|
||||
|
||||
lg.Debug("listening for metrics", "url", metricsURL)
|
||||
|
||||
go func() {
|
||||
@@ -73,8 +108,15 @@ func (s *Server) Run(ctx context.Context, done func()) error {
|
||||
}
|
||||
}()
|
||||
|
||||
if err := srv.Serve(ln); !errors.Is(err, http.ErrServerClosed) {
|
||||
return fmt.Errorf("can't serve metrics server: %w", err)
|
||||
switch s.Config.TLS != nil {
|
||||
case true:
|
||||
if err := srv.ServeTLS(ln, "", ""); !errors.Is(err, http.ErrServerClosed) {
|
||||
return fmt.Errorf("can't serve TLS metrics server: %w", err)
|
||||
}
|
||||
case false:
|
||||
if err := srv.Serve(ln); !errors.Is(err, http.ErrServerClosed) {
|
||||
return fmt.Errorf("can't serve metrics server: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user