traefik/pkg/middlewares/tcp/ipwhitelist/ip_whitelist.go
2021-06-11 15:30:05 +02:00

65 lines
1.7 KiB
Go

package tcpipwhitelist
import (
"context"
"errors"
"fmt"
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/ip"
"github.com/traefik/traefik/v2/pkg/log"
"github.com/traefik/traefik/v2/pkg/middlewares"
"github.com/traefik/traefik/v2/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 := log.FromContext(middlewares.GetLoggerCtx(ctx, name, typeName))
logger.Debug("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.Debugf("Setting up IPWhiteLister with sourceRange: %s", config.SourceRange)
return &ipWhiteLister{
whiteLister: checker,
next: next,
name: name,
}, nil
}
func (wl *ipWhiteLister) ServeTCP(conn tcp.WriteCloser) {
ctx := middlewares.GetLoggerCtx(context.Background(), wl.name, typeName)
logger := log.FromContext(ctx)
addr := conn.RemoteAddr().String()
err := wl.whiteLister.IsAuthorized(addr)
if err != nil {
logger.Errorf("Connection from %s rejected: %v", addr, err)
conn.Close()
return
}
logger.Debugf("Connection from %s accepted", addr)
wl.next.ServeTCP(conn)
}