diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go
index 77930754b..151e71e58 100644
--- a/cmd/traefik/traefik.go
+++ b/cmd/traefik/traefik.go
@@ -3,7 +3,6 @@ package main
import (
"context"
"crypto/x509"
- "encoding/json"
"fmt"
"io"
stdlog "log"
@@ -40,6 +39,7 @@ import (
"github.com/traefik/traefik/v3/pkg/provider/traefik"
"github.com/traefik/traefik/v3/pkg/proxy"
"github.com/traefik/traefik/v3/pkg/proxy/httputil"
+ "github.com/traefik/traefik/v3/pkg/redactor"
"github.com/traefik/traefik/v3/pkg/safe"
"github.com/traefik/traefik/v3/pkg/server"
"github.com/traefik/traefik/v3/pkg/server/middleware"
@@ -104,12 +104,11 @@ func runCmd(staticConfiguration *static.Configuration) error {
log.Info().Str("version", version.Version).
Msgf("Traefik version %s built on %s", version.Version, version.BuildDate)
- jsonConf, err := json.Marshal(staticConfiguration)
+ redactedStaticConfiguration, err := redactor.RemoveCredentials(staticConfiguration)
if err != nil {
- log.Error().Err(err).Msg("Could not marshal static configuration")
- log.Debug().Interface("staticConfiguration", staticConfiguration).Msg("Static configuration loaded [struct]")
+ log.Error().Err(err).Msg("Could not redact static configuration")
} else {
- log.Debug().RawJSON("staticConfiguration", jsonConf).Msg("Static configuration loaded [json]")
+ log.Debug().RawJSON("staticConfiguration", []byte(redactedStaticConfiguration)).Msg("Static configuration loaded [json]")
}
if staticConfiguration.Global.CheckNewVersion {
diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md
index 7dc9bc975..e022118b8 100644
--- a/docs/content/https/tls.md
+++ b/docs/content/https/tls.md
@@ -384,11 +384,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/migration/v2.md b/docs/content/migration/v2.md
index d0a879781..74e6e3ea1 100644
--- a/docs/content/migration/v2.md
+++ b/docs/content/migration/v2.md
@@ -706,3 +706,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/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
index 59fc65910..6a1aca029 100644
--- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
+++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
@@ -2533,7 +2533,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/v3.4/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
new file mode 100644
index 000000000..6c7fdc914
--- /dev/null
+++ b/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml
@@ -0,0 +1,114 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.1
+ name: tlsoptions.traefik.containo.us
+spec:
+ group: traefik.containo.us
+ names:
+ kind: TLSOption
+ listKind: TLSOptionList
+ plural: tlsoptions
+ singular: tlsoption
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: |-
+ TLSOption is the CRD implementation of a Traefik TLS Option, allowing to configure some parameters of the TLS connection.
+ More info: https://doc.traefik.io/traefik/v2.11/https/tls/#tls-options
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: TLSOptionSpec defines the desired state of a TLSOption.
+ properties:
+ alpnProtocols:
+ description: |-
+ ALPNProtocols defines the list of supported application level protocols for the TLS handshake, in order of preference.
+ More info: https://doc.traefik.io/traefik/v2.11/https/tls/#alpn-protocols
+ items:
+ type: string
+ type: array
+ cipherSuites:
+ description: |-
+ 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
+ items:
+ type: string
+ type: array
+ clientAuth:
+ description: ClientAuth defines the server's policy for TLS Client
+ Authentication.
+ properties:
+ clientAuthType:
+ description: ClientAuthType defines the client authentication
+ type to apply.
+ enum:
+ - NoClientCert
+ - RequestClientCert
+ - RequireAnyClientCert
+ - VerifyClientCertIfGiven
+ - RequireAndVerifyClientCert
+ type: string
+ secretNames:
+ description: SecretNames defines the names of the referenced Kubernetes
+ Secret storing certificate details.
+ items:
+ type: string
+ type: array
+ type: object
+ curvePreferences:
+ description: |-
+ CurvePreferences defines the preferred elliptic curves.
+ More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
+ items:
+ type: string
+ type: array
+ maxVersion:
+ description: |-
+ MaxVersion defines the maximum TLS version that Traefik will accept.
+ Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13.
+ Default: None.
+ type: string
+ minVersion:
+ description: |-
+ MinVersion defines the minimum TLS version that Traefik will accept.
+ Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13.
+ Default: VersionTLS10.
+ type: string
+ preferServerCipherSuites:
+ description: |-
+ PreferServerCipherSuites defines whether the server chooses a cipher suite among his own instead of among the client's.
+ It is enabled automatically when minVersion or maxVersion is set.
+ Deprecated: https://github.com/golang/go/issues/45430
+ type: boolean
+ sniStrict:
+ description: SniStrict defines whether Traefik allows connections
+ from clients connections that do not specify a server_name extension.
+ type: boolean
+ type: object
+ required:
+ - metadata
+ - spec
+ type: object
+ served: true
+ storage: true
diff --git a/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml b/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml
index 758a0ab96..07d7b9d03 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/v3.4/https/tls/#curve-preferences
items:
type: string
diff --git a/docs/content/reference/routing-configuration/http/tls/tls-options.md b/docs/content/reference/routing-configuration/http/tls/tls-options.md
index 992b3497c..2cea7c661 100644
--- a/docs/content/reference/routing-configuration/http/tls/tls-options.md
+++ b/docs/content/reference/routing-configuration/http/tls/tls-options.md
@@ -106,7 +106,7 @@ tls:
### Curve Preferences
-This option allows to set the preferred elliptic curves in a specific order.
+This option allows to set the preferred elliptic curves.
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.
diff --git a/docs/content/reference/routing-configuration/kubernetes/crd/http/tlsoption.md b/docs/content/reference/routing-configuration/kubernetes/crd/http/tlsoption.md
index 6887e8516..76bb932cf 100644
--- a/docs/content/reference/routing-configuration/kubernetes/crd/http/tlsoption.md
+++ b/docs/content/reference/routing-configuration/kubernetes/crd/http/tlsoption.md
@@ -51,7 +51,7 @@ spec:
| `minVersion` | Minimum TLS version that is acceptable. | "VersionTLS12" | No |
| `maxVersion` | Maximum TLS version that is acceptable.
We do not recommend setting this option to disable TLS 1.3. | | No |
| `cipherSuites` | List of supported [cipher suites](https://godoc.org/crypto/tls#pkg-constants) for TLS versions up to TLS 1.2.
[Cipher suites defined for TLS 1.2 and below cannot be used in TLS 1.3, and vice versa.](https://tools.ietf.org/html/rfc8446)
With TLS 1.3, [the cipher suites are not configurable](https://golang.org/doc/go1.12#tls_1_3) (all supported cipher suites are safe in this case). | | No |
-| `curvePreferences` | List of the elliptic curves references that will be used in an ECDHE handshake, in preference order.
Use curves names from [`crypto`](https://godoc.org/crypto/tls#CurveID) or the [RFC](https://tools.ietf.org/html/rfc8446#section-4.2.7).
See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information. | | No |
+| `curvePreferences` | List of the elliptic curves references that will be used in an ECDHE handshake.
Use curves names from [`crypto`](https://godoc.org/crypto/tls#CurveID) or the [RFC](https://tools.ietf.org/html/rfc8446#section-4.2.7).
See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information. | | No |
| `clientAuth.secretNames` | Client Authentication (mTLS) option.
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. | | No |
| `clientAuth.clientAuthType` | Client Authentication (mTLS) option.
Client authentication type to apply. Available values [here](#client-authentication-mtls). | | No |
| `sniStrict` | Allow rejecting connections from clients connections that do not specify a server_name extension.
The [default certificate](../../../http/tls/tls-certificates.md#default-certificate) is never served is the option is enabled. | false | No |
@@ -60,7 +60,7 @@ spec:
### Client Authentication (mTLS)
-The `clientAuth.clientAuthType` option governs the behaviour as follows:
+The `clientAuth.clientAuthType` option governs the behavior as follows:
- `NoClientCert`: disregards any client certificate.
- `RequestClientCert`: asks for a certificate but proceeds anyway if none is provided.
diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md
index d19c4c66c..fd47e8813 100644
--- a/docs/content/routing/providers/kubernetes-crd.md
+++ b/docs/content/routing/providers/kubernetes-crd.md
@@ -1671,7 +1671,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 59fc65910..6a1aca029 100644
--- a/integration/fixtures/k8s/01-traefik-crd.yml
+++ b/integration/fixtures/k8s/01-traefik-crd.yml
@@ -2533,7 +2533,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/v3.4/https/tls/#curve-preferences
items:
type: string
diff --git a/pkg/plugins/client.go b/pkg/plugins/client.go
index ac4e71bcf..8d119ddec 100644
--- a/pkg/plugins/client.go
+++ b/pkg/plugins/client.go
@@ -238,6 +238,9 @@ 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.
+ // This is also useful for wasm plugins.
return c.unzipArchive(pName, pVersion)
}
@@ -278,32 +281,52 @@ func unzipFile(f *zipa.File, dest string) error {
defer func() { _ = rc.Close() }()
+ // Split to discard the first part of the path when the archive is a Yaegi go plugin with vendoring.
+ // In this case the path starts with `[organization]-[project]-[release commit sha1]/`.
pathParts := strings.SplitN(f.Name, "/", 2)
-
- var pp string
+ var fileName string
if len(pathParts) < 2 {
- pp = pathParts[0]
+ fileName = pathParts[0]
} else {
- pp = pathParts[1]
+ fileName = pathParts[1]
}
- p := filepath.Join(dest, pp)
+ // Validate and sanitize the file path.
+ cleanName := filepath.Clean(fileName)
+ 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
}
diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go
index af8aceeb5..f32953423 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/v3.4/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/v3.4/https/tls/#curve-preferences
CurvePreferences []string `json:"curvePreferences,omitempty"`
// ClientAuth defines the server's policy for TLS Client Authentication.
diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go
index ea8ea6e48..16c6e3fa0 100644
--- a/pkg/server/server_entrypoint_tcp.go
+++ b/pkg/server/server_entrypoint_tcp.go
@@ -476,6 +476,13 @@ func buildListener(ctx context.Context, name string, config *static.EntryPoint)
if listener == nil {
listenConfig := newListenConfig(config)
+
+ // 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") {
+ listenConfig.SetMultipathTCP(false)
+ }
+
listener, err = listenConfig.Listen(ctx, "tcp", config.GetAddress())
if err != nil {
return nil, fmt.Errorf("error opening listener: %w", err)