From f32f05f811f58d4b1fae32ba620f6fd43388aa13 Mon Sep 17 00:00:00 2001 From: Romain Date: Thu, 4 Jun 2026 16:12:05 +0200 Subject: [PATCH 1/4] Bump github.com/quic-go/quic-go to v0.59.1 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index cf0276f98c..358198fe63 100644 --- a/go.mod +++ b/go.mod @@ -58,7 +58,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // No tag on the repo. github.com/prometheus/client_golang v1.22.0 github.com/prometheus/client_model v0.6.1 - github.com/quic-go/quic-go v0.57.1 + github.com/quic-go/quic-go v0.59.1 github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac // No tag on the repo. github.com/sirupsen/logrus v1.9.4 github.com/stretchr/testify v1.11.1 diff --git a/go.sum b/go.sum index 5ca5859d6a..4085371ad7 100644 --- a/go.sum +++ b/go.sum @@ -1946,8 +1946,8 @@ github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++ github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= -github.com/quic-go/quic-go v0.57.1 h1:25KAAR9QR8KZrCZRThWMKVAwGoiHIrNbT72ULHTuI10= -github.com/quic-go/quic-go v0.57.1/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s= +github.com/quic-go/quic-go v0.59.1 h1:0Gmua0HW1Tv7ANR7hUYwRyD0MG5OJfgvYSZasGZzBic= +github.com/quic-go/quic-go v0.59.1/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac h1:wBGhHdXKICZmvAPWS8gQoMyOWDH7QAi9bU4Z1nDWnFU= github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac/go.mod h1:67sLWL17mVlO1HFROaTBmU71NB4R8UNCesFHhg0f6LQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= From 5404f6fb25c74ee31910f70f97f0ee0bd20f1b61 Mon Sep 17 00:00:00 2001 From: "Gina A." <70909035+gndz07@users.noreply.github.com> Date: Fri, 5 Jun 2026 11:22:05 +0200 Subject: [PATCH 2/4] Bump axios to v1.17.0 --- webui/package.json | 2 +- webui/yarn.lock | 35 +++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/webui/package.json b/webui/package.json index a1e0b5ae0a..3fae976adc 100644 --- a/webui/package.json +++ b/webui/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@quasar/extras": "^1.16.12", - "axios": "1.15.1", + "axios": "1.17.0", "chart.js": "^4.4.1", "core-js": "^3.35.1", "dot-prop": "^8.0.2", diff --git a/webui/yarn.lock b/webui/yarn.lock index 0c6ee58cb5..9883515301 100644 --- a/webui/yarn.lock +++ b/webui/yarn.lock @@ -1939,6 +1939,13 @@ acorn@^8.11.0, acorn@^8.12.1, acorn@^8.8.2, acorn@^8.9.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -2163,13 +2170,14 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -axios@1.15.1: - version "1.15.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.15.1.tgz#075420b785da8adbdf545785b69f90c926b28542" - integrity sha512-WOG+Jj8ZOvR0a3rAn+Tuf1UQJRxw5venr6DgdbJzngJE3qG7X0kL83CZGpdHMxEm+ZK3seAbvFsw4FfOfP9vxg== +axios@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.17.0.tgz#ae5a1164a4f719942cd73c67e6a3f62d3ccb8f2b" + integrity sha512-J8SwNxprqqpbfenehxWYXE7CW+wM1BB4w3+N+g+/Wx40xM4rsLrfPmHHxSWIxJLYDgSY/HqlFPIYb2/S3rxafw== dependencies: - follow-redirects "^1.15.11" + follow-redirects "^1.16.0" form-data "^4.0.5" + https-proxy-agent "^5.0.1" proxy-from-env "^2.1.0" b4a@^1.6.4: @@ -2744,6 +2752,13 @@ debug@2.6.9: dependencies: ms "2.0.0" +debug@4: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -3580,7 +3595,7 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== -follow-redirects@^1.15.11: +follow-redirects@^1.16.0: version "1.16.0" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.16.0.tgz#28474a159d3b9d11ef62050a14ed60e4df6d61bc" integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw== @@ -3920,6 +3935,14 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +https-proxy-agent@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + human-signals@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" From b6bb80f8ff7e564f47acebade9f78e01f689264d Mon Sep 17 00:00:00 2001 From: Julien Salleyron Date: Fri, 5 Jun 2026 14:36:05 +0200 Subject: [PATCH 3/4] Fix snicheck with keepalive --- .golangci.yml | 4 +- pkg/server/conncontext.go | 29 +++++++++++ pkg/server/conncontext_test.go | 26 ++++++++++ pkg/server/router/tcp/manager.go | 22 ++++---- pkg/server/server_entrypoint_tcp.go | 80 ++++++++++++++--------------- 5 files changed, 111 insertions(+), 50 deletions(-) create mode 100644 pkg/server/conncontext.go create mode 100644 pkg/server/conncontext_test.go diff --git a/.golangci.yml b/.golangci.yml index 02749c267d..feefe53c34 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -327,7 +327,9 @@ linters: text: 'SA1008: keys in http.Header are canonicalized, "x-user" is not canonical; fix the constant or use http.CanonicalHeaderKey' - path: pkg/middlewares/auth/digest_auth_test.go text: 'SA1008: keys in http.Header are canonicalized, "x-user" is not canonical; fix the constant or use http.CanonicalHeaderKey' - + - path: pkg/server/conncontext.go + linters: + - fatcontext paths: - pkg/provider/kubernetes/crd/generated/ diff --git a/pkg/server/conncontext.go b/pkg/server/conncontext.go new file mode 100644 index 0000000000..a93290c7a2 --- /dev/null +++ b/pkg/server/conncontext.go @@ -0,0 +1,29 @@ +package server + +import ( + "context" + "net" +) + +type connContextFunc func(context.Context, net.Conn) context.Context + +type multipleConnContext struct { + fns []connContextFunc +} + +func (m *multipleConnContext) AddConnContextFunc(fn connContextFunc) { + m.fns = append(m.fns, fn) +} + +func (m *multipleConnContext) Build() connContextFunc { + if len(m.fns) == 0 { + return nil + } + + return func(ctx context.Context, c net.Conn) context.Context { + for _, contextFunc := range m.fns { + ctx = contextFunc(ctx, c) + } + return ctx + } +} diff --git a/pkg/server/conncontext_test.go b/pkg/server/conncontext_test.go new file mode 100644 index 0000000000..6160ea358e --- /dev/null +++ b/pkg/server/conncontext_test.go @@ -0,0 +1,26 @@ +package server + +import ( + "context" + "net" + "testing" + + "github.com/stretchr/testify/require" +) + +type keyTest string + +func TestConnContext(t *testing.T) { + var connContext multipleConnContext + connContext.AddConnContextFunc(func(ctx context.Context, _ net.Conn) context.Context { + return context.WithValue(ctx, keyTest("test"), "test") + }) + connContext.AddConnContextFunc(func(ctx context.Context, _ net.Conn) context.Context { + return context.WithValue(ctx, keyTest("test2"), "test2") + }) + + ctx := connContext.Build()(context.Background(), nil) + + require.Equal(t, "test", ctx.Value(keyTest("test"))) + require.Equal(t, "test2", ctx.Value(keyTest("test2"))) +} diff --git a/pkg/server/router/tcp/manager.go b/pkg/server/router/tcp/manager.go index 0a17dfb272..de9e9e2762 100644 --- a/pkg/server/router/tcp/manager.go +++ b/pkg/server/router/tcp/manager.go @@ -114,6 +114,13 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string ctxRouter := log.With(provider.AddInContext(ctx, routerHTTPName), log.Str(log.RouterName, routerHTTPName)) logger := log.FromContext(ctxRouter) + // Even if the TLS options mismatch between the configured and the resolved one is handled in the aggregator + // we also have to handle it here to be able to mark the router in error. + tlsOptionsName := traefiktls.DefaultTLSConfigName + if len(routerHTTPConfig.TLS.Options) > 0 && routerHTTPConfig.TLS.Options != traefiktls.DefaultTLSConfigName { + tlsOptionsName = provider.GetQualifiedName(ctxRouter, routerHTTPConfig.TLS.Options) + } + domains, err := httpmuxer.ParseDomains(routerHTTPConfig.Rule) if err != nil { routerErr := fmt.Errorf("invalid rule %s, error: %w", routerHTTPConfig.Rule, err) @@ -153,17 +160,14 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string // # When a request for "/foo" comes, even though it won't be routed by httpRouter2, // # if its SNI is set to foo.com, myTLSOptions will be used for the TLS connection. // # Otherwise, it will fallback to the default TLS config. - logger.Warnf("No domain found in rule %v, the TLS options applied for this router will depend on the SNI of each request", routerHTTPConfig.Rule) + if tlsOptionsName != traefiktls.DefaultTLSConfigName { + logger.Warnf("No domain found in rule %v, the TLS options applied for this router will depend on the SNI of each request", routerHTTPConfig.Rule) + routerHTTPConfig.AddError(fmt.Errorf("no domain found in rule %v, the TLS option %s cannot be applied", routerHTTPConfig.Rule, tlsOptionsName), false) + } } - // Even if the TLS options mismatch between the configured and the resolved one is handled in the aggregator - // we also have to handle it here to be able to mark the router in error. - tlsOptionsName := traefiktls.DefaultTLSConfigName - if len(routerHTTPConfig.TLS.Options) > 0 && routerHTTPConfig.TLS.Options != traefiktls.DefaultTLSConfigName { - tlsOptionsName = provider.GetQualifiedName(ctxRouter, routerHTTPConfig.TLS.Options) - } - - if routerHTTPConfig.TLS.ResolvedOptions != tlsOptionsName { + if len(domains) > 0 && routerHTTPConfig.TLS.ResolvedOptions != tlsOptionsName { + logger.Warn("Found different TLS options for routers on the same host, so using the default TLS options instead.") routerHTTPConfig.AddError(errors.New("found different TLS options for routers on the same host, so using the default TLS options instead"), false) } diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go index 39dd3b42fe..252ec0514a 100644 --- a/pkg/server/server_entrypoint_tcp.go +++ b/pkg/server/server_entrypoint_tcp.go @@ -601,6 +601,44 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati handler = denyFragment(handler) + var connContext multipleConnContext + connContext.AddConnContextFunc(func(ctx context.Context, c net.Conn) context.Context { + // This adds an empty struct in order to store a RoundTripper in the ConnContext in case of Kerberos or NTLM. + ctx = service.AddTransportOnContext(ctx) + + if tlsConn, ok := c.(*tls.Conn); ok { + if tlsConnWithOptionsName, ok := tlsConn.NetConn().(tcp.TLSConn); ok { + return tcp.AddTLSOptionsNameInContext(ctx, tlsConnWithOptionsName.TLSOptionsName) + } + } + + return ctx + }) + + if debugConnection || (configuration.Transport != nil && (configuration.Transport.KeepAliveMaxTime > 0 || configuration.Transport.KeepAliveMaxRequests > 0)) { + connContext.AddConnContextFunc(func(ctx context.Context, c net.Conn) context.Context { + cState := &connState{Start: time.Now()} + if debugConnection { + clientConnectionStatesMu.Lock() + clientConnectionStates[getConnKey(c)] = cState + clientConnectionStatesMu.Unlock() + } + + return context.WithValue(ctx, connStateKey, cState) + }) + } + + var connState func(c net.Conn, state http.ConnState) + if debugConnection { + connState = func(c net.Conn, state http.ConnState) { + clientConnectionStatesMu.Lock() + if clientConnectionStates[getConnKey(c)] != nil { + clientConnectionStates[getConnKey(c)].State = state.String() + } + clientConnectionStatesMu.Unlock() + } + } + serverHTTP := &http.Server{ Protocols: &protocols, Handler: handler, @@ -611,46 +649,8 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati HTTP2: &http.HTTP2Config{ MaxConcurrentStreams: int(configuration.HTTP2.MaxConcurrentStreams), }, - ConnContext: func(ctx context.Context, c net.Conn) context.Context { - if tlsConn, ok := c.(*tls.Conn); ok { - if tlsConnWithOptionsName, ok := tlsConn.NetConn().(tcp.TLSConn); ok { - return tcp.AddTLSOptionsNameInContext(ctx, tlsConnWithOptionsName.TLSOptionsName) - } - } - - return ctx - }, - } - if debugConnection || (configuration.Transport != nil && (configuration.Transport.KeepAliveMaxTime > 0 || configuration.Transport.KeepAliveMaxRequests > 0)) { - serverHTTP.ConnContext = func(ctx context.Context, c net.Conn) context.Context { - cState := &connState{Start: time.Now()} - if debugConnection { - clientConnectionStatesMu.Lock() - clientConnectionStates[getConnKey(c)] = cState - clientConnectionStatesMu.Unlock() - } - return context.WithValue(ctx, connStateKey, cState) - } - - if debugConnection { - serverHTTP.ConnState = func(c net.Conn, state http.ConnState) { - clientConnectionStatesMu.Lock() - if clientConnectionStates[getConnKey(c)] != nil { - clientConnectionStates[getConnKey(c)].State = state.String() - } - clientConnectionStatesMu.Unlock() - } - } - } - - prevConnContext := serverHTTP.ConnContext - serverHTTP.ConnContext = func(ctx context.Context, c net.Conn) context.Context { - // This adds an empty struct in order to store a RoundTripper in the ConnContext in case of Kerberos or NTLM. - ctx = service.AddTransportOnContext(ctx) - if prevConnContext != nil { - return prevConnContext(ctx, c) - } - return ctx + ConnContext: connContext.Build(), + ConnState: connState, } listener := newHTTPForwarder(ln) From ba8830fdef9ea6e9f0497b06128b36cf5d4a2760 Mon Sep 17 00:00:00 2001 From: Romain Date: Fri, 5 Jun 2026 14:48:04 +0200 Subject: [PATCH 4/4] Prepare release v2.11.49 --- CHANGELOG.md | 8 ++++++++ script/gcg/traefik-bugfix.toml | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 335030a399..b3b6e5402b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [v2.11.49](https://github.com/traefik/traefik/tree/v2.11.49) (2026-06-05) +[All Commits](https://github.com/traefik/traefik/compare/v2.11.48...v2.11.49) + +**Bug fixes:** +- **[http3]** Bump github.com/quic-go/quic-go to v0.59.1 ([#13300](https://github.com/traefik/traefik/pull/13300) @rtribotte) +- **[webui]** Bump axios to v1.17.0 ([#13299](https://github.com/traefik/traefik/pull/13299) @gndz07) +- **[tls]** Fix snicheck with keepalive ([#13305](https://github.com/traefik/traefik/pull/13305) @juliens) + ## [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) diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index 6f161f1556..4bc6c9e476 100644 --- a/script/gcg/traefik-bugfix.toml +++ b/script/gcg/traefik-bugfix.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example new bugfix v2.11.48 +# example new bugfix v2.11.49 CurrentRef = "v2.11" -PreviousRef = "v2.11.47" +PreviousRef = "v2.11.48" BaseBranch = "v2.11" -FutureCurrentRefName = "v2.11.48" +FutureCurrentRefName = "v2.11.49" ThresholdPreviousRef = 10000 ThresholdCurrentRef = 10000