Merge branch v2.11 into v3.0
This commit is contained in:
commit
8d016f5e16
12 changed files with 180 additions and 39 deletions
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -91,10 +92,11 @@ func (ip *Checker) ContainsIP(addr net.IP) bool {
|
|||
}
|
||||
|
||||
func parseIP(addr string) (net.IP, error) {
|
||||
userIP := net.ParseIP(addr)
|
||||
if userIP == nil {
|
||||
parsedAddr, err := netip.ParseAddr(addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't parse IP from address %s", addr)
|
||||
}
|
||||
|
||||
return userIP, nil
|
||||
ip := parsedAddr.As16()
|
||||
return ip[:], nil
|
||||
}
|
||||
|
|
|
@ -258,6 +258,7 @@ func TestContainsIsAllowed(t *testing.T) {
|
|||
"2a03:4000:6:d080::42",
|
||||
"fe80::1",
|
||||
"fe80:aa00:00bb:4232:ff00:eeee:00ff:1111",
|
||||
"fe80:aa00:00bb:4232:ff00:eeee:00ff:1111%vEthernet",
|
||||
"fe80::fe80",
|
||||
"1.2.3.1",
|
||||
"1.2.3.32",
|
||||
|
@ -271,6 +272,7 @@ func TestContainsIsAllowed(t *testing.T) {
|
|||
rejectIPs: []string{
|
||||
"2a03:4000:7:d080::",
|
||||
"2a03:4000:7:d080::1",
|
||||
"2a03:4000:7:d080::1%vmnet1",
|
||||
"4242::1",
|
||||
"1.2.16.1",
|
||||
"1.2.32.1",
|
||||
|
|
|
@ -3,18 +3,21 @@ package ecs
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/aws/aws-sdk-go/service/ssm"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/patrickmn/go-cache"
|
||||
"github.com/rs/zerolog"
|
||||
|
@ -119,20 +122,24 @@ func (p *Provider) createClient(logger zerolog.Logger) (*awsClient, error) {
|
|||
p.Region = identity.Region
|
||||
}
|
||||
|
||||
cfg := &aws.Config{
|
||||
Credentials: credentials.NewChainCredentials(
|
||||
[]credentials.Provider{
|
||||
&credentials.StaticProvider{
|
||||
Value: credentials.Value{
|
||||
AccessKeyID: p.AccessKeyID,
|
||||
SecretAccessKey: p.SecretAccessKey,
|
||||
},
|
||||
cfg := aws.NewConfig().
|
||||
WithCredentials(credentials.NewChainCredentials([]credentials.Provider{
|
||||
&credentials.StaticProvider{
|
||||
Value: credentials.Value{
|
||||
AccessKeyID: p.AccessKeyID,
|
||||
SecretAccessKey: p.SecretAccessKey,
|
||||
},
|
||||
&credentials.EnvProvider{},
|
||||
&credentials.SharedCredentialsProvider{},
|
||||
defaults.RemoteCredProvider(*(defaults.Config()), defaults.Handlers()),
|
||||
}),
|
||||
}
|
||||
},
|
||||
&credentials.EnvProvider{},
|
||||
&credentials.SharedCredentialsProvider{},
|
||||
defaults.RemoteCredProvider(*(defaults.Config()), defaults.Handlers()),
|
||||
stscreds.NewWebIdentityRoleProviderWithOptions(
|
||||
sts.New(sess),
|
||||
os.Getenv("AWS_ROLE_ARN"),
|
||||
"",
|
||||
stscreds.FetchTokenPath(os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE")),
|
||||
),
|
||||
}))
|
||||
|
||||
// Set the region if it is defined by the user or resolved from the EC2 metadata.
|
||||
if p.Region != "" {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
"github.com/quic-go/quic-go/http3"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/traefik/traefik/v3/pkg/config/static"
|
||||
|
@ -51,12 +52,15 @@ func newHTTP3Server(ctx context.Context, configuration *static.EntryPoint, https
|
|||
Port: configuration.HTTP3.AdvertisedPort,
|
||||
Handler: httpsServer.Server.(*http.Server).Handler,
|
||||
TLSConfig: &tls.Config{GetConfigForClient: h3.getGetConfigForClient},
|
||||
QUICConfig: &quic.Config{
|
||||
Allow0RTT: false,
|
||||
},
|
||||
}
|
||||
|
||||
previousHandler := httpsServer.Server.(*http.Server).Handler
|
||||
|
||||
httpsServer.Server.(*http.Server).Handler = http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
if err := h3.Server.SetQuicHeaders(rw.Header()); err != nil {
|
||||
if err := h3.Server.SetQUICHeaders(rw.Header()); err != nil {
|
||||
log.Ctx(ctx).Error().Err(err).Msg("Failed to set HTTP3 headers")
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,12 @@ import (
|
|||
"bufio"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/traefik/traefik/v3/pkg/config/static"
|
||||
|
@ -86,7 +88,7 @@ func TestHTTP3AdvertisedPort(t *testing.T) {
|
|||
epConfig.SetDefaults()
|
||||
|
||||
entryPoint, err := NewTCPEntryPoint(context.Background(), &static.EntryPoint{
|
||||
Address: "127.0.0.1:8090",
|
||||
Address: "127.0.0.1:0",
|
||||
Transport: epConfig,
|
||||
ForwardedHeaders: &static.ForwardedHeaders{},
|
||||
HTTP2: &static.HTTP2Config{},
|
||||
|
@ -106,14 +108,20 @@ func TestHTTP3AdvertisedPort(t *testing.T) {
|
|||
rw.WriteHeader(http.StatusOK)
|
||||
}), nil)
|
||||
|
||||
go entryPoint.Start(context.Background())
|
||||
ctx := context.Background()
|
||||
go entryPoint.Start(ctx)
|
||||
entryPoint.SwitchRouter(router)
|
||||
|
||||
conn, err := tls.Dial("tcp", "127.0.0.1:8090", &tls.Config{
|
||||
conn, err := tls.Dial("tcp", entryPoint.listener.Addr().String(), &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = conn.Close()
|
||||
entryPoint.Shutdown(ctx)
|
||||
})
|
||||
|
||||
// We are racing with the http3Server readiness happening in the goroutine starting the entrypoint
|
||||
time.Sleep(time.Second)
|
||||
|
||||
|
@ -129,3 +137,109 @@ func TestHTTP3AdvertisedPort(t *testing.T) {
|
|||
assert.NotContains(t, r.Header.Get("Alt-Svc"), ":8090")
|
||||
assert.Contains(t, r.Header.Get("Alt-Svc"), ":8080")
|
||||
}
|
||||
|
||||
func TestHTTP30RTT(t *testing.T) {
|
||||
certContent, err := localhostCert.Read()
|
||||
require.NoError(t, err)
|
||||
|
||||
keyContent, err := localhostKey.Read()
|
||||
require.NoError(t, err)
|
||||
|
||||
tlsCert, err := tls.X509KeyPair(certContent, keyContent)
|
||||
require.NoError(t, err)
|
||||
|
||||
epConfig := &static.EntryPointsTransport{}
|
||||
epConfig.SetDefaults()
|
||||
|
||||
entryPoint, err := NewTCPEntryPoint(context.Background(), &static.EntryPoint{
|
||||
Address: "127.0.0.1:8090",
|
||||
Transport: epConfig,
|
||||
ForwardedHeaders: &static.ForwardedHeaders{},
|
||||
HTTP2: &static.HTTP2Config{},
|
||||
HTTP3: &static.HTTP3Config{},
|
||||
}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
router, err := tcprouter.NewRouter()
|
||||
require.NoError(t, err)
|
||||
|
||||
router.AddHTTPTLSConfig("example.com", &tls.Config{
|
||||
Certificates: []tls.Certificate{tlsCert},
|
||||
})
|
||||
router.SetHTTPSHandler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), nil)
|
||||
|
||||
ctx := context.Background()
|
||||
go entryPoint.Start(ctx)
|
||||
entryPoint.SwitchRouter(router)
|
||||
|
||||
// We are racing with the http3Server readiness happening in the goroutine starting the entrypoint.
|
||||
time.Sleep(time.Second)
|
||||
|
||||
certPool := x509.NewCertPool()
|
||||
certPool.AppendCertsFromPEM(certContent)
|
||||
|
||||
tlsConf := &tls.Config{
|
||||
RootCAs: certPool,
|
||||
ServerName: "example.com",
|
||||
NextProtos: []string{"h3"},
|
||||
}
|
||||
|
||||
// Define custom cache.
|
||||
gets := make(chan string, 100)
|
||||
puts := make(chan string, 100)
|
||||
cache := newClientSessionCache(tls.NewLRUClientSessionCache(10), gets, puts)
|
||||
tlsConf.ClientSessionCache = cache
|
||||
|
||||
// This first DialAddrEarly connection is here to populate the cache.
|
||||
earlyConnection, err := quic.DialAddrEarly(context.Background(), "127.0.0.1:8090", tlsConf, &quic.Config{})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = earlyConnection.CloseWithError(0, "")
|
||||
entryPoint.Shutdown(ctx)
|
||||
})
|
||||
|
||||
// wait for the handshake complete.
|
||||
<-earlyConnection.HandshakeComplete()
|
||||
|
||||
// 0RTT is always false on the first connection.
|
||||
require.False(t, earlyConnection.ConnectionState().Used0RTT)
|
||||
|
||||
earlyConnection, err = quic.DialAddrEarly(context.Background(), "127.0.0.1:8090", tlsConf, &quic.Config{})
|
||||
require.NoError(t, err)
|
||||
|
||||
<-earlyConnection.HandshakeComplete()
|
||||
|
||||
// 0RTT need to be false.
|
||||
assert.False(t, earlyConnection.ConnectionState().Used0RTT)
|
||||
}
|
||||
|
||||
type clientSessionCache struct {
|
||||
cache tls.ClientSessionCache
|
||||
|
||||
gets chan<- string
|
||||
puts chan<- string
|
||||
}
|
||||
|
||||
func newClientSessionCache(cache tls.ClientSessionCache, gets, puts chan<- string) *clientSessionCache {
|
||||
return &clientSessionCache{
|
||||
cache: cache,
|
||||
gets: gets,
|
||||
puts: puts,
|
||||
}
|
||||
}
|
||||
|
||||
var _ tls.ClientSessionCache = &clientSessionCache{}
|
||||
|
||||
func (c *clientSessionCache) Get(sessionKey string) (*tls.ClientSessionState, bool) {
|
||||
session, ok := c.cache.Get(sessionKey)
|
||||
c.gets <- sessionKey
|
||||
return session, ok
|
||||
}
|
||||
|
||||
func (c *clientSessionCache) Put(sessionKey string, cs *tls.ClientSessionState) {
|
||||
c.cache.Put(sessionKey, cs)
|
||||
c.puts <- sessionKey
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue