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
2 changes: 2 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ extensions/filters/common/original_src @klarose @mattklein123
/*/extensions/filters/network/sni_cluster @rshriram @ggreenway
# sni_dynamic_forward_proxy extension
/*/extensions/filters/network/sni_dynamic_forward_proxy @rshriram @UNOWNED
# sni_to_metadata extension
/*/extensions/filters/network/sni_to_metadata @bplotnick @kbaichoo
# tracers.datadog extension
/*/extensions/tracers/datadog @dmehala @mattklein123
# tracers.xray extension
Expand Down
1 change: 1 addition & 0 deletions api/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ proto_library(
"//envoy/extensions/filters/network/set_filter_state/v3:pkg",
"//envoy/extensions/filters/network/sni_cluster/v3:pkg",
"//envoy/extensions/filters/network/sni_dynamic_forward_proxy/v3:pkg",
"//envoy/extensions/filters/network/sni_to_metadata/v3:pkg",
"//envoy/extensions/filters/network/tcp_proxy/v3:pkg",
"//envoy/extensions/filters/network/thrift_proxy/filters/header_to_metadata/v3:pkg",
"//envoy/extensions/filters/network/thrift_proxy/filters/payload_to_metadata/v3:pkg",
Expand Down
12 changes: 12 additions & 0 deletions api/envoy/extensions/filters/network/sni_to_metadata/v3/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.

load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")

licenses(["notice"]) # Apache 2

api_proto_package(
deps = [
"//envoy/type/matcher/v3:pkg",
"@com_github_cncf_xds//udpa/annotations:pkg",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
syntax = "proto3";

package envoy.extensions.filters.network.sni_to_metadata.v3;

import "envoy/type/matcher/v3/regex.proto";

import "udpa/annotations/status.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.extensions.filters.network.sni_to_metadata.v3";
option java_outer_classname = "SniToMetadataProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/sni_to_metadata/v3;sni_to_metadatav3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: SNI to Metadata Filter]

// Configuration proto schema for ``envoy.extensions.filters.network.sni_to_metadata`` network filter.
// [#extension: envoy.filters.network.sni_to_metadata]
message SniToMetadataFilter {
// MetadataTarget defines where to store extracted metadata.
message MetadataTarget {
// The metadata namespace to use when storing the result.
// If empty, defaults to ``envoy.filters.network.sni_to_metadata``
string metadata_namespace = 1;

// The metadata key to use when storing the result.
string metadata_key = 2 [(validate.rules).string = {min_len: 1}];

// The metadata value to store. If empty, the entire matched SNI value will be used.
// This field supports capture group substitution using numbered groups from the regex pattern.
// For example: ``app-\\1-\\2`` where ``\\1`` and ``\\2`` refer to the first and second capture groups (note escaped backslashes).
string metadata_value = 3;
}

// ConnectionRule defines a rule for extracting metadata from SNI.
message ConnectionRule {
// The regex pattern to match against the SNI value.
// Supports Google RE2 numbered capture groups.
// Example: ``^([^.]+)\.([^.]+)\.([^.]+)\.example\.com$``
// If not specified, the rule will always match and use the entire SNI value.
type.matcher.v3.RegexMatcher pattern = 1;
Copy link
Member

Choose a reason for hiding this comment

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

We prefer StringMatcher rather than single regex matcher. :)


// List of metadata targets to populate when this rule matches.
// Each target can use capture groups from the regex pattern in its metadata_value.
// If no pattern is specified, metadata_value will be used as-is or default to the full SNI.
repeated MetadataTarget metadata_targets = 2 [(validate.rules).repeated = {min_items: 1}];
}

// List of connection rules to evaluate against the SNI.
// Rules are evaluated in order, and the first matching rule will be applied.
repeated ConnectionRule connection_rules = 1 [(validate.rules).repeated = {min_items: 1}];
}
Comment on lines +20 to +53
Copy link
Member

Choose a reason for hiding this comment

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

Could you take the HeaderToMetadata as a reference and use the similar API (like the same KeyValuePair)? So, it would be more friendly for new users.

1 change: 1 addition & 0 deletions api/versioning/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ proto_library(
"//envoy/extensions/filters/network/set_filter_state/v3:pkg",
"//envoy/extensions/filters/network/sni_cluster/v3:pkg",
"//envoy/extensions/filters/network/sni_dynamic_forward_proxy/v3:pkg",
"//envoy/extensions/filters/network/sni_to_metadata/v3:pkg",
"//envoy/extensions/filters/network/tcp_proxy/v3:pkg",
"//envoy/extensions/filters/network/thrift_proxy/filters/header_to_metadata/v3:pkg",
"//envoy/extensions/filters/network/thrift_proxy/filters/payload_to_metadata/v3:pkg",
Expand Down
5 changes: 5 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -523,5 +523,10 @@ new_features:
change: |
Added ``max_downstream_connection_duration_jitter_percentage`` to allow adding a jitter to the max downstream connection duration.
This can be used to avoid thundering herd problems with many clients being disconnected and possibly reconnecting at the same time.
- area: sni_to_metadata
change: |
Added a new SNI-to-Metadata filter that extracts the SNI of the client connection and stores it in the connection dynamic metadata.
It is able to conditionally extract based on regex patters as well as extract fields and format the metadata using regex capture groups.
See :ref:`SNI-to-Metadata Filter <config_network_filters_sni_to_metadata>` for more details.

deprecated:
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ filters.
set_filter_state
sni_cluster_filter
sni_dynamic_forward_proxy_filter
sni_to_metadata_filter
tcp_proxy_filter
thrift_proxy_filter
wasm_filter
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.. _config_network_filters_sni_to_metadata:

SNI-to-Metadata Filter
=======================

.. attention::

SNI-to-Metadata Filter support should be considered alpha and not production ready.


The SNI-to-Metadata Filter is a filter that extracts the SNI of the client connection and stores it in the connection dynamic metadata.
It is able to conditionally extract based on regex patters as well as extract fields and format the metadata using regex capture groups.

Example Configuration
----------------------

.. code-block:: yaml

network_filters:
- name: envoy.filters.network.sni_to_metadata
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.sni_to_metadata.v3.SniToMetadataFilter
connection_rules:
- pattern: ^([^.]+)\.([^.]+)\.([^.]+)\.example\.com$
metadata_targets:
- metadata_key: app_name
metadata_namespace: envoy.lb
metadata_value: \1
1 change: 1 addition & 0 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ EXTENSIONS = {
"envoy.filters.network.set_filter_state": "//source/extensions/filters/network/set_filter_state:config",
"envoy.filters.network.sni_cluster": "//source/extensions/filters/network/sni_cluster:config",
"envoy.filters.network.sni_dynamic_forward_proxy": "//source/extensions/filters/network/sni_dynamic_forward_proxy:config",
"envoy.filters.network.sni_to_metadata": "//source/extensions/filters/network/sni_to_metadata:config",
"envoy.filters.network.wasm": "//source/extensions/filters/network/wasm:config",
"envoy.filters.network.zookeeper_proxy": "//source/extensions/filters/network/zookeeper_proxy:config",
"envoy.filters.network.generic_proxy": "//source/extensions/filters/network/generic_proxy:config",
Expand Down
7 changes: 7 additions & 0 deletions source/extensions/extensions_metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,13 @@ envoy.filters.network.sni_dynamic_forward_proxy:
status: alpha
type_urls:
- envoy.extensions.filters.network.sni_dynamic_forward_proxy.v3.FilterConfig
envoy.filters.network.sni_to_metadata:
categories:
- envoy.filters.network
security_posture: unknown
status: alpha
type_urls:
- envoy.extensions.filters.network.sni_to_metadata.v3.SniToMetadataFilter
envoy.filters.network.tcp_proxy:
categories:
- envoy.filters.network
Expand Down
39 changes: 39 additions & 0 deletions source/extensions/filters/network/sni_to_metadata/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_extension",
"envoy_cc_library",
"envoy_extension_package",
)

licenses(["notice"]) # Apache 2

envoy_extension_package()

envoy_cc_extension(
name = "config",
srcs = ["config.cc"],
hdrs = ["config.h"],
deps = [
":filter_lib",
"//source/common/common:logger_lib",
"//source/extensions/filters/network:well_known_names",
"//source/extensions/filters/network/common:factory_base_lib",
"@envoy_api//envoy/extensions/filters/network/sni_to_metadata/v3:pkg_cc_proto",
],
)

envoy_cc_library(
name = "filter_lib",
srcs = ["filter.cc"],
hdrs = ["filter.h"],
deps = [
"//envoy/network:connection_interface",
"//envoy/network:filter_interface",
"//source/common/common:logger_lib",
"//source/common/common:regex_lib",
"//source/common/protobuf",
"@com_google_absl//absl/strings",
"@com_googlesource_code_re2//:re2",
"@envoy_api//envoy/extensions/filters/network/sni_to_metadata/v3:pkg_cc_proto",
],
)
37 changes: 37 additions & 0 deletions source/extensions/filters/network/sni_to_metadata/config.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "source/extensions/filters/network/sni_to_metadata/config.h"

#include "envoy/registry/registry.h"

#include "source/extensions/filters/network/sni_to_metadata/filter.h"
#include "source/extensions/filters/network/well_known_names.h"

namespace Envoy {
namespace Extensions {
namespace NetworkFilters {
namespace SniToMetadata {

SniToMetadataFilterFactory::SniToMetadataFilterFactory()
: Common::ExceptionFreeFactoryBase<FilterConfig>(NetworkFilterNames::get().SniToMetadata) {}

absl::StatusOr<Network::FilterFactoryCb>
SniToMetadataFilterFactory::createFilterFactoryFromProtoTyped(
const FilterConfig& config, Server::Configuration::FactoryContext& context) {

absl::Status creation_status = absl::OkStatus();
ConfigSharedPtr filter_config = std::make_shared<Config>(
config, context.serverFactoryContext().regexEngine(), creation_status);

RETURN_IF_NOT_OK_REF(creation_status);

return [filter_config](Network::FilterManager& filter_manager) -> void {
filter_manager.addReadFilter(std::make_shared<Filter>(filter_config));
};
}

REGISTER_FACTORY(SniToMetadataFilterFactory,
Server::Configuration::NamedNetworkFilterConfigFactory);

} // namespace SniToMetadata
} // namespace NetworkFilters
} // namespace Extensions
} // namespace Envoy
31 changes: 31 additions & 0 deletions source/extensions/filters/network/sni_to_metadata/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "envoy/extensions/filters/network/sni_to_metadata/v3/sni_to_metadata.pb.h"
#include "envoy/extensions/filters/network/sni_to_metadata/v3/sni_to_metadata.pb.validate.h"

#include "source/extensions/filters/network/common/factory_base.h"

namespace Envoy {
namespace Extensions {
namespace NetworkFilters {
namespace SniToMetadata {

using FilterConfig = envoy::extensions::filters::network::sni_to_metadata::v3::SniToMetadataFilter;

/**
* Config registration for the SNI to metadata filter. @see NamedNetworkFilterConfigFactory.
*/
class SniToMetadataFilterFactory : public Common::ExceptionFreeFactoryBase<FilterConfig> {
public:
SniToMetadataFilterFactory();

private:
absl::StatusOr<Network::FilterFactoryCb>
createFilterFactoryFromProtoTyped(const FilterConfig& config,
Server::Configuration::FactoryContext& context) override;
};

} // namespace SniToMetadata
} // namespace NetworkFilters
} // namespace Extensions
} // namespace Envoy
Loading