Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to use "X-Forwarded-For" as a source of IP for white list. #3070

Merged
merged 9 commits into from
Mar 23, 2018

Conversation

ldez
Copy link
Contributor

@ldez ldez commented Mar 22, 2018

What does this PR do?

Adds the ability to use X-Forwarded-For as a source of IP for white list.

  • Docker: waiting for Segment labels: Docker #3055
  • Rancher
  • Marathon
  • k8s
  • Mesos
  • ECS
  • Consul Catalog
  • KV (bold, consul, etcd, zk)
  • Service Fabric: I must do a PR after the merge of this PR

Motivation

Fixes #2942

More

  • Added/updated tests
  • Added/updated documentation

Additional Notes

Related to #2260

Copy link
Member

@mmatur mmatur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job @ldez 👏
First review with few comments :)

| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the order changed between traefik.frontend.rateLimit.rateSet.<name>.period and traefik.frontend.rateLimit.extractorFunc ?

@@ -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) // FIXME
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// FIXME ?

errMessage: "parsing CIDR whitelist [foo]: parsing CIDR white list <nil>: invalid CIDR address: foo",
},
{
desc: "whitelists configured )",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whitelists configured instead of whitelists configured )

Copy link
Member

@emilevauge emilevauge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Impressive job @ldez 👏
I think we definitely need a user guide (in the future) on chaining Traefik with another LB that would also explain X-Forwarded-For and white listing.

}

// contains checks if provided address is in the white list
func (ip *IP) contains(addr string) (bool, net.IP, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the returned bool still needed ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes due to insecure management.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I misunderstood the code initially.

Copy link
Member

@mmatur mmatur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few comments

@@ -54,7 +54,10 @@ Træfik can be configured with a file.
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
]
whitelistSourceRange = ["10.42.0.0/16", "152.89.1.33/32", "afed:be44::/16"]

[frontends.frontend2.whiteList]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it should be frontend1 instead of frontend2

@@ -112,7 +115,8 @@ Redirect.Regex:http://localhost/(.*)
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
WhiteList.useXForwardedFor:true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be WhiteList.UseXForwardedFor instead of WhiteList.useXForwardedFor

Copy link
Member

@juliens juliens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@mmatur mmatur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👏

Copy link
Member

@emilevauge emilevauge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@nemosupremo
Copy link
Contributor

I was looking at this PR as it reflected some functionality we had implemented in a fork, and as it's implemented here it doesn't seem secure (or at least has a large foot gun).

As I understand from this test:

+		{
+			desc:                "allow UseXForwardedFor, remoteAddr not in range, UseXForwardedFor in range",
+			whiteList:           []string{"1.2.3.4/24"},
+			allowXForwardedFor:  true,
+			remoteAddr:          "10.2.3.1:123",
+			xForwardedForValues: []string{"1.2.3.1", "10.2.3.1"},
+			expected:            true,
+		},

If my whitelist is set to 1.2.3.4/24 and the 'attacker' has a remote IP of 10.2.3.1, he can bypass my whitelist by just setting the appropriate X-Forwarded-For header. This seems like a dangerous feature as it means if your the attacker knows your whitelist (which will probably likely be something like 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16), he can essentially access your service from wherever.

What nginx does, which I think it safer, is it only allows you to pass the whitelist if all the IPs pass the whitelist. So in this case, nginx would fail because the remoteAddr is not in the whitelist, so it doesn't trust the X-Forwarded-For header. It also takes into the account the order of the IP's in X-Forwarded-For from right to left. It essentially uses the left-most non-whitelisted IP as the "real IP".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants