1
0
Fork 0

feat: re introduce IpWhitelist middleware as deprecated

This commit is contained in:
Michael 2024-01-11 10:40:06 +01:00 committed by GitHub
parent 3bbc560283
commit ff7966f9cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 1314 additions and 200 deletions

View file

@ -12,12 +12,14 @@ import (
// Middleware holds the Middleware configuration.
type Middleware struct {
AddPrefix *AddPrefix `json:"addPrefix,omitempty" toml:"addPrefix,omitempty" yaml:"addPrefix,omitempty" export:"true"`
StripPrefix *StripPrefix `json:"stripPrefix,omitempty" toml:"stripPrefix,omitempty" yaml:"stripPrefix,omitempty" export:"true"`
StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty" toml:"stripPrefixRegex,omitempty" yaml:"stripPrefixRegex,omitempty" export:"true"`
ReplacePath *ReplacePath `json:"replacePath,omitempty" toml:"replacePath,omitempty" yaml:"replacePath,omitempty" export:"true"`
ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" toml:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty" export:"true"`
Chain *Chain `json:"chain,omitempty" toml:"chain,omitempty" yaml:"chain,omitempty" export:"true"`
AddPrefix *AddPrefix `json:"addPrefix,omitempty" toml:"addPrefix,omitempty" yaml:"addPrefix,omitempty" export:"true"`
StripPrefix *StripPrefix `json:"stripPrefix,omitempty" toml:"stripPrefix,omitempty" yaml:"stripPrefix,omitempty" export:"true"`
StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty" toml:"stripPrefixRegex,omitempty" yaml:"stripPrefixRegex,omitempty" export:"true"`
ReplacePath *ReplacePath `json:"replacePath,omitempty" toml:"replacePath,omitempty" yaml:"replacePath,omitempty" export:"true"`
ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" toml:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty" export:"true"`
Chain *Chain `json:"chain,omitempty" toml:"chain,omitempty" yaml:"chain,omitempty" export:"true"`
// Deprecated: please use IPAllowList instead.
IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty" export:"true"`
IPAllowList *IPAllowList `json:"ipAllowList,omitempty" toml:"ipAllowList,omitempty" yaml:"ipAllowList,omitempty" export:"true"`
Headers *Headers `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"`
Errors *ErrorPage `json:"errors,omitempty" toml:"errors,omitempty" yaml:"errors,omitempty" export:"true"`
@ -376,6 +378,18 @@ func (s *IPStrategy) Get() (ip.Strategy, error) {
// +k8s:deepcopy-gen=true
// IPWhiteList holds the IP whitelist middleware configuration.
// This middleware accepts / refuses requests based on the client IP.
// More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipwhitelist/
// Deprecated: please use IPAllowList instead.
type IPWhiteList struct {
// SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation).
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
}
// +k8s:deepcopy-gen=true
// IPAllowList holds the IP allowlist middleware configuration.
// This middleware accepts / refuses requests based on the client IP.
// More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/

View file

@ -5,7 +5,9 @@ package dynamic
// TCPMiddleware holds the TCPMiddleware configuration.
type TCPMiddleware struct {
InFlightConn *TCPInFlightConn `json:"inFlightConn,omitempty" toml:"inFlightConn,omitempty" yaml:"inFlightConn,omitempty" export:"true"`
IPAllowList *TCPIPAllowList `json:"ipAllowList,omitempty" toml:"ipAllowList,omitempty" yaml:"ipAllowList,omitempty" export:"true"`
// Deprecated: please use IPAllowList instead.
IPWhiteList *TCPIPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty" export:"true"`
IPAllowList *TCPIPAllowList `json:"ipAllowList,omitempty" toml:"ipAllowList,omitempty" yaml:"ipAllowList,omitempty" export:"true"`
}
// +k8s:deepcopy-gen=true
@ -22,6 +24,15 @@ type TCPInFlightConn struct {
// +k8s:deepcopy-gen=true
// TCPIPWhiteList holds the TCP IPWhiteList middleware configuration.
// Deprecated: please use IPAllowList instead.
type TCPIPWhiteList struct {
// SourceRange defines the allowed IPs (or ranges of allowed IPs by using CIDR notation).
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
}
// +k8s:deepcopy-gen=true
// TCPIPAllowList holds the TCP IPAllowList middleware configuration.
type TCPIPAllowList struct {
// SourceRange defines the allowed IPs (or ranges of allowed IPs by using CIDR notation).

View file

@ -600,6 +600,32 @@ func (in *IPStrategy) DeepCopy() *IPStrategy {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IPWhiteList) DeepCopyInto(out *IPWhiteList) {
*out = *in
if in.SourceRange != nil {
in, out := &in.SourceRange, &out.SourceRange
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.IPStrategy != nil {
in, out := &in.IPStrategy, &out.IPStrategy
*out = new(IPStrategy)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPWhiteList.
func (in *IPWhiteList) DeepCopy() *IPWhiteList {
if in == nil {
return nil
}
out := new(IPWhiteList)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InFlightReq) DeepCopyInto(out *InFlightReq) {
*out = *in
@ -675,6 +701,11 @@ func (in *Middleware) DeepCopyInto(out *Middleware) {
*out = new(Chain)
(*in).DeepCopyInto(*out)
}
if in.IPWhiteList != nil {
in, out := &in.IPWhiteList, &out.IPWhiteList
*out = new(IPWhiteList)
(*in).DeepCopyInto(*out)
}
if in.IPAllowList != nil {
in, out := &in.IPAllowList, &out.IPAllowList
*out = new(IPAllowList)
@ -1443,6 +1474,27 @@ func (in *TCPIPAllowList) DeepCopy() *TCPIPAllowList {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TCPIPWhiteList) DeepCopyInto(out *TCPIPWhiteList) {
*out = *in
if in.SourceRange != nil {
in, out := &in.SourceRange, &out.SourceRange
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPIPWhiteList.
func (in *TCPIPWhiteList) DeepCopy() *TCPIPWhiteList {
if in == nil {
return nil
}
out := new(TCPIPWhiteList)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TCPInFlightConn) DeepCopyInto(out *TCPInFlightConn) {
*out = *in
@ -1467,6 +1519,11 @@ func (in *TCPMiddleware) DeepCopyInto(out *TCPMiddleware) {
*out = new(TCPInFlightConn)
**out = **in
}
if in.IPWhiteList != nil {
in, out := &in.IPWhiteList, &out.IPWhiteList
*out = new(TCPIPWhiteList)
(*in).DeepCopyInto(*out)
}
if in.IPAllowList != nil {
in, out := &in.IPAllowList, &out.IPAllowList
*out = new(TCPIPAllowList)

View file

@ -0,0 +1,88 @@
package ipwhitelist
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/rs/zerolog/log"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/ip"
"github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/tracing"
"go.opentelemetry.io/otel/trace"
)
const (
typeName = "IPWhiteLister"
)
// ipWhiteLister is a middleware that provides Checks of the Requesting IP against a set of Whitelists.
type ipWhiteLister struct {
next http.Handler
whiteLister *ip.Checker
strategy ip.Strategy
name string
}
// New builds a new IPWhiteLister given a list of CIDR-Strings to whitelist.
func New(ctx context.Context, next http.Handler, config dynamic.IPWhiteList, name string) (http.Handler, error) {
logger := middlewares.GetLogger(ctx, name, typeName)
logger.Debug().Msg("Creating middleware")
if len(config.SourceRange) == 0 {
return nil, errors.New("sourceRange is empty, IPWhiteLister not created")
}
checker, err := ip.NewChecker(config.SourceRange)
if err != nil {
return nil, fmt.Errorf("cannot parse CIDR whitelist %s: %w", config.SourceRange, err)
}
strategy, err := config.IPStrategy.Get()
if err != nil {
return nil, err
}
logger.Debug().Msgf("Setting up IPWhiteLister with sourceRange: %s", config.SourceRange)
return &ipWhiteLister{
strategy: strategy,
whiteLister: checker,
next: next,
name: name,
}, nil
}
func (wl *ipWhiteLister) GetTracingInformation() (string, string, trace.SpanKind) {
return wl.name, typeName, trace.SpanKindInternal
}
func (wl *ipWhiteLister) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
logger := middlewares.GetLogger(req.Context(), wl.name, typeName)
ctx := logger.WithContext(req.Context())
clientIP := wl.strategy.GetIP(req)
err := wl.whiteLister.IsAuthorized(clientIP)
if err != nil {
msg := fmt.Sprintf("Rejecting IP %s: %v", clientIP, err)
logger.Debug().Msg(msg)
tracing.SetStatusErrorf(req.Context(), msg)
reject(ctx, rw)
return
}
logger.Debug().Msgf("Accepting IP %s", clientIP)
wl.next.ServeHTTP(rw, req)
}
func reject(ctx context.Context, rw http.ResponseWriter) {
statusCode := http.StatusForbidden
rw.WriteHeader(statusCode)
_, err := rw.Write([]byte(http.StatusText(statusCode)))
if err != nil {
log.Ctx(ctx).Error().Err(err).Send()
}
}

View file

@ -0,0 +1,100 @@
package ipwhitelist
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
)
func TestNewIPWhiteLister(t *testing.T) {
testCases := []struct {
desc string
whiteList dynamic.IPWhiteList
expectedError bool
}{
{
desc: "invalid IP",
whiteList: dynamic.IPWhiteList{
SourceRange: []string{"foo"},
},
expectedError: true,
},
{
desc: "valid IP",
whiteList: dynamic.IPWhiteList{
SourceRange: []string{"10.10.10.10"},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
whiteLister, err := New(context.Background(), next, test.whiteList, "traefikTest")
if test.expectedError {
assert.Error(t, err)
} else {
require.NoError(t, err)
assert.NotNil(t, whiteLister)
}
})
}
}
func TestIPWhiteLister_ServeHTTP(t *testing.T) {
testCases := []struct {
desc string
whiteList dynamic.IPWhiteList
remoteAddr string
expected int
}{
{
desc: "authorized with remote address",
whiteList: dynamic.IPWhiteList{
SourceRange: []string{"20.20.20.20"},
},
remoteAddr: "20.20.20.20:1234",
expected: 200,
},
{
desc: "non authorized with remote address",
whiteList: dynamic.IPWhiteList{
SourceRange: []string{"20.20.20.20"},
},
remoteAddr: "20.20.20.21:1234",
expected: 403,
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
whiteLister, err := New(context.Background(), next, test.whiteList, "traefikTest")
require.NoError(t, err)
recorder := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "http://10.10.10.10", nil)
if len(test.remoteAddr) > 0 {
req.RemoteAddr = test.remoteAddr
}
whiteLister.ServeHTTP(recorder, req)
assert.Equal(t, test.expected, recorder.Code)
})
}
}

View file

@ -0,0 +1,63 @@
package ipwhitelist
import (
"context"
"errors"
"fmt"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/ip"
"github.com/traefik/traefik/v3/pkg/middlewares"
"github.com/traefik/traefik/v3/pkg/tcp"
)
const (
typeName = "IPWhiteListerTCP"
)
// ipWhiteLister is a middleware that provides Checks of the Requesting IP against a set of Whitelists.
type ipWhiteLister struct {
next tcp.Handler
whiteLister *ip.Checker
name string
}
// New builds a new TCP IPWhiteLister given a list of CIDR-Strings to whitelist.
func New(ctx context.Context, next tcp.Handler, config dynamic.TCPIPWhiteList, name string) (tcp.Handler, error) {
logger := middlewares.GetLogger(ctx, name, typeName)
logger.Debug().Msg("Creating middleware")
if len(config.SourceRange) == 0 {
return nil, errors.New("sourceRange is empty, IPWhiteLister not created")
}
checker, err := ip.NewChecker(config.SourceRange)
if err != nil {
return nil, fmt.Errorf("cannot parse CIDR whitelist %s: %w", config.SourceRange, err)
}
logger.Debug().Msgf("Setting up IPWhiteLister with sourceRange: %s", config.SourceRange)
return &ipWhiteLister{
whiteLister: checker,
next: next,
name: name,
}, nil
}
func (wl *ipWhiteLister) ServeTCP(conn tcp.WriteCloser) {
logger := middlewares.GetLogger(context.Background(), wl.name, typeName)
addr := conn.RemoteAddr().String()
err := wl.whiteLister.IsAuthorized(addr)
if err != nil {
logger.Error().Err(err).Msgf("Connection from %s rejected", addr)
conn.Close()
return
}
logger.Debug().Msgf("Connection from %s accepted", addr)
wl.next.ServeTCP(conn)
}

View file

@ -0,0 +1,139 @@
package ipwhitelist
import (
"context"
"io"
"net"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/tcp"
)
func TestNewIPWhiteLister(t *testing.T) {
testCases := []struct {
desc string
whiteList dynamic.TCPIPWhiteList
expectedError bool
}{
{
desc: "Empty config",
whiteList: dynamic.TCPIPWhiteList{},
expectedError: true,
},
{
desc: "invalid IP",
whiteList: dynamic.TCPIPWhiteList{
SourceRange: []string{"foo"},
},
expectedError: true,
},
{
desc: "valid IP",
whiteList: dynamic.TCPIPWhiteList{
SourceRange: []string{"10.10.10.10"},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
next := tcp.HandlerFunc(func(conn tcp.WriteCloser) {})
whiteLister, err := New(context.Background(), next, test.whiteList, "traefikTest")
if test.expectedError {
assert.Error(t, err)
} else {
require.NoError(t, err)
assert.NotNil(t, whiteLister)
}
})
}
}
func TestIPWhiteLister_ServeHTTP(t *testing.T) {
testCases := []struct {
desc string
whiteList dynamic.TCPIPWhiteList
remoteAddr string
expected string
}{
{
desc: "authorized with remote address",
whiteList: dynamic.TCPIPWhiteList{
SourceRange: []string{"20.20.20.20"},
},
remoteAddr: "20.20.20.20:1234",
expected: "OK",
},
{
desc: "non authorized with remote address",
whiteList: dynamic.TCPIPWhiteList{
SourceRange: []string{"20.20.20.20"},
},
remoteAddr: "20.20.20.21:1234",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
next := tcp.HandlerFunc(func(conn tcp.WriteCloser) {
write, err := conn.Write([]byte("OK"))
require.NoError(t, err)
assert.Equal(t, 2, write)
err = conn.Close()
require.NoError(t, err)
})
whiteLister, err := New(context.Background(), next, test.whiteList, "traefikTest")
require.NoError(t, err)
server, client := net.Pipe()
go func() {
whiteLister.ServeTCP(&contextWriteCloser{client, addr{test.remoteAddr}})
}()
read, err := io.ReadAll(server)
require.NoError(t, err)
assert.Equal(t, test.expected, string(read))
})
}
}
type contextWriteCloser struct {
net.Conn
addr
}
type addr struct {
remoteAddr string
}
func (a addr) Network() string {
panic("implement me")
}
func (a addr) String() string {
return a.remoteAddr
}
func (c contextWriteCloser) CloseWrite() error {
panic("implement me")
}
func (c contextWriteCloser) RemoteAddr() net.Addr { return c.addr }
func (c contextWriteCloser) Context() context.Context {
return context.Background()
}

View file

@ -288,6 +288,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
ReplacePath: middleware.Spec.ReplacePath,
ReplacePathRegex: middleware.Spec.ReplacePathRegex,
Chain: createChainMiddleware(ctxMid, middleware.Namespace, middleware.Spec.Chain),
IPWhiteList: middleware.Spec.IPWhiteList,
IPAllowList: middleware.Spec.IPAllowList,
Headers: middleware.Spec.Headers,
Errors: errorPage,
@ -314,6 +315,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
conf.TCP.Middlewares[id] = &dynamic.TCPMiddleware{
InFlightConn: middlewareTCP.Spec.InFlightConn,
IPWhiteList: middlewareTCP.Spec.IPWhiteList,
IPAllowList: middlewareTCP.Spec.IPAllowList,
}
}

View file

@ -26,12 +26,14 @@ type Middleware struct {
// MiddlewareSpec defines the desired state of a Middleware.
type MiddlewareSpec struct {
AddPrefix *dynamic.AddPrefix `json:"addPrefix,omitempty"`
StripPrefix *dynamic.StripPrefix `json:"stripPrefix,omitempty"`
StripPrefixRegex *dynamic.StripPrefixRegex `json:"stripPrefixRegex,omitempty"`
ReplacePath *dynamic.ReplacePath `json:"replacePath,omitempty"`
ReplacePathRegex *dynamic.ReplacePathRegex `json:"replacePathRegex,omitempty"`
Chain *Chain `json:"chain,omitempty"`
AddPrefix *dynamic.AddPrefix `json:"addPrefix,omitempty"`
StripPrefix *dynamic.StripPrefix `json:"stripPrefix,omitempty"`
StripPrefixRegex *dynamic.StripPrefixRegex `json:"stripPrefixRegex,omitempty"`
ReplacePath *dynamic.ReplacePath `json:"replacePath,omitempty"`
ReplacePathRegex *dynamic.ReplacePathRegex `json:"replacePathRegex,omitempty"`
Chain *Chain `json:"chain,omitempty"`
// Deprecated: please use IPAllowList instead.
IPWhiteList *dynamic.IPWhiteList `json:"ipWhiteList,omitempty"`
IPAllowList *dynamic.IPAllowList `json:"ipAllowList,omitempty"`
Headers *dynamic.Headers `json:"headers,omitempty"`
Errors *ErrorPage `json:"errors,omitempty"`

View file

@ -25,6 +25,9 @@ type MiddlewareTCP struct {
type MiddlewareTCPSpec struct {
// InFlightConn defines the InFlightConn middleware configuration.
InFlightConn *dynamic.TCPInFlightConn `json:"inFlightConn,omitempty"`
// IPWhiteList defines the IPWhiteList middleware configuration.
// Deprecated: please use IPAllowList instead.
IPWhiteList *dynamic.TCPIPWhiteList `json:"ipWhiteList,omitempty"`
// IPAllowList defines the IPAllowList middleware configuration.
IPAllowList *dynamic.TCPIPAllowList `json:"ipAllowList,omitempty"`
}

View file

@ -689,6 +689,11 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) {
*out = new(Chain)
(*in).DeepCopyInto(*out)
}
if in.IPWhiteList != nil {
in, out := &in.IPWhiteList, &out.IPWhiteList
*out = new(dynamic.IPWhiteList)
(*in).DeepCopyInto(*out)
}
if in.IPAllowList != nil {
in, out := &in.IPAllowList, &out.IPAllowList
*out = new(dynamic.IPAllowList)
@ -862,6 +867,11 @@ func (in *MiddlewareTCPSpec) DeepCopyInto(out *MiddlewareTCPSpec) {
*out = new(dynamic.TCPInFlightConn)
**out = **in
}
if in.IPWhiteList != nil {
in, out := &in.IPWhiteList, &out.IPWhiteList
*out = new(dynamic.TCPIPWhiteList)
(*in).DeepCopyInto(*out)
}
if in.IPAllowList != nil {
in, out := &in.IPAllowList, &out.IPAllowList
*out = new(dynamic.TCPIPAllowList)

View file

@ -9,6 +9,7 @@ import (
"strings"
"github.com/containous/alice"
"github.com/rs/zerolog/log"
"github.com/traefik/traefik/v3/pkg/config/runtime"
"github.com/traefik/traefik/v3/pkg/middlewares/addprefix"
"github.com/traefik/traefik/v3/pkg/middlewares/auth"
@ -22,6 +23,7 @@ import (
"github.com/traefik/traefik/v3/pkg/middlewares/headers"
"github.com/traefik/traefik/v3/pkg/middlewares/inflightreq"
"github.com/traefik/traefik/v3/pkg/middlewares/ipallowlist"
"github.com/traefik/traefik/v3/pkg/middlewares/ipwhitelist"
"github.com/traefik/traefik/v3/pkg/middlewares/passtlsclientcert"
"github.com/traefik/traefik/v3/pkg/middlewares/ratelimiter"
"github.com/traefik/traefik/v3/pkg/middlewares/redirect"
@ -236,6 +238,18 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) (
}
}
// IPWhiteList
if config.IPWhiteList != nil {
log.Warn().Msg("IPWhiteList is deprecated, please use IPAllowList instead.")
if middleware != nil {
return nil, badConf
}
middleware = func(next http.Handler) (http.Handler, error) {
return ipwhitelist.New(ctx, next, *config.IPWhiteList, middlewareName)
}
}
// IPAllowList
if config.IPAllowList != nil {
if middleware != nil {

View file

@ -5,9 +5,11 @@ import (
"fmt"
"strings"
"github.com/rs/zerolog/log"
"github.com/traefik/traefik/v3/pkg/config/runtime"
"github.com/traefik/traefik/v3/pkg/middlewares/tcp/inflightconn"
"github.com/traefik/traefik/v3/pkg/middlewares/tcp/ipallowlist"
"github.com/traefik/traefik/v3/pkg/middlewares/tcp/ipwhitelist"
"github.com/traefik/traefik/v3/pkg/server/provider"
"github.com/traefik/traefik/v3/pkg/tcp"
)
@ -94,6 +96,15 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) (
}
}
// IPWhiteList
if config.IPWhiteList != nil {
log.Warn().Msg("IPWhiteList is deprecated, please use IPAllowList instead.")
middleware = func(next tcp.Handler) (tcp.Handler, error) {
return ipwhitelist.New(ctx, next, *config.IPWhiteList, middlewareName)
}
}
// IPAllowList
if config.IPAllowList != nil {
middleware = func(next tcp.Handler) (tcp.Handler, error) {