From 9d451b7168fb6d624bd4797517cb7e8259a9545e Mon Sep 17 00:00:00 2001 From: Blake Rouse Date: Mon, 22 Feb 2021 09:11:03 -0500 Subject: [PATCH] Add ssl configuration to fleet server http. (#98) * Add ssl configuration to fleet server http configuration. * Add log message when tls disabled. * Fix import. * Fix integration test. --- cmd/fleet/server.go | 40 ++++++++++++++-------------- cmd/fleet/server_integration_test.go | 2 +- internal/pkg/config/input.go | 20 +++++++------- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/cmd/fleet/server.go b/cmd/fleet/server.go index 0e418adee..3e52dab36 100644 --- a/cmd/fleet/server.go +++ b/cmd/fleet/server.go @@ -6,13 +6,15 @@ package fleet import ( "context" - "github.com/elastic/fleet-server/v7/internal/pkg/config" + "crypto/tls" slog "log" "net" "net/http" + "github.com/elastic/fleet-server/v7/internal/pkg/config" "github.com/elastic/fleet-server/v7/internal/pkg/rate" + "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" "github.com/julienschmidt/httprouter" "github.com/rs/zerolog/log" ) @@ -37,7 +39,7 @@ func runServer(ctx context.Context, router *httprouter.Router, cfg *config.Serve Str("bind", addr). Dur("rdTimeout", rdto). Dur("wrTimeout", wrto). - Msg("Server listening") + Msg("server listening") server := http.Server{ Addr: addr, @@ -57,28 +59,32 @@ func runServer(ctx context.Context, router *httprouter.Router, cfg *config.Serve go func() { select { case <-ctx.Done(): - log.Debug().Msg("Force server close on ctx.Done()") + log.Debug().Msg("force server close on ctx.Done()") server.Close() case <-forceCh: - log.Debug().Msg("Go routine forced closed on exit") + log.Debug().Msg("go routine forced closed on exit") } }() - ln, err := makeListener(ctx, addr, cfg) + ln, err := net.Listen("tcp", addr) if err != nil { return err } defer ln.Close() - // TODO: Use tls.Config to properly mux down tls connection - keyFile := cfg.TLS.Key - certFile := cfg.TLS.Cert - - if keyFile != "" || certFile != "" { - return server.ServeTLS(ln, certFile, keyFile) + if cfg.TLS != nil && cfg.TLS.IsEnabled() { + tlsCfg, err := tlscommon.LoadTLSConfig(cfg.TLS) + if err != nil { + return err + } + server.TLSConfig = tlsCfg.ToConfig() + ln = tls.NewListener(ln, server.TLSConfig) + } else { + log.Warn().Msg("exposed over insecure HTTP; enablement of TLS is strongly recommended") } + ln = wrapRateLimitter(ctx, ln, cfg) if err := server.Serve(ln); err != nil && err != context.Canceled { return err } @@ -86,13 +92,7 @@ func runServer(ctx context.Context, router *httprouter.Router, cfg *config.Serve return nil } -func makeListener(ctx context.Context, addr string, cfg *config.Server) (net.Listener, error) { - // Create listener - ln, err := net.Listen("tcp", addr) - if err != nil { - return nil, err - } - +func wrapRateLimitter(ctx context.Context, ln net.Listener, cfg *config.Server) net.Listener { rateLimitBurst := cfg.RateLimitBurst rateLimitInterval := cfg.RateLimitInterval @@ -100,10 +100,10 @@ func makeListener(ctx context.Context, addr string, cfg *config.Server) (net.Lis log.Info().Dur("interval", rateLimitInterval).Int("burst", rateLimitBurst).Msg("Server rate limiter installed") ln = rate.NewRateListener(ctx, ln, rateLimitBurst, rateLimitInterval) } else { - log.Info().Msg("Server connection rate limiter disabled") + log.Info().Msg("server connection rate limiter disabled") } - return ln, err + return ln } type stubLogger struct { diff --git a/cmd/fleet/server_integration_test.go b/cmd/fleet/server_integration_test.go index 61cbd3bf4..5f9d726c9 100644 --- a/cmd/fleet/server_integration_test.go +++ b/cmd/fleet/server_integration_test.go @@ -47,7 +47,7 @@ func (s *tserver) baseUrl() string { input := s.cfg.Inputs[0] tls := input.Server.TLS schema := "http" - if tls.Key != "" || tls.Cert != "" { + if tls != nil && tls.IsEnabled() { schema = "https" } return fmt.Sprintf("%s://%s:%d", schema, input.Server.Host, input.Server.Port) diff --git a/internal/pkg/config/input.go b/internal/pkg/config/input.go index 28e7296ca..391bfc48c 100644 --- a/internal/pkg/config/input.go +++ b/internal/pkg/config/input.go @@ -8,6 +8,8 @@ import ( "fmt" "strings" "time" + + "github.com/elastic/beats/v7/libbeat/common/transport/tlscommon" ) const kDefaultHost = "localhost" @@ -48,15 +50,15 @@ type ServerTLS struct { // Server is the configuration for the server type Server struct { - Host string `config:"host"` - Port uint16 `config:"port"` - TLS ServerTLS `config:"tls"` - Timeouts ServerTimeouts `config:"timeouts"` - MaxHeaderByteSize int `config:"max_header_byte_size"` - RateLimitBurst int `config:"rate_limit_burst"` - RateLimitInterval time.Duration `config:"rate_limit_interval"` - MaxEnrollPending int64 `config:"max_enroll_pending"` - Profile ServerProfile `config:"profile"` + Host string `config:"host"` + Port uint16 `config:"port"` + TLS *tlscommon.Config `config:"ssl"` + Timeouts ServerTimeouts `config:"timeouts"` + MaxHeaderByteSize int `config:"max_header_byte_size"` + RateLimitBurst int `config:"rate_limit_burst"` + RateLimitInterval time.Duration `config:"rate_limit_interval"` + MaxEnrollPending int64 `config:"max_enroll_pending"` + Profile ServerProfile `config:"profile"` } // InitDefaults initializes the defaults for the configuration.