mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-07-28 02:52:50 +00:00
Merge pull request #1789 from vmware-tanzu/http2
Defensive changes to mitigate potential http2 rapid reset attacks
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
"k8s.io/client-go/rest"
|
||||
@@ -27,6 +28,7 @@ import (
|
||||
"go.pinniped.dev/internal/concierge/apiserver"
|
||||
conciergescheme "go.pinniped.dev/internal/concierge/scheme"
|
||||
"go.pinniped.dev/internal/config/concierge"
|
||||
"go.pinniped.dev/internal/config/featuregates"
|
||||
"go.pinniped.dev/internal/controller/authenticator/authncache"
|
||||
"go.pinniped.dev/internal/controllerinit"
|
||||
"go.pinniped.dev/internal/controllermanager"
|
||||
@@ -103,6 +105,9 @@ func addCommandlineFlagsToCommand(cmd *cobra.Command, app *App) {
|
||||
// Boot the aggregated API server, which will in turn boot the controllers.
|
||||
// In practice, the ctx passed in should be one which will be cancelled when the process receives SIGTERM or SIGINT.
|
||||
func (a *App) runServer(ctx context.Context) error {
|
||||
// Enable the feature gate from https://github.com/kubernetes/kubernetes/pull/121120.
|
||||
featuregates.EnableKubeFeatureGate(features.UnauthenticatedHTTP2DOSMitigation)
|
||||
|
||||
// Read the server config file.
|
||||
cfg, err := concierge.FromPath(ctx, a.configPath)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package featuregates
|
||||
|
||||
import (
|
||||
"k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/component-base/featuregate"
|
||||
|
||||
"go.pinniped.dev/internal/plog"
|
||||
)
|
||||
|
||||
func EnableKubeFeatureGate(f featuregate.Feature) {
|
||||
initialValue := feature.DefaultFeatureGate.Enabled(f)
|
||||
|
||||
if err := feature.DefaultMutableFeatureGate.SetFromMap(map[string]bool{string(f): true}); err != nil {
|
||||
panic(err) // this should never happen as long as a feature gate still exists
|
||||
}
|
||||
|
||||
plog.Always("feature gate status",
|
||||
"name", f,
|
||||
"initialEnabledValue", initialValue,
|
||||
"updatedEnabledValue", feature.DefaultFeatureGate.Enabled(f),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package featuregates
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
)
|
||||
|
||||
func TestEnableKubeFeatureGate(t *testing.T) {
|
||||
f := features.UnauthenticatedHTTP2DOSMitigation
|
||||
|
||||
// This feature gate is currently disabled by default in the Kubernetes library.
|
||||
// Assert this as a precondition so if that ever changes during a dependency bump
|
||||
// we will be forced to take note and decide if any code deserves to change.
|
||||
require.False(t, feature.DefaultFeatureGate.Enabled(f))
|
||||
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, f, false)()
|
||||
|
||||
require.False(t, feature.DefaultFeatureGate.Enabled(f))
|
||||
EnableKubeFeatureGate(f)
|
||||
require.True(t, feature.DefaultFeatureGate.Enabled(f))
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
|
||||
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
k8sinformers "k8s.io/client-go/informers"
|
||||
@@ -43,6 +44,7 @@ import (
|
||||
supervisorinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
|
||||
supervisoropenapi "go.pinniped.dev/generated/latest/client/supervisor/openapi"
|
||||
"go.pinniped.dev/internal/apiserviceref"
|
||||
"go.pinniped.dev/internal/config/featuregates"
|
||||
"go.pinniped.dev/internal/config/supervisor"
|
||||
"go.pinniped.dev/internal/controller/apicerts"
|
||||
"go.pinniped.dev/internal/controller/supervisorconfig"
|
||||
@@ -386,6 +388,9 @@ func prepareControllers(
|
||||
// and start serving the health endpoint and the endpoints of the configured FederationDomains.
|
||||
// In practice, the ctx passed in should be one which will be cancelled when the process receives SIGTERM or SIGINT.
|
||||
func runSupervisor(ctx context.Context, podInfo *downward.PodInfo, cfg *supervisor.Config) error { //nolint:funlen
|
||||
// Enable the feature gate from https://github.com/kubernetes/kubernetes/pull/121120.
|
||||
featuregates.EnableKubeFeatureGate(features.UnauthenticatedHTTP2DOSMitigation)
|
||||
|
||||
serverInstallationNamespace := podInfo.Namespace
|
||||
clientSecretSupervisorGroupData := groupsuffix.SupervisorAggregatedGroups(*cfg.APIGroupSuffix)
|
||||
|
||||
@@ -526,6 +531,10 @@ func runSupervisor(ctx context.Context, podInfo *downward.PodInfo, cfg *supervis
|
||||
}
|
||||
|
||||
c := ptls.Default(nil)
|
||||
// Remove "h2" from the list for now, until we have a better idea of how to mitigate
|
||||
// potential http2 rapid reset vulnerabilities. This disables serving requests using http2.
|
||||
c.NextProtos = []string{"http/1.1"}
|
||||
|
||||
c.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
cert := dynamicTLSCertProvider.GetTLSCert(strings.ToLower(info.ServerName))
|
||||
foundServerNameCert := cert != nil
|
||||
|
||||
Reference in New Issue
Block a user