WASM filter for Envoy that adds GeoIP data to HTTP requests
- On start of WASM VM the singleton service fetches the MaxMind DB from the web server.
- Singleton service persists MaxMind DB to WASM VM shared storage.
- Each worker thread's GeoIP Filter process loads the MaxMind DB from shared storage when it's available and uses it to initialize a MaxMind Reader.
- Incoming request from downstream is intercepted by GeoIP Filter in filter chain. GeoIP Filter uses Reader to lookup geoip data of request IP and appends geoip data to request headers.
- GeoIP Filter signals Envoy to continue processing request down filter chain.
- Router filter routes request to correct upstream.
- Clean up (error handling, logging, refresh of mmdb, race conditions)
- Handle XFF appropriately
- Allow customization of request header that source IP is extracted from. Currently, limited to first IP in XFF header.
- Allow customization of request header geoip data is injected into. Currently, limited to
x-country-code
. - Allow customization of geoip data that is resolved. Currently, limited to Country Code of source IP.
- Benchmark and compare to external processor solution.
Install the wasm compiler into the rust toolchain.
rustup update
rustup rustup target add wasm32-unknown-unknown
Build the binaries for both the singleton service and the GeoIP Filter
make build
In order to test this, you must have the MaxMind GeoLite2 or GeoIP2 mmdb present locally. This project is currently hardcoded to use country DB.
# bring up Envoy, httpbin and webserver hosting GeoLite2 mmdb
make run
# test via httpbin. Spoof IP by manually setting XFF header and note x-country-code in response
# US IP
$ curl -H "X-Forwarded-For: 8.8.8.8" 127.0.0.1:10000/headers
{
"headers": {
"Accept": "*/*",
"Host": "127.0.0.1:10000",
"User-Agent": "curl/7.79.1",
"X-Country-Code": "US",
"X-Envoy-Expected-Rq-Timeout-Ms": "15000"
}
}
# Indian IP
$ curl -H "X-Forwarded-For: 3.6.203.25" 127.0.0.1:10000/headers
{
"headers": {
"Accept": "*/*",
"Host": "127.0.0.1:10000",
"User-Agent": "curl/7.79.1",
"X-Country-Code": "IN",
"X-Envoy-Expected-Rq-Timeout-Ms": "15000"
}
}
# Australian IP
$ curl -H "X-Forwarded-For: 13.210.4.1" 127.0.0.1:10000/headers
{
"headers": {
"Accept": "*/*",
"Host": "127.0.0.1:10000",
"User-Agent": "curl/7.79.1",
"X-Country-Code": "AU",
"X-Envoy-Expected-Rq-Timeout-Ms": "15000"
}
}