-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
fix(core) set SNI server name for upstream SSL connections #2225
Conversation
I think this warrants a test. |
Good idea to write a test for it. An existing test spec/02-integration/05-proxy/01-router_spec.lua Router preserve_host preserves downstream host if enabled seems to fail on my PR. |
Should this PR also consider the SNI sent in the downstream Client Hello? If Kong has received a TLS connection from the downstream client, should we not consider that SNI as well, rather than just the Host header/ |
@konrade Thanks for raising this issue. We also experienced the same one internally, and were about to implement your fix in #2129. I am glad it is coming from the community instead, at your initiative :) @p0pr0ck5 I feel like such a use-case would be handled already when configuring the |
@thibaultcha my question was centered around your presented assumption indeed being incorrect. While I don't think this is a common case, there's certainly nothing preventing the (layer 4) SNI value from being different from the (layer 7) Host HTTP header. Indeed, this is something Kong currently allows for, which is why I brought it up for the sake of completeness. Certainly I don't want to be objectionist for objections' sake; I just want to make sure we're covering all cases we want to support. My biggest concern is that we're not offering the option to configure the upstream SNI value; indeed, in other cases, the HTTP Host value is not directly tied to the SNI (curl/curl#607). Not saying we need all the flexibility the curl does ;) |
This was certainly very clear already, but my assumption was that "in most places, this isn't the case". As of now, I think such a configuration would be outside the scope of this hotfix though, and would be considered if requested, which hasn't happened so far. |
Agreed, I don't think it's a common use case. My thought is, rather than treating this as a quick hotfix only, is it an opportunity to add some additional flexibility to meet future use cases. It seems like the answer to that question is 'no', which is okay with me- just wanted to explore the opportunity. @konrade what are your thoughts on the above discussion? |
Based on what I've seen other web servers doing I think Kong should reject incoming requests where SNI server name does not match Host header (see: TLS Virtual Host Confusion). I guess there are two scenarios regarding upstream SNI:
Scenario 2 could potentially require an option to configure what HTTP Host and SNI server name to use when upstream is specified by IP. A very real case for me when starting to evaluate Kong was that I already had an older web gateway that did all kinds of reverse proxying (some with upstream TLS). Instead of trying to replicate all mappings directly I tried to put Kong in front of the old gateway with a default routing sending all that didn't match any configured APIs to the old gateway. In this scenario I ran into another problem with upstream SNI and it was due to Kong/NGINX keeping the upstream connection alive between multiple requests even if they downstream request was on different FQDNs. This caused HTTP Host to missmatch with SNI for subsequent request that wasn't on same FQDN that opened upstream TLS connection in the first place. |
Following 5d86d09, it should be fairly easy to test this functionality by using an |
I mocked up some tests related to this PR here: 3f3b476 Also, @konrade one point that's come up in discussion of this is the handling of the SNI header when |
A bit tricky since Host header allows for IP but not SNI.
I have the feeling that the correct way to handle it is to not include SNI for upstream TLS when |
Any reason we couldn't use the downstream Host header here? Also, this PR should still have tests :) |
Should I take in your tests @p0pr0ck5 ? |
@thibaultcha what are you thoughts here? Can we merge this PR as-is and bring in the tests later, or is having the tests in the same PR are blocker? @konrade do you strongly disagree that we should use the downstream Host header as the value of |
I would think that the tests here are quite the blocker, since we don't want to have an edge-case indeed... That said, they could be unit for now and simply testing the value of |
@thibaultcha fwiw, there are integration (ish) tests here: 3f3b476 |
It should be possible to merge in your tests @p0pr0ck5 in |
Regarding the edge case when preserve_host is false and upstream is https and an IP then the only problem I see with passing on Host header value as SNI is when downstream request is done with IP. This would wrongly put an IP in SNI. |
In such a case, Nginx would simply silently strip it from the Client Hello (https://github.com/nginx/nginx/blob/master/src/http/ngx_http_upstream.c#L1792). We could add in our own logic to handle this, but it would just be a waste of CPU cycles. |
Would Host header also be passed on to upstream in this case? (I would guess not due to |
As your PR sits now, there would still be a mismatch between the Host header seen by the upstream, and the SNI seen by the upstream, when I spose in such a case (IP As for the tests, I'd imagine you can just merge that branch into your PR if you like. No promises someone else won't want some changes though ;) |
@konrade can you rebase this? We recently made some additions to the Nginx template that are resulting in a conflict here. BTW we'd like to get this merged soon, thanks again for the contribution; any movements on tests? |
Made sure server name for upstream SSL connections match Host header.
Sorry for the delay but I've been traveling the last weeks so haven't been able to look into the tests. |
No problem. Happy to help and to see that it got fixed. |
Made sure server name for upstream SSL connections match Host header.
Summary
Fixes problem when having configured upstream server using https://... where Kong initiates upstream SSL connection using SNI with server name "kong_upstream".
This does not match the "Host: " header forwarded from the incoming request and is seen by most web servers as an error and they won't process such request.
Full changelog
Issues resolved
Fix #2129