diff --git a/docs/BUILD b/docs/BUILD index 47190e4d..5157d7c5 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -30,6 +30,7 @@ proto_library( "//envoy/config/filter/http/fault/v2:fault", "//envoy/config/filter/http/gzip/v2:gzip", "//envoy/config/filter/http/health_check/v2:health_check", + "//envoy/config/filter/http/ip_tagging/v2:ip_tagging", "//envoy/config/filter/http/lua/v2:lua", "//envoy/config/filter/http/rate_limit/v2:rate_limit", "//envoy/config/filter/http/router/v2:router", diff --git a/docs/build.sh b/docs/build.sh index 9a0de269..a41ffcee 100755 --- a/docs/build.sh +++ b/docs/build.sh @@ -55,6 +55,7 @@ PROTO_RST=" /envoy/config/filter/http/fault/v2/fault/envoy/config/filter/http/fault/v2/fault.proto.rst /envoy/config/filter/http/gzip/v2/gzip/envoy/config/filter/http/gzip/v2/gzip.proto.rst /envoy/config/filter/http/health_check/v2/health_check/envoy/config/filter/http/health_check/v2/health_check.proto.rst + /envoy/config/filter/http/ip_tagging/v2/ip_tagging/envoy/config/filter/http/ip_tagging/v2/ip_tagging.proto.rst /envoy/config/filter/http/lua/v2/lua/envoy/config/filter/http/lua/v2/lua.proto.rst /envoy/config/filter/http/rate_limit/v2/rate_limit/envoy/config/filter/http/rate_limit/v2/rate_limit.proto.rst /envoy/config/filter/http/router/v2/router/envoy/config/filter/http/router/v2/router.proto.rst diff --git a/docs/root/api-v1/http_filters/ip_tagging_filter.rst b/docs/root/api-v1/http_filters/ip_tagging_filter.rst new file mode 100644 index 00000000..c82e356e --- /dev/null +++ b/docs/root/api-v1/http_filters/ip_tagging_filter.rst @@ -0,0 +1,52 @@ +.. _config_http_filters_ip_tagging_v1: + +HTTP IP Tagging Filter +====================== + +HTTP IP Tagging :ref:`configuration overview `. + +.. code-block:: json + + { + "name": "ip_tagging", + "config": { + "request_type": "...", + "ip_tags": [] + } + } + +request_type + *(optional, string)* The type of requests the filter should apply to. The supported + types are *INTERNAL*, *EXTERNAL* or *BOTH*. The + :ref:`x-forwarded-for` header is + used to determine if a request is internal and will result in + :ref:`x-envoy-internal` + being set. The filter defaults to both, and it will apply to all request types. + +ip_tags + *(required, array)* A list of tags and the associated IP addresses subnets. + +IP Tags +------- + +.. code-block:: json + + { + "ip_tag_name": {}, + "ip_list": [] + } + +ip_tag_name + *(required, string)* Specifies the IP tag name to apply to a request. + +ip_list + *(required, array)* A list of IP address subnets in the form "ip_address/xx". + + .. code-block:: json + + [ + "10.15.0.0/16", + "2001:db8::/32" + ] + + diff --git a/docs/root/configuration/http_conn_man/headers.rst b/docs/root/configuration/http_conn_man/headers.rst index 9c72fc6e..3b9b8341 100644 --- a/docs/root/configuration/http_conn_man/headers.rst +++ b/docs/root/configuration/http_conn_man/headers.rst @@ -283,6 +283,9 @@ A few very important notes about XFF: 1. If *use_remote_address* is set to true, Envoy sets the :ref:`config_http_conn_man_headers_x-envoy-external-address` header to the trusted client address. + +.. _config_http_conn_man_headers_x-forwarded-for_internal_origin: + 2. XFF is what Envoy uses to determine whether a request is internal origin or external origin. If *use_remote_address* is set to true, the request is internal if and only if the request contains no XFF and the immediate downstream node's connection to Envoy has diff --git a/docs/root/configuration/http_filters/http_filters.rst b/docs/root/configuration/http_filters/http_filters.rst index d16e2cdc..e7a513f7 100644 --- a/docs/root/configuration/http_filters/http_filters.rst +++ b/docs/root/configuration/http_filters/http_filters.rst @@ -15,6 +15,7 @@ HTTP filters grpc_web_filter gzip_filter health_check_filter + ip_tagging_filter lua_filter rate_limit_filter router_filter diff --git a/docs/root/configuration/http_filters/ip_tagging_filter.rst b/docs/root/configuration/http_filters/ip_tagging_filter.rst new file mode 100644 index 00000000..7a1bc9f7 --- /dev/null +++ b/docs/root/configuration/http_filters/ip_tagging_filter.rst @@ -0,0 +1,42 @@ +.. _config_http_filters_ip_tagging: + +IP Tagging +========== + +The HTTP IP Tagging filter sets the header *x-envoy-ip-tags* with the string tags for the trusted address from +:ref:`x-forwarded-for `. If there are no tags for an address, +the header is not set. + +The implementation for IP Tagging provides a scalable way to compare an IP address to a large list of CIDR +ranges efficiently. The underlying algorithm for storing tags and IP address subnets is a Level-Compressed trie +described in the paper `IP-address lookup using +LC-tries `_ by S. Nilsson and +G. Karlsson. + + +Configuration +------------- +* :ref:`v1 API reference ` +* :ref:`v2 API reference ` + +Statistics +---------- + +The IP Tagging filter outputs statistics in the *http..ip_tagging.* namespace. The stat prefix comes from +the owning HTTP connection manager. + +.. csv-table:: + :header: Name, Type, Description + :widths: 1, 1, 2 + + .hit, Counter, Total number of requests that have the applied to it. + no_hit, Counter, Total number of requests with no applicable IP tags. + total, Counter, Total number of requests the IP Tagging Filter operated on. + +Runtime +------- + +The IP Tagging filter supports the following runtime settings: + +ip_tagging.http_filter_enabled + The % of requests for which the filter is enabled. Default is 100. diff --git a/envoy/config/filter/http/ip_tagging/v2/ip_tagging.proto b/envoy/config/filter/http/ip_tagging/v2/ip_tagging.proto index c6742b14..33c03ed8 100644 --- a/envoy/config/filter/http/ip_tagging/v2/ip_tagging.proto +++ b/envoy/config/filter/http/ip_tagging/v2/ip_tagging.proto @@ -1,37 +1,47 @@ syntax = "proto3"; -// [#proto-status: experimental] - package envoy.config.filter.http.ip_tagging.v2; option go_package = "v2"; import "envoy/api/v2/core/address.proto"; -// 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. +import "google/protobuf/wrappers.proto"; + +import "validate/validate.proto"; + message IPTagging { + + // The type of requests the filter should apply to. The supported types + // are internal, external or both. The + // :ref:`x-forwarded-for` header is + // used to determine if a request is internal and will result in + // :ref:`x-envoy-internal` + // being set. The filter defaults to both, and it will apply to all request types. enum RequestType { + // Both external and internal requests will be tagged. This is the default value. BOTH = 0; + + // Only internal requests will be tagged. INTERNAL = 1; + + // Only external requests will be tagged. EXTERNAL = 2; } - // The type of requests the filter should apply to. The supported types - // are internal, external or both. A request is considered internal if - // x-envoy-internal is set to true. If 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. - RequestType request_type = 1; - - repeated IPTag ip_tags = 2; + // The type of request the filter should apply to. + RequestType request_type = 1 [(validate.rules).enum.defined_only = true]; + // Supplies the IP tag name and the IP address subnets. message IPTag { - // Specifies the ip tag name to apply. + // Specifies the IP tag name to apply. string ip_tag_name = 1; - // 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. + // A list of IP address subnets that will be tagged with + // ip_tag_name. Both IPv4 and IPv6 are supported. repeated envoy.api.v2.core.CidrRange ip_list = 2; } + + // [#comment:TODO(ccaraman): Extend functionality to load IP tags from file system.] + // The set of IP tags for the filter. + repeated IPTag ip_tags = 4 [(validate.rules).repeated .min_items = 1]; } diff --git a/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto b/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto index 2066b256..34951e09 100644 --- a/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +++ b/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto @@ -272,6 +272,7 @@ message HttpFilter { // * :ref:`envoy.grpc_json_transcoder ` // * :ref:`envoy.grpc_web ` // * :ref:`envoy.health_check ` + // * :ref:`envoy.ip_tagging ` // * :ref:`envoy.lua ` // * :ref:`envoy.rate_limit ` // * :ref:`envoy.router ` diff --git a/test/validate/BUILD b/test/validate/BUILD index 6ff25055..5ccc9f1b 100644 --- a/test/validate/BUILD +++ b/test/validate/BUILD @@ -19,6 +19,7 @@ api_cc_test( "//envoy/config/filter/http/fault/v2:fault", "//envoy/config/filter/http/gzip/v2:gzip", "//envoy/config/filter/http/health_check/v2:health_check", + "//envoy/config/filter/http/ip_tagging/v2:ip_tagging", "//envoy/config/filter/http/lua/v2:lua", "//envoy/config/filter/http/router/v2:router", "//envoy/config/filter/http/squash/v2:squash", diff --git a/test/validate/pgv_test.cc b/test/validate/pgv_test.cc index 07f49b92..31d64fe7 100644 --- a/test/validate/pgv_test.cc +++ b/test/validate/pgv_test.cc @@ -13,6 +13,7 @@ #include "envoy/config/filter/http/fault/v2/fault.pb.validate.h" #include "envoy/config/filter/http/gzip/v2/gzip.pb.validate.h" #include "envoy/config/filter/http/health_check/v2/health_check.pb.validate.h" +#include "envoy/config/filter/http/ip_tagging/v2/ip_tagging.pb.validate.h" #include "envoy/config/filter/http/lua/v2/lua.pb.validate.h" #include "envoy/config/filter/http/router/v2/router.pb.validate.h" #include "envoy/config/filter/http/squash/v2/squash.pb.validate.h"