set ReadHeaderTimeout for http server

Signed-off-by: RainbowMango <qdurenhongcai@gmail.com>
This commit is contained in:
RainbowMango 2022-09-28 16:59:31 +08:00
parent c817ace443
commit 50d01d3ac9
4 changed files with 90 additions and 6 deletions

View File

@ -7,6 +7,7 @@ import (
"net/http" "net/http"
"os" "os"
"strconv" "strconv"
"time"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
@ -30,6 +31,19 @@ import (
"github.com/karmada-io/karmada/pkg/version/sharedcommand" "github.com/karmada-io/karmada/pkg/version/sharedcommand"
) )
const (
// ReadHeaderTimeout is the amount of time allowed to read
// request headers.
// HTTP timeouts are necessary to expire inactive connections
// and failing to do so might make the application vulnerable
// to attacks like slowloris which work by sending data very slow,
// which in case of no timeout will keep the connection active
// eventually leading to a denial-of-service (DoS) attack.
// References:
// - https://en.wikipedia.org/wiki/Slowloris_(computer_security)
ReadHeaderTimeout = 32 * time.Second
)
// NewDeschedulerCommand creates a *cobra.Command object with default parameters // NewDeschedulerCommand creates a *cobra.Command object with default parameters
func NewDeschedulerCommand(stopChan <-chan struct{}) *cobra.Command { func NewDeschedulerCommand(stopChan <-chan struct{}) *cobra.Command {
opts := options.NewOptions() opts := options.NewOptions()
@ -152,6 +166,13 @@ func serveHealthzAndMetrics(address string) {
}) })
mux.Handle("/metrics", promhttp.Handler()) mux.Handle("/metrics", promhttp.Handler())
httpServer := http.Server{
klog.Fatal(http.ListenAndServe(address, mux)) Addr: address,
Handler: mux,
ReadHeaderTimeout: ReadHeaderTimeout,
}
if err := httpServer.ListenAndServe(); err != nil {
klog.Errorf("Failed to serve healthz and metrics: %v", err)
os.Exit(1)
}
} }

View File

@ -5,7 +5,9 @@ import (
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"os"
"strconv" "strconv"
"time"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -26,6 +28,19 @@ import (
"github.com/karmada-io/karmada/pkg/version/sharedcommand" "github.com/karmada-io/karmada/pkg/version/sharedcommand"
) )
const (
// ReadHeaderTimeout is the amount of time allowed to read
// request headers.
// HTTP timeouts are necessary to expire inactive connections
// and failing to do so might make the application vulnerable
// to attacks like slowloris which work by sending data very slow,
// which in case of no timeout will keep the connection active
// eventually leading to a denial-of-service (DoS) attack.
// References:
// - https://en.wikipedia.org/wiki/Slowloris_(computer_security)
ReadHeaderTimeout = 32 * time.Second
)
// NewSchedulerEstimatorCommand creates a *cobra.Command object with default parameters // NewSchedulerEstimatorCommand creates a *cobra.Command object with default parameters
func NewSchedulerEstimatorCommand(ctx context.Context) *cobra.Command { func NewSchedulerEstimatorCommand(ctx context.Context) *cobra.Command {
opts := options.NewOptions() opts := options.NewOptions()
@ -98,5 +113,13 @@ func serveHealthzAndMetrics(address string) {
mux.Handle("/metrics", promhttp.Handler()) mux.Handle("/metrics", promhttp.Handler())
klog.Fatal(http.ListenAndServe(address, mux)) httpServer := http.Server{
Addr: address,
Handler: mux,
ReadHeaderTimeout: ReadHeaderTimeout,
}
if err := httpServer.ListenAndServe(); err != nil {
klog.Errorf("Failed to serve healthz and metrics: %v", err)
os.Exit(1)
}
} }

View File

@ -7,6 +7,7 @@ import (
"net/http" "net/http"
"os" "os"
"strconv" "strconv"
"time"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
@ -32,6 +33,19 @@ import (
"github.com/karmada-io/karmada/pkg/version/sharedcommand" "github.com/karmada-io/karmada/pkg/version/sharedcommand"
) )
const (
// ReadHeaderTimeout is the amount of time allowed to read
// request headers.
// HTTP timeouts are necessary to expire inactive connections
// and failing to do so might make the application vulnerable
// to attacks like slowloris which work by sending data very slow,
// which in case of no timeout will keep the connection active
// eventually leading to a denial-of-service (DoS) attack.
// References:
// - https://en.wikipedia.org/wiki/Slowloris_(computer_security)
ReadHeaderTimeout = 32 * time.Second
)
// Option configures a framework.Registry. // Option configures a framework.Registry.
type Option func(runtime.Registry) error type Option func(runtime.Registry) error
@ -180,6 +194,13 @@ func serveHealthzAndMetrics(address string) {
}) })
mux.Handle("/metrics", promhttp.Handler()) mux.Handle("/metrics", promhttp.Handler())
httpServer := http.Server{
klog.Fatal(http.ListenAndServe(address, mux)) Addr: address,
Handler: mux,
ReadHeaderTimeout: ReadHeaderTimeout,
}
if err := httpServer.ListenAndServe(); err != nil {
klog.Errorf("Failed to serve healthz and metrics: %v", err)
os.Exit(1)
}
} }

View File

@ -4,11 +4,25 @@ import (
"net/http" "net/http"
"net/http/pprof" "net/http/pprof"
"os" "os"
"time"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/klog/v2" "k8s.io/klog/v2"
) )
const (
// ReadHeaderTimeout is the amount of time allowed to read
// request headers.
// HTTP timeouts are necessary to expire inactive connections
// and failing to do so might make the application vulnerable
// to attacks like slowloris which work by sending data very slow,
// which in case of no timeout will keep the connection active
// eventually leading to a denial-of-service (DoS) attack.
// References:
// - https://en.wikipedia.org/wiki/Slowloris_(computer_security)
ReadHeaderTimeout = 32 * time.Second
)
// Options are options for pprof. // Options are options for pprof.
type Options struct { type Options struct {
// EnableProfile is the flag about whether to enable pprof profiling. // EnableProfile is the flag about whether to enable pprof profiling.
@ -39,7 +53,12 @@ func ListenAndServe(opts Options) {
installHandlerForPProf(mux) installHandlerForPProf(mux)
klog.Infof("Starting profiling on port %s", opts.ProfilingBindAddress) klog.Infof("Starting profiling on port %s", opts.ProfilingBindAddress)
go func() { go func() {
if err := http.ListenAndServe(opts.ProfilingBindAddress, mux); err != nil { httpServer := http.Server{
Addr: opts.ProfilingBindAddress,
Handler: mux,
ReadHeaderTimeout: ReadHeaderTimeout,
}
if err := httpServer.ListenAndServe(); err != nil {
klog.Errorf("Failed to enable profiling: %v", err) klog.Errorf("Failed to enable profiling: %v", err)
os.Exit(1) os.Exit(1)
} }