@@ -17,6 +17,7 @@ limitations under the License.
1717package main
1818
1919import (
20+ "context"
2021 "crypto/tls"
2122 "flag"
2223 "os"
@@ -25,12 +26,16 @@ import (
2526 // to ensure that exec-entrypoint and run can make use of them.
2627 _ "k8s.io/client-go/plugin/pkg/client/auth"
2728
29+ configv1 "github.com/openshift/api/config/v1"
30+ tlspkg "github.com/openshift/controller-runtime-common/pkg/tls"
2831 appsv1 "k8s.io/api/apps/v1"
2932 autoscalingv2 "k8s.io/api/autoscaling/v2"
3033 batchv1 "k8s.io/api/batch/v1"
3134 corev1 "k8s.io/api/core/v1"
3235 policyv1 "k8s.io/api/policy/v1"
3336 rbacv1 "k8s.io/api/rbac/v1"
37+ apierrors "k8s.io/apimachinery/pkg/api/errors"
38+ apimeta "k8s.io/apimachinery/pkg/api/meta"
3439 "k8s.io/apimachinery/pkg/labels"
3540 "k8s.io/apimachinery/pkg/runtime"
3641 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
6166
6267func init () {
6368 utilruntime .Must (clientgoscheme .AddToScheme (scheme ))
69+ utilruntime .Must (configv1 .Install (scheme ))
6470 utilruntime .Must (routev1 .AddToScheme (scheme ))
6571 utilruntime .Must (feastdevv1alpha1 .AddToScheme (scheme ))
6672 utilruntime .Must (feastdevv1 .AddToScheme (scheme ))
@@ -95,7 +101,6 @@ func main() {
95101 var enableLeaderElection bool
96102 var probeAddr string
97103 var secureMetrics bool
98- var enableHTTP2 bool
99104 var featureStoreMetrics bool
100105 var tlsOpts []func (* tls.Config )
101106 flag .StringVar (& metricsAddr , "metrics-bind-address" , "0" , "The address the metrics endpoint binds to. " +
@@ -106,8 +111,6 @@ func main() {
106111 "Enabling this will ensure there is only one active controller manager." )
107112 flag .BoolVar (& secureMetrics , "metrics-secure" , true ,
108113 "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead." )
109- flag .BoolVar (& enableHTTP2 , "enable-http2" , false ,
110- "If set, HTTP/2 will be enabled for the metrics and webhook servers" )
111114 flag .BoolVar (& featureStoreMetrics , "feature-store-metrics" , true ,
112115 "Enable Prometheus gauges exposing online/offline store and registry configuration per FeatureStore. " +
113116 "Disable with --feature-store-metrics=false." )
@@ -119,21 +122,55 @@ func main() {
119122
120123 ctrl .SetLogger (zap .New (zap .UseFlagOptions (& opts )))
121124
122- // if the enable-http2 flag is false (the default), http/2 should be disabled
123- // due to its vulnerabilities. More specifically, disabling http/2 will
124- // prevent from being vulnerable to the HTTP/2 Stream Cancellation and
125- // Rapid Reset CVEs. For more information see:
126- // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
127- // - https://github.com/advisories/GHSA-4374-p667-p6c8
128- disableHTTP2 := func (c * tls.Config ) {
129- setupLog .Info ("disabling http/2" )
130- c .NextProtos = []string {"http/1.1" }
125+ // Fetch cluster TLS profile from apiservers.config.openshift.io/cluster
126+ cfg := ctrl .GetConfigOrDie ()
127+ bootstrapClient , err := client .New (cfg , client.Options {Scheme : scheme })
128+ if err != nil {
129+ setupLog .Error (err , "unable to create bootstrap client for TLS profile fetch" )
130+ os .Exit (1 )
131131 }
132132
133- if ! enableHTTP2 {
134- tlsOpts = append (tlsOpts , disableHTTP2 )
133+ tlsProfileFetched := false
134+ tlsProfile , err := tlspkg .FetchAPIServerTLSProfile (context .Background (), bootstrapClient )
135+ if err != nil {
136+ switch {
137+ case apimeta .IsNoMatchError (err ):
138+ setupLog .Info ("TLS profile not available, using hardened defaults (non-OpenShift cluster)" )
139+ case apierrors .IsNotFound (err ):
140+ setupLog .Info ("APIServer resource not found, using hardened defaults" )
141+ default :
142+ setupLog .Error (err , "unable to read APIServer TLS profile, refusing to start with unknown TLS posture" )
143+ os .Exit (1 )
144+ }
145+ } else {
146+ tlsProfileFetched = true
147+ tlsConfigFn , unsupported := tlspkg .NewTLSConfigFromProfile (tlsProfile )
148+ if len (unsupported ) > 0 {
149+ setupLog .Info ("TLS profile contains ciphers unsupported by Go" , "unsupported" , unsupported )
150+ }
151+ tlsOpts = append (tlsOpts , tlsConfigFn )
152+ }
153+
154+ tlsAdherenceFetched := false
155+ tlsAdherence , err := tlspkg .FetchAPIServerTLSAdherencePolicy (context .Background (), bootstrapClient )
156+ if err != nil {
157+ switch {
158+ case apimeta .IsNoMatchError (err ):
159+ setupLog .Info ("TLS adherence policy not available (non-OpenShift cluster)" )
160+ case apierrors .IsNotFound (err ):
161+ setupLog .Info ("APIServer resource not found, skipping adherence policy" )
162+ default :
163+ setupLog .Error (err , "unable to read APIServer TLS adherence policy, refusing to start" )
164+ os .Exit (1 )
165+ }
166+ } else {
167+ tlsAdherenceFetched = true
135168 }
136169
170+ tlsOpts = append (tlsOpts , func (c * tls.Config ) {
171+ c .NextProtos = []string {"h2" , "http/1.1" }
172+ })
173+
137174 webhookServer := webhook .NewServer (webhook.Options {
138175 TLSOpts : tlsOpts ,
139176 })
@@ -162,7 +199,7 @@ func main() {
162199 metricsServerOptions .FilterProvider = filters .WithAuthenticationAndAuthorization
163200 }
164201
165- mgr , err := ctrl .NewManager (ctrl . GetConfigOrDie () , ctrl.Options {
202+ mgr , err := ctrl .NewManager (cfg , ctrl.Options {
166203 Scheme : scheme ,
167204 Metrics : metricsServerOptions ,
168205 WebhookServer : webhookServer ,
@@ -230,6 +267,32 @@ func main() {
230267 }
231268 // +kubebuilder:scaffold:builder
232269
270+ // Register SecurityProfileWatcher to restart on TLS profile changes
271+ ctx , cancel := context .WithCancel (ctrl .SetupSignalHandler ())
272+ defer cancel ()
273+
274+ if tlsProfileFetched {
275+ watcher := & tlspkg.SecurityProfileWatcher {
276+ Client : mgr .GetClient (),
277+ InitialTLSProfileSpec : tlsProfile ,
278+ OnProfileChange : func (_ context.Context , _ , _ configv1.TLSProfileSpec ) {
279+ setupLog .Info ("TLS profile changed, initiating shutdown to reload" )
280+ cancel ()
281+ },
282+ }
283+ if tlsAdherenceFetched {
284+ watcher .InitialTLSAdherencePolicy = tlsAdherence
285+ watcher .OnAdherencePolicyChange = func (_ context.Context , _ , _ configv1.TLSAdherencePolicy ) {
286+ setupLog .Info ("TLS adherence policy changed, initiating shutdown to reload" )
287+ cancel ()
288+ }
289+ }
290+ if err := watcher .SetupWithManager (mgr ); err != nil {
291+ setupLog .Error (err , "unable to set up TLS profile watcher" )
292+ os .Exit (1 )
293+ }
294+ }
295+
233296 if err := mgr .AddHealthzCheck ("healthz" , healthz .Ping ); err != nil {
234297 setupLog .Error (err , "unable to set up health check" )
235298 os .Exit (1 )
@@ -240,7 +303,7 @@ func main() {
240303 }
241304
242305 setupLog .Info ("starting manager" )
243- if err := mgr .Start (ctrl . SetupSignalHandler () ); err != nil {
306+ if err := mgr .Start (ctx ); err != nil {
244307 setupLog .Error (err , "problem running manager" )
245308 os .Exit (1 )
246309 }
0 commit comments