Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// Allows detecting whether the transport appears to be TLS or plaintext.
// [#extension: envoy.filters.listener.tls_inspector]

// [#next-free-field: 6]
message TlsInspector {
option (udpa.annotations.versioning).previous_message_type =
"envoy.config.filter.listener.tls_inspector.v2.TlsInspector";
Expand Down Expand Up @@ -48,4 +49,11 @@ message TlsInspector {
// counter to be incremented if the ClientHello message is over implementation defined limit
// (currently 16Kb).
bool close_connection_on_client_hello_parsing_errors = 4;

// The maximum size in bytes of the ClientHello that the tls_inspector will
// process. If the ClientHello is larger than this size, the tls_inspector
// will stop processing and indicate failure. If not defined, defaults to
// 16KiB.
google.protobuf.UInt32Value max_client_hello_size = 5
[(validate.rules).uint32 = {lte: 16384 gt: 255}];
}
3 changes: 3 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,9 @@ new_features:
change: |
Propagate the transport error from the tls_inspector to the DownstreamTransportFailureReason in StreamInfo
for access logging prior to the TLS handshake.
- area: tls_inspector
change: |
Add configuration parameter to TLS inspector for maximum acceptable client hello size.
- area: ext_proc
change: |
Add support for forwarding cluster metadata to ext_proc server.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ const unsigned Config::TLS_MAX_SUPPORTED_VERSION = TLS1_3_VERSION;

Config::Config(
Stats::Scope& scope,
const envoy::extensions::filters::listener::tls_inspector::v3::TlsInspector& proto_config,
uint32_t max_client_hello_size)
const envoy::extensions::filters::listener::tls_inspector::v3::TlsInspector& proto_config)
: stats_{ALL_TLS_INSPECTOR_STATS(POOL_COUNTER_PREFIX(scope, "tls_inspector."),
POOL_HISTOGRAM_PREFIX(scope, "tls_inspector."))},
ssl_ctx_(SSL_CTX_new(TLS_with_buffers_method())),
Expand All @@ -61,11 +60,12 @@ Config::Config(
PROTOBUF_GET_WRAPPED_OR_DEFAULT(proto_config, enable_ja4_fingerprinting, false)),
close_connection_on_client_hello_parsing_errors_(
proto_config.close_connection_on_client_hello_parsing_errors()),
max_client_hello_size_(max_client_hello_size),
max_client_hello_size_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(proto_config, max_client_hello_size,
TLS_MAX_CLIENT_HELLO)),
initial_read_buffer_size_(
std::min(PROTOBUF_GET_WRAPPED_OR_DEFAULT(proto_config, initial_read_buffer_size,
max_client_hello_size),
max_client_hello_size)) {
max_client_hello_size_),
max_client_hello_size_)) {
if (max_client_hello_size_ > TLS_MAX_CLIENT_HELLO) {
throw EnvoyException(fmt::format("max_client_hello_size of {} is greater than maximum of {}.",
max_client_hello_size_, size_t(TLS_MAX_CLIENT_HELLO)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ enum class ParseState {
class Config {
public:
Config(Stats::Scope& scope,
const envoy::extensions::filters::listener::tls_inspector::v3::TlsInspector& proto_config,
uint32_t max_client_hello_size = TLS_MAX_CLIENT_HELLO);
const envoy::extensions::filters::listener::tls_inspector::v3::TlsInspector& proto_config);

const TlsInspectorStats& stats() const { return stats_; }
bssl::UniquePtr<SSL> newSsl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@ DEFINE_PROTO_FUZZER(
Stats::IsolatedStoreImpl store;
ConfigSharedPtr cfg;

if (input.max_size() == 0) {
// If max_size not set, use default constructor
cfg = std::make_shared<Config>(*store.rootScope(), input.config());
} else {
cfg = std::make_shared<Config>(*store.rootScope(), input.config(), input.max_size());
}
cfg = std::make_shared<Config>(*store.rootScope(), input.config());

auto filter = std::make_unique<Filter>(std::move(cfg));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import "validate/validate.proto";
message TlsInspectorTestCase {
envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector config = 1
[(validate.rules).message.required = true];
uint32 max_size = 2 [(validate.rules).uint32.lte = 65536];
test.extensions.filters.listener.FilterFuzzWithDataTestCase fuzzed = 3
[(validate.rules).message.required = true];
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ INSTANTIATE_TEST_SUITE_P(TlsProtocolVersions, TlsInspectorTest,
// Test that an exception is thrown for an invalid value for max_client_hello_size
TEST_P(TlsInspectorTest, MaxClientHelloSize) {
envoy::extensions::filters::listener::tls_inspector::v3::TlsInspector proto_config;
EXPECT_THROW_WITH_MESSAGE(
Config(*store_.rootScope(), proto_config, Config::TLS_MAX_CLIENT_HELLO + 1), EnvoyException,
"max_client_hello_size of 16385 is greater than maximum of 16384.");
proto_config.mutable_max_client_hello_size()->set_value(Config::TLS_MAX_CLIENT_HELLO + 1);
EXPECT_THROW_WITH_MESSAGE(Config(*store_.rootScope(), proto_config), EnvoyException,
"max_client_hello_size of 16385 is greater than maximum of 16384.");
}

// Test that a ClientHello with an SNI value causes the correct name notification.
Expand Down Expand Up @@ -518,7 +518,8 @@ TEST_P(TlsInspectorTest, RequestedMaxReadSizeDoesNotGoBeyondMaxSize) {
const uint32_t initial_buffer_size = 15;
const size_t max_size = 50;
proto_config.mutable_initial_read_buffer_size()->set_value(initial_buffer_size);
cfg_ = std::make_shared<Config>(*store_.rootScope(), proto_config, max_size);
proto_config.mutable_max_client_hello_size()->set_value(max_size);
cfg_ = std::make_shared<Config>(*store_.rootScope(), proto_config);
buffer_ = std::make_unique<Network::ListenerFilterBufferImpl>(
*io_handle_, dispatcher_, [](bool) {}, [](Network::ListenerFilterBuffer&) {},
cfg_->initialReadBufferSize() == 0, cfg_->initialReadBufferSize());
Expand Down