From 27326e6569d888224ec40a1aa719abdfc4eb44d7 Mon Sep 17 00:00:00 2001 From: Harold Ozouf Date: Fri, 18 Jul 2025 17:16:04 +0200 Subject: [PATCH 1/4] Redact logged install configuration --- cmd/traefik/traefik.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index 9d3c7c953..b918c9f41 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -3,7 +3,6 @@ package main import ( "context" "crypto/x509" - "encoding/json" "fmt" stdlog "log" "net/http" @@ -34,6 +33,7 @@ import ( "github.com/traefik/traefik/v2/pkg/provider/acme" "github.com/traefik/traefik/v2/pkg/provider/aggregator" "github.com/traefik/traefik/v2/pkg/provider/traefik" + "github.com/traefik/traefik/v2/pkg/redactor" "github.com/traefik/traefik/v2/pkg/safe" "github.com/traefik/traefik/v2/pkg/server" "github.com/traefik/traefik/v2/pkg/server/middleware" @@ -100,12 +100,11 @@ func runCmd(staticConfiguration *static.Configuration) error { log.WithoutContext().Infof("Traefik version %s built on %s", version.Version, version.BuildDate) - jsonConf, err := json.Marshal(staticConfiguration) + redactedStaticConfiguration, err := redactor.RemoveCredentials(staticConfiguration) if err != nil { - log.WithoutContext().Errorf("Could not marshal static configuration: %v", err) - log.WithoutContext().Debugf("Static configuration loaded [struct] %#v", staticConfiguration) + log.WithoutContext().Errorf("Could not redact static configuration: %v", err) } else { - log.WithoutContext().Debugf("Static configuration loaded %s", string(jsonConf)) + log.WithoutContext().Debugf("Static configuration loaded %s", redactedStaticConfiguration) } if staticConfiguration.Global.CheckNewVersion { From b2b4b66b08e6386a4e4251dc974da5fef73c6d54 Mon Sep 17 00:00:00 2001 From: Romain Date: Tue, 22 Jul 2025 11:10:05 +0200 Subject: [PATCH 2/4] Disable MPTCP by default Co-authored-by: Kevin Pollet --- docs/content/migration/v2.md | 11 +++++++++++ pkg/server/server_entrypoint_tcp.go | 10 +++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/content/migration/v2.md b/docs/content/migration/v2.md index a2106a5cd..70261ead3 100644 --- a/docs/content/migration/v2.md +++ b/docs/content/migration/v2.md @@ -703,3 +703,14 @@ and Traefik now keeps them encoded to avoid any ambiguity. | `/foo/../bar` | PathPrefix(`/bar`) | Match | Match | | `/foo/%2E%2E/bar` | PathPrefix(`/foo`) | Match | No match | | `/foo/%2E%2E/bar` | PathPrefix(`/bar`) | No match | Match | + +## v2.11.28 + +### MultiPath TCP + +Since `v2.11.28`, the MultiPath TCP support introduced with `v2.11.26` has been removed. +It appears that enabling MPTCP on some platforms can cause Traefik to stop with the following error logs message: + +- `set tcp X.X.X.X:X->X.X.X.X:X: setsockopt: operation not supported` + +However, it can be re-enabled by setting the `multipathtcp` variable in the GODEBUG environment variable, see the related [go documentation](https://go.dev/doc/godebug#go-124). diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go index 3257d6720..1036240cf 100644 --- a/pkg/server/server_entrypoint_tcp.go +++ b/pkg/server/server_entrypoint_tcp.go @@ -457,7 +457,15 @@ func buildProxyProtocolListener(ctx context.Context, entryPoint *static.EntryPoi } func buildListener(ctx context.Context, entryPoint *static.EntryPoint) (net.Listener, error) { - listener, err := net.Listen("tcp", entryPoint.GetAddress()) + config := net.ListenConfig{} + + // TODO: Look into configuring keepAlive period through listenConfig instead of our custom tcpKeepAliveListener, to reactivate MultipathTCP? + // MultipathTCP is not supported on all platforms, and is notably unsupported in combination with TCP keep-alive. + if !strings.Contains(os.Getenv("GODEBUG"), "multipathtcp") { + config.SetMultipathTCP(false) + } + + listener, err := config.Listen(ctx, "tcp", entryPoint.GetAddress()) if err != nil { return nil, fmt.Errorf("error opening listener: %w", err) } From 5ef853a0c53068f69a6c229a5815a0dc6e0a8800 Mon Sep 17 00:00:00 2001 From: Zeroday BYTE Date: Tue, 22 Jul 2025 05:24:05 -0700 Subject: [PATCH 3/4] Fix client arbitrary file access during archive extraction zipslip --- pkg/plugins/client.go | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/pkg/plugins/client.go b/pkg/plugins/client.go index 642b2dc68..1cee55d3f 100644 --- a/pkg/plugins/client.go +++ b/pkg/plugins/client.go @@ -240,6 +240,8 @@ func (c *Client) Unzip(pName, pVersion string) error { return nil } + // Unzip as a generic archive if the module unzip fails. + // This is useful for plugins that have vendor directories or other structures. return c.unzipArchive(pName, pVersion) } @@ -280,24 +282,48 @@ func unzipFile(f *zipa.File, dest string) error { defer func() { _ = rc.Close() }() + // Split to discard the first part of the path, which is [organization]-[project]-[release commit sha1] when the archive is a Yaegi go plugin with vendoring. pathParts := strings.SplitN(f.Name, "/", 2) - p := filepath.Join(dest, pathParts[1]) + if len(pathParts) < 2 { + return fmt.Errorf("no root directory: %s", f.Name) + } + + // Validate and sanitize the file path. + cleanName := filepath.Clean(pathParts[1]) + if strings.Contains(cleanName, "..") { + return fmt.Errorf("invalid file path in archive: %s", f.Name) + } + + filePath := filepath.Join(dest, cleanName) + absFilePath, err := filepath.Abs(filePath) + if err != nil { + return fmt.Errorf("resolving file path: %w", err) + } + + absDest, err := filepath.Abs(dest) + if err != nil { + return fmt.Errorf("resolving destination directory: %w", err) + } + + if !strings.HasPrefix(absFilePath, absDest) { + return fmt.Errorf("file path escapes destination directory: %s", absFilePath) + } if f.FileInfo().IsDir() { - err = os.MkdirAll(p, f.Mode()) + err = os.MkdirAll(filePath, f.Mode()) if err != nil { - return fmt.Errorf("unable to create archive directory %s: %w", p, err) + return fmt.Errorf("unable to create archive directory %s: %w", filePath, err) } return nil } - err = os.MkdirAll(filepath.Dir(p), 0o750) + err = os.MkdirAll(filepath.Dir(filePath), 0o750) if err != nil { - return fmt.Errorf("unable to create archive directory %s for file %s: %w", filepath.Dir(p), p, err) + return fmt.Errorf("unable to create archive directory %s for file %s: %w", filepath.Dir(filePath), filePath, err) } - elt, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) + elt, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } From 50931813f2eeb178e78a641e6aedd314fa000043 Mon Sep 17 00:00:00 2001 From: Jesper Noordsij <45041769+jnoordsij@users.noreply.github.com> Date: Tue, 22 Jul 2025 15:44:05 +0200 Subject: [PATCH 4/4] Remove all mentions of ordering for TLSOption CurvePreferences field --- docs/content/https/tls.md | 4 ++-- .../dynamic-configuration/kubernetes-crd-definition-v1.yml | 4 ++-- .../dynamic-configuration/traefik.containo.us_tlsoptions.yaml | 2 +- .../dynamic-configuration/traefik.io_tlsoptions.yaml | 2 +- docs/content/routing/providers/kubernetes-crd.md | 2 +- integration/fixtures/k8s/01-traefik-crd.yml | 4 ++-- .../kubernetes/crd/traefikcontainous/v1alpha1/tlsoption.go | 2 +- pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index 0323eb2e6..505043259 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -392,11 +392,11 @@ spec: ### Curve Preferences -This option allows to set the preferred elliptic curves in a specific order. +This option allows to set the enabled elliptic curves for key exchange. The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used. -See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information. +See [CurvePreferences](https://godoc.org/crypto/tls#Config.CurvePreferences) and [CurveID](https://godoc.org/crypto/tls#CurveID) for more information. ```yaml tab="File (YAML)" # Dynamic configuration diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml index 6f901cb57..b5c41bb8c 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml @@ -1886,7 +1886,7 @@ spec: type: object curvePreferences: description: |- - CurvePreferences defines the preferred elliptic curves in a specific order. + CurvePreferences defines the preferred elliptic curves. More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences items: type: string @@ -4316,7 +4316,7 @@ spec: type: object curvePreferences: description: |- - CurvePreferences defines the preferred elliptic curves in a specific order. + CurvePreferences defines the preferred elliptic curves. More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences items: type: string diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml b/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml index daa25640d..6c7fdc914 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml @@ -78,7 +78,7 @@ spec: type: object curvePreferences: description: |- - CurvePreferences defines the preferred elliptic curves in a specific order. + CurvePreferences defines the preferred elliptic curves. More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences items: type: string diff --git a/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml b/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml index 0fdd05bc4..20f817125 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml @@ -78,7 +78,7 @@ spec: type: object curvePreferences: description: |- - CurvePreferences defines the preferred elliptic curves in a specific order. + CurvePreferences defines the preferred elliptic curves. More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences items: type: string diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index 20e67ce2a..cf168ff91 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -1644,7 +1644,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre | [2] | `minVersion` | Defines the [minimum TLS version](../../https/tls.md#minimum-tls-version) that is acceptable. | | [3] | `maxVersion` | Defines the [maximum TLS version](../../https/tls.md#maximum-tls-version) that is acceptable. | | [4] | `cipherSuites` | list of supported [cipher suites](../../https/tls.md#cipher-suites) for TLS versions up to TLS 1.2. | -| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake, in preference order. | +| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake. | | [6] | `clientAuth` | determines the server's policy for TLS [Client Authentication](../../https/tls.md#client-authentication-mtls). | | [7] | `clientAuth.secretNames` | list of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace). The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. | | [8] | `clientAuth.clientAuthType` | defines the client authentication type to apply. The available values are: `NoClientCert`, `RequestClientCert`, `VerifyClientCertIfGiven` and `RequireAndVerifyClientCert`. | diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml index 6f901cb57..b5c41bb8c 100644 --- a/integration/fixtures/k8s/01-traefik-crd.yml +++ b/integration/fixtures/k8s/01-traefik-crd.yml @@ -1886,7 +1886,7 @@ spec: type: object curvePreferences: description: |- - CurvePreferences defines the preferred elliptic curves in a specific order. + CurvePreferences defines the preferred elliptic curves. More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences items: type: string @@ -4316,7 +4316,7 @@ spec: type: object curvePreferences: description: |- - CurvePreferences defines the preferred elliptic curves in a specific order. + CurvePreferences defines the preferred elliptic curves. More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences items: type: string diff --git a/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1/tlsoption.go index 0e6e2274d..74aba1a91 100644 --- a/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1/tlsoption.go @@ -34,7 +34,7 @@ type TLSOptionSpec struct { // CipherSuites defines the list of supported cipher suites for TLS versions up to TLS 1.2. // More info: https://doc.traefik.io/traefik/v2.11/https/tls/#cipher-suites CipherSuites []string `json:"cipherSuites,omitempty"` - // CurvePreferences defines the preferred elliptic curves in a specific order. + // CurvePreferences defines the preferred elliptic curves. // More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences CurvePreferences []string `json:"curvePreferences,omitempty"` // ClientAuth defines the server's policy for TLS Client Authentication. diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go index 0e6e2274d..74aba1a91 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go @@ -34,7 +34,7 @@ type TLSOptionSpec struct { // CipherSuites defines the list of supported cipher suites for TLS versions up to TLS 1.2. // More info: https://doc.traefik.io/traefik/v2.11/https/tls/#cipher-suites CipherSuites []string `json:"cipherSuites,omitempty"` - // CurvePreferences defines the preferred elliptic curves in a specific order. + // CurvePreferences defines the preferred elliptic curves. // More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences CurvePreferences []string `json:"curvePreferences,omitempty"` // ClientAuth defines the server's policy for TLS Client Authentication.