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
[THREESCALE-1430] Avoid trying to use path-based routing when using HTTPS #938
Conversation
I think this makes the tests clearer now. More importantly, it will allow us to avoid duplicating tests when testing the "ssl_certificate" phase of the "find_service" policy.
@@ -0,0 +1,23 @@ | |||
local _M = {} | |||
|
|||
function _M.find_service(config_store, host) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cyclomatic complexity of function '_M.find_service' is too high (8 > 7)
|
||
local _M = {} | ||
|
||
function _M.find_service(config_store, host) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cyclomatic complexity of function '_M.find_service' is too high (8 > 7)
9e8c28c
to
7b59455
Compare
end | ||
|
||
context.service = context.service or | ||
host_based_finder.find_service(context.configuration, context.host) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you can store just find_service
in the local variable, so the JIT has it easier and does not have to check if the table changed.
But I see that because of the testing code and stubs you actually need it to be in a table. That is unfortunate.
|
||
function _M.new(...) | ||
local self = new(...) | ||
|
||
if configuration_store.path_routing then | ||
ngx.log(ngx.WARN, 'apicast path routing enabled') | ||
self.find_service = find_service_cascade | ||
self.find_service = function(configuration, host) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can be defined in a local variable when loading the file, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be problematic to test as you mentioned above.
This only runs when the configuration is loaded, so it should be fine.
@davidor While it doesn't matter for SSL in current version, wouldn't it cause unexpected behavior for the rest of the functionality? (as, from what I understand, the found service is stored in the |
@mayorova during TLS handshake there is no information about the request method, path or any other HTTP data. It is just the TLS protocol, not HTTP. So the only piece of information available is the hostname through the SNI. Regarding the context, it makes sense that this context should not be reused for the normal request because it wasn't part of the HTTP protocol. Not sure that is the case now and it is definitely something to verify. |
@mikz Yes, I understand that it's not possible to perform method/path-based matching at the TLS-handshake stage.
I'm also not sure if it's taken into account in this PR :) |
@davidor Can you please have a look at the comments above?
Basically, I think now Path routing might not work correctly with HTTPS (if there are >1 services with the same host). |
Hello, We can agree that we cannot use Path Routing to find the matching service to find the correct TLS certificate during the TLS negociation. However, I do not agree that we should disable Path Routing with HTTPS. We can still use the Since finding the correct TLS certificate is quite a standard mechanism, we could also provide the global policy that implement this mechanism :
Certificates can be supplied as a Kubernetes secret and mounted in a well-known or configured folder. That way, we could also leverage the OpenShift Service Signing Certificates and have a fully automated HTTPS setup on OpenShift. |
I imagine that when Path Routing is enabled, then the |
Hi @mikz, @davidor, @mayorova, I don't want to bother you but I really need to make sure I correctly understood this PR. The issue was that we were looking for the service by host + path when path routing was enabled and when SSL was enabled we could not find the correct service since we cannot have access to the path at this stage. I initially understood from both the changelog and the discussions in this PR that the proposed fix was to disable Path Routing when HTTPS was in use. I tested this PR and it seems that we implemented host-based routing for the ssl_certificate phase but still use the correct service found through the path routing for the later stages. Can you confirm the former or the later understanding is correct ? |
@nmasse-itix you're not bothering. We should've explained it better. The issue was that there was a crash because we tried to use API that wasn't available in that phase of a request. We could not access the request path. So the mitigation was to use the same technique as without path routing: just compare the service host against the SNI and pick a first one that matches. That mitigation is applied only to the After the TLS is established it is business as usual and the request path is used to find the correct service. |
When APICAST_HTTPS_ env vars are used to configure SSL certs, enabling path routing does not work. The reason is that when those envs are configured, the
find_service
policy runs in thessl_certificate
phase which does not have access to the http method nor the path, needed for the path-based routing.Apart from fixing the issue, this PR refactors the
find_service
by extracting a couple of classes and reorganizing the tests. I think that properly testing thessl_certiticate
phase without this refactor would have needed lots of duplicated tests.Ref: https://issues.jboss.org/browse/THREESCALE-1430