Ability to use "X-Forwarded-For" as a source of IP for white list.
This commit is contained in:
parent
4802484729
commit
d2766b1b4f
50 changed files with 1496 additions and 599 deletions
|
@ -1,7 +1,6 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
|
@ -12,7 +11,7 @@ import (
|
|||
|
||||
// NewHeaderRewriter Create a header rewriter
|
||||
func NewHeaderRewriter(trustedIPs []string, insecure bool) (forward.ReqRewriter, error) {
|
||||
IPs, err := whitelist.NewIP(trustedIPs, insecure)
|
||||
IPs, err := whitelist.NewIP(trustedIPs, insecure, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -38,14 +37,7 @@ type headerRewriter struct {
|
|||
}
|
||||
|
||||
func (h *headerRewriter) Rewrite(req *http.Request) {
|
||||
clientIP, _, err := net.SplitHostPort(req.RemoteAddr)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
h.secureRewriter.Rewrite(req)
|
||||
return
|
||||
}
|
||||
|
||||
authorized, _, err := h.ips.Contains(clientIP)
|
||||
authorized, _, err := h.ips.IsAuthorized(req)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
h.secureRewriter.Rewrite(req)
|
||||
|
|
|
@ -326,8 +326,8 @@ func (s *Server) setupServerEntryPoint(newServerEntryPointName string, newServer
|
|||
}
|
||||
serverMiddlewares = append(serverMiddlewares, s.globalConfiguration.API.StatsRecorder)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if s.globalConfiguration.EntryPoints[newServerEntryPointName].Auth != nil {
|
||||
authMiddleware, err := mauth.NewAuthenticator(s.globalConfiguration.EntryPoints[newServerEntryPointName].Auth, s.tracingMiddleware)
|
||||
if err != nil {
|
||||
|
@ -336,17 +336,22 @@ func (s *Server) setupServerEntryPoint(newServerEntryPointName string, newServer
|
|||
serverMiddlewares = append(serverMiddlewares, s.wrapNegroniHandlerWithAccessLog(authMiddleware, fmt.Sprintf("Auth for entrypoint %s", newServerEntryPointName)))
|
||||
serverInternalMiddlewares = append(serverInternalMiddlewares, authMiddleware)
|
||||
}
|
||||
|
||||
if s.globalConfiguration.EntryPoints[newServerEntryPointName].Compress {
|
||||
serverMiddlewares = append(serverMiddlewares, &middlewares.Compress{})
|
||||
}
|
||||
if len(s.globalConfiguration.EntryPoints[newServerEntryPointName].WhitelistSourceRange) > 0 {
|
||||
ipWhitelistMiddleware, err := middlewares.NewIPWhitelister(s.globalConfiguration.EntryPoints[newServerEntryPointName].WhitelistSourceRange)
|
||||
if err != nil {
|
||||
log.Fatal("Error starting server: ", err)
|
||||
}
|
||||
|
||||
ipWhitelistMiddleware, err := buildIPWhiteLister(
|
||||
s.globalConfiguration.EntryPoints[newServerEntryPointName].WhiteList,
|
||||
s.globalConfiguration.EntryPoints[newServerEntryPointName].WhitelistSourceRange)
|
||||
if err != nil {
|
||||
log.Fatal("Error starting server: ", err)
|
||||
}
|
||||
if ipWhitelistMiddleware != nil {
|
||||
serverMiddlewares = append(serverMiddlewares, s.wrapNegroniHandlerWithAccessLog(ipWhitelistMiddleware, fmt.Sprintf("ipwhitelister for entrypoint %s", newServerEntryPointName)))
|
||||
serverInternalMiddlewares = append(serverInternalMiddlewares, ipWhitelistMiddleware)
|
||||
}
|
||||
|
||||
newSrv, listener, err := s.prepareServer(newServerEntryPointName, s.globalConfiguration.EntryPoints[newServerEntryPointName], newServerEntryPoint.httpRouter, serverMiddlewares, serverInternalMiddlewares)
|
||||
if err != nil {
|
||||
log.Fatal("Error preparing server: ", err)
|
||||
|
@ -794,7 +799,7 @@ func (s *Server) prepareServer(entryPointName string, entryPoint *configuration.
|
|||
}
|
||||
|
||||
if entryPoint.ProxyProtocol != nil {
|
||||
IPs, err := whitelist.NewIP(entryPoint.ProxyProtocol.TrustedIPs, entryPoint.ProxyProtocol.Insecure)
|
||||
IPs, err := whitelist.NewIP(entryPoint.ProxyProtocol.TrustedIPs, entryPoint.ProxyProtocol.Insecure, false)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error creating whitelist: %s", err)
|
||||
}
|
||||
|
@ -1137,13 +1142,16 @@ func (s *Server) loadConfig(configurations types.Configurations, globalConfigura
|
|||
n.Use(middlewares.NewBackendMetricsMiddleware(s.metricsRegistry, frontend.Backend))
|
||||
}
|
||||
|
||||
ipWhitelistMiddleware, err := configureIPWhitelistMiddleware(frontend.WhitelistSourceRange)
|
||||
ipWhitelistMiddleware, err := buildIPWhiteLister(frontend.WhiteList, frontend.WhitelistSourceRange)
|
||||
if err != nil {
|
||||
log.Errorf("Error creating IP Whitelister: %s", err)
|
||||
} else if ipWhitelistMiddleware != nil {
|
||||
ipWhitelistMiddleware = s.wrapNegroniHandlerWithAccessLog(ipWhitelistMiddleware, fmt.Sprintf("ipwhitelister for %s", frontendName))
|
||||
n.Use(s.tracingMiddleware.NewNegroniHandlerWrapper("IP whitelist", ipWhitelistMiddleware, false))
|
||||
log.Infof("Configured IP Whitelists: %s", frontend.WhitelistSourceRange)
|
||||
n.Use(
|
||||
s.tracingMiddleware.NewNegroniHandlerWrapper(
|
||||
"IP whitelist",
|
||||
s.wrapNegroniHandlerWithAccessLog(ipWhitelistMiddleware, fmt.Sprintf("ipwhitelister for %s", frontendName)),
|
||||
false))
|
||||
log.Debugf("Configured IP Whitelists: %s", frontend.WhitelistSourceRange)
|
||||
}
|
||||
|
||||
if frontend.Redirect != nil && entryPointName != frontend.Redirect.EntryPoint {
|
||||
|
@ -1256,18 +1264,13 @@ func (s *Server) configureLBServers(lb healthcheck.LoadBalancer, config *types.C
|
|||
return nil
|
||||
}
|
||||
|
||||
func configureIPWhitelistMiddleware(whitelistSourceRanges []string) (negroni.Handler, error) {
|
||||
if len(whitelistSourceRanges) > 0 {
|
||||
ipSourceRanges := whitelistSourceRanges
|
||||
ipWhitelistMiddleware, err := middlewares.NewIPWhitelister(ipSourceRanges)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ipWhitelistMiddleware, nil
|
||||
func buildIPWhiteLister(whiteList *types.WhiteList, wlRange []string) (*middlewares.IPWhiteLister, error) {
|
||||
if whiteList != nil &&
|
||||
len(whiteList.SourceRange) > 0 {
|
||||
return middlewares.NewIPWhiteLister(whiteList.SourceRange, whiteList.UseXForwardedFor)
|
||||
} else if len(wlRange) > 0 {
|
||||
return middlewares.NewIPWhiteLister(wlRange, false)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -571,48 +571,75 @@ func TestServerParseHealthCheckOptions(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewServerWithWhitelistSourceRange(t *testing.T) {
|
||||
cases := []struct {
|
||||
func TestBuildIPWhiteLister(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
whitelistStrings []string
|
||||
whitelistSourceRange []string
|
||||
whiteList *types.WhiteList
|
||||
middlewareConfigured bool
|
||||
errMessage string
|
||||
}{
|
||||
{
|
||||
desc: "no whitelists configued",
|
||||
whitelistStrings: nil,
|
||||
desc: "no whitelists configured",
|
||||
whitelistSourceRange: nil,
|
||||
middlewareConfigured: false,
|
||||
errMessage: "",
|
||||
}, {
|
||||
desc: "whitelists configued",
|
||||
whitelistStrings: []string{
|
||||
},
|
||||
{
|
||||
desc: "whitelists configured (deprecated)",
|
||||
whitelistSourceRange: []string{
|
||||
"1.2.3.4/24",
|
||||
"fe80::/16",
|
||||
},
|
||||
middlewareConfigured: true,
|
||||
errMessage: "",
|
||||
}, {
|
||||
desc: "invalid whitelists configued",
|
||||
whitelistStrings: []string{
|
||||
},
|
||||
{
|
||||
desc: "invalid whitelists configured (deprecated)",
|
||||
whitelistSourceRange: []string{
|
||||
"foo",
|
||||
},
|
||||
middlewareConfigured: false,
|
||||
errMessage: "parsing CIDR whitelist [foo]: parsing CIDR whitelist <nil>: invalid CIDR address: foo",
|
||||
errMessage: "parsing CIDR whitelist [foo]: parsing CIDR white list <nil>: invalid CIDR address: foo",
|
||||
},
|
||||
{
|
||||
desc: "whitelists configured",
|
||||
whiteList: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"1.2.3.4/24",
|
||||
"fe80::/16",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
middlewareConfigured: true,
|
||||
errMessage: "",
|
||||
},
|
||||
{
|
||||
desc: "invalid whitelists configured (deprecated)",
|
||||
whiteList: &types.WhiteList{
|
||||
SourceRange: []string{
|
||||
"foo",
|
||||
},
|
||||
UseXForwardedFor: false,
|
||||
},
|
||||
middlewareConfigured: false,
|
||||
errMessage: "parsing CIDR whitelist [foo]: parsing CIDR white list <nil>: invalid CIDR address: foo",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
middleware, err := configureIPWhitelistMiddleware(tc.whitelistStrings)
|
||||
|
||||
if tc.errMessage != "" {
|
||||
require.EqualError(t, err, tc.errMessage)
|
||||
middleware, err := buildIPWhiteLister(test.whiteList, test.whitelistSourceRange)
|
||||
|
||||
if test.errMessage != "" {
|
||||
require.EqualError(t, err, test.errMessage)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
|
||||
if tc.middlewareConfigured {
|
||||
if test.middlewareConfigured {
|
||||
require.NotNil(t, middleware, "not expected middleware to be configured")
|
||||
} else {
|
||||
require.Nil(t, middleware, "expected middleware to be configured")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue