|
|
@@ -18,7 +18,9 @@ package controller
|
|
|
|
|
|
import (
|
|
|
"crypto/tls"
|
|
|
+ "fmt"
|
|
|
"os"
|
|
|
+ "strings"
|
|
|
"time"
|
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
@@ -52,6 +54,7 @@ import (
|
|
|
"github.com/external-secrets/external-secrets/pkg/controllers/secretstore"
|
|
|
"github.com/external-secrets/external-secrets/pkg/controllers/secretstore/cssmetrics"
|
|
|
"github.com/external-secrets/external-secrets/pkg/controllers/secretstore/ssmetrics"
|
|
|
+ "github.com/external-secrets/external-secrets/runtime/esutils"
|
|
|
"github.com/external-secrets/external-secrets/runtime/feature"
|
|
|
|
|
|
// To allow using gcp auth.
|
|
|
@@ -106,6 +109,7 @@ var (
|
|
|
certLookaheadInterval time.Duration
|
|
|
tlsCiphers string
|
|
|
tlsMinVersion string
|
|
|
+ tlsCurvePreferences []string
|
|
|
enableHTTP2 bool
|
|
|
allowGenericTargets bool
|
|
|
)
|
|
|
@@ -167,10 +171,12 @@ var rootCmd = &cobra.Command{
|
|
|
setupLog.Error(nil, "--metrics-auth requires --metrics-secure; bearer tokens over plaintext HTTP is not allowed")
|
|
|
os.Exit(1)
|
|
|
}
|
|
|
- // Disable HTTP/2 if not explicitly enabled
|
|
|
- if !enableHTTP2 {
|
|
|
- metricsOpts.TLSOpts = []func(*tls.Config){disableHTTP2}
|
|
|
+ metricsTLSOpts, err := buildTLSConfigFuncs(tlsCiphers, tlsMinVersion, tlsCurvePreferences, enableHTTP2)
|
|
|
+ if err != nil {
|
|
|
+ setupLog.Error(err, "unable to configure TLS for metrics server")
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
|
+ metricsOpts.TLSOpts = metricsTLSOpts
|
|
|
mgrOpts := ctrl.Options{
|
|
|
Scheme: scheme,
|
|
|
Metrics: metricsOpts,
|
|
|
@@ -385,6 +391,15 @@ func init() {
|
|
|
rootCmd.Flags().BoolVar(&enableFloodGate, "enable-flood-gate", true, "Enable flood gate. External secret will be reconciled only if the ClusterStore or Store have an healthy or unknown state.")
|
|
|
rootCmd.Flags().BoolVar(&enableGeneratorState, "enable-generator-state", true, "Whether the Controller should manage GeneratorState")
|
|
|
rootCmd.Flags().BoolVar(&enableExtendedMetricLabels, "enable-extended-metric-labels", false, "Enable recommended kubernetes annotations as labels in metrics.")
|
|
|
+ rootCmd.Flags().StringVar(&tlsCiphers, "tls-ciphers", "", "comma separated list of tls ciphers allowed for the metrics server. "+
|
|
|
+ "This does not apply to TLS 1.3 as the ciphers are selected automatically. "+
|
|
|
+ "Full lists of available ciphers can be found at https://pkg.go.dev/crypto/tls#pkg-constants")
|
|
|
+ rootCmd.Flags().StringVar(&tlsMinVersion, "tls-min-version", "", "minimum version of TLS supported for the metrics server. "+
|
|
|
+ "If not specified, Go's default minimum version is used. Valid values: 1.0, 1.1, 1.2, 1.3")
|
|
|
+ rootCmd.Flags().StringSliceVar(&tlsCurvePreferences, "tls-curve-preferences", nil,
|
|
|
+ "ordered list of TLS key exchange curves for the metrics server "+
|
|
|
+ "(for example X25519,CurveP256, or decimal tls.CurveID values supported by this Go toolchain). "+
|
|
|
+ "If omitted, Go defaults are used.")
|
|
|
rootCmd.Flags().BoolVar(&enableHTTP2, "enable-http2", false,
|
|
|
"If set, HTTP/2 will be enabled for the metrics server")
|
|
|
rootCmd.Flags().
|
|
|
@@ -399,3 +414,67 @@ func init() {
|
|
|
func disableHTTP2(cfg *tls.Config) {
|
|
|
cfg.NextProtos = []string{"http/1.1"}
|
|
|
}
|
|
|
+
|
|
|
+// parseTLSCurvePreferences converts human-readable curve names to tls.CurveID values.
|
|
|
+// It accepts well-known names (X25519, CurveP256, CurveP384, CurveP521 and aliases)
|
|
|
+// as well as decimal tls.CurveID values for forward-compat with new Go toolchains.
|
|
|
+func parseTLSCurvePreferences(names []string) ([]tls.CurveID, error) {
|
|
|
+ filtered := make([]string, 0, len(names))
|
|
|
+ for _, n := range names {
|
|
|
+ n = strings.TrimSpace(n)
|
|
|
+ if n == "" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ filtered = append(filtered, n)
|
|
|
+ }
|
|
|
+ if len(filtered) == 0 {
|
|
|
+ return nil, nil
|
|
|
+ }
|
|
|
+ return esutils.ParseCurvePreferences(filtered)
|
|
|
+}
|
|
|
+
|
|
|
+// buildTLSConfigFuncs assembles a slice of tls.Config mutators from the current
|
|
|
+// flag values. It is shared across all subcommands (controller, webhook, certcontroller).
|
|
|
+func buildTLSConfigFuncs(ciphers, minVer string, curves []string, http2 bool) ([]func(*tls.Config), error) {
|
|
|
+ var opts []func(*tls.Config)
|
|
|
+
|
|
|
+ if !http2 {
|
|
|
+ opts = append(opts, disableHTTP2)
|
|
|
+ }
|
|
|
+
|
|
|
+ if ciphers != "" {
|
|
|
+ ids, err := getTLSCipherSuitesIDs(ciphers)
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Errorf("unable to parse tls ciphers: %w", err)
|
|
|
+ }
|
|
|
+ if len(ids) > 0 {
|
|
|
+ opts = append(opts, func(cfg *tls.Config) {
|
|
|
+ cfg.CipherSuites = ids
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if minVer != "" {
|
|
|
+ ver, err := tlsVersion(minVer)
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Errorf("unable to parse tls min version: %w", err)
|
|
|
+ }
|
|
|
+ opts = append(opts, func(cfg *tls.Config) {
|
|
|
+ cfg.MinVersion = ver
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(curves) > 0 {
|
|
|
+ curveIDs, err := parseTLSCurvePreferences(curves)
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Errorf("unable to parse tls curve preferences: %w", err)
|
|
|
+ }
|
|
|
+ if len(curveIDs) > 0 {
|
|
|
+ opts = append(opts, func(cfg *tls.Config) {
|
|
|
+ cfg.CurvePreferences = curveIDs
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return opts, nil
|
|
|
+}
|