-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
MaxMind Geolocation provider #28490
MaxMind Geolocation provider #28490
Changes from all commits
aeffe67
8b62ccb
569a987
5ba28ed
6e3287c
04368f1
8784a98
8df0173
52efec3
1237ed7
bea685b
aa124fa
e502d25
87d06bb
5fdf71b
ac7d26d
728e668
b72dd29
9eba89e
6cd9757
ef2c242
3f20397
480d6a2
80ae14a
01f2030
011085f
f95320e
fee7009
0f1e241
589223c
b7aa80c
e33798a
9e2e620
7e570ca
60ef4ac
d485807
9162b23
c6d0ae7
ef299ec
50020d2
d5fdbf7
3e8e2d7
9751802
051b1bc
6480a0a
b3d0b15
c3ccfd9
b2006b7
b861cfc
631a2ef
b304f70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# 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 = ["@com_github_cncf_udpa//udpa/annotations:pkg"], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
syntax = "proto3"; | ||
|
||
package envoy.extensions.geoip_providers.common.v3; | ||
|
||
import "udpa/annotations/status.proto"; | ||
import "validate/validate.proto"; | ||
|
||
option java_package = "io.envoyproxy.envoy.extensions.geoip_providers.common.v3"; | ||
option java_outer_classname = "CommonProto"; | ||
option java_multiple_files = true; | ||
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/geoip_providers/common/v3;commonv3"; | ||
option (udpa.annotations.file_status).package_version_status = ACTIVE; | ||
|
||
// [#protodoc-title: Common Geolocation Provider Configuration] | ||
// Common geolocation provider :ref:`configuration overview <config_geoip_providers_common>`. | ||
// Common configuration shared across geolocation providers. | ||
|
||
message CommonGeoipProviderConfig { | ||
// The set of geolocation headers to add to request. If any of the configured headers is present | ||
// in the incoming request, it will be overridden by the :ref:`Geoip filter <config_http_filters_geoip>`. | ||
// [#next-free-field: 10] | ||
message GeolocationHeadersToAdd { | ||
// If set, the header will be used to populate the country ISO code associated with the IP address. | ||
string country = 1 | ||
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; | ||
|
||
// If set, the header will be used to populate the city associated with the IP address. | ||
string city = 2 | ||
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; | ||
|
||
// If set, the header will be used to populate the region ISO code associated with the IP address. | ||
// The least specific subdivision will be selected as region value. | ||
string region = 3 | ||
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; | ||
|
||
// If set, the header will be used to populate the ASN associated with the IP address. | ||
string asn = 4 | ||
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; | ||
|
||
// If set, the IP address will be checked if it belongs to any type of anonymization network (e.g. VPN, public proxy etc) | ||
// and header will be populated with the check result. Header value will be set to either "true" or "false" depending on the check result. | ||
string is_anon = 5 | ||
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; | ||
|
||
// If set, the IP address will be checked if it belongs to a VPN and header will be populated with the check result. | ||
// Header value will be set to either "true" or "false" depending on the check result. | ||
string anon_vpn = 6 | ||
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; | ||
|
||
// If set, the IP address will be checked if it belongs to a hosting provider and header will be populated with the check result. | ||
// Header value will be set to either "true" or "false" depending on the check result. | ||
string anon_hosting = 7 | ||
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; | ||
|
||
// If set, the IP address will be checked if it belongs to a TOR exit node and header will be populated with the check result. | ||
// Header value will be set to either "true" or "false" depending on the check result. | ||
string anon_tor = 8 | ||
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; | ||
|
||
// If set, the IP address will be checked if it belongs to a public proxy and header will be populated with the check result. | ||
// Header value will be set to either "true" or "false" depending on the check result. | ||
string anon_proxy = 9 | ||
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; | ||
} | ||
|
||
// Configuration for geolocation headers to add to request. | ||
GeolocationHeadersToAdd geo_headers_to_add = 1 [(validate.rules).message = {required: true}]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking out loud here, why was this moved into the provider? In other words, say one has 2 providers, do they need a different headers to add for each one of them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, it makes more sense logically to have this part of config in geoip filter. The disadvantage is that we will not be able to do certain perf optimisation (like not opening mmdb files that are not needed to be open on provider creation) and more complex data structures/interface between filter and provider will be used. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @adisuissa It is possible to have 2 providers with different configuration, as not all geolocation providers offer anonymous dataset (most of them don't). |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# 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/extensions/geoip_providers/common/v3:pkg", | ||
"@com_github_cncf_udpa//udpa/annotations:pkg", | ||
"@com_github_cncf_udpa//xds/annotations/v3:pkg", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
syntax = "proto3"; | ||
|
||
package envoy.extensions.geoip_providers.maxmind.v3; | ||
|
||
import "envoy/extensions/geoip_providers/common/v3/common.proto"; | ||
|
||
import "xds/annotations/v3/status.proto"; | ||
|
||
import "udpa/annotations/status.proto"; | ||
import "validate/validate.proto"; | ||
|
||
option java_package = "io.envoyproxy.envoy.extensions.geoip_providers.maxmind.v3"; | ||
option java_outer_classname = "MaxmindProto"; | ||
option java_multiple_files = true; | ||
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/geoip_providers/maxmind/v3;maxmindv3"; | ||
option (udpa.annotations.file_status).package_version_status = ACTIVE; | ||
option (xds.annotations.v3.file_status).work_in_progress = true; | ||
|
||
// [#protodoc-title: MaxMind Geolocation Provider] | ||
// MaxMind geolocation provider :ref:`configuration overview <config_geoip_providers_maxmind>`. | ||
// At least one geolocation database path :ref:`city_db_path <envoy_v3_api_field_extensions.geoip_providers.maxmind.v3.MaxMindConfig.city_db_path>`, | ||
// :ref:`isp_db_path <envoy_v3_api_field_extensions.geoip_providers.maxmind.v3.MaxMindConfig.isp_db_path>` or | ||
// :ref:`anon_db_path <envoy_v3_api_field_extensions.geoip_providers.maxmind.v3.MaxMindConfig.anon_db_path>` must be configured. | ||
// [#extension: envoy.geoip_providers.maxmind] | ||
|
||
message MaxMindConfig { | ||
// Full file path to the Maxmind city database, e.g. /etc/GeoLite2-City.mmdb. | ||
// Database file is expected to have .mmdb extension. | ||
string city_db_path = 1 [(validate.rules).string = {pattern: "^$|^.*\\.mmdb$"}]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will there ever be a need for non path input sources? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's highly unlikely unless we will switch to a different maxmind library, and we are currently relying on a stable official one. That library expects an absolute file path format to initialise a database. If database is consumed from remote source, users can implement an external tool to download db files to filesystem local to Envoy process. |
||
|
||
// Full file path to the Maxmind ASN database, e.g. /etc/GeoLite2-ASN.mmdb. | ||
// Database file is expected to have .mmdb extension. | ||
string isp_db_path = 2 [(validate.rules).string = {pattern: "^$|^.*\\.mmdb$"}]; | ||
|
||
// Full file path to the Maxmind anonymous IP database, e.g. /etc/GeoIP2-Anonymous-IP.mmdb. | ||
// Database file is expected to have .mmdb extension. | ||
string anon_db_path = 3 [(validate.rules).string = {pattern: "^$|^.*\\.mmdb$"}]; | ||
|
||
// Common provider configuration that specifies which geolocation headers will be populated with geolocation data. | ||
common.v3.CommonGeoipProviderConfig common_provider_config = 4 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking out loud here, why was this moved into the provider? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question, initially i added
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apologies, I might be missing something, so bear with me while I offer a design that may not be fully correct. IIUC there could be multiple listeners/routes with the GeoIP filter. Each one may have a different set of headers to add, and could maybe reuse the same (or different) providers. As a first part, I guess the manager could only support a single filter-config (not shared across other configs). It could have a single method that receives both configs (the provider and the high-level config one that contains "headers-to-add"). Let me know if I missed some optimization that could not be achieved this way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @adisuissa, overall design suggestion sounds good to me. It solves the problem of need for sharing part of configuration between filter and provider and offers clean api to users. I would like to keep per route configuration out of scope for now if possible, as filter is still WIP and the current PR is large in size and has been ongoing for quite some time. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I forgot that it is still WIP, thanks for reminding me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No worries, there are remaining obligatory chunks of work, like for example support of db file reload, make encoding type configurable (maxmind only does UTF8 which may not work with H2), so filter is not fully production ready yet. Geoip headers will be moved back to filter api as part of obligatory work. |
||
[(validate.rules).message = {required: true}]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1459,6 +1459,21 @@ REPOSITORY_LOCATIONS_SPEC = dict( | |
license = "MIT", | ||
license_url = "https://github.com/protocolbuffers/utf8_range/blob/{version}/LICENSE", | ||
), | ||
com_github_maxmind_libmaxminddb = dict( | ||
project_name = "maxmind_libmaxminddb", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this comply with https://github.com/envoyproxy/envoy/blob/main/DEPENDENCY_POLICY.md#new-external-dependencies? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, I need to file the dedicated issue for dependency review. Working on it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Waiting for input from libmaxminddb maintainers: maxmind/libmaxminddb#319 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I'm reasonably convinced this is a dependency we can on-board. @moderation @phlax any objection? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ping @phlax @moderation for opinions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @phlax @moderation ping. |
||
project_desc = "C library for reading MaxMind DB files", | ||
project_url = "https://github.com/maxmind/libmaxminddb", | ||
version = "1.7.1", | ||
sha256 = "e8414f0dedcecbc1f6c31cb65cd81650952ab0677a4d8c49cab603b3b8fb083e", | ||
strip_prefix = "libmaxminddb-{version}", | ||
urls = ["https://github.com/maxmind/libmaxminddb/releases/download/{version}/libmaxminddb-{version}.tar.gz"], | ||
use_category = ["dataplane_ext"], | ||
extensions = ["envoy.geoip_providers.maxmind"], | ||
release_date = "2022-09-30", | ||
cpe = "cpe:2.3:a:maxmind:libmaxminddb:*", | ||
license = "Apache-2.0", | ||
license_url = "https://github.com/maxmind/libmaxminddb/blob/{version}/LICENSE", | ||
), | ||
) | ||
|
||
def _compiled_protoc_deps(locations, versions): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.. _api-v3_config_geoip_providers: | ||
|
||
Geolocation providers | ||
===================== | ||
|
||
.. toctree:: | ||
:glob: | ||
:maxdepth: 2 | ||
|
||
../../extensions/geoip_providers/*/v3/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to future reviewers: Although this is a breaking API change, it is allowed. This is because the filter is still WIP.