IP Geolocation

The IP geolocation network filter performs geolocation lookups on incoming connections and stores the results in the connection’s filter state under the well-known key envoy.geoip. The filter uses the client’s remote IP address to determine geographic information such as country, city, region, and ASN using a configured geolocation provider.

Tip

This filter is useful for logging geolocation data, making routing decisions based on client location, or passing location information to upstream services.

Note

The geolocation filter and providers are not yet supported on Windows.

Geolocation Providers

The filter requires a geolocation provider to perform the actual IP lookups. Currently, only the MaxMind provider is supported.

The provider configuration specifies which geolocation fields to look up and what keys to use when storing the results. Use the geo_field_keys field in the provider configuration to define the field names for each geolocation attribute.

Example

A sample filter configuration:

geoip-network-filter.yaml
 1static_resources:
 2  listeners:
 3  - name: listener_0
 4    address:
 5      socket_address:
 6        address: 0.0.0.0
 7        port_value: 10000
 8    filter_chains:
 9    - filters:
10      - name: envoy.filters.network.geoip
11        typed_config:
12          "@type": type.googleapis.com/envoy.extensions.filters.network.geoip.v3.Geoip
13          provider:
14            name: envoy.geoip_providers.maxmind
15            typed_config:
16              "@type": type.googleapis.com/envoy.extensions.geoip_providers.maxmind.v3.MaxMindConfig
17              common_provider_config:
18                geo_field_keys:
19                  country: "country"
20                  city: "city"
21                  region: "region"
22                  asn: "asn"
23              city_db_path: "/etc/GeoLite2-City.mmdb"
24              asn_db_path: "/etc/GeoLite2-ASN.mmdb"
25      - name: envoy.filters.network.tcp_proxy
26        typed_config:
27          "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
28          stat_prefix: tcp
29          cluster: cluster_0
30          access_log:
31          - name: envoy.access_loggers.file
32            typed_config:
33              "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
34              path: /dev/stdout
35              log_format:
36                text_format_source:
37                  inline_string: "[%START_TIME%] %DOWNSTREAM_REMOTE_ADDRESS% geo=%FILTER_STATE(envoy.geoip:PLAIN)%\n"
38  clusters:
39  - name: cluster_0
40    type: STATIC
41    load_assignment:
42      cluster_name: cluster_0
43      endpoints:
44      - lb_endpoints:
45        - endpoint:
46            address:
47              socket_address:
48                address: 127.0.0.1
49                port_value: 10001

Dynamic Client IP Override

By default, the filter uses the downstream connection’s remote address for geolocation lookups. For most deployments, this is sufficient since Envoy can obtain the correct client IP through:

  • Direct client connections (remote address is the client IP)

  • PROXY protocol (listener filter updates the connection’s remote address)

  • Original destination filter (preserves the original destination)

However, in advanced scenarios where the client IP needs to be extracted from another source, you can configure client_ip. This field accepts the same format specifiers as used for HTTP access logging. The format string is evaluated at connection time to produce the client IP address.

This is useful for scenarios such as:

  • Reading client IP from filter state populated by a custom filter that parses application-layer protocol headers

  • Extracting client IP from dynamic metadata set by another filter

Example using filter state

If a preceding filter has stored the client IP in filter state, you can read it using the FILTER_STATE formatter:

filter_chains:
- filters:
  # First, a custom filter sets the client IP in filter state.
  - name: envoy.filters.network.set_filter_state
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.network.set_filter_state.v3.Config
      on_new_connection:
      - object_key: my.custom.client.ip
        format_string:
          text_format_source:
            inline_string: "192.0.2.1"
  # Then use the geoip filter to read from filter state.
  - name: envoy.filters.network.geoip
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.network.geoip.v3.Geoip
      client_ip: "%FILTER_STATE(my.custom.client.ip:PLAIN)%"
      provider:
        # ... provider configuration ...

If the result is empty, -, or not a valid IP address, the filter falls back to the downstream connection’s remote address.

Accessing Geolocation Data

The filter stores geolocation results in a GeoipInfo object in the connection’s filter state under the well-known key envoy.geoip. See well known filter state for details.

The data can be accessed in several ways:

Access Logs

Use the FILTER_STATE format specifier:

# Get all geo data as JSON
%FILTER_STATE(envoy.geoip:PLAIN)%

# Get a specific field
%FILTER_STATE(envoy.geoip:FIELD:country)%

Other Filters

Downstream filters can access the GeoipInfo object from the connection’s filter state using the well-known key envoy.geoip.

Statistics

The filter outputs statistics in the geoip. namespace.

Name

Type

Description

total

Counter

Total number of connections processed by the filter.

The MaxMind provider emits additional statistics in the <stat_prefix>.maxmind. namespace per database type. Database type can be one of city_db, country_db, isp_db, anon_db, asn_db.

Name

Type

Description

<db_type>.total

Counter

Total number of lookups performed for a given geolocation database file.

<db_type>.hit

Counter

Total number of successful lookups (with non empty lookup result) performed for a given geolocation database file.

<db_type>.lookup_error

Counter

Total number of errors that occured during lookups for a given geolocation database file.

<db_type>.db_reload_success

Counter

Total number of times when the geolocation database file was reloaded successfully.

<db_type>.db_reload_error

Counter

Total number of times when the geolocation database file failed to reload.

<db_type>.db_build_epoch

Gauge

The build timestamp of the geolocation database file represented as a Unix epoch value.