diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 95e921ebf..542cd056b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -4,6 +4,10 @@ on: pull_request: branches: - '*' + paths-ignore: + - 'docs/**' + - '**.md' + - 'script/gcg/**' env: GO_VERSION: '1.22' diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 584dccd5c..adfdcc74e 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -24,7 +24,7 @@ jobs: fetch-depth: 0 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/experimental.yaml b/.github/workflows/experimental.yaml index fa91bfda5..7d9e2e2ea 100644 --- a/.github/workflows/experimental.yaml +++ b/.github/workflows/experimental.yaml @@ -56,10 +56,10 @@ jobs: password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Build docker experimental image env: diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index d121c6df4..c00cad272 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -4,6 +4,10 @@ on: pull_request: branches: - '*' + paths-ignore: + - 'docs/**' + - '**.md' + - 'script/gcg/**' env: GO_VERSION: '1.22' @@ -60,7 +64,7 @@ jobs: - name: Generate go test Slice id: test_split - uses: hashicorp-forge/go-test-split-action@v1 + uses: hashicorp-forge/go-test-split-action@v2.0.0 with: packages: ./integration total: ${{ matrix.parallel }} diff --git a/.github/workflows/test-unit.yaml b/.github/workflows/test-unit.yaml index 43ea42853..a22dc4cda 100644 --- a/.github/workflows/test-unit.yaml +++ b/.github/workflows/test-unit.yaml @@ -4,6 +4,10 @@ on: pull_request: branches: - '*' + paths-ignore: + - 'docs/**' + - '**.md' + - 'script/gcg/**' env: GO_VERSION: '1.22' diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f419e89f..33c5e8b8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +## [v2.11.7](https://github.com/traefik/traefik/tree/v2.11.7) (2024-07-30) +[All Commits](https://github.com/traefik/traefik/compare/v2.11.6...v2.11.7) + +**Bug fixes:** +- **[logs]** Make the log about new version more accurate ([#10903](https://github.com/traefik/traefik/pull/10903) by [jmcbri](https://github.com/jmcbri)) +- **[tls,k8s/crd,k8s]** Enforce default cipher suites list ([#10907](https://github.com/traefik/traefik/pull/10907) by [rtribotte](https://github.com/rtribotte)) + +**Documentation:** +- **[acme]** Modify certificatesDuration documentation ([#10920](https://github.com/traefik/traefik/pull/10920) by [peacewalker122](https://github.com/peacewalker122)) +- **[api]** Improve explanation on API exposition ([#10926](https://github.com/traefik/traefik/pull/10926) by [mloiseleur](https://github.com/mloiseleur)) +- **[docker,consul,rancher,ecs]** Improve doc on sensitive data stored into labels/tags ([#10873](https://github.com/traefik/traefik/pull/10873) by [emilevauge](https://github.com/emilevauge)) +- **[docker,logs]** Improve error and documentation on the needed link between router and service ([#10262](https://github.com/traefik/traefik/pull/10262) by [mloiseleur](https://github.com/mloiseleur)) +- **[docker]** Document Docker port selection on multiple exposed ports ([#10935](https://github.com/traefik/traefik/pull/10935) by [mbrodala](https://github.com/mbrodala)) +- Update the supported versions table for v3.1 release ([#10933](https://github.com/traefik/traefik/pull/10933) by [jnoordsij](https://github.com/jnoordsij)) +- Update PR approval process ([#10887](https://github.com/traefik/traefik/pull/10887) by [emilevauge](https://github.com/emilevauge)) + ## [v3.1.0](https://github.com/traefik/traefik/tree/v3.1.0) (2024-07-15) [All Commits](https://github.com/traefik/traefik/compare/v3.1.0-rc1...v3.1.0) diff --git a/docs/content/deprecation/releases.md b/docs/content/deprecation/releases.md index 4ac402236..fa3387cda 100644 --- a/docs/content/deprecation/releases.md +++ b/docs/content/deprecation/releases.md @@ -6,7 +6,8 @@ Below is a non-exhaustive list of versions and their maintenance status: | Version | Release Date | Community Support | |---------|--------------|--------------------| -| 3.0 | Apr 29, 2024 | Yes | +| 3.1 | Jul 15, 2024 | Yes | +| 3.0 | Apr 29, 2024 | Ended Jul 15, 2024 | | 2.11 | Feb 12, 2024 | Ends Apr 29, 2025 | | 2.10 | Apr 24, 2023 | Ended Feb 12, 2024 | | 2.9 | Oct 03, 2022 | Ended Apr 24, 2023 | diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index c4eafafd8..62509b32c 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -606,9 +606,21 @@ docker run -v "/my/host/acme:/etc/traefik/acme" traefik _Optional, Default=2160_ -The `certificatesDuration` option defines the certificates' duration in hours. +`certificatesDuration` is used to calculate two durations: + +- `Renew Period`: the period before the end of the certificate duration, during which the certificate should be renewed. +- `Renew Interval`: the interval between renew attempts. + It defaults to `2160` (90 days) to follow Let's Encrypt certificates' duration. +| Certificate Duration | Renew Period | Renew Interval | +|----------------------|-------------------|-------------------------| +| >= 1 year | 4 months | 1 week | +| >= 90 days | 30 days | 1 day | +| >= 7 days | 1 day | 1 hour | +| >= 24 hours | 6 hours | 10 min | +| < 24 hours | 20 min | 1 min | + !!! warning "Traefik cannot manage certificates with a duration lower than 1 hour." ```yaml tab="File (YAML)" @@ -633,19 +645,6 @@ certificatesResolvers: # ... ``` -`certificatesDuration` is used to calculate two durations: - -- `Renew Period`: the period before the end of the certificate duration, during which the certificate should be renewed. -- `Renew Interval`: the interval between renew attempts. - -| Certificate Duration | Renew Period | Renew Interval | -|----------------------|-------------------|-------------------------| -| >= 1 year | 4 months | 1 week | -| >= 90 days | 30 days | 1 day | -| >= 7 days | 1 day | 1 hour | -| >= 24 hours | 6 hours | 10 min | -| < 24 hours | 20 min | 1 min | - ### `preferredChain` _Optional, Default=""_ diff --git a/docs/content/operations/api.md b/docs/content/operations/api.md index 3b30993a5..f6786f6d5 100644 --- a/docs/content/operations/api.md +++ b/docs/content/operations/api.md @@ -16,13 +16,9 @@ including sensitive data. In production, it should be at least secured by authentication and authorizations. -A good sane default (non exhaustive) set of recommendations -would be to apply the following protection mechanisms: - -* At the transport level: - NOT publicly exposing the API's port, - keeping it restricted to internal networks - (as in the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege), applied to networks). +!!! info + It's recommended to NOT publicly exposing the API's port, keeping it restricted to internal networks + (as in the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege), applied to networks). ## Configuration diff --git a/docs/content/providers/docker.md b/docs/content/providers/docker.md index a17d3a876..e9cf20a09 100644 --- a/docs/content/providers/docker.md +++ b/docs/content/providers/docker.md @@ -20,7 +20,7 @@ This provider works with [Docker (standalone) Engine](https://docs.docker.com/en ## Configuration Examples -??? example "Configuring Docker & Deploying / Exposing Services" +??? example "Configuring Docker & Deploying / Exposing one Service" Enabling the docker provider @@ -73,12 +73,14 @@ When using Docker Compose, labels are specified by the directive Traefik retrieves the private IP and port of containers from the Docker API. -Port detection works as follows: +Port detection for private communication works as follows: - If a container [exposes](https://docs.docker.com/engine/reference/builder/#expose) a single port, - then Traefik uses this port for private communication. + then Traefik uses this port. - If a container [exposes](https://docs.docker.com/engine/reference/builder/#expose) multiple ports, - or does not expose any port, then you must manually specify which port Traefik should use for communication + then Traefik uses the lowest port. E.g. if `80` and `8080` are exposed, Traefik will use `80`. +- If a container does not expose any port, or the selection from multiple ports does not fit, + then you must manually specify which port Traefik should use for communication by using the label `traefik.http.services..loadbalancer.server.port` (Read more on this label in the dedicated section in [routing](../routing/providers/docker.md#services)). @@ -586,7 +588,7 @@ providers: _Optional, Default=false_ If the parameter is set to `true`, -any [servers load balancer](../routing/services/index.md#servers-load-balancer) defined for Docker containers is created +any [servers load balancer](../routing/services/index.md#servers-load-balancer) defined for Docker containers is created regardless of the [healthiness](https://docs.docker.com/engine/reference/builder/#healthcheck) of the corresponding containers. It also then stays alive and responsive even at times when it becomes empty, i.e. when all its children containers become unhealthy. diff --git a/docs/content/providers/swarm.md b/docs/content/providers/swarm.md index ef26b1dca..8e790c203 100644 --- a/docs/content/providers/swarm.md +++ b/docs/content/providers/swarm.md @@ -20,7 +20,7 @@ This provider works with [Docker Swarm Mode](https://docs.docker.com/engine/swar ## Configuration Examples -??? example "Configuring Docker Swarm & Deploying / Exposing Services" +??? example "Configuring Docker Swarm & Deploying / Exposing one Service" Enabling the Swarm provider @@ -48,7 +48,9 @@ This provider works with [Docker Swarm Mode](https://docs.docker.com/engine/swar --providers.swarm.endpoint=tcp://127.0.0.1:2377 ``` - Attach labels to services (not to containers) while in Swarm mode (in your docker compose file) + Attach labels to a single service (not containers) while in Swarm mode (in your Docker compose file). + When there is only one service, and the router does not specify a service, + then that service is automatically assigned to the router. ```yaml version: "3" diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md index 2c45dc295..41452de4d 100644 --- a/docs/content/routing/providers/docker.md +++ b/docs/content/routing/providers/docker.md @@ -22,7 +22,7 @@ With Docker, Traefik can leverage labels attached to a container to generate rou ## Configuration Examples -??? example "Configuring Docker & Deploying / Exposing Services" +??? example "Configuring Docker & Deploying / Exposing one Service" Enabling the docker provider @@ -109,7 +109,7 @@ and the router automatically gets a rule defined by `defaultRule` (if no rule fo --8<-- "content/routing/providers/service-by-label.md" -??? example "Automatic service assignment with labels" +??? example "Automatic assignment with one Service" With labels in a compose file @@ -120,7 +120,7 @@ and the router automatically gets a rule defined by `defaultRule` (if no rule fo - "traefik.http.services.myservice.loadbalancer.server.port=80" ``` -??? example "Automatic service creation and assignment with labels" +??? example "Automatic service creation with one Router" With labels in a compose file @@ -131,6 +131,18 @@ and the router automatically gets a rule defined by `defaultRule` (if no rule fo - "traefik.http.routers.myproxy.rule=Host(`example.net`)" ``` +??? example "Explicit definition with one Service" + + With labels in a compose file + + ```yaml + labels: + - traefik.http.routers.www-router.rule=Host(`example-a.com`) + # Explicit link between the router and the service + - traefik.http.routers.www-router.service=www-service + - traefik.http.services.www-service.loadbalancer.server.port=8000 + ``` + ### Routers To update the configuration of the Router automatically attached to the container, @@ -433,7 +445,7 @@ More information about available middlewares in the dedicated [middlewares secti You can declare TCP Routers and/or Services using labels. -??? example "Declaring TCP Routers and Services" +??? example "Declaring TCP Routers with one Service" ```yaml services: @@ -571,7 +583,7 @@ You can declare TCP Routers and/or Services using labels. You can declare UDP Routers and/or Services using labels. -??? example "Declaring UDP Routers and Services" +??? example "Declaring UDP Routers with one Service" ```yaml services: diff --git a/docs/content/routing/providers/swarm.md b/docs/content/routing/providers/swarm.md index af1f56d51..cdf406f75 100644 --- a/docs/content/routing/providers/swarm.md +++ b/docs/content/routing/providers/swarm.md @@ -22,7 +22,7 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate ## Configuration Examples -??? example "Configuring Docker Swarm & Deploying / Exposing Services" +??? example "Configuring Docker Swarm & Deploying / Exposing one Service" Enabling the docker provider (Swarm Mode) @@ -50,7 +50,9 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate --providers.swarm.endpoint=tcp://127.0.0.1:2377 ``` - Attach labels to services (not to containers) while in Swarm mode (in your docker compose file) + Attach labels to services (not containers) while in Swarm mode (in your Docker compose file). + When there is only one service, and the router does not specify a service, + then that service is automatically assigned to the router. ```yaml version: "3" @@ -67,6 +69,30 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate Therefore, if you use a compose file with Swarm Mode, labels should be defined in the `deploy` part of your service. This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/compose-file-v3/#labels-1)). +??? example "Specify a Custom Port for the Container" + + Forward requests for `http://example.com` to `http://:12345`: + + ```yaml + version: "3" + services: + my-container: + # ... + deploy: + labels: + - traefik.http.routers.my-container.rule=Host(`example.com`) + - traefik.http.routers.my-container.service=my-service" + # Tell Traefik to use the port 12345 to connect to `my-container` + - traefik.http.services.my-service.loadbalancer.server.port=12345 + ``` + + !!! important "Traefik Connecting to the Wrong Port: `HTTP/502 Gateway Error`" + By default, Traefik uses the lowest exposed port of a container as detailed in + [Port Detection](../providers/swarm.md#port-detection) of the Swarm provider. + + Setting the label `traefik.http.services.xxx.loadbalancer.server.port` + overrides this behavior. + ??? example "Specifying more than one router and service per container" Forwarding requests to more than one port on a container requires referencing the service loadbalancer port definition using the service parameter on the router. @@ -232,7 +258,7 @@ you'd add the label `traefik.http.services..loadbalancer.pa Registers a port. Useful when the container exposes multiples ports. - Mandatory for Docker Swarm (see the section ["Port Detection with Docker Swarm"](../../providers/docker.md#port-detection)). + Mandatory for Docker Swarm (see the section ["Port Detection with Docker Swarm"](../../providers/swarm.md#port-detection)). {: #port } ```yaml diff --git a/pkg/provider/configuration.go b/pkg/provider/configuration.go index 4cfcc1c5c..9c2406acc 100644 --- a/pkg/provider/configuration.go +++ b/pkg/provider/configuration.go @@ -14,6 +14,7 @@ import ( "github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/logs" "github.com/traefik/traefik/v3/pkg/tls" + "golang.org/x/exp/maps" ) // Merge merges multiple configurations. @@ -422,7 +423,7 @@ func BuildTCPRouterConfiguration(ctx context.Context, configuration *dynamic.TCP if len(configuration.Services) > 1 { delete(configuration.Routers, routerName) loggerRouter.Error(). - Msg("Could not define the service name for the router: too many services") + Msgf("Router %s cannot be linked automatically with multiple Services: %q", routerName, maps.Keys(configuration.Services)) continue } @@ -444,8 +445,8 @@ func BuildUDPRouterConfiguration(ctx context.Context, configuration *dynamic.UDP if len(configuration.Services) > 1 { delete(configuration.Routers, routerName) - loggerRouter. - Error().Msg("Could not define the service name for the router: too many services") + loggerRouter.Error(). + Msgf("Router %s cannot be linked automatically with multiple Services: %q", routerName, maps.Keys(configuration.Services)) continue } @@ -493,7 +494,7 @@ func BuildRouterConfiguration(ctx context.Context, configuration *dynamic.HTTPCo if len(configuration.Services) > 1 { delete(configuration.Routers, routerName) loggerRouter.Error(). - Msg("Could not define the service name for the router: too many services") + Msgf("Router %s cannot be linked automatically with multiple Services: %q", routerName, maps.Keys(configuration.Services)) continue } diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index 025632387..89efa3502 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -978,65 +978,69 @@ func createChainMiddleware(ctx context.Context, namespace string, chain *traefik } func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options { - tlsOptionsCRD := client.GetTLSOptions() + tlsOptionsCRDs := client.GetTLSOptions() var tlsOptions map[string]tls.Options - if len(tlsOptionsCRD) == 0 { + if len(tlsOptionsCRDs) == 0 { return tlsOptions } tlsOptions = make(map[string]tls.Options) var nsDefault []string - for _, tlsOption := range tlsOptionsCRD { - logger := log.Ctx(ctx).With().Str("tlsOption", tlsOption.Name).Str("namespace", tlsOption.Namespace).Logger() + for _, tlsOptionsCRD := range tlsOptionsCRDs { + logger := log.Ctx(ctx).With().Str("tlsOption", tlsOptionsCRD.Name).Str("namespace", tlsOptionsCRD.Namespace).Logger() var clientCAs []types.FileOrContent - for _, secretName := range tlsOption.Spec.ClientAuth.SecretNames { - secret, exists, err := client.GetSecret(tlsOption.Namespace, secretName) + for _, secretName := range tlsOptionsCRD.Spec.ClientAuth.SecretNames { + secret, exists, err := client.GetSecret(tlsOptionsCRD.Namespace, secretName) if err != nil { - logger.Error().Err(err).Msgf("Failed to fetch secret %s/%s", tlsOption.Namespace, secretName) + logger.Error().Err(err).Msgf("Failed to fetch secret %s/%s", tlsOptionsCRD.Namespace, secretName) continue } if !exists { - logger.Warn().Msgf("Secret %s/%s does not exist", tlsOption.Namespace, secretName) + logger.Warn().Msgf("Secret %s/%s does not exist", tlsOptionsCRD.Namespace, secretName) continue } - cert, err := getCABlocks(secret, tlsOption.Namespace, secretName) + cert, err := getCABlocks(secret, tlsOptionsCRD.Namespace, secretName) if err != nil { - logger.Error().Err(err).Msgf("Failed to extract CA from secret %s/%s", tlsOption.Namespace, secretName) + logger.Error().Err(err).Msgf("Failed to extract CA from secret %s/%s", tlsOptionsCRD.Namespace, secretName) continue } clientCAs = append(clientCAs, types.FileOrContent(cert)) } - id := makeID(tlsOption.Namespace, tlsOption.Name) + id := makeID(tlsOptionsCRD.Namespace, tlsOptionsCRD.Name) // If the name is default, we override the default config. - if tlsOption.Name == tls.DefaultTLSConfigName { - id = tlsOption.Name - nsDefault = append(nsDefault, tlsOption.Namespace) + if tlsOptionsCRD.Name == tls.DefaultTLSConfigName { + id = tlsOptionsCRD.Name + nsDefault = append(nsDefault, tlsOptionsCRD.Namespace) } - alpnProtocols := tls.DefaultTLSOptions.ALPNProtocols - if len(tlsOption.Spec.ALPNProtocols) > 0 { - alpnProtocols = tlsOption.Spec.ALPNProtocols + tlsOption := tls.Options{} + tlsOption.SetDefaults() + + tlsOption.MinVersion = tlsOptionsCRD.Spec.MinVersion + tlsOption.MaxVersion = tlsOptionsCRD.Spec.MaxVersion + + if tlsOptionsCRD.Spec.CipherSuites != nil { + tlsOption.CipherSuites = tlsOptionsCRD.Spec.CipherSuites } - tlsOptions[id] = tls.Options{ - MinVersion: tlsOption.Spec.MinVersion, - MaxVersion: tlsOption.Spec.MaxVersion, - CipherSuites: tlsOption.Spec.CipherSuites, - CurvePreferences: tlsOption.Spec.CurvePreferences, - ClientAuth: tls.ClientAuth{ - CAFiles: clientCAs, - ClientAuthType: tlsOption.Spec.ClientAuth.ClientAuthType, - }, - SniStrict: tlsOption.Spec.SniStrict, - ALPNProtocols: alpnProtocols, - PreferServerCipherSuites: tlsOption.Spec.PreferServerCipherSuites, + tlsOption.CurvePreferences = tlsOptionsCRD.Spec.CurvePreferences + tlsOption.ClientAuth = tls.ClientAuth{ + CAFiles: clientCAs, + ClientAuthType: tlsOptionsCRD.Spec.ClientAuth.ClientAuthType, } + tlsOption.SniStrict = tlsOptionsCRD.Spec.SniStrict + + if tlsOptionsCRD.Spec.ALPNProtocols != nil { + tlsOption.ALPNProtocols = tlsOptionsCRD.Spec.ALPNProtocols + } + + tlsOptions[id] = tlsOption } if len(nsDefault) > 1 { diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 8f53e1a0c..8f9f5c2c5 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -886,6 +886,21 @@ func TestLoadIngressRouteTCPs(t *testing.T) { "http/1.1", "acme-tls/1", }, + CipherSuites: []string{ + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + }, }, }, }, @@ -942,6 +957,21 @@ func TestLoadIngressRouteTCPs(t *testing.T) { "http/1.1", "acme-tls/1", }, + CipherSuites: []string{ + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + }, }, }, }, @@ -3549,6 +3579,21 @@ func TestLoadIngressRoutes(t *testing.T) { "http/1.1", "acme-tls/1", }, + CipherSuites: []string{ + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + }, }, }, }, @@ -3611,6 +3656,21 @@ func TestLoadIngressRoutes(t *testing.T) { "http/1.1", "acme-tls/1", }, + CipherSuites: []string{ + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + }, }, }, }, @@ -6334,6 +6394,21 @@ func TestCrossNamespace(t *testing.T) { "cross-ns-tls-options-cn": { MinVersion: "VersionTLS12", ALPNProtocols: []string{"h2", "http/1.1", "acme-tls/1"}, + CipherSuites: []string{ + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + }, }, }, }, @@ -6382,6 +6457,21 @@ func TestCrossNamespace(t *testing.T) { "cross-ns-tls-options-cn": { MinVersion: "VersionTLS12", ALPNProtocols: []string{"h2", "http/1.1", "acme-tls/1"}, + CipherSuites: []string{ + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + }, }, }, }, @@ -6723,6 +6813,21 @@ func TestCrossNamespace(t *testing.T) { "cross-ns-tls-options-cn": { MinVersion: "VersionTLS12", ALPNProtocols: []string{"h2", "http/1.1", "acme-tls/1"}, + CipherSuites: []string{ + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + }, }, }, }, @@ -6767,6 +6872,21 @@ func TestCrossNamespace(t *testing.T) { "cross-ns-tls-options-cn": { MinVersion: "VersionTLS12", ALPNProtocols: []string{"h2", "http/1.1", "acme-tls/1"}, + CipherSuites: []string{ + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + }, }, }, }, diff --git a/pkg/tls/tls.go b/pkg/tls/tls.go index 7851a8ca0..c8964d0ed 100644 --- a/pkg/tls/tls.go +++ b/pkg/tls/tls.go @@ -34,6 +34,7 @@ type Options struct { func (o *Options) SetDefaults() { // ensure http2 enabled o.ALPNProtocols = DefaultTLSOptions.ALPNProtocols + o.CipherSuites = DefaultTLSOptions.CipherSuites } // +k8s:deepcopy-gen=true