-
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
router: Create InternalRedirectPolicy in side RouteAction and extend it with pluggable predicates #10908
router: Create InternalRedirectPolicy in side RouteAction and extend it with pluggable predicates #10908
Conversation
pluggable predicates. Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
/assign @alyssawilk |
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
/retest |
🔨 rebuilding |
/retest |
🔨 rebuilding |
/retest |
🔨 rebuilding |
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
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.
API looks reasonable, a few comments..
|
||
// HTTP scheme combinations that are allowed to be handled as internal | ||
// redirect. Downstream scheme comes first and redirect target URL scheme | ||
// follows. |
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 seems pretty strange to be including the target URL scheme; why isn't is sufficient to include just the downstream?
For that matter, why do we even need this, given that the route match that leads to the redirect itself has a scheme matcher?
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 was from the preexisting behavior: it allows a HTTP downstream to be redirected to only HTTP targets; it allows HTTPS downstream to be redirected to any targets.
My understanding is that, if an origin redirect an HTTP request to an HTTPS target, there is a chance that the origin would like to move the downstream to a secure transport for sensitive payload.
While this is not always the case, certainly not our use case, I decided to make this configurable but preserving the existing behavior.
By "scheme matcher" did you mean VirtualHost. require_tls?
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.
Scheme seems an odd one here IMO.
upstream scheme is generally just based on "is the connection to upstream secure or not"
I think in general we want to make sure that x-forwarded-proto matches the scheme of the redirect URI. If we want to say we only redirect https:// requests or http:// requests that'd be the request x-forwarded-proto header not scheme
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.
Ah, thanks @alyssawilk and @htuch!
I think I had misunderstood the purpose of the existing check on x-forwarded-proto vs redirect URI scheme. Our use case led me to think about the redirect URL more as a way to define the desired upstream for a request, but the redirect URL should really be treated purely as a property of the downstream, which makes the existing check make perfect sense, and indeed makes the scheme option here very odd. In other words, Upstream's scheme is completely orthogonal to what the downstream's scheme is.
I'll remove this option completely.
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 is now done. I removed this option.
I added an option to allow cross scheme redirect - I think this should be fine since as @hutch said, there are scheme match in routes, we can selectively allow certain route to be redirected to, across scheme boundary if we know this is safe.
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
…-more-options Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
behavior change is documented in the release note. Signed-off-by: pengg <[email protected]>
Signed-off-by: pengg <[email protected]>
/retest |
🔨 rebuilding |
Signed-off-by: pengg <[email protected]>
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.
Almost there!
repeated google.protobuf.Any predicates = 3; | ||
|
||
// Disallow internal redirect to follow a target URI with a different scheme than the value of | ||
// x-forwarded-proto. Default behavior is to follow such redirects. |
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.
Ugh, sorry I didn't comment earlier, but I don't think I like the default behavior being IMO sketchy (forwarding https content over http connections)
How about we either switch the default (last time I swear!) which means the behavioral change between the old and the new is the new is more strict, and folks can flip it and apply your predicate if they want old behavior?
* router: internal redirect configs are moved to the :ref`internal_redirect_policy | ||
<envoy_api_field_router.RouterAction.internal_redirect_policy>` field, which defines more fine | ||
grained control of the internal redirect behavior. This changes the default cross scheme redirect behavior. | ||
All cross scheme redirect is allowed by default, but http downstream to https target is disallowed. To restore |
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.
I think you also need to doc up the deprecated field in the Deprecated section and maybe move comments on how to preserve behavior there?
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.
Done.
It looks like I ran into windows 259 path length limit with the long predicate name. |
windows path length limitation. Change default behavior to be disallowing cross scheme redirect. Rename the option to allow_cross_scheme (default to false). Update tests. Document implemeneted default behavior change. Signed-off-by: pengg <[email protected]>
I renamed the predicate with a shorter name to get around window bazel path length limit as well. Thanks! |
cc @wrowe anything we can do about the path limits? Given the directory names are fairly long I'm hoping we can find a workaround to not have to reduce readability |
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.
LGTM modulo a few tiny nits. Huzzah!
api/envoy/extensions/internal_redirect/allow_listed_routes/v3/allow_listed_routes_config.proto
Outdated
Show resolved
Hide resolved
AllowListed -> Allow listed. Signed-off-by: pengg <[email protected]>
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.
Thanks!
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.
@mattklein123 or @htuch for final API changes?
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.
API LGTM!
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.
/lgtm api
Description: router: Create InternalRedirectPolicy to capture all internal redirect related options and extend it with pluggable predicates similar to retry plugins. The previous_routes and whitelisted_routes predicate allow creating a DAG of routes for internal redirects. Each node in the DAG is a route. whitelisted_routes defines the edges of each node. previous_routes serves as visited status keeper for each of the edge. This prevents infinite loop, while allowing loop to exist in the DAG.
Risk Level: Medium
Testing: Unit tests. Integration tests.
Docs Changes: Updated HCM architecture overview page. Added toctree for the predicates.
Release Notes: Updated version history.