mirror of
https://github.com/traefik/traefik.git
synced 2026-06-09 00:32:27 -04:00
Merge branch v3.6 into v3.7
This commit is contained in:
commit
48ba249ba7
9 changed files with 192 additions and 15 deletions
24
CHANGELOG.md
24
CHANGELOG.md
|
|
@ -31,10 +31,11 @@
|
|||
- **[k8s/ingress-nginx]** Add nginx.ingress.kubernetes.io/enable-global-auth to the list of supported annotations ([#13219](https://github.com/traefik/traefik/pull/13219) @filip2mac)
|
||||
- **[k8s/ingress-nginx]** Capitalize NGINX in kubernetesIngressNGINX ([#13236](https://github.com/traefik/traefik/pull/13236) @smellems)
|
||||
|
||||
## [v3.6.18](https://github.com/traefik/traefik/tree/v3.6.18) (2026-06-03)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.6.17...v3.6.18)
|
||||
## [v3.6.19](https://github.com/traefik/traefik/tree/v3.6.19) (2026-06-04)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.6.17...v3.6.19)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[tls]** Compute resolved tlsOptions after applying models ([#13291](https://github.com/traefik/traefik/pull/13291) @rtribotte)
|
||||
- **[accesslogs]** Escape double quotes in quoted log fields ([#13180](https://github.com/traefik/traefik/pull/13180) @KaanSimsek)
|
||||
- **[k8s/gatewayapi]** Escape exact gRPC method matches ([#13201](https://github.com/traefik/traefik/pull/13201) @nickmnt)
|
||||
- **[logs, middleware]** Allow query parameters to be dropped from RequestPath in access log ([#13091](https://github.com/traefik/traefik/pull/13091) @calinelson)
|
||||
|
|
@ -51,17 +52,18 @@
|
|||
|
||||
**Documentation:**
|
||||
- **[file]** Replace generated File routing reference page ([#13170](https://github.com/traefik/traefik/pull/13170) @sheddy-traefik)
|
||||
- **[middleware]** Remove whitespace in HTML tag ([#13160](https://github.com/traefik/traefik/pull/13160) @marbon87)
|
||||
- **[k8s/crd]** Fix typo in accesslogs field name ([#13177](https://github.com/traefik/traefik/pull/13177) @PlayMTL)
|
||||
- **[k8s/ingress-nginx]** Surface the Ingress status race condition during NGINX coexistence ([#13205](https://github.com/traefik/traefik/pull/13205) @emilevauge)
|
||||
- **[k8s/ingress-nginx]** Capitalize NGINX in kubernetesIngressNGINX ([#13236](https://github.com/traefik/traefik/pull/13236) @smellems)
|
||||
- Polish grammar in migration guides ([#13174](https://github.com/traefik/traefik/pull/13174) @quyentonndbs)
|
||||
- **[middleware]** Remove whitespace in HTML tag ([#13160](https://github.com/traefik/traefik/pull/13160) @marbon87)
|
||||
- Add @LBF38 as a current maintainer ([#13225](https://github.com/traefik/traefik/pull/13225) @emilevauge)
|
||||
- **[k8s/ingress-nginx]** Capitalize NGINX in kubernetesIngressNGINX ([#13236](https://github.com/traefik/traefik/pull/13236) @smellems)
|
||||
|
||||
## [v2.11.47](https://github.com/traefik/traefik/tree/v2.11.47) (2026-06-03)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.46...v2.11.47)
|
||||
## [v2.11.48](https://github.com/traefik/traefik/tree/v2.11.48) (2026-06-04)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.46...v2.11.48)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[tls]** Compute resolved tlsOptions after applying models ([#13291](https://github.com/traefik/traefik/pull/13291) @rtribotte)
|
||||
- **[middleware, authentication]** Add error on basic auth build if users is empty ([#13195](https://github.com/traefik/traefik/pull/13195) @rtribotte)
|
||||
- **[k8s/ingress]** Avoid ingress path matcher injection and backport 11d251415 ([#13227](https://github.com/traefik/traefik/pull/13227) @rtribotte)
|
||||
- **[server]** Move snicheck to ctx instead of simulated routing ([#13214](https://github.com/traefik/traefik/pull/13214) @juliens)
|
||||
|
|
@ -69,6 +71,16 @@
|
|||
- **[server]** Bump golang.org/x/net to v0.55.0 ([#13251](https://github.com/traefik/traefik/pull/13251) @kevinpollet)
|
||||
- **[server]** Bump golang.org/x/crypto to v0.52.0 ([#13276](https://github.com/traefik/traefik/pull/13276) @rtribotte)
|
||||
|
||||
## [v3.6.18](https://github.com/traefik/traefik/tree/v3.6.18) (2026-06-03)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.6.17...v3.6.18)
|
||||
|
||||
Release canceled.
|
||||
|
||||
## [v2.11.47](https://github.com/traefik/traefik/tree/v2.11.47) (2026-06-03)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.46...v2.11.47)
|
||||
|
||||
Release canceled.
|
||||
|
||||
## [v3.7.1](https://github.com/traefik/traefik/tree/v3.7.1) (2026-05-11)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v3.7.0...v3.7.1)
|
||||
|
||||
|
|
|
|||
|
|
@ -144,11 +144,11 @@ Note: TLSOptions for `HostRegexp` matchers remains unsupported. Use wildcard `Ho
|
|||
|
||||
---
|
||||
|
||||
## v3.6.18
|
||||
## v3.6.19
|
||||
|
||||
### Kubernetes Gateway API Provider
|
||||
|
||||
Starting with `v3.6.18`, the QPS and Burst values of the Kubernetes client used by the Kubernetes Gateway API provider have been increased to `50` and `100` respectively (10x the default values of the Kubernetes client).
|
||||
Starting with `v3.6.19`, the QPS and Burst values of the Kubernetes client used by the Kubernetes Gateway API provider have been increased to `50` and `100` respectively (10x the default values of the Kubernetes client).
|
||||
|
||||
The Kubernetes Gateway API provider writes status updates intensively to comply with the Kubernetes Gateway API specification.
|
||||
This change helps avoid performance issues related to Kubernetes API rate limiting, which can increase the setup time when a new routing configuration is built.
|
||||
|
|
@ -158,13 +158,13 @@ and [`kubernetesGateway.burst`](../reference/install-configuration/providers/kub
|
|||
|
||||
### BasicAuth Middleware
|
||||
|
||||
From version `v3.6.18` onwards, the BasicAuth middleware requires a non-empty users configuration in order to be built successfully.
|
||||
From version `v3.6.19` onwards, the BasicAuth middleware requires a non-empty users configuration in order to be built successfully.
|
||||
Previously, the middleware would be built successfully but always return a 401 status code for any request.
|
||||
Now, an error occurs and any routers using it will be unmounted. For the same request, a 404 status code is served instead of a 401 status code.
|
||||
|
||||
### StripPrefix and StripPrefixRegex Middleware
|
||||
|
||||
From version `v3.6.18` onwards, the StripPrefix middleware and the StripPrefixRegex middleware reject requests (`400 Bad Request`)
|
||||
From version `v3.6.19` onwards, the StripPrefix middleware and the StripPrefixRegex middleware reject requests (`400 Bad Request`)
|
||||
when stripping the configured prefix produces a path that differs from its normalised form
|
||||
(i.e. a path containing `.` or `..` segments that would be collapsed by normalisation).
|
||||
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -22,7 +22,7 @@ require (
|
|||
github.com/docker/cli v29.4.0+incompatible
|
||||
github.com/docker/go-connections v0.6.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/fsnotify/fsnotify v1.10.1
|
||||
github.com/go-acme/lego/v4 v4.35.2
|
||||
github.com/go-kit/kit v0.13.0
|
||||
github.com/go-kit/log v0.2.1
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -1004,8 +1004,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
|
|||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
|
||||
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
|
||||
|
|
|
|||
53
integration/fixtures/https/https_entrypoint_tls.toml
Normal file
53
integration/fixtures/https/https_entrypoint_tls.toml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.websecure]
|
||||
address = ":4443"
|
||||
[entryPoints.websecure.http.tls]
|
||||
|
||||
[entryPoints.websecure-options]
|
||||
address = ":4444"
|
||||
[entryPoints.websecure-options.http.tls]
|
||||
options = "foo"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers.file]
|
||||
filename = "{{ .SelfFilename }}"
|
||||
|
||||
## dynamic configuration ##
|
||||
|
||||
[http.routers]
|
||||
[http.routers.router1]
|
||||
entryPoints = ["websecure"]
|
||||
service = "service1"
|
||||
rule = "Host(`snitest.com`)"
|
||||
|
||||
[http.routers.router2]
|
||||
entryPoints = ["websecure-options"]
|
||||
service = "service1"
|
||||
rule = "Host(`snitest.org`)"
|
||||
|
||||
[http.services]
|
||||
[http.services.service1]
|
||||
[http.services.service1.loadBalancer]
|
||||
[[http.services.service1.loadBalancer.servers]]
|
||||
url = "http://127.0.0.1:9010"
|
||||
|
||||
[[tls.certificates]]
|
||||
certFile = "fixtures/https/snitest.com.cert"
|
||||
keyFile = "fixtures/https/snitest.com.key"
|
||||
|
||||
[[tls.certificates]]
|
||||
certFile = "fixtures/https/snitest.org.cert"
|
||||
keyFile = "fixtures/https/snitest.org.key"
|
||||
|
||||
[tls.options]
|
||||
[tls.options.foo]
|
||||
maxVersion = "VersionTLS12"
|
||||
|
|
@ -150,7 +150,69 @@ func (s *HTTPSSuite) TestWithSNIConfigRoute() {
|
|||
require.NoError(s.T(), err)
|
||||
}
|
||||
|
||||
// TestWithTLSOptions verifies that traefik routes the requests with the associated tls options.
|
||||
// TestWithEntryPointTLSConfig verifies that a router relying on the entry point
|
||||
// TLS configuration (without an explicit router TLS section) is served over HTTPS,
|
||||
// including when the entry point references user-defined TLS options.
|
||||
// Regression test for https://github.com/traefik/traefik/issues/13289.
|
||||
func (s *HTTPSSuite) TestWithEntryPointTLSConfig() {
|
||||
file := s.adaptFile("fixtures/https/https_entrypoint_tls.toml", struct{}{})
|
||||
s.traefikCmd(withConfigFile(file))
|
||||
|
||||
// wait for Traefik
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.com`)"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
backend := startTestServer("9010", http.StatusNoContent, "")
|
||||
defer backend.Close()
|
||||
|
||||
err = try.GetRequest(backend.URL, 1*time.Second, try.StatusCodeIs(http.StatusNoContent))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
ServerName: "snitest.com",
|
||||
},
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:4443/", nil)
|
||||
require.NoError(s.T(), err)
|
||||
req.Host = tr.TLSClientConfig.ServerName
|
||||
req.Header.Set("Host", tr.TLSClientConfig.ServerName)
|
||||
req.Header.Set("Accept", "*/*")
|
||||
|
||||
err = try.RequestWithTransport(req, 30*time.Second, tr, try.HasCn(tr.TLSClientConfig.ServerName), try.StatusCodeIs(http.StatusNoContent))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// The websecure-options entry point references the user-defined "foo" TLS options (maxVersion VersionTLS12).
|
||||
// A request with no router-level TLS must still have these options resolved and applied.
|
||||
trOptions := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
ServerName: "snitest.org",
|
||||
},
|
||||
}
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, "https://127.0.0.1:4444/", nil)
|
||||
require.NoError(s.T(), err)
|
||||
req.Host = trOptions.TLSClientConfig.ServerName
|
||||
req.Header.Set("Host", trOptions.TLSClientConfig.ServerName)
|
||||
req.Header.Set("Accept", "*/*")
|
||||
|
||||
err = try.RequestWithTransport(req, 30*time.Second, trOptions, try.HasCn(trOptions.TLSClientConfig.ServerName), try.StatusCodeIs(http.StatusNoContent))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// A TLS 1.3-only client must fail the handshake, proving the "foo" options
|
||||
// (resolved from the entry point) are effectively enforced.
|
||||
_, err = tls.Dial("tcp", "127.0.0.1:4444", &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
ServerName: "snitest.org",
|
||||
MinVersion: tls.VersionTLS13,
|
||||
})
|
||||
assert.Error(s.T(), err)
|
||||
}
|
||||
|
||||
// TestWithTLSOptions verifies that traefik routes the requests with the associated tls options.
|
||||
func (s *HTTPSSuite) TestWithTLSOptions() {
|
||||
file := s.adaptFile("fixtures/https/https_tls_options.toml", struct{}{})
|
||||
s.traefikCmd(withConfigFile(file))
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ func mergeConfiguration(configurations dynamic.Configurations, defaultEntryPoint
|
|||
delete(conf.TLS.Options, traefiktls.DefaultTLSConfigName)
|
||||
}
|
||||
|
||||
return resolveHTTPTLSOptions(conf)
|
||||
return conf
|
||||
}
|
||||
|
||||
func resolveHTTPTLSOptions(cfg dynamic.Configuration) dynamic.Configuration {
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ func (c *ConfigurationWatcher) applyConfigurations(ctx context.Context) {
|
|||
|
||||
conf := mergeConfiguration(newConfigs.DeepCopy(), c.defaultEntryPoints)
|
||||
conf = applyModel(conf)
|
||||
conf = resolveHTTPTLSOptions(conf)
|
||||
|
||||
for _, listener := range c.configurationListeners {
|
||||
listener(conf)
|
||||
|
|
|
|||
|
|
@ -992,3 +992,52 @@ func TestConfigurationWatcher_MultipleTransformers(t *testing.T) {
|
|||
assert.Equal(t, 1, callCount1)
|
||||
assert.Equal(t, 1, callCount2)
|
||||
}
|
||||
|
||||
// TestEntryPointTLSResolvedOptions is a regression test for
|
||||
// https://github.com/traefik/traefik/issues/13289: a router whose TLS
|
||||
// configuration comes from the entry point (and not from an explicit router TLS
|
||||
// section) must still have its TLS options resolved in the published configuration.
|
||||
func TestEntryPointTLSResolvedOptions(t *testing.T) {
|
||||
routinesPool := safe.NewPool(t.Context())
|
||||
t.Cleanup(routinesPool.Stop)
|
||||
|
||||
pvd := &mockProvider{
|
||||
messages: []dynamic.Message{{
|
||||
ProviderName: "internal",
|
||||
Configuration: &dynamic.Configuration{
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"foo": {
|
||||
EntryPoints: []string{"websecure"},
|
||||
Rule: "Host(`foo.example.com`)",
|
||||
Service: "service",
|
||||
},
|
||||
},
|
||||
Models: map[string]*dynamic.Model{
|
||||
"websecure": {
|
||||
TLS: &dynamic.RouterTLSConfig{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
}
|
||||
|
||||
watcher := NewConfigurationWatcher(routinesPool, pvd, []string{}, "")
|
||||
|
||||
run := make(chan struct{})
|
||||
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||
router := conf.HTTP.Routers["foo@internal"]
|
||||
if router == nil || router.TLS == nil {
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, "default", router.TLS.ResolvedOptions)
|
||||
close(run)
|
||||
})
|
||||
|
||||
watcher.Start()
|
||||
t.Cleanup(watcher.Stop)
|
||||
|
||||
<-run
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue