router: Create InternalRedirectPolicy in side RouteAction and extend it with pluggable predicates#10908
Conversation
pluggable predicates. Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
|
/assign @alyssawilk |
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
|
/retest |
|
🔨 rebuilding |
|
/retest |
|
🔨 rebuilding |
|
/retest |
|
🔨 rebuilding |
Signed-off-by: pengg <pengg@google.com>
htuch
left a comment
There was a problem hiding this comment.
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.
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.
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.
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.
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.
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 <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
…-more-options Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
behavior change is documented in the release note. Signed-off-by: pengg <pengg@google.com>
Signed-off-by: pengg <pengg@google.com>
|
/retest |
|
🔨 rebuilding |
Signed-off-by: pengg <pengg@google.com>
| 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.
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.
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?
|
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 <pengg@google.com>
|
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 |
alyssawilk
left a comment
There was a problem hiding this comment.
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 <pengg@google.com>
alyssawilk
left a comment
There was a problem hiding this comment.
@mattklein123 or @htuch for final API changes?
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.