IPStrategy for selecting IP in whitelist
This commit is contained in:
parent
1ec4e03738
commit
00728e711c
65 changed files with 2444 additions and 1837 deletions
|
@ -108,7 +108,7 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
|
|||
if len(gc.EntryPoints) == 0 {
|
||||
gc.EntryPoints = map[string]*EntryPoint{"http": {
|
||||
Address: ":80",
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
|
||||
ForwardedHeaders: &ForwardedHeaders{},
|
||||
}}
|
||||
gc.DefaultEntryPoints = []string{"http"}
|
||||
}
|
||||
|
@ -126,18 +126,7 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
|
|||
entryPoint := gc.EntryPoints[entryPointName]
|
||||
// ForwardedHeaders must be remove in the next breaking version
|
||||
if entryPoint.ForwardedHeaders == nil {
|
||||
entryPoint.ForwardedHeaders = &ForwardedHeaders{Insecure: true}
|
||||
}
|
||||
|
||||
if len(entryPoint.WhitelistSourceRange) > 0 {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", "whiteListSourceRange", "whiteList.sourceRange")
|
||||
|
||||
if entryPoint.WhiteList == nil {
|
||||
entryPoint.WhiteList = &types.WhiteList{
|
||||
SourceRange: entryPoint.WhitelistSourceRange,
|
||||
}
|
||||
entryPoint.WhitelistSourceRange = nil
|
||||
}
|
||||
entryPoint.ForwardedHeaders = &ForwardedHeaders{}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package configuration
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containous/traefik/log"
|
||||
|
@ -11,20 +12,19 @@ import (
|
|||
|
||||
// EntryPoint holds an entry point configuration of the reverse proxy (ip, port, TLS...)
|
||||
type EntryPoint struct {
|
||||
Address string
|
||||
TLS *tls.TLS `export:"true"`
|
||||
Redirect *types.Redirect `export:"true"`
|
||||
Auth *types.Auth `export:"true"`
|
||||
WhitelistSourceRange []string // Deprecated
|
||||
WhiteList *types.WhiteList `export:"true"`
|
||||
Compress *Compress `export:"true"`
|
||||
ProxyProtocol *ProxyProtocol `export:"true"`
|
||||
ForwardedHeaders *ForwardedHeaders `export:"true"`
|
||||
Address string
|
||||
TLS *tls.TLS `export:"true"`
|
||||
Redirect *types.Redirect `export:"true"`
|
||||
Auth *types.Auth `export:"true"`
|
||||
WhiteList *types.WhiteList `export:"true"`
|
||||
Compress *Compress `export:"true"`
|
||||
ProxyProtocol *ProxyProtocol `export:"true"`
|
||||
ForwardedHeaders *ForwardedHeaders `export:"true"`
|
||||
ClientIPStrategy *types.IPStrategy `export:"true"`
|
||||
}
|
||||
|
||||
// Compress contains compress configuration
|
||||
type Compress struct {
|
||||
}
|
||||
type Compress struct{}
|
||||
|
||||
// ProxyProtocol contains Proxy-Protocol configuration
|
||||
type ProxyProtocol struct {
|
||||
|
@ -68,11 +68,6 @@ func (ep *EntryPoints) Type() string {
|
|||
func (ep *EntryPoints) Set(value string) error {
|
||||
result := parseEntryPointsConfiguration(value)
|
||||
|
||||
var whiteListSourceRange []string
|
||||
if len(result["whitelistsourcerange"]) > 0 {
|
||||
whiteListSourceRange = strings.Split(result["whitelistsourcerange"], ",")
|
||||
}
|
||||
|
||||
var compress *Compress
|
||||
if len(result["compress"]) > 0 {
|
||||
compress = &Compress{}
|
||||
|
@ -84,29 +79,42 @@ func (ep *EntryPoints) Set(value string) error {
|
|||
}
|
||||
|
||||
(*ep)[result["name"]] = &EntryPoint{
|
||||
Address: result["address"],
|
||||
TLS: configTLS,
|
||||
Auth: makeEntryPointAuth(result),
|
||||
Redirect: makeEntryPointRedirect(result),
|
||||
Compress: compress,
|
||||
WhitelistSourceRange: whiteListSourceRange,
|
||||
WhiteList: makeWhiteList(result),
|
||||
ProxyProtocol: makeEntryPointProxyProtocol(result),
|
||||
ForwardedHeaders: makeEntryPointForwardedHeaders(result),
|
||||
Address: result["address"],
|
||||
TLS: configTLS,
|
||||
Auth: makeEntryPointAuth(result),
|
||||
Redirect: makeEntryPointRedirect(result),
|
||||
Compress: compress,
|
||||
WhiteList: makeWhiteList(result),
|
||||
ProxyProtocol: makeEntryPointProxyProtocol(result),
|
||||
ForwardedHeaders: makeEntryPointForwardedHeaders(result),
|
||||
ClientIPStrategy: makeIPStrategy("clientipstrategy", result),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeWhiteList(result map[string]string) *types.WhiteList {
|
||||
var wl *types.WhiteList
|
||||
if rawRange, ok := result["whitelist_sourcerange"]; ok {
|
||||
wl = &types.WhiteList{
|
||||
SourceRange: strings.Split(rawRange, ","),
|
||||
UseXForwardedFor: toBool(result, "whitelist_usexforwardedfor"),
|
||||
return &types.WhiteList{
|
||||
SourceRange: strings.Split(rawRange, ","),
|
||||
IPStrategy: makeIPStrategy("whitelist_ipstrategy", result),
|
||||
}
|
||||
}
|
||||
return wl
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeIPStrategy(prefix string, result map[string]string) *types.IPStrategy {
|
||||
depth := toInt(result, prefix+"_depth")
|
||||
excludedIPs := result[prefix+"_excludedips"]
|
||||
|
||||
if depth == 0 && len(excludedIPs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &types.IPStrategy{
|
||||
Depth: depth,
|
||||
ExcludedIPs: strings.Split(excludedIPs, ","),
|
||||
}
|
||||
}
|
||||
|
||||
func makeEntryPointAuth(result map[string]string) *types.Auth {
|
||||
|
@ -184,15 +192,14 @@ func makeEntryPointProxyProtocol(result map[string]string) *ProxyProtocol {
|
|||
}
|
||||
|
||||
if proxyProtocol != nil && proxyProtocol.Insecure {
|
||||
log.Warn("ProxyProtocol.Insecure:true is dangerous. Please use 'ProxyProtocol.TrustedIPs:IPs' and remove 'ProxyProtocol.Insecure:true'")
|
||||
log.Warn("ProxyProtocol.insecure:true is dangerous. Please use 'ProxyProtocol.TrustedIPs:IPs' and remove 'ProxyProtocol.insecure:true'")
|
||||
}
|
||||
|
||||
return proxyProtocol
|
||||
}
|
||||
|
||||
func makeEntryPointForwardedHeaders(result map[string]string) *ForwardedHeaders {
|
||||
// TODO must be changed to false by default in the next breaking version.
|
||||
forwardedHeaders := &ForwardedHeaders{Insecure: true}
|
||||
forwardedHeaders := &ForwardedHeaders{}
|
||||
if _, ok := result["forwardedheaders_insecure"]; ok {
|
||||
forwardedHeaders.Insecure = toBool(result, "forwardedheaders_insecure")
|
||||
}
|
||||
|
@ -300,3 +307,14 @@ func toBool(conf map[string]string, key string) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func toInt(conf map[string]string, key string) int {
|
||||
if val, ok := conf[key]; ok {
|
||||
intVal, err := strconv.Atoi(val)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return intVal
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -45,9 +45,11 @@ func Test_parseEntryPointsConfiguration(t *testing.T) {
|
|||
"Auth.Forward.TLS.Cert:path/to/foo.cert " +
|
||||
"Auth.Forward.TLS.Key:path/to/foo.key " +
|
||||
"Auth.Forward.TLS.InsecureSkipVerify:true " +
|
||||
"WhiteListSourceRange:10.42.0.0/16,152.89.1.33/32,afed:be44::/16 " +
|
||||
"whiteList.sourceRange:10.42.0.0/16,152.89.1.33/32,afed:be44::/16 " +
|
||||
"whiteList.useXForwardedFor:true ",
|
||||
"WhiteList.SourceRange:10.42.0.0/16,152.89.1.33/32,afed:be44::/16 " +
|
||||
"WhiteList.IPStrategy.depth:3 " +
|
||||
"WhiteList.IPStrategy.ExcludedIPs:10.0.0.3/24,20.0.0.3/24 " +
|
||||
"ClientIPStrategy.depth:3 " +
|
||||
"ClientIPStrategy.ExcludedIPs:10.0.0.3/24,20.0.0.3/24 ",
|
||||
expectedResult: map[string]string{
|
||||
"address": ":8000",
|
||||
"auth_basic_users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
|
@ -73,13 +75,15 @@ func Test_parseEntryPointsConfiguration(t *testing.T) {
|
|||
"redirect_permanent": "true",
|
||||
"redirect_regex": "http://localhost/(.*)",
|
||||
"redirect_replacement": "http://mydomain/$1",
|
||||
"tls": "goo,gii",
|
||||
"tls_acme": "TLS",
|
||||
"tls_ciphersuites": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
||||
"tls_minversion": "VersionTLS11",
|
||||
"whitelistsourcerange": "10.42.0.0/16,152.89.1.33/32,afed:be44::/16",
|
||||
"whitelist_sourcerange": "10.42.0.0/16,152.89.1.33/32,afed:be44::/16",
|
||||
"whitelist_usexforwardedfor": "true",
|
||||
"tls": "goo,gii",
|
||||
"tls_acme": "TLS",
|
||||
"tls_ciphersuites": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
||||
"tls_minversion": "VersionTLS11",
|
||||
"whitelist_sourcerange": "10.42.0.0/16,152.89.1.33/32,afed:be44::/16",
|
||||
"whitelist_ipstrategy_depth": "3",
|
||||
"whitelist_ipstrategy_excludedips": "10.0.0.3/24,20.0.0.3/24",
|
||||
"clientipstrategy_depth": "3",
|
||||
"clientipstrategy_excludedips": "10.0.0.3/24,20.0.0.3/24",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -206,9 +210,11 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
"Auth.Forward.TLS.Cert:path/to/foo.cert " +
|
||||
"Auth.Forward.TLS.Key:path/to/foo.key " +
|
||||
"Auth.Forward.TLS.InsecureSkipVerify:true " +
|
||||
"WhiteListSourceRange:10.42.0.0/16,152.89.1.33/32,afed:be44::/16 " +
|
||||
"whiteList.sourceRange:10.42.0.0/16,152.89.1.33/32,afed:be44::/16 " +
|
||||
"whiteList.useXForwardedFor:true ",
|
||||
"WhiteList.SourceRange:10.42.0.0/16,152.89.1.33/32,afed:be44::/16 " +
|
||||
"WhiteList.IPStrategy.depth:3 " +
|
||||
"WhiteList.IPStrategy.ExcludedIPs:10.0.0.3/24,20.0.0.3/24 " +
|
||||
"ClientIPStrategy.depth:3 " +
|
||||
"ClientIPStrategy.ExcludedIPs:10.0.0.3/24,20.0.0.3/24 ",
|
||||
expectedEntryPointName: "foo",
|
||||
expectedEntryPoint: &EntryPoint{
|
||||
Address: ":8000",
|
||||
|
@ -265,18 +271,19 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
},
|
||||
HeaderField: "X-WebAuth-User",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.42.0.0/16",
|
||||
"152.89.1.33/32",
|
||||
"afed:be44::/16",
|
||||
},
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.42.0.0/16",
|
||||
"152.89.1.33/32",
|
||||
"afed:be44::/16",
|
||||
},
|
||||
UseXForwardedFor: true,
|
||||
IPStrategy: &types.IPStrategy{
|
||||
Depth: 3,
|
||||
ExcludedIPs: []string{
|
||||
"10.0.0.3/24",
|
||||
"20.0.0.3/24",
|
||||
},
|
||||
},
|
||||
},
|
||||
Compress: &Compress{},
|
||||
ProxyProtocol: &ProxyProtocol{
|
||||
|
@ -290,6 +297,13 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
"20.0.0.3/24",
|
||||
},
|
||||
},
|
||||
ClientIPStrategy: &types.IPStrategy{
|
||||
Depth: 3,
|
||||
ExcludedIPs: []string{
|
||||
"10.0.0.3/24",
|
||||
"20.0.0.3/24",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -307,7 +321,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
"redirect.replacement:http://mydomain/$1 " +
|
||||
"redirect.permanent:true " +
|
||||
"compress:true " +
|
||||
"whiteListSourceRange:10.42.0.0/16,152.89.1.33/32,afed:be44::/16 " +
|
||||
"whiteList.sourceRange:10.42.0.0/16,152.89.1.33/32,afed:be44::/16 " +
|
||||
"proxyProtocol.TrustedIPs:192.168.0.1 " +
|
||||
"forwardedHeaders.TrustedIPs:10.0.0.3/24,20.0.0.3/24 " +
|
||||
"auth.basic.users:test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0 " +
|
||||
|
@ -375,10 +389,12 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
},
|
||||
HeaderField: "X-WebAuth-User",
|
||||
},
|
||||
WhitelistSourceRange: []string{
|
||||
"10.42.0.0/16",
|
||||
"152.89.1.33/32",
|
||||
"afed:be44::/16",
|
||||
WhiteList: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"10.42.0.0/16",
|
||||
"152.89.1.33/32",
|
||||
"afed:be44::/16",
|
||||
},
|
||||
},
|
||||
Compress: &Compress{},
|
||||
ProxyProtocol: &ProxyProtocol{
|
||||
|
@ -399,12 +415,12 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
expression: "Name:foo",
|
||||
expectedEntryPointName: "foo",
|
||||
expectedEntryPoint: &EntryPoint{
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: false},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ForwardedHeaders insecure true",
|
||||
expression: "Name:foo ForwardedHeaders.Insecure:true",
|
||||
expression: "Name:foo ForwardedHeaders.insecure:true",
|
||||
expectedEntryPointName: "foo",
|
||||
expectedEntryPoint: &EntryPoint{
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
|
||||
|
@ -412,7 +428,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "ForwardedHeaders insecure false",
|
||||
expression: "Name:foo ForwardedHeaders.Insecure:false",
|
||||
expression: "Name:foo ForwardedHeaders.insecure:false",
|
||||
expectedEntryPointName: "foo",
|
||||
expectedEntryPoint: &EntryPoint{
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: false},
|
||||
|
@ -430,19 +446,19 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "ProxyProtocol insecure true",
|
||||
expression: "Name:foo ProxyProtocol.Insecure:true",
|
||||
expression: "Name:foo ProxyProtocol.insecure:true",
|
||||
expectedEntryPointName: "foo",
|
||||
expectedEntryPoint: &EntryPoint{
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
|
||||
ForwardedHeaders: &ForwardedHeaders{},
|
||||
ProxyProtocol: &ProxyProtocol{Insecure: true},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ProxyProtocol insecure false",
|
||||
expression: "Name:foo ProxyProtocol.Insecure:false",
|
||||
expression: "Name:foo ProxyProtocol.insecure:false",
|
||||
expectedEntryPointName: "foo",
|
||||
expectedEntryPoint: &EntryPoint{
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
|
||||
ForwardedHeaders: &ForwardedHeaders{},
|
||||
ProxyProtocol: &ProxyProtocol{},
|
||||
},
|
||||
},
|
||||
|
@ -451,7 +467,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
expression: "Name:foo ProxyProtocol.TrustedIPs:10.0.0.3/24,20.0.0.3/24",
|
||||
expectedEntryPointName: "foo",
|
||||
expectedEntryPoint: &EntryPoint{
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
|
||||
ForwardedHeaders: &ForwardedHeaders{},
|
||||
ProxyProtocol: &ProxyProtocol{
|
||||
TrustedIPs: []string{"10.0.0.3/24", "20.0.0.3/24"},
|
||||
},
|
||||
|
@ -463,7 +479,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
expectedEntryPointName: "foo",
|
||||
expectedEntryPoint: &EntryPoint{
|
||||
Compress: &Compress{},
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
|
||||
ForwardedHeaders: &ForwardedHeaders{},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -472,7 +488,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
|||
expectedEntryPointName: "foo",
|
||||
expectedEntryPoint: &EntryPoint{
|
||||
Compress: &Compress{},
|
||||
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
|
||||
ForwardedHeaders: &ForwardedHeaders{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -16,9 +16,17 @@ func NewInternalRouterAggregator(globalConfiguration configuration.GlobalConfigu
|
|||
var serverMiddlewares []negroni.Handler
|
||||
|
||||
if globalConfiguration.EntryPoints[entryPointName].WhiteList != nil {
|
||||
ipWhitelistMiddleware, err := middlewares.NewIPWhiteLister(
|
||||
globalConfiguration.EntryPoints[entryPointName].WhiteList.SourceRange,
|
||||
globalConfiguration.EntryPoints[entryPointName].WhiteList.UseXForwardedFor)
|
||||
ipStrategy := globalConfiguration.EntryPoints[entryPointName].ClientIPStrategy
|
||||
if globalConfiguration.EntryPoints[entryPointName].WhiteList.IPStrategy != nil {
|
||||
ipStrategy = globalConfiguration.EntryPoints[entryPointName].WhiteList.IPStrategy
|
||||
}
|
||||
|
||||
strategy, err := ipStrategy.Get()
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating whitelist middleware: %s", err)
|
||||
}
|
||||
|
||||
ipWhitelistMiddleware, err := middlewares.NewIPWhiteLister(globalConfiguration.EntryPoints[entryPointName].WhiteList.SourceRange, strategy)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating whitelist middleware: %s", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue