Skip to content

Commit

Permalink
Merge pull request #253 from slashpai/release-4.14
Browse files Browse the repository at this point in the history
[release-4.14] OCPBUGS-20881: fix: disable HTTP2 connections by default
  • Loading branch information
openshift-merge-bot[bot] committed Nov 6, 2023
2 parents 3de5e6d + f858900 commit 73729ed
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
2 changes: 2 additions & 0 deletions Documentation/operator.md
Expand Up @@ -87,6 +87,8 @@ Usage of ./operator:
Cert file to be used for operator web server endpoints. (default "/etc/tls/private/tls.crt")
-web.client-ca-file string
Client CA certificate file to be used for operator web server endpoints. (default "/etc/tls/private/tls-ca.crt")
-web.enable-http2
Enable HTTP2 connections.
-web.enable-tls
Activate prometheus operator web server TLS. This is useful for example when using the rule validation webhook.
-web.key-file string
Expand Down
39 changes: 27 additions & 12 deletions cmd/admission-webhook/main.go
Expand Up @@ -53,12 +53,22 @@ var (
cfg = config{}
flagset = flag.CommandLine

enableHTTP2 bool
serverTLS bool
rawTLSCipherSuites string
)

func main() {
flagset.StringVar(&cfg.ListenAddress, "web.listen-address", ":8443", "Address on which the admission webhook service listens")
// Mitigate CVE-2023-44487 by disabling HTTP2 by default until the Go
// standard library and golang.org/x/net are fully fixed.
// Right now, it is possible for authenticated and unauthenticated users to
// hold open HTTP2 connections and consume huge amounts of memory.
// See:
// * https://github.com/kubernetes/kubernetes/pull/121120
// * https://github.com/kubernetes/kubernetes/issues/121197
// * https://github.com/golang/go/issues/63417#issuecomment-1758858612
flagset.BoolVar(&enableHTTP2, "web.enable-http2", false, "Enable HTTP2 connections.")
flagset.BoolVar(&serverTLS, "web.enable-tls", true, "Enable TLS web server")

flagset.StringVar(&cfg.ServerTLSConfig.CertFile, "web.cert-file", defaultCrtFile, "Certificate file to be used for the web server.")
Expand Down Expand Up @@ -127,7 +137,7 @@ func (s *srv) run(listener net.Listener) error {
log := log.With(s.logger, "address", listener.Addr().String())

if s.s.TLSConfig != nil {
level.Info(log).Log("msg", "Starting TLS enabled server")
level.Info(log).Log("msg", "Starting TLS enabled server", "http2", enableHTTP2)
if err := s.s.ServeTLS(listener, "", ""); err != http.ErrServerClosed {
return err
}
Expand Down Expand Up @@ -159,22 +169,27 @@ func newSrv(logger log.Logger, tlsConf *tls.Config) *srv {
mux.Handle("/metrics", promhttp.HandlerFor(r, promhttp.HandlerOpts{}))

mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`{"status":"up"}`))
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status":"up"}`))
})

httpServer := http.Server{
Handler: mux,
TLSConfig: tlsConf,
ReadHeaderTimeout: 30 * time.Second,
ReadTimeout: 30 * time.Second,
// use flags on standard logger to align with base logger and get consistent parsed fields form adapter:
// use shortfile flag to get proper 'caller' field (avoid being wrongly parsed/extracted from message)
// and no datetime related flag to keep 'ts' field from base logger (with controlled format)
ErrorLog: stdlog.New(log.NewStdlibAdapter(logger), "", stdlog.Lshortfile),
}
if !enableHTTP2 {
httpServer.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
}

return &srv{
logger: logger,
s: &http.Server{
Handler: mux,
TLSConfig: tlsConf,
ReadHeaderTimeout: 30 * time.Second,
ReadTimeout: 30 * time.Second,
// use flags on standard logger to align with base logger and get consistent parsed fields form adapter:
// use shortfile flag to get proper 'caller' field (avoid being wrongly parsed/extracted from message)
// and no datetime related flag to keep 'ts' field from base logger (with controlled format)
ErrorLog: stdlog.New(log.NewStdlibAdapter(logger), "", stdlog.Lshortfile),
},
s: &httpServer,
}
}

Expand Down
15 changes: 14 additions & 1 deletion cmd/operator/main.go
Expand Up @@ -126,7 +126,7 @@ func serve(srv *http.Server, listener net.Listener, logger log.Logger) func() er

func serveTLS(srv *http.Server, listener net.Listener, logger log.Logger) func() error {
return func() error {
level.Info(logger).Log("msg", "Starting secure server on "+listener.Addr().String())
level.Info(logger).Log("msg", "Starting secure server on "+listener.Addr().String(), "http2", enableHTTP2)
if err := srv.ServeTLS(listener, "", ""); err != http.ErrServerClosed {
return err
}
Expand All @@ -138,6 +138,7 @@ var (
cfg = operator.Config{}

rawTLSCipherSuites string
enableHTTP2 bool
serverTLS bool

flagset = flag.CommandLine
Expand All @@ -146,6 +147,15 @@ var (
func init() {
// With migration to klog-gokit, calling klogv2.InitFlags(flagset) is not applicable.
flagset.StringVar(&cfg.ListenAddress, "web.listen-address", ":8080", "Address on which to expose metrics and web interface.")
// Mitigate CVE-2023-44487 by disabling HTTP2 by default until the Go
// standard library and golang.org/x/net are fully fixed.
// Right now, it is possible for authenticated and unauthenticated users to
// hold open HTTP2 connections and consume huge amounts of memory.
// See:
// * https://github.com/kubernetes/kubernetes/pull/121120
// * https://github.com/kubernetes/kubernetes/issues/121197
// * https://github.com/golang/go/issues/63417#issuecomment-1758858612
flagset.BoolVar(&enableHTTP2, "web.enable-http2", false, "Enable HTTP2 connections.")
flagset.BoolVar(&serverTLS, "web.enable-tls", false, "Activate prometheus operator web server TLS. "+
" This is useful for example when using the rule validation webhook.")
flagset.StringVar(&cfg.ServerTLSConfig.CertFile, "web.cert-file", defaultOperatorTLSDir+"/tls.crt", "Cert file to be used for operator web server endpoints.")
Expand Down Expand Up @@ -467,6 +477,9 @@ func Main() int {
// and no datetime related flag to keep 'ts' field from base logger (with controlled format)
ErrorLog: stdlog.New(log.NewStdlibAdapter(logger), "", stdlog.Lshortfile),
}
if !enableHTTP2 {
srv.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
}
if srv.TLSConfig == nil {
wg.Go(serve(srv, l, logger))
} else {
Expand Down

0 comments on commit 73729ed

Please sign in to comment.