GeoIP support for envoy gateway
Description: we would like to use GeoIP support with envoy gateway. It seems that envoyproxy itself supports that already https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/geoip_filter
What could be the correct place for this configuration? I am thinking could it fit under securitypolicy? basically this is similar stuff that "authorization" has, but no idea should it be under authorization or just under securitypolicy spec
cc @nezdolik
geoip databases are pretty large, so I think the envoy gateway should download the database from normal http url and then somehow upload that to envoyproxy? Wasm uses http, but envoyproxy handles the download https://github.com/envoyproxy/gateway/blob/main/api/v1alpha1/wasm_types.go#L74
perhaps that geoip plugin in envoyproxy could handle the download from http_uri, but it needs envoyproxy changes.
Currently Envoyproxy expects the databases to be present at configured location on startup, so Envoy Gateway (infra module?) could download the databases prior to spinning up Envoyproxies.
What could be the correct place for this configuration? I am thinking could it fit under securitypolicy?
Logically it does not belong to SecurityPolicy (API allowing system administrators to configure authentication and authorization policies to the traffic entering the gateway).
@zetaab feel free to raise feature request to envoyproxy repo.
imo, it does belong to securitypolicy api. If we have like 2 apis: https://foobar.com and https://huuh.com. We want that https://huh.com allows all traffic from everywhere and we want limit https://foobar.com only for instance to allow Sweden. What could be the better place for that? In securitypolicy api we can already configure do we allow or deny ip addresses, this is kind of similar stuff but with countries in it?
@zetaab from that perspective yes, if you bundle geolocation feature with rbac. But geolocation filter on its own just appends geolocation information to the request.
@nezdolik right. So basically geoip filter should be before rbac (securitypolicy authorization) and then in authorization we should have possibility deny/allow by header for instance. If authorization is not used, then geoip headers are just applied to the request and forwarded.
This issue has been automatically marked as stale because it has not had activity in the last 30 days.
/assign @nezdolik
thanks for driving this work @nezdolik !
jotting down the various items required to get this to work end to end
- the ability to download the Geo IP DB via http in envoyproxy https://github.com/envoyproxy/envoy/issues/36501
- API and functionality in EG to enable Geo IP in ClientTraficPolicy to enrich headers
- Ability to authorize on the enriched headers in SecurityPolicy https://github.com/envoyproxy/gateway/issues/4661
This issue has been automatically marked as stale because it has not had activity in the last 30 days.
still valid
This issue has been automatically marked as stale because it has not had activity in the last 30 days.
ping
hey @nezdolik still planning on working on this one ?
This issue has been automatically marked as stale because it has not had activity in the last 30 days.
Probably not stale
This issue has been automatically marked as stale because it has not had activity in the last 30 days.
Same as before
In case someone comes accross this issue, while wating for a proper implementation. I managed to get it working with the current version of envoy-gateway.
Question for someoe with more experience with the xDS API:
- Is there a more robust way to patch the HTTP-Filter-Chain, than assuming the first Network-Filter is the HTTP-Connection-Manager?
- Can there be more than 1 Network-Filters, with the current implementation of envoy-gateway?
Guide
First you need to the EnvoyPatchPolicy Resource in the envoy-gateway-controller. If you used the gateway-helm Chart you can do this in the values file:
config:
envoyGateway:
extensionApis:
# EnvoyPatchPolicy resources are disabled by default and need to be enabled explicitly
enableEnvoyPatchPolicy: true
Step 2 is to get a GeoIP database into to container. I opted for building a Container-Image, that copies the file into an emptyDir volume and run it as an Init-Container.
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: config
spec:
provider:
type: Kubernetes
kubernetes:
envoyDeployment:
# Add an emptyDir volume to the pod
pod:
volumes:
- name: geoip
emptyDir: {}
# Mount the emptyDir to envoy container
container:
volumeMounts:
- name: geoip
mountPath: /geoip-envoy
# This patch adds an init container that populated the emptyDir
patch:
value:
spec:
template:
spec:
initContainers:
- name: download-geoip
image: custom-container-image
command:
- sh
- -c
- cp /data/GeoLite2-City.mmdb /geoip-envoy/GeoLite2-City.mmdb
volumeMounts:
- name: geoip
mountPath: /geoip-envoy
Finally you can patch the default_filter_chain of the your Listener (see https://gateway.envoyproxy.io/docs/tasks/extensibility/envoy-patch-policy/). This needs to be repeated for every listener in your config
You can enable the Admin-API to get a config dump for debugging: https://gateway.envoyproxy.io/docs/troubleshooting/envoy-proxy-admin-interface/
NOTE: I am assuming, that the first Network-Filter is the HTTP-Conntection-Manager. In my Configuration it is the only Network-Filter.
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
name: patch-geoip-filter
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: external-gateway
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
name: external-gateway/external-gateway/http
operation:
op: add
# NOTE: I am assuming the first Network-Filter is envoy.filters.network.http_connection_manager
path: "/default_filter_chain/filters/0/typed_config/http_filters/0"
value:
name: envoy.filters.http.geoip
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.geoip.v3.Geoip
xff_config:
xff_num_trusted_hops: 1
provider:
name: "envoy.geoip_providers.maxmind"
typed_config:
"@type": type.googleapis.com/envoy.extensions.geoip_providers.maxmind.v3.MaxMindConfig
common_provider_config:
geo_headers_to_add:
country: "x-geo-country"
# region: "x-geo-region"
city: "x-geo-city"
# asn: "x-geo-asn"
city_db_path: "/geoip-envoy/GeoLite2-City.mmdb"
# isp_db_path: "geoip/GeoLite2-ASN.mmdb"
This issue has been automatically marked as stale because it has not had activity in the last 30 days.
Not stale