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

feat(proxy) X-Forwarded-* upstream headers #2236

Closed
wants to merge 17 commits into from
Closed

Conversation

bungle
Copy link
Member

@bungle bungle commented Mar 22, 2017

Summary

Implementation of #2202, taking care of all X-Forwarded-* upstream headers and introducing configuration options for the ngx_http_realip_module.

Full changelog

  • Move the real_ip directives to the Kong proxy location block
  • Introduce trusted_ips config property
  • Introduce real_ip_header config property
  • New lua-resty-mediador library for ip utils, supporting both IPv4 and IPv6 & CIDR blocks
  • Implement logic to validate client ips as trusted from the new trusted_ips config value
  • Implement Lua logic for the X-Forwarded-For upstream header
  • Related tests (renamed real_ip test suite to upstream_headers)

Issues resolved

Fix #2202, #2240

* Add real_ip_recursive and set_real_ip_from Kong configuration fields to
configure ngx_http_realip_module directives.
* Move the real_ip directives to the Kong proxy location block.
* Add configuration building unit tests for those 2 new directives.

Fix #1661
Deprecates #1662
@bungle bungle force-pushed the feat/hop-to-hop-headers branch 7 times, most recently from aa9d19e to 475e653 Compare March 22, 2017 06:02
@bungle bungle force-pushed the feat/hop-to-hop-headers branch 2 times, most recently from cf47c58 to 56c080c Compare March 23, 2017 17:57
* Introduce trusted_ips config property
* Introduce real_ip_header
* New lua-resty-mediador
* Implement logic to validate client ips as trusted
* Implement Lua logic for the X-Forwarded-For upstream header
* Related tests (renamed real_ip test suite to upstream_headers)

Fix #2202
@bungle bungle force-pushed the feat/hop-to-hop-headers branch from 56c080c to 8e2fcb1 Compare March 23, 2017 22:08
CHANGELOG.md Outdated

- :fireworks: Configurable `X-Forwarded-*` and `X-Real-IP` upstream headers.
[#2236](https://github.com/Mashape/kong/pull/2236)
- :fireworks: Support for The PROXY protocol.
Copy link
Contributor

Choose a reason for hiding this comment

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

pedantic: lowercase 'the'

@bungle bungle added this to the 0.10.2 milestone Apr 3, 2017
Copy link
Member

@thibaultcha thibaultcha left a comment

Choose a reason for hiding this comment

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

Almost ready it seems! I think there are still 1 or 2 small leftovers or so it seems? Will squash and merge properly for 0.10.2 when ready :)

read more about this change from our
[0.10.x Proxy Reference](https://getkong.org/docs/0.10.x/proxy/)
and
[0.10.x Configuration Reference](https://getkong.org/docs/0.10.x/configuration/)
Copy link
Member

Choose a reason for hiding this comment

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

note to self: slightly rephrase for merge

proxy_set_header Upgrade $upstream_upgrade;
proxy_set_header Connection $upstream_connection;
proxy_pass_header Server;
proxy_pass_header Date;
Copy link
Member

Choose a reason for hiding this comment

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

note: We should also mention this in the changelog and add it to the proxy guide list of forwarded headers from upstream

}
end

if trust_all_ipv4 and trust_all_ipv6 then
Copy link
Member

Choose a reason for hiding this comment

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

note: we need to make sure to document that one needs both ipv4 and ipv6 forms specified to "trust all"

(but tbh, I feel like we should respect the --with-ipv6 option of Nginx, and ignore all IPv6 settings/values if support is not enabled in Nginx)

Copy link
Member Author

Choose a reason for hiding this comment

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

Wasn't it so that --with-ipv6 was dropped already from Nginx mainline, or does OpenResty still continue having them somehow?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah sorry I wasn't very clear here. Yes, --with-ipv6 was dropped. What I meant is split in 2 parts:

  • I think that users should be able to enable/disable ipv6 support through Kong
  • Currently doable via the --with-nginx option check in the current OpenResty (I think 1.11.2still has it? not sure?), but in the future, the need for disabling ipv6 will be even greater, because the OS might support ipv6, but not the network, and we cannot rely on the --with-ipv6 option anymore to assume what the user wanted, hence, it simply increased the need for this behavior to be configurable.

Copy link
Member Author

Choose a reason for hiding this comment

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

map $http_x_forwarded_port $upstream_x_forwarded_port {
default $http_x_forwarded_port;
'' $server_port;
}
Copy link
Member

Choose a reason for hiding this comment

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

Any reason why we're not handling those in the Lua logic but need those maps again instead? I don't remember if there was a special case that they handle in lieu of an else in the Lua code?

Copy link
Member Author

Choose a reason for hiding this comment

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

We just initialize the vars with defaults. We can do it in Lua land as well.

Copy link
Member

Choose a reason for hiding this comment

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

That would avoid having pieces of the logic in two different places indeed

end)
end)

describe("with the downstream host preserved (pending: because the test fails to connect to API when preserve_host = true)", function()
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can remove this "pending" comment now? Assuming this was related to one of the recent fixes on master

var.upstream_x_forwarded_for = http_x_forwarded_for .. ", " .. realip_remote_addr

else
var.upstream_x_forwarded_for = var.remote_addr
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 some comments here would be very beneficial to avoid future confusion, regarding the usage of realip_remote_addr vs var.remove_addr, and why we need to build the X-Forwarded-For upstream header ourselves (due to the ngx_http_proxy_module limitation we discovered).

Copy link
Member Author

Choose a reason for hiding this comment

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

Comments were added.

@bungle bungle force-pushed the feat/hop-to-hop-headers branch from 75be12b to 79c2743 Compare April 11, 2017 21:07
-- is okay for us to use it in case no X-Forwarded-For header was present.
-- But in case it was given, we will append the $realip_remote_addr that
-- contains the IP that was originally in $remote_addr before realip module
-- overrode that (aka the client that connected us).
Copy link
Member

@thibaultcha thibaultcha Apr 13, 2017

Choose a reason for hiding this comment

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

👍 great! This will give future contributors a good reason as to why things are done like this

balancer_address.hostname..":"..balancer_address.port

-- Keep-Alive and WebSocket Protocol Upgrade Headers
if var.http_upgrade == "websocket" then
Copy link
Member

Choose a reason for hiding this comment

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

Sorry if you thought I implied that we should move those as well in the Lua-land. I only meant to apply changes to the PR that apply to this scope, and did not mean to add extra work to it! It would have been perfectly if this had stayed in the Nginx configuration. Maybe it still should be moved back there to avoid introducing breaking changes? As of this stands, we perform a case-sensitive check on the content of those headers, and that is a breaking change since Nginx's map is case-insensitive.

Sorry for the misunderstanding!

Copy link
Member Author

@bungle bungle Apr 13, 2017

Choose a reason for hiding this comment

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

While I was doing it, I thought, why not do them all similarly in Lua-land (they are somewhat related). But that case-insensitivity thing was something I didn't think about. Great catch! Basically two choices, case insensitive match on Lua or move them back to maps?

Copy link
Member Author

@bungle bungle Apr 14, 2017

Choose a reason for hiding this comment

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

@thibaultcha, I pushed a patch to make case-insensitive comparison on Lua-land. I can always move it back to map, but I like this because it keeps our user facing nginx.conf cleaner.

Copy link
Member

Choose a reason for hiding this comment

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

I like this because it keeps our user facing nginx.conf cleaner.

Exactly, we should keep it on the Lua-land indeed.

@thibaultcha
Copy link
Member

(In the future, please don't merge next or master in your branch. Rebasing is fine though. Thanks!)

local http_x_forwarded_for = var.http_x_forwarded_for

Copy link
Member

Choose a reason for hiding this comment

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

You got it! 😉

thibaultcha added a commit that referenced this pull request Apr 15, 2017
@thibaultcha thibaultcha deleted the feat/hop-to-hop-headers branch April 15, 2017 00:36
@thibaultcha
Copy link
Member

Merged to next with a few modifications to the docs (changelog + conf), and a clean git history. Thank you!

@subnetmarco
Copy link
Member

@thibaultcha can this be also merged into master so that it will be available in 0.10.2?

@braedon
Copy link

braedon commented May 12, 2017

It doesn't look like this actually made it into 0.10.2 - any word on when it will be released?

@thibaultcha
Copy link
Member

This is scheduled for 0.11 as it introduces some breaking changes.

@bungle bungle modified the milestones: 0.11.0, 0.10.2 May 12, 2017
thibaultcha added a commit to Kong/docs.konghq.com that referenced this pull request Aug 11, 2017
thibaultcha added a commit to Kong/docs.konghq.com that referenced this pull request Aug 11, 2017
thibaultcha added a commit to Kong/docs.konghq.com that referenced this pull request Aug 11, 2017
thibaultcha added a commit to Kong/docs.konghq.com that referenced this pull request Aug 16, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants