From 689af405dd34f570ecb87849c94db74b032368ba Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Fri, 19 May 2017 14:17:37 -0500 Subject: [PATCH 01/20] ip tagging: filter skeleton --- source/common/http/filter/BUILD | 16 +++ .../common/http/filter/ip_tagging_filter.cc | 29 +++++ source/common/http/filter/ip_tagging_filter.h | 104 ++++++++++++++++++ source/common/json/config_schemas.cc | 35 ++++++ source/common/json/config_schemas.h | 1 + source/server/config/http/BUILD | 12 ++ source/server/config/http/ip_tagging.cc | 36 ++++++ source/server/config/http/ip_tagging.h | 26 +++++ 8 files changed, 259 insertions(+) create mode 100644 source/common/http/filter/ip_tagging_filter.cc create mode 100644 source/common/http/filter/ip_tagging_filter.h create mode 100644 source/server/config/http/ip_tagging.cc create mode 100644 source/server/config/http/ip_tagging.h diff --git a/source/common/http/filter/BUILD b/source/common/http/filter/BUILD index d01ea3ca42076..099198fb62135 100644 --- a/source/common/http/filter/BUILD +++ b/source/common/http/filter/BUILD @@ -49,6 +49,22 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "ip_tagging_filter_lib", + srcs = ["ip_tagging_filter.cc"], + hdrs = ["ip_tagging_filter.h"], + deps = [ + "//include/envoy/http:filter_interface", + "//include/envoy/json:json_object_interface", + "//include/envoy/runtime:runtime_interface", + "//include/envoy/stats:stats_interface", + "//include/envoy/stats:stats_macros", + "//source/common/common:assert_lib", + "//source/common/json:config_schemas_lib", + "//source/common/json:json_validator_lib", + ], +) + envoy_cc_library( name = "ratelimit_lib", srcs = ["ratelimit.cc"], diff --git a/source/common/http/filter/ip_tagging_filter.cc b/source/common/http/filter/ip_tagging_filter.cc new file mode 100644 index 0000000000000..19ac2e2bbd870 --- /dev/null +++ b/source/common/http/filter/ip_tagging_filter.cc @@ -0,0 +1,29 @@ +#include "common/http/filter/ip_tagging_filter.h" + +namespace Envoy { +namespace Http { + +IpTaggingFilterStats IpTaggingFilterConfig::generateStats(const std::string& prefix, + Stats::Store& store) { + std::string final_prefix = prefix + "ip_tagging."; + return {ALL_IP_TAGGING_FILTER_STATS(POOL_COUNTER_PREFIX(store, final_prefix))}; +} + +void IpTaggingFilter::onDestroy() {} + +FilterHeadersStatus IpTaggingFilter::decodeHeaders(HeaderMap&, bool) { + return FilterHeadersStatus::Continue; +} + +FilterDataStatus IpTaggingFilter::decodeData(Buffer::Instance&, bool) { + return FilterDataStatus::Continue; +} + +FilterTrailersStatus IpTaggingFilter::decodeTrailers(HeaderMap&) { + return FilterTrailersStatus::Continue; +} + +void IpTaggingFilter::setDecoderFilterCallbacks(StreamDecoderFilterCallbacks&) {} + +} // Http +} // Envoy \ No newline at end of file diff --git a/source/common/http/filter/ip_tagging_filter.h b/source/common/http/filter/ip_tagging_filter.h new file mode 100644 index 0000000000000..a7637c1d64292 --- /dev/null +++ b/source/common/http/filter/ip_tagging_filter.h @@ -0,0 +1,104 @@ +#pragma once + +#include +#include +#include +#include + +#include "envoy/http/filter.h" +#include "envoy/json/json_object.h" +#include "envoy/runtime/runtime.h" +#include "envoy/stats/stats_macros.h" + +#include "common/common/assert.h" +#include "common/json/config_schemas.h" +#include "common/json/json_validator.h" + +namespace Envoy { +namespace Http { + +/** + * All stats for the ip tagging filter. @see stats_macros.h + */ +// clang-format off +#define ALL_IP_TAGGING_FILTER_STATS(COUNTER) \ + COUNTER(placeholder) \ +// clang-format on + +/** + * Wrapper struct for connection manager stats. @see stats_macros.h + */ +struct IpTaggingFilterStats { + ALL_IP_TAGGING_FILTER_STATS(GENERATE_COUNTER_STRUCT) +}; + +/** + * Type of requests the filter should apply to. + */ +enum class FilterRequestType { + Internal, External, Both +}; + +/** + * Configuration for the ip tagging filter. + */ +class IpTaggingFilterConfig : Json::Validator { +public: + IpTaggingFilterConfig(const Json::Object& json_config, Runtime::Loader& runtime, + const std::string& stat_prefix, Stats::Store& stats) + : Json::Validator(json_config, Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA), + runtime_(runtime), stats_(generateStats(stat_prefix, stats)), + request_type_(stringToType(json_config.getString("request_type", "both"))) {} + + FilterRequestType requestType() const { return request_type_; } + //const Trie& ipTags() { return ip_tags_; } + Runtime::Loader &runtime() { return runtime_; } + IpTaggingFilterStats &stats() { return stats_; } + +private: + static FilterRequestType stringToType(const std::string& request_type) { + if (request_type == "internal") { + return FilterRequestType::Internal; + } else if (request_type == "external") { + return FilterRequestType::External; + } else { + ASSERT(request_type == "both"); + return FilterRequestType::Both; + } + } + + static IpTaggingFilterStats generateStats(const std::string& prefix, Stats::Store& store); + + //Trie ip_tags_; + Runtime::Loader& runtime_; + IpTaggingFilterStats stats_; + const FilterRequestType request_type_; +}; + +typedef std::shared_ptr IpTaggingFilterConfigSharedPtr; + +/** + * A filter that tags requests via the x-envoy-ip-tags header based on the request's trusted XFF address. + */ +class IpTaggingFilter : public StreamDecoderFilter { +public: + IpTaggingFilter(IpTaggingFilterConfigSharedPtr config) : config_(config) {} + + ~IpTaggingFilter(); + + // Http::StreamFilterBase + void onDestroy() override; + + // Http::StreamDecoderFilter + FilterHeadersStatus decodeHeaders(HeaderMap& headers, bool end_stream) override; + FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override; + FilterTrailersStatus decodeTrailers(HeaderMap& trailers) override; + void setDecoderFilterCallbacks(StreamDecoderFilterCallbacks& callbacks) override; + +private: + IpTaggingFilterConfigSharedPtr config_; + StreamDecoderFilterCallbacks* callbacks_{}; +}; + +} // Http +} // Envoy \ No newline at end of file diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index 48e758386345c..e6810b6d07d4f 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -832,6 +832,41 @@ const std::string Json::Schema::FAULT_HTTP_FILTER_SCHEMA(R"EOF( } )EOF"); +const std::string Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA(R"EOF( + { + "$schema": "http://json-schema.org/schema#", + "type" : "object", + "properties" : { + "request_type" : { + "type" : "string", + "enum" : ["internal", "external", "both"] + }, + "ip_tags" : { + "type" : "object", + "properties" : { + "ip_tag_name" : { + "type" : "string" + }, + "ip_list" : { + "type" : "array", + "minItems" : 1, + "uniqueItems": true, + "items" : { + "type": "string", + "oneOf": [ + { "format": "host-name" }, + { "format": "ipv4" }, + { "format": "ipv6" } + ] + } + } + } + } + }, + "additionalProperties" : false + } + )EOF"); + const std::string Json::Schema::HEALTH_CHECK_HTTP_FILTER_SCHEMA(R"EOF( { "$schema": "http://json-schema.org/schema#", diff --git a/source/common/json/config_schemas.h b/source/common/json/config_schemas.h index 7037390e93108..414a9044b192d 100644 --- a/source/common/json/config_schemas.h +++ b/source/common/json/config_schemas.h @@ -33,6 +33,7 @@ class Schema { static const std::string BUFFER_HTTP_FILTER_SCHEMA; static const std::string FAULT_HTTP_FILTER_SCHEMA; static const std::string HEALTH_CHECK_HTTP_FILTER_SCHEMA; + static const std::string IP_TAGGING_HTTP_FILTER_SCHEMA; static const std::string RATE_LIMIT_HTTP_FILTER_SCHEMA; static const std::string ROUTER_HTTP_FILTER_SCHEMA; diff --git a/source/server/config/http/BUILD b/source/server/config/http/BUILD index 49800b12c3492..85ec45e5af777 100644 --- a/source/server/config/http/BUILD +++ b/source/server/config/http/BUILD @@ -53,6 +53,18 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "ip_tagging_lib", + srcs = ["ip_tagging.cc"], + hdrs = ["ip_tagging.h"], + deps = [ + "//include/envoy/server:instance_interface", + "//source/common/http/filter:ip_tagging_filter_lib", + "//source/common/json:config_schemas_lib", + "//source/server/config/network:http_connection_manager_lib", + ], +) + envoy_cc_library( name = "ratelimit_lib", srcs = ["ratelimit.cc"], diff --git a/source/server/config/http/ip_tagging.cc b/source/server/config/http/ip_tagging.cc new file mode 100644 index 0000000000000..316e1e48c2a2b --- /dev/null +++ b/source/server/config/http/ip_tagging.cc @@ -0,0 +1,36 @@ +#include "server/config/http/ip_tagging.h" + +#include + +#include "common/http/filter/ip_tagging_filter.h" +#include "common/json/config_schemas.h" + +namespace Envoy { +namespace Server { +namespace Configuration { + +HttpFilterFactoryCb IpTaggingFilterConfig::tryCreateFilterFactory(HttpFilterType type, + const std::string& name, + const Json::Object& json_config, + const std::string& stats_prefix, + Server::Instance& server) { + if (type != HttpFilterType::Decoder || name != "ip_tagging") { + return nullptr; + } + + Http::IpTaggingFilterConfigSharedPtr config( + new Http::IpTaggingFilterConfig(json_config, server.runtime(), stats_prefix, server.stats())); + return [config](Http::FilterChainFactoryCallbacks& callbacks) -> void { + callbacks.addStreamDecoderFilter( + Http::StreamDecoderFilterSharedPtr{new Http::IpTaggingFilter(config)}); + }; +} + +/** + * Static registration for the ip tagging filter. @see RegisterHttpFilterConfigFactory. + */ +static RegisterHttpFilterConfigFactory register_; + +} // Configuration +} // Server +} // Envoy \ No newline at end of file diff --git a/source/server/config/http/ip_tagging.h b/source/server/config/http/ip_tagging.h new file mode 100644 index 0000000000000..fb7db31d8f425 --- /dev/null +++ b/source/server/config/http/ip_tagging.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "envoy/server/instance.h" + +#include "server/config/network/http_connection_manager.h" + +namespace Envoy { +namespace Server { +namespace Configuration { + +/** + * Config registration for the router filter. @see HttpFilterConfigFactory. + */ +class IpTaggingFilterConfig : public HttpFilterConfigFactory { +public: + HttpFilterFactoryCb tryCreateFilterFactory(HttpFilterType type, const std::string& name, + const Json::Object& json_config, + const std::string& stat_prefix, + Server::Instance& server) override; +}; + +} // Configuration +} // Server +} // Envoy \ No newline at end of file From 61a794d00e8268af2c448c3dbaa4611fedf7a55d Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Tue, 23 May 2017 12:46:36 -0700 Subject: [PATCH 02/20] comments --- source/common/http/filter/ip_tagging_filter.h | 6 ++-- source/common/json/config_schemas.cc | 35 ++++++++++--------- source/server/config/http/ip_tagging.cc | 2 +- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/source/common/http/filter/ip_tagging_filter.h b/source/common/http/filter/ip_tagging_filter.h index a7637c1d64292..cb312f4f8db0c 100644 --- a/source/common/http/filter/ip_tagging_filter.h +++ b/source/common/http/filter/ip_tagging_filter.h @@ -44,15 +44,14 @@ enum class FilterRequestType { */ class IpTaggingFilterConfig : Json::Validator { public: - IpTaggingFilterConfig(const Json::Object& json_config, Runtime::Loader& runtime, + IpTaggingFilterConfig(const Json::Object& json_config, const std::string& stat_prefix, Stats::Store& stats) : Json::Validator(json_config, Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA), - runtime_(runtime), stats_(generateStats(stat_prefix, stats)), + stats_(generateStats(stat_prefix, stats)), request_type_(stringToType(json_config.getString("request_type", "both"))) {} FilterRequestType requestType() const { return request_type_; } //const Trie& ipTags() { return ip_tags_; } - Runtime::Loader &runtime() { return runtime_; } IpTaggingFilterStats &stats() { return stats_; } private: @@ -70,7 +69,6 @@ class IpTaggingFilterConfig : Json::Validator { static IpTaggingFilterStats generateStats(const std::string& prefix, Stats::Store& store); //Trie ip_tags_; - Runtime::Loader& runtime_; IpTaggingFilterStats stats_; const FilterRequestType request_type_; }; diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index e6810b6d07d4f..e4d3ca79ddad8 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -842,22 +842,25 @@ const std::string Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA(R"EOF( "enum" : ["internal", "external", "both"] }, "ip_tags" : { - "type" : "object", - "properties" : { - "ip_tag_name" : { - "type" : "string" - }, - "ip_list" : { - "type" : "array", - "minItems" : 1, - "uniqueItems": true, - "items" : { - "type": "string", - "oneOf": [ - { "format": "host-name" }, - { "format": "ipv4" }, - { "format": "ipv6" } - ] + "type" : "array", + "minItems" : 1, + "items" : { + "type" : "object", + "properties" : { + "ip_tag_name" : { + "type" : "string" + }, + "ip_list" : { + "type" : "array", + "minItems" : 1, + "uniqueItems": true, + "items" : { + "type": "string", + "oneOf": [ + { "pattern" : "^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$" }, + { "pattern": "^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$" } + ] + } } } } diff --git a/source/server/config/http/ip_tagging.cc b/source/server/config/http/ip_tagging.cc index 316e1e48c2a2b..0f6267aa4ae9f 100644 --- a/source/server/config/http/ip_tagging.cc +++ b/source/server/config/http/ip_tagging.cc @@ -19,7 +19,7 @@ HttpFilterFactoryCb IpTaggingFilterConfig::tryCreateFilterFactory(HttpFilterType } Http::IpTaggingFilterConfigSharedPtr config( - new Http::IpTaggingFilterConfig(json_config, server.runtime(), stats_prefix, server.stats())); + new Http::IpTaggingFilterConfig(json_config, stats_prefix, server.stats())); return [config](Http::FilterChainFactoryCallbacks& callbacks) -> void { callbacks.addStreamDecoderFilter( Http::StreamDecoderFilterSharedPtr{new Http::IpTaggingFilter(config)}); From 3e94d5d1f3d646b974c369421b79c151c64dc103 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Wed, 24 May 2017 13:58:19 -0700 Subject: [PATCH 03/20] correction --- source/common/json/config_schemas.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index e4d3ca79ddad8..df464a2a04231 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -857,8 +857,8 @@ const std::string Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA(R"EOF( "items" : { "type": "string", "oneOf": [ - { "pattern" : "^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$" }, - { "pattern": "^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$" } + { "format" : "ipv4" }, + { "format": "ipv6" } ] } } From 70e473d4640083eee928a34416748d3e853680ee Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Fri, 26 May 2017 08:37:21 -0700 Subject: [PATCH 04/20] some testing --- .../common/http/filter/ip_tagging_filter.cc | 4 ++ source/common/http/filter/ip_tagging_filter.h | 9 +--- source/common/json/config_schemas.cc | 5 ++- source/server/config/http/ip_tagging.cc | 6 +-- test/server/config/http/BUILD | 1 + test/server/config/http/config_test.cc | 43 +++++++++++++++++++ 6 files changed, 56 insertions(+), 12 deletions(-) diff --git a/source/common/http/filter/ip_tagging_filter.cc b/source/common/http/filter/ip_tagging_filter.cc index 19ac2e2bbd870..20a5931e52129 100644 --- a/source/common/http/filter/ip_tagging_filter.cc +++ b/source/common/http/filter/ip_tagging_filter.cc @@ -9,6 +9,10 @@ IpTaggingFilterStats IpTaggingFilterConfig::generateStats(const std::string& pre return {ALL_IP_TAGGING_FILTER_STATS(POOL_COUNTER_PREFIX(store, final_prefix))}; } +IpTaggingFilter::IpTaggingFilter(IpTaggingFilterConfigSharedPtr config) : config_(config) {} + +IpTaggingFilter::~IpTaggingFilter() {} + void IpTaggingFilter::onDestroy() {} FilterHeadersStatus IpTaggingFilter::decodeHeaders(HeaderMap&, bool) { diff --git a/source/common/http/filter/ip_tagging_filter.h b/source/common/http/filter/ip_tagging_filter.h index cb312f4f8db0c..eb46cc5d9f386 100644 --- a/source/common/http/filter/ip_tagging_filter.h +++ b/source/common/http/filter/ip_tagging_filter.h @@ -44,15 +44,12 @@ enum class FilterRequestType { */ class IpTaggingFilterConfig : Json::Validator { public: - IpTaggingFilterConfig(const Json::Object& json_config, - const std::string& stat_prefix, Stats::Store& stats) + IpTaggingFilterConfig(const Json::Object& json_config) : Json::Validator(json_config, Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA), - stats_(generateStats(stat_prefix, stats)), request_type_(stringToType(json_config.getString("request_type", "both"))) {} FilterRequestType requestType() const { return request_type_; } //const Trie& ipTags() { return ip_tags_; } - IpTaggingFilterStats &stats() { return stats_; } private: static FilterRequestType stringToType(const std::string& request_type) { @@ -69,7 +66,6 @@ class IpTaggingFilterConfig : Json::Validator { static IpTaggingFilterStats generateStats(const std::string& prefix, Stats::Store& store); //Trie ip_tags_; - IpTaggingFilterStats stats_; const FilterRequestType request_type_; }; @@ -80,8 +76,7 @@ typedef std::shared_ptr IpTaggingFilterConfigSharedPtr; */ class IpTaggingFilter : public StreamDecoderFilter { public: - IpTaggingFilter(IpTaggingFilterConfigSharedPtr config) : config_(config) {} - + IpTaggingFilter(IpTaggingFilterConfigSharedPtr config); ~IpTaggingFilter(); // Http::StreamFilterBase diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index df464a2a04231..a9b5f61672ebf 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -856,12 +856,13 @@ const std::string Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA(R"EOF( "uniqueItems": true, "items" : { "type": "string", - "oneOf": [ + "anyOf": [ { "format" : "ipv4" }, { "format": "ipv6" } ] } - } + }, + "required" : ["ip_tag_name", "ip_list"] } } } diff --git a/source/server/config/http/ip_tagging.cc b/source/server/config/http/ip_tagging.cc index 0f6267aa4ae9f..018ec6ff427c5 100644 --- a/source/server/config/http/ip_tagging.cc +++ b/source/server/config/http/ip_tagging.cc @@ -12,14 +12,14 @@ namespace Configuration { HttpFilterFactoryCb IpTaggingFilterConfig::tryCreateFilterFactory(HttpFilterType type, const std::string& name, const Json::Object& json_config, - const std::string& stats_prefix, - Server::Instance& server) { + const std::string&, + Server::Instance&) { if (type != HttpFilterType::Decoder || name != "ip_tagging") { return nullptr; } Http::IpTaggingFilterConfigSharedPtr config( - new Http::IpTaggingFilterConfig(json_config, stats_prefix, server.stats())); + new Http::IpTaggingFilterConfig(json_config)); return [config](Http::FilterChainFactoryCallbacks& callbacks) -> void { callbacks.addStreamDecoderFilter( Http::StreamDecoderFilterSharedPtr{new Http::IpTaggingFilter(config)}); diff --git a/test/server/config/http/BUILD b/test/server/config/http/BUILD index 373c8530f4379..66a37f052bbd0 100644 --- a/test/server/config/http/BUILD +++ b/test/server/config/http/BUILD @@ -16,6 +16,7 @@ envoy_cc_test( "//source/server/config/http:dynamo_lib", "//source/server/config/http:fault_lib", "//source/server/config/http:grpc_http1_bridge_lib", + "//source/server/config/http:ip_tagging_lib", "//source/server/config/http:ratelimit_lib", "//source/server/config/http:router_lib", "//source/server/http:health_check_lib", diff --git a/test/server/config/http/config_test.cc b/test/server/config/http/config_test.cc index 42f8e3bb39b04..494a6c435e64b 100644 --- a/test/server/config/http/config_test.cc +++ b/test/server/config/http/config_test.cc @@ -4,6 +4,7 @@ #include "server/config/http/dynamo.h" #include "server/config/http/fault.h" #include "server/config/http/grpc_http1_bridge.h" +#include "server/config/http/ip_tagging.h" #include "server/config/http/ratelimit.h" #include "server/config/http/router.h" #include "server/http/health_check.h" @@ -175,6 +176,48 @@ TEST(HttpFilterConfigTest, BadRouterFilterConfig) { Json::Exception); } +TEST(HttpFilterConfigTest, IpTaggingFilter) { +std::string json_string = R"EOF( + { + "request_type" : "internal", + "ip_tags" : [ + { "ip_tag_name" : "example_tag", + "ip_list" : ["10.98.103.4", "3.67.89.9/4"] + } + ] + } + )EOF"; + +Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); +NiceMock server; +IpTaggingFilterConfig factory; +HttpFilterFactoryCb cb = factory.tryCreateFilterFactory(HttpFilterType::Decoder, "ip_tagging", + *json_config, "stats", server); +Http::MockFilterChainFactoryCallbacks filter_callback; +EXPECT_CALL(filter_callback, addStreamDecoderFilter(_)); +cb(filter_callback); +} + +TEST(HttpFilterConfigTest, BadIpTaggingFilterConfig) { +std::string json_string = R"EOF( + { + "ip_tags" : [ + { + "ip_tag_name" : "example", + "ip_list" : [] + } + ] + } + )EOF"; + +Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); +NiceMock server; +IpTaggingFilterConfig factory; +EXPECT_THROW(factory.tryCreateFilterFactory(HttpFilterType::Decoder, "ip_tagging", *json_config, +"stats", server), +Json::Exception); +} + } // Configuration } // Server } // Envoy From 3c73c735ab64057268630f74c9ec428b5349d950 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Fri, 26 May 2017 08:38:27 -0700 Subject: [PATCH 05/20] format --- source/server/config/http/ip_tagging.cc | 3 +-- test/server/config/http/config_test.cc | 32 ++++++++++++------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/source/server/config/http/ip_tagging.cc b/source/server/config/http/ip_tagging.cc index 018ec6ff427c5..5ffe21ad9814d 100644 --- a/source/server/config/http/ip_tagging.cc +++ b/source/server/config/http/ip_tagging.cc @@ -18,8 +18,7 @@ HttpFilterFactoryCb IpTaggingFilterConfig::tryCreateFilterFactory(HttpFilterType return nullptr; } - Http::IpTaggingFilterConfigSharedPtr config( - new Http::IpTaggingFilterConfig(json_config)); + Http::IpTaggingFilterConfigSharedPtr config(new Http::IpTaggingFilterConfig(json_config)); return [config](Http::FilterChainFactoryCallbacks& callbacks) -> void { callbacks.addStreamDecoderFilter( Http::StreamDecoderFilterSharedPtr{new Http::IpTaggingFilter(config)}); diff --git a/test/server/config/http/config_test.cc b/test/server/config/http/config_test.cc index 494a6c435e64b..50f91259de2dc 100644 --- a/test/server/config/http/config_test.cc +++ b/test/server/config/http/config_test.cc @@ -177,7 +177,7 @@ TEST(HttpFilterConfigTest, BadRouterFilterConfig) { } TEST(HttpFilterConfigTest, IpTaggingFilter) { -std::string json_string = R"EOF( + std::string json_string = R"EOF( { "request_type" : "internal", "ip_tags" : [ @@ -188,18 +188,18 @@ std::string json_string = R"EOF( } )EOF"; -Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); -NiceMock server; -IpTaggingFilterConfig factory; -HttpFilterFactoryCb cb = factory.tryCreateFilterFactory(HttpFilterType::Decoder, "ip_tagging", - *json_config, "stats", server); -Http::MockFilterChainFactoryCallbacks filter_callback; -EXPECT_CALL(filter_callback, addStreamDecoderFilter(_)); -cb(filter_callback); + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); + NiceMock server; + IpTaggingFilterConfig factory; + HttpFilterFactoryCb cb = factory.tryCreateFilterFactory(HttpFilterType::Decoder, "ip_tagging", + *json_config, "stats", server); + Http::MockFilterChainFactoryCallbacks filter_callback; + EXPECT_CALL(filter_callback, addStreamDecoderFilter(_)); + cb(filter_callback); } TEST(HttpFilterConfigTest, BadIpTaggingFilterConfig) { -std::string json_string = R"EOF( + std::string json_string = R"EOF( { "ip_tags" : [ { @@ -210,12 +210,12 @@ std::string json_string = R"EOF( } )EOF"; -Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); -NiceMock server; -IpTaggingFilterConfig factory; -EXPECT_THROW(factory.tryCreateFilterFactory(HttpFilterType::Decoder, "ip_tagging", *json_config, -"stats", server), -Json::Exception); + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); + NiceMock server; + IpTaggingFilterConfig factory; + EXPECT_THROW(factory.tryCreateFilterFactory(HttpFilterType::Decoder, "ip_tagging", *json_config, + "stats", server), + Json::Exception); } } // Configuration From db04ac6283f0adc9cb5652463c28d54850ba09e3 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Fri, 26 May 2017 12:22:56 -0700 Subject: [PATCH 06/20] docs --- .../http_filters/http_filters.rst | 1 + .../http_filters/ip_tagging_filter.rst | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 docs/configuration/http_filters/ip_tagging_filter.rst diff --git a/docs/configuration/http_filters/http_filters.rst b/docs/configuration/http_filters/http_filters.rst index 7efb0bfc73aa8..8834b1cbbeb3a 100644 --- a/docs/configuration/http_filters/http_filters.rst +++ b/docs/configuration/http_filters/http_filters.rst @@ -12,5 +12,6 @@ HTTP filters grpc_http1_bridge_filter grpc_web_filter health_check_filter + ip_tagging_filter rate_limit_filter router_filter diff --git a/docs/configuration/http_filters/ip_tagging_filter.rst b/docs/configuration/http_filters/ip_tagging_filter.rst new file mode 100644 index 0000000000000..f0fa25239195a --- /dev/null +++ b/docs/configuration/http_filters/ip_tagging_filter.rst @@ -0,0 +1,45 @@ +.. _config_http_filters_ip_tagging: + +Ip tagging filter +==================== + +This is a filter which enables Envoy to tag requests with extra information such as location, cloud source and any +extra data. This is useful to prevent against DDoS. + +**Note**: this filter is under active development, and currently does not perform any tagging on requests. In other +words, installing this filter is a nop in the filter chain. + +.. code-block:: json + + { + "type": "decoder", + "name": "ip_tagging", + "config": { + "request_type": "...", + "ip_tags": [] + } + } + +request_type: + (optional, string) The type of requests the filter should apply to. ``external``, ``internal``, or ``both``. + Defaults to ``both``. + +ip_tags: + (optional, array) Specifies the list of ip tags to set for a request. + +Ip tags +------- +.. code-block:: json + + { + "ip_tag_name": "...", + "ip_list": [] + } + +ip_tag_name: + (required, string) Specifies the ip tag name to apply. The names will be added to the request's ``x-envoy-ip-tag`` + header if the request's XFF address belongs to a range present in the ``ip_list`` + +ip_list: + (required, list of strings) A list of IP address and subnet masks that will be tagged with the ``ip_tag_name``. Both + IPv4, and IPv6 CIDR addresses are allowed here. \ No newline at end of file From 232ab0617b825e50b3206900adcef4e6e589ae2b Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Fri, 26 May 2017 12:33:51 -0700 Subject: [PATCH 07/20] fix --- source/server/config/http/BUILD | 1 + test/server/config/http/config_test.cc | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/source/server/config/http/BUILD b/source/server/config/http/BUILD index 0d7b71f06571c..3829c15d3c784 100644 --- a/source/server/config/http/BUILD +++ b/source/server/config/http/BUILD @@ -72,6 +72,7 @@ envoy_cc_library( "//include/envoy/server:instance_interface", "//source/common/http/filter:ip_tagging_filter_lib", "//source/common/json:config_schemas_lib", + "//source/server/config/network:http_connection_manager_lib", ], ) diff --git a/test/server/config/http/config_test.cc b/test/server/config/http/config_test.cc index bb2ab97722b62..69900a3cbf5d0 100644 --- a/test/server/config/http/config_test.cc +++ b/test/server/config/http/config_test.cc @@ -4,12 +4,9 @@ #include "server/config/http/dynamo.h" #include "server/config/http/fault.h" #include "server/config/http/grpc_http1_bridge.h" -<<<<<<< HEAD -#include "server/config/http/ip_tagging.h" -======= #include "server/config/http/grpc_web.h" +#include "server/config/http/ip_tagging.h" #include "server/config/http/lightstep_http_tracer.h" ->>>>>>> master #include "server/config/http/ratelimit.h" #include "server/config/http/router.h" #include "server/config/http/zipkin_http_tracer.h" @@ -197,7 +194,6 @@ TEST(HttpFilterConfigTest, BadRouterFilterConfig) { Json::Exception); } -<<<<<<< HEAD TEST(HttpFilterConfigTest, IpTaggingFilter) { std::string json_string = R"EOF( { @@ -238,6 +234,7 @@ TEST(HttpFilterConfigTest, BadIpTaggingFilterConfig) { EXPECT_THROW(factory.tryCreateFilterFactory(HttpFilterType::Decoder, "ip_tagging", *json_config, "stats", server), Json::Exception); +} TEST(HttpFilterConfigTest, DoubleRegistrationTest) { EXPECT_THROW_WITH_MESSAGE( From 133780f18366a2c78e7ba732ceacbacc4e1043fb Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Fri, 26 May 2017 12:37:12 -0700 Subject: [PATCH 08/20] remove baggage --- source/common/http/filter/BUILD | 3 --- source/common/http/filter/ip_tagging_filter.cc | 6 ------ source/common/http/filter/ip_tagging_filter.h | 6 ------ 3 files changed, 15 deletions(-) diff --git a/source/common/http/filter/BUILD b/source/common/http/filter/BUILD index 099198fb62135..4d7bb76a3f39d 100644 --- a/source/common/http/filter/BUILD +++ b/source/common/http/filter/BUILD @@ -56,9 +56,6 @@ envoy_cc_library( deps = [ "//include/envoy/http:filter_interface", "//include/envoy/json:json_object_interface", - "//include/envoy/runtime:runtime_interface", - "//include/envoy/stats:stats_interface", - "//include/envoy/stats:stats_macros", "//source/common/common:assert_lib", "//source/common/json:config_schemas_lib", "//source/common/json:json_validator_lib", diff --git a/source/common/http/filter/ip_tagging_filter.cc b/source/common/http/filter/ip_tagging_filter.cc index 20a5931e52129..f5cf61db5e4e2 100644 --- a/source/common/http/filter/ip_tagging_filter.cc +++ b/source/common/http/filter/ip_tagging_filter.cc @@ -3,12 +3,6 @@ namespace Envoy { namespace Http { -IpTaggingFilterStats IpTaggingFilterConfig::generateStats(const std::string& prefix, - Stats::Store& store) { - std::string final_prefix = prefix + "ip_tagging."; - return {ALL_IP_TAGGING_FILTER_STATS(POOL_COUNTER_PREFIX(store, final_prefix))}; -} - IpTaggingFilter::IpTaggingFilter(IpTaggingFilterConfigSharedPtr config) : config_(config) {} IpTaggingFilter::~IpTaggingFilter() {} diff --git a/source/common/http/filter/ip_tagging_filter.h b/source/common/http/filter/ip_tagging_filter.h index eb46cc5d9f386..4e44cafbe2d4d 100644 --- a/source/common/http/filter/ip_tagging_filter.h +++ b/source/common/http/filter/ip_tagging_filter.h @@ -7,8 +7,6 @@ #include "envoy/http/filter.h" #include "envoy/json/json_object.h" -#include "envoy/runtime/runtime.h" -#include "envoy/stats/stats_macros.h" #include "common/common/assert.h" #include "common/json/config_schemas.h" @@ -49,7 +47,6 @@ class IpTaggingFilterConfig : Json::Validator { request_type_(stringToType(json_config.getString("request_type", "both"))) {} FilterRequestType requestType() const { return request_type_; } - //const Trie& ipTags() { return ip_tags_; } private: static FilterRequestType stringToType(const std::string& request_type) { @@ -63,9 +60,6 @@ class IpTaggingFilterConfig : Json::Validator { } } - static IpTaggingFilterStats generateStats(const std::string& prefix, Stats::Store& store); - - //Trie ip_tags_; const FilterRequestType request_type_; }; From f3d3da281dd642b6e2372fd3f87dd70d0ecbce5f Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Fri, 26 May 2017 12:39:57 -0700 Subject: [PATCH 09/20] nits --- source/common/http/filter/ip_tagging_filter.cc | 2 +- source/common/http/filter/ip_tagging_filter.h | 17 +---------------- source/server/config/http/ip_tagging.cc | 2 +- source/server/config/http/ip_tagging.h | 2 +- 4 files changed, 4 insertions(+), 19 deletions(-) diff --git a/source/common/http/filter/ip_tagging_filter.cc b/source/common/http/filter/ip_tagging_filter.cc index f5cf61db5e4e2..4e2f4939ef1f0 100644 --- a/source/common/http/filter/ip_tagging_filter.cc +++ b/source/common/http/filter/ip_tagging_filter.cc @@ -24,4 +24,4 @@ FilterTrailersStatus IpTaggingFilter::decodeTrailers(HeaderMap&) { void IpTaggingFilter::setDecoderFilterCallbacks(StreamDecoderFilterCallbacks&) {} } // Http -} // Envoy \ No newline at end of file +} // Envoy diff --git a/source/common/http/filter/ip_tagging_filter.h b/source/common/http/filter/ip_tagging_filter.h index 4e44cafbe2d4d..b210612ec14b2 100644 --- a/source/common/http/filter/ip_tagging_filter.h +++ b/source/common/http/filter/ip_tagging_filter.h @@ -15,21 +15,6 @@ namespace Envoy { namespace Http { -/** - * All stats for the ip tagging filter. @see stats_macros.h - */ -// clang-format off -#define ALL_IP_TAGGING_FILTER_STATS(COUNTER) \ - COUNTER(placeholder) \ -// clang-format on - -/** - * Wrapper struct for connection manager stats. @see stats_macros.h - */ -struct IpTaggingFilterStats { - ALL_IP_TAGGING_FILTER_STATS(GENERATE_COUNTER_STRUCT) -}; - /** * Type of requests the filter should apply to. */ @@ -88,4 +73,4 @@ class IpTaggingFilter : public StreamDecoderFilter { }; } // Http -} // Envoy \ No newline at end of file +} // Envoy diff --git a/source/server/config/http/ip_tagging.cc b/source/server/config/http/ip_tagging.cc index 5ffe21ad9814d..2028393d069aa 100644 --- a/source/server/config/http/ip_tagging.cc +++ b/source/server/config/http/ip_tagging.cc @@ -32,4 +32,4 @@ static RegisterHttpFilterConfigFactory register_; } // Configuration } // Server -} // Envoy \ No newline at end of file +} // Envoy diff --git a/source/server/config/http/ip_tagging.h b/source/server/config/http/ip_tagging.h index fb7db31d8f425..0760b5186d37e 100644 --- a/source/server/config/http/ip_tagging.h +++ b/source/server/config/http/ip_tagging.h @@ -23,4 +23,4 @@ class IpTaggingFilterConfig : public HttpFilterConfigFactory { } // Configuration } // Server -} // Envoy \ No newline at end of file +} // Envoy From 291bb69cb0f9dcdcede02f0f95a1d1432f2dbf61 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Fri, 26 May 2017 15:56:35 -0700 Subject: [PATCH 10/20] format --- source/common/http/filter/ip_tagging_filter.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/source/common/http/filter/ip_tagging_filter.h b/source/common/http/filter/ip_tagging_filter.h index b210612ec14b2..13841d6fb1577 100644 --- a/source/common/http/filter/ip_tagging_filter.h +++ b/source/common/http/filter/ip_tagging_filter.h @@ -18,9 +18,7 @@ namespace Http { /** * Type of requests the filter should apply to. */ -enum class FilterRequestType { - Internal, External, Both -}; +enum class FilterRequestType { Internal, External, Both }; /** * Configuration for the ip tagging filter. @@ -28,8 +26,8 @@ enum class FilterRequestType { class IpTaggingFilterConfig : Json::Validator { public: IpTaggingFilterConfig(const Json::Object& json_config) - : Json::Validator(json_config, Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA), - request_type_(stringToType(json_config.getString("request_type", "both"))) {} + : Json::Validator(json_config, Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA), + request_type_(stringToType(json_config.getString("request_type", "both"))) {} FilterRequestType requestType() const { return request_type_; } @@ -51,7 +49,8 @@ class IpTaggingFilterConfig : Json::Validator { typedef std::shared_ptr IpTaggingFilterConfigSharedPtr; /** - * A filter that tags requests via the x-envoy-ip-tags header based on the request's trusted XFF address. + * A filter that tags requests via the x-envoy-ip-tags header based on the request's trusted XFF + * address. */ class IpTaggingFilter : public StreamDecoderFilter { public: From 8f6de6643a2b65236ca01ee38c22953769ebfe60 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Fri, 26 May 2017 17:54:09 -0700 Subject: [PATCH 11/20] fix --- source/common/http/filter/ip_tagging_filter.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/common/http/filter/ip_tagging_filter.cc b/source/common/http/filter/ip_tagging_filter.cc index 4e2f4939ef1f0..f8d292ded42d9 100644 --- a/source/common/http/filter/ip_tagging_filter.cc +++ b/source/common/http/filter/ip_tagging_filter.cc @@ -21,7 +21,9 @@ FilterTrailersStatus IpTaggingFilter::decodeTrailers(HeaderMap&) { return FilterTrailersStatus::Continue; } -void IpTaggingFilter::setDecoderFilterCallbacks(StreamDecoderFilterCallbacks&) {} +void IpTaggingFilter::setDecoderFilterCallbacks(StreamDecoderFilterCallbacks& callbacks) { + callbacks_ = &callbacks; +} } // Http } // Envoy From 3b96d32560df198a71bfb6705015fcaf55eb7405 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Tue, 30 May 2017 12:23:31 -0700 Subject: [PATCH 12/20] address comments --- docs/configuration/http_conn_man/headers.rst | 10 ++++++++ .../http_filters/ip_tagging_filter.rst | 23 +++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/docs/configuration/http_conn_man/headers.rst b/docs/configuration/http_conn_man/headers.rst index 03ba36d616499..838adaee7b2b9 100644 --- a/docs/configuration/http_conn_man/headers.rst +++ b/docs/configuration/http_conn_man/headers.rst @@ -90,6 +90,16 @@ the header value to *true*. This is a convenience to avoid having to parse and understand XFF. +.. _config_http_conn_man_headers_x-envoy-ip-tags: + +x-envoy-ip-tags +--------------- + +This header is populated by the :ref:`Ip Tagging Filter`. +The header contains a comma delimited list of Ip Tags as +defined by the ``ip_tag_name`` property of an Ip Tag. If a request's final XFF contents belong to a range specified +by an Ip Tag's ``ip_list``, then ``ip_tag_name`` will be appended to the ``x-envoy-ip-tags`` header. + .. _config_http_conn_man_headers_x-forwarded-for: x-forwarded-for diff --git a/docs/configuration/http_filters/ip_tagging_filter.rst b/docs/configuration/http_filters/ip_tagging_filter.rst index f0fa25239195a..5f9d42c94f4f0 100644 --- a/docs/configuration/http_filters/ip_tagging_filter.rst +++ b/docs/configuration/http_filters/ip_tagging_filter.rst @@ -7,7 +7,7 @@ This is a filter which enables Envoy to tag requests with extra information such extra data. This is useful to prevent against DDoS. **Note**: this filter is under active development, and currently does not perform any tagging on requests. In other -words, installing this filter is a nop in the filter chain. +words, installing this filter is a no-op in the filter chain. .. code-block:: json @@ -20,12 +20,16 @@ words, installing this filter is a nop in the filter chain. } } -request_type: - (optional, string) The type of requests the filter should apply to. ``external``, ``internal``, or ``both``. - Defaults to ``both``. +request_type + *(optional, string)* The type of requests the filter should apply to. The supported + types are *internal*, *external* or *both*. A request is considered internal if + :ref:`x-envoy-internal` is set to true. If + :ref:`x-envoy-internal` is not set or false, a + request is considered external. The filter defaults to *both*, and it will apply to all request + types. ip_tags: - (optional, array) Specifies the list of ip tags to set for a request. + *(optional, array)* Specifies the list of ip tags to set for a request. Ip tags ------- @@ -37,9 +41,10 @@ Ip tags } ip_tag_name: - (required, string) Specifies the ip tag name to apply. The names will be added to the request's ``x-envoy-ip-tag`` - header if the request's XFF address belongs to a range present in the ``ip_list`` + *(required, string)* Specifies the ip tag name to apply. The ``ip_tag_name`` will be appended to the request's + :ref:`x-envoy-ip-tags` header if the request's final XFF contents + belong to a range present in the ``ip_list``. ip_list: - (required, list of strings) A list of IP address and subnet masks that will be tagged with the ``ip_tag_name``. Both - IPv4, and IPv6 CIDR addresses are allowed here. \ No newline at end of file + *(required, list of strings)* A list of IP address and subnet masks that will be tagged with the ``ip_tag_name``. Both + IPv4 and IPv6 CIDR addresses are allowed here. \ No newline at end of file From b0ed6323eb090dc5aa0c1bdf196bdd8840ceb441 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Tue, 30 May 2017 13:41:16 -0700 Subject: [PATCH 13/20] new filter registration --- source/server/config/http/ip_tagging.cc | 18 ++++++++++-------- source/server/config/http/ip_tagging.h | 13 +++++++------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/source/server/config/http/ip_tagging.cc b/source/server/config/http/ip_tagging.cc index 2028393d069aa..d5d910c6adf3f 100644 --- a/source/server/config/http/ip_tagging.cc +++ b/source/server/config/http/ip_tagging.cc @@ -9,13 +9,13 @@ namespace Envoy { namespace Server { namespace Configuration { -HttpFilterFactoryCb IpTaggingFilterConfig::tryCreateFilterFactory(HttpFilterType type, - const std::string& name, - const Json::Object& json_config, - const std::string&, - Server::Instance&) { - if (type != HttpFilterType::Decoder || name != "ip_tagging") { - return nullptr; +HttpFilterFactoryCb IpTaggingFilterConfig::createFilterFactory(HttpFilterType type, + const Json::Object& json_config, + const std::string&, + Server::Instance&) { + if (type != HttpFilterType::Decoder) { + throw EnvoyException( + fmt::format("{} ip tagging filter must be configured as a decoder filter.", name())); } Http::IpTaggingFilterConfigSharedPtr config(new Http::IpTaggingFilterConfig(json_config)); @@ -25,10 +25,12 @@ HttpFilterFactoryCb IpTaggingFilterConfig::tryCreateFilterFactory(HttpFilterType }; } +std::string IpTaggingFilterConfig::name() { return "ip_tagging"; } + /** * Static registration for the ip tagging filter. @see RegisterHttpFilterConfigFactory. */ -static RegisterHttpFilterConfigFactory register_; +static RegisterNamedHttpFilterConfigFactory register_; } // Configuration } // Server diff --git a/source/server/config/http/ip_tagging.h b/source/server/config/http/ip_tagging.h index 0760b5186d37e..1be838ed71e0b 100644 --- a/source/server/config/http/ip_tagging.h +++ b/source/server/config/http/ip_tagging.h @@ -11,14 +11,15 @@ namespace Server { namespace Configuration { /** - * Config registration for the router filter. @see HttpFilterConfigFactory. + * Config registration for the router filter. @see NamedHttpFilterConfigFactory. */ -class IpTaggingFilterConfig : public HttpFilterConfigFactory { +class IpTaggingFilterConfig : public NamedHttpFilterConfigFactory { public: - HttpFilterFactoryCb tryCreateFilterFactory(HttpFilterType type, const std::string& name, - const Json::Object& json_config, - const std::string& stat_prefix, - Server::Instance& server) override; + HttpFilterFactoryCb createFilterFactory(HttpFilterType type, const Json::Object& json_config, + const std::string& stat_prefix, + Server::Instance& server) override; + + std::string name() override; }; } // Configuration From 0843393cf92bbce957e20dc892dcf152a64d2592 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Tue, 30 May 2017 13:49:37 -0700 Subject: [PATCH 14/20] comment --- source/server/config/http/ip_tagging.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/server/config/http/ip_tagging.cc b/source/server/config/http/ip_tagging.cc index d5d910c6adf3f..fa8a2f0ac84d1 100644 --- a/source/server/config/http/ip_tagging.cc +++ b/source/server/config/http/ip_tagging.cc @@ -28,7 +28,7 @@ HttpFilterFactoryCb IpTaggingFilterConfig::createFilterFactory(HttpFilterType ty std::string IpTaggingFilterConfig::name() { return "ip_tagging"; } /** - * Static registration for the ip tagging filter. @see RegisterHttpFilterConfigFactory. + * Static registration for the ip tagging filter. @see NamedRegisterHttpFilterConfigFactory. */ static RegisterNamedHttpFilterConfigFactory register_; From bbb539dfc047aa3c0dce6cfc119e4588ac8f3600 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Tue, 30 May 2017 13:50:16 -0700 Subject: [PATCH 15/20] comment --- source/server/config/http/ip_tagging.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/server/config/http/ip_tagging.cc b/source/server/config/http/ip_tagging.cc index fa8a2f0ac84d1..c4cbaea85ad2c 100644 --- a/source/server/config/http/ip_tagging.cc +++ b/source/server/config/http/ip_tagging.cc @@ -28,7 +28,7 @@ HttpFilterFactoryCb IpTaggingFilterConfig::createFilterFactory(HttpFilterType ty std::string IpTaggingFilterConfig::name() { return "ip_tagging"; } /** - * Static registration for the ip tagging filter. @see NamedRegisterHttpFilterConfigFactory. + * Static registration for the ip tagging filter. @see RegisterNamedHttpFilterConfigFactory. */ static RegisterNamedHttpFilterConfigFactory register_; From 588c59c6aafb01efca55b02bd4955255702193e0 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Wed, 31 May 2017 16:33:59 -0700 Subject: [PATCH 16/20] update --- docs/configuration/http_conn_man/headers.rst | 5 +---- docs/configuration/http_filters/ip_tagging_filter.rst | 4 +--- test/server/config/http/config_test.cc | 4 ++-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/docs/configuration/http_conn_man/headers.rst b/docs/configuration/http_conn_man/headers.rst index a3bdcc8a8510e..24020d0ae40d5 100644 --- a/docs/configuration/http_conn_man/headers.rst +++ b/docs/configuration/http_conn_man/headers.rst @@ -104,10 +104,7 @@ This is a convenience to avoid having to parse and understand XFF. x-envoy-ip-tags --------------- -This header is populated by the :ref:`Ip Tagging Filter`. -The header contains a comma delimited list of Ip Tags as -defined by the ``ip_tag_name`` property of an Ip Tag. If a request's final XFF contents belong to a range specified -by an Ip Tag's ``ip_list``, then ``ip_tag_name`` will be appended to the ``x-envoy-ip-tags`` header. +This header is populated by the :ref:`Ip Tagging Filter`. Behavior is under development. .. _config_http_conn_man_headers_x-forwarded-for: diff --git a/docs/configuration/http_filters/ip_tagging_filter.rst b/docs/configuration/http_filters/ip_tagging_filter.rst index 5f9d42c94f4f0..0b17d9b53fefa 100644 --- a/docs/configuration/http_filters/ip_tagging_filter.rst +++ b/docs/configuration/http_filters/ip_tagging_filter.rst @@ -41,9 +41,7 @@ Ip tags } ip_tag_name: - *(required, string)* Specifies the ip tag name to apply. The ``ip_tag_name`` will be appended to the request's - :ref:`x-envoy-ip-tags` header if the request's final XFF contents - belong to a range present in the ``ip_list``. + *(required, string)* Specifies the ip tag name to apply. ip_list: *(required, list of strings)* A list of IP address and subnet masks that will be tagged with the ``ip_tag_name``. Both diff --git a/test/server/config/http/config_test.cc b/test/server/config/http/config_test.cc index 69900a3cbf5d0..e069afe7e62ec 100644 --- a/test/server/config/http/config_test.cc +++ b/test/server/config/http/config_test.cc @@ -209,7 +209,7 @@ TEST(HttpFilterConfigTest, IpTaggingFilter) { Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); NiceMock server; IpTaggingFilterConfig factory; - HttpFilterFactoryCb cb = factory.tryCreateFilterFactory(HttpFilterType::Decoder, "ip_tagging", + HttpFilterFactoryCb cb = factory.createFilterFactory(HttpFilterType::Decoder, *json_config, "stats", server); Http::MockFilterChainFactoryCallbacks filter_callback; EXPECT_CALL(filter_callback, addStreamDecoderFilter(_)); @@ -231,7 +231,7 @@ TEST(HttpFilterConfigTest, BadIpTaggingFilterConfig) { Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); NiceMock server; IpTaggingFilterConfig factory; - EXPECT_THROW(factory.tryCreateFilterFactory(HttpFilterType::Decoder, "ip_tagging", *json_config, + EXPECT_THROW(factory.createFilterFactory(HttpFilterType::Decoder, *json_config, "stats", server), Json::Exception); } From 970e112a29e20d3e2f45b24ac275ccce8f508731 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Wed, 31 May 2017 17:24:36 -0700 Subject: [PATCH 17/20] update --- source/common/json/config_schemas.cc | 22 ++++++++-------------- test/server/config/http/config_test.cc | 7 +++---- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/source/common/json/config_schemas.cc b/source/common/json/config_schemas.cc index b4cdf552f0330..33e83729cf815 100644 --- a/source/common/json/config_schemas.cc +++ b/source/common/json/config_schemas.cc @@ -844,26 +844,20 @@ const std::string Json::Schema::IP_TAGGING_HTTP_FILTER_SCHEMA(R"EOF( "ip_tags" : { "type" : "array", "minItems" : 1, + "uniqueItems" : true, "items" : { "type" : "object", "properties" : { - "ip_tag_name" : { - "type" : "string" - }, + "ip_tag_name" : { "type" : "string" }, "ip_list" : { "type" : "array", "minItems" : 1, - "uniqueItems": true, - "items" : { - "type": "string", - "anyOf": [ - { "format" : "ipv4" }, - { "format": "ipv6" } - ] - } - }, - "required" : ["ip_tag_name", "ip_list"] - } + "uniqueItems" : true, + "items" : { "type" : "string" } + } + }, + "required" : ["ip_tag_name", "ip_list"], + "additionalProperties" : false } } }, diff --git a/test/server/config/http/config_test.cc b/test/server/config/http/config_test.cc index e069afe7e62ec..67fed2ecf4e58 100644 --- a/test/server/config/http/config_test.cc +++ b/test/server/config/http/config_test.cc @@ -200,7 +200,7 @@ TEST(HttpFilterConfigTest, IpTaggingFilter) { "request_type" : "internal", "ip_tags" : [ { "ip_tag_name" : "example_tag", - "ip_list" : ["10.98.103.4", "3.67.89.9/4"] + "ip_list" : ["0.0.0.0"] } ] } @@ -219,10 +219,9 @@ TEST(HttpFilterConfigTest, IpTaggingFilter) { TEST(HttpFilterConfigTest, BadIpTaggingFilterConfig) { std::string json_string = R"EOF( { + "request_type" : "internal", "ip_tags" : [ - { - "ip_tag_name" : "example", - "ip_list" : [] + { "ip_tag_name" : "example_tag" } ] } From 476c46af7a8d31595b1e747d1e209d795b52e51d Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Wed, 31 May 2017 17:32:33 -0700 Subject: [PATCH 18/20] fix --- test/common/upstream/cluster_manager_impl_test.cc | 2 +- test/server/config/http/config_test.cc | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index efae2dacd721a..02554f89d8ea1 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -208,7 +208,7 @@ TEST_F(ClusterManagerImplTest, LocalClusterDefined) { "connect_timeout_ms": 250, "type": "static", "lb_type": "round_robin", - "hosts": [{"url": "tcp://127.0.0.1:11001"}] + "hosts": [{"url": "tcp://127.0.0.1:11001"}, {}] }, { "name": "cluster_2", diff --git a/test/server/config/http/config_test.cc b/test/server/config/http/config_test.cc index 67fed2ecf4e58..b141ac9351ba5 100644 --- a/test/server/config/http/config_test.cc +++ b/test/server/config/http/config_test.cc @@ -209,8 +209,8 @@ TEST(HttpFilterConfigTest, IpTaggingFilter) { Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); NiceMock server; IpTaggingFilterConfig factory; - HttpFilterFactoryCb cb = factory.createFilterFactory(HttpFilterType::Decoder, - *json_config, "stats", server); + HttpFilterFactoryCb cb = + factory.createFilterFactory(HttpFilterType::Decoder, *json_config, "stats", server); Http::MockFilterChainFactoryCallbacks filter_callback; EXPECT_CALL(filter_callback, addStreamDecoderFilter(_)); cb(filter_callback); @@ -230,8 +230,7 @@ TEST(HttpFilterConfigTest, BadIpTaggingFilterConfig) { Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); NiceMock server; IpTaggingFilterConfig factory; - EXPECT_THROW(factory.createFilterFactory(HttpFilterType::Decoder, *json_config, - "stats", server), + EXPECT_THROW(factory.createFilterFactory(HttpFilterType::Decoder, *json_config, "stats", server), Json::Exception); } From c43598b679248069259e9df817fb5c6577898ac1 Mon Sep 17 00:00:00 2001 From: Jose Nino Date: Wed, 31 May 2017 22:53:01 -0700 Subject: [PATCH 19/20] fix --- test/common/upstream/cluster_manager_impl_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index 02554f89d8ea1..efae2dacd721a 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -208,7 +208,7 @@ TEST_F(ClusterManagerImplTest, LocalClusterDefined) { "connect_timeout_ms": 250, "type": "static", "lb_type": "round_robin", - "hosts": [{"url": "tcp://127.0.0.1:11001"}, {}] + "hosts": [{"url": "tcp://127.0.0.1:11001"}] }, { "name": "cluster_2", From 27900bc78499c72f8036285a340b0d6ed510f262 Mon Sep 17 00:00:00 2001 From: Jose Ulises Nino Rivera Date: Thu, 1 Jun 2017 11:54:16 -0700 Subject: [PATCH 20/20] nit --- docs/configuration/http_filters/ip_tagging_filter.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration/http_filters/ip_tagging_filter.rst b/docs/configuration/http_filters/ip_tagging_filter.rst index 0b17d9b53fefa..0810d748132a0 100644 --- a/docs/configuration/http_filters/ip_tagging_filter.rst +++ b/docs/configuration/http_filters/ip_tagging_filter.rst @@ -3,7 +3,7 @@ Ip tagging filter ==================== -This is a filter which enables Envoy to tag requests with extra information such as location, cloud source and any +This is an HTTP filter which enables Envoy to tag requests with extra information such as location, cloud source, and any extra data. This is useful to prevent against DDoS. **Note**: this filter is under active development, and currently does not perform any tagging on requests. In other @@ -45,4 +45,4 @@ ip_tag_name: ip_list: *(required, list of strings)* A list of IP address and subnet masks that will be tagged with the ``ip_tag_name``. Both - IPv4 and IPv6 CIDR addresses are allowed here. \ No newline at end of file + IPv4 and IPv6 CIDR addresses are allowed here.