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

http2: Add flag protected checks for frame flood and abuse by upstream servers #13635

Merged

Conversation

yanavlasov
Copy link
Contributor

@yanavlasov yanavlasov commented Oct 19, 2020

Commit Message:
Add flag protected checks for frame flood and abuse by upstream servers

Additional Description:
This is the starter PR to enable frame flood and abuse checks for upstream codecs. The check is disabled by default and can be enabled via runtime flag envoy.reloadable_features.upstream_http2_flood_checks. These checks will be enabled by default once all unit and integration tests are implemented.

This PR also introduces mechanism for writing arbitrary H/2 frames to the fake upstream connection.

Part of #12281

Risk Level: Low (disabled by default)
Testing: Unit Tests
Docs Changes: Yes (through proto comments)
Release Notes: Yes
Platform Specific Features: N/A
Runtime guard: envoy.reloadable_features.upstream_http2_flood_checks

Signed-off-by: Yan Avlasov yavlasov@google.com

Signed-off-by: Yan Avlasov <yavlasov@google.com>
Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

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

Great to see that we're getting closer to having functional parity between downstream and upstream H2 flood protection.

} else if (isBufferFloodError(status) || isInboundFramesWithEmptyPayloadError(status)) {
ENVOY_CONN_LOG(debug, "flood detected: {}", *connection_, status.message());
close();
protocol_error = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if some generalization of this error handling code is appropriate. The isCodecProtocolError is very similar to this path. Having to extend this further as we add other error types seems like unnecessary toil and aspirational ASSERTs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

return ProtocolConstraints::ReleasorProc([]() {});
}
Status trackInboundFrames(const nghttp2_frame_hd*, uint32_t) override { return okStatus(); }
// TODO(yanavlasov): move to the base class once upstream flood checks are not flag protected.
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a reference to envoy.reloadable_features.upstream_http2_flood_checks so it's easier to find as we remove this feature flag? Alternatively, also add this cleanup comment to the cc file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -33,6 +33,7 @@ New Features
* grpc: implemented header value syntax support when defining :ref:`initial metadata <envoy_v3_api_field_config.core.v3.GrpcService.initial_metadata>` for gRPC-based `ext_authz` :ref:`HTTP <envoy_v3_api_field_extensions.filters.http.ext_authz.v3.ExtAuthz.grpc_service>` and :ref:`network <envoy_v3_api_field_extensions.filters.network.ext_authz.v3.ExtAuthz.grpc_service>` filters, and :ref:`ratelimit <envoy_v3_api_field_config.ratelimit.v3.RateLimitServiceConfig.grpc_service>` filters.
* hds: added support for delta updates in the :ref:`HealthCheckSpecifier <envoy_v3_api_msg_service.health.v3.HealthCheckSpecifier>`, making only the Endpoints and Health Checkers that changed be reconstructed on receiving a new message, rather than the entire HDS.
* health_check: added option to use :ref:`no_traffic_healthy_interval <envoy_v3_api_field_config.core.v3.HealthCheck.no_traffic_healthy_interval>` which allows a different no traffic interval when the host is healthy.
* http: added frame flood and abuse checks to the upstream HTTP/2 codec. This check is off by default and can be enabled by setting the `envoy.reloadable_features.upstream_http2_flood_checks` runtime key to true.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please update API comments now that this is implemented for the upstream direction: https://github.com/envoyproxy/envoy/blob/master/api/envoy/config/core/v3/protocol.proto#L273

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -223,9 +223,12 @@ class ConfigHelper {
// and write it to the lds file.
void setLds(absl::string_view version_info);

// Set limits on pending outbound frames.
// Set limits on pending downstream outbound frames.
void setOutboundFramesLimits(uint32_t max_all_frames, uint32_t max_control_frames);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please rename to setDownstreamOutboundFramesLimits

There are only about 2 call sites in tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

// Note: that this write bypasses any processing by the upstream codec.
ABSL_MUST_USE_RESULT
testing::AssertionResult
writeConnection(uint32_t index, const std::string& data, bool end_stream = false,
Copy link
Contributor

Choose a reason for hiding this comment

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

optional naming suggestion: rawWriteConnection

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

@adisuissa adisuissa left a comment

Choose a reason for hiding this comment

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

Thanks for working on this!

@@ -1109,6 +1109,18 @@ void ConfigHelper::setOutboundFramesLimits(uint32_t max_all_frames, uint32_t max
}
}

void ConfigHelper::setUpstreamOutboundFramesLimits(uint32_t max_all_frames,
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to @antoniovicente suggestion, can you please rename setOutboundFramesLimits to setDownstreamOutboundFramesLimits.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Signed-off-by: Yan Avlasov <yavlasov@google.com>
@repokitteh-read-only
Copy link

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/envoy/.
CC @envoyproxy/api-watchers: FYI only for changes made to api/envoy/.

🐱

Caused by: #13635 was synchronize by yanavlasov.

see: more, trace.

Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

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

Thanks!

@htuch
Copy link
Member

htuch commented Oct 21, 2020

/lgtm api

@yanavlasov
Copy link
Contributor Author

/azp help

@azure-pipelines
Copy link

Supported commands
  • help:
    • Get descriptions, examples and documentation about supported commands
    • Example: help "command_name"
  • list:
    • List all pipelines for this repository using a comment.
    • Example: "list"
  • run:
    • Run all pipelines or specific pipelines for this repository using a comment. Use this command by itself to trigger all related pipelines, or specify specific pipelines to run.
    • Example: "run" or "run pipeline_name, pipeline_name, pipeline_name"
  • where:
    • Report back the Azure DevOps orgs that are related to this repository and org
    • Example: "where"

See additional documentation.

@yanavlasov
Copy link
Contributor Author

/azp list

@azure-pipelines
Copy link

CI/CD Pipelines for this repository:

@yanavlasov
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@yanavlasov
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@yanavlasov
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@yanavlasov
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@yanavlasov
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Signed-off-by: Yan Avlasov <yavlasov@google.com>
@yanavlasov
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@yanavlasov
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@yanavlasov yanavlasov merged commit 6b0f592 into envoyproxy:master Oct 27, 2020
@yanavlasov yanavlasov deleted the upstream-flood-protection-enable branch February 1, 2021 19:26
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