geo-cidr — Traefik middleware plugin
Features
- Blocks requests by IP and CIDR from multiple sources: a local default blocklist and a remote Maltrail-style list.
- Applies a whitelist that overrides any blocklist entries.
- Blocks by geography using a MaxMind GeoIP2/GeoLite2 database with configurable country codes.
- Background updaters: blocklists (default 5m) and GeoIP DB (default nightly, optional URL).
- Dynamic reloads: optional polling-based watcher that detects changes to local blocklist/whitelist files and reloads immediately.
- Prometheus metrics exposed via an in-path endpoint (default
/metrics).
Configuration (example)
# .traefik.yml (plugin manifest) contains sample testDataKey options
maltrailURL: Remote URL returning newline-separated IPs/CIDRs. Default:http://127.0.0.1:8338/fail2ban.defaultBlocklistPath: Local file with IPs/CIDRs.whitelistPath: Local file with IPs/CIDRs to allow.metricsPath: Path served by the middleware for Prometheus metrics.updateInterval: Blocklist refresh interval (e.g.,5m).timeout: HTTP client timeout for remote fetches (e.g., maltrail, GeoIP DB download). Default:10s.fileWatchInterval: Polling interval to detect local file changes fordefaultBlocklistPathandwhitelistPath.0disables (default0).geoDBPath: Path to a MaxMind GeoIP2/GeoLite2 database.geoDBUpdateURL: Optional URL to periodically download a new GeoIP DB.geoDBUpdateInterval: Interval for GeoIP DB updates (e.g.,24h).blockCountries: List of ISO country codes to block.realIPHeader: Header used to extract client IP (X-Forwarded-Fordefault).failOpen: Allow traffic if updaters/geo lookup fail (defaultfalse).
Prometheus metrics
geo_cidr_block_total{source="default|maltrail|geo"}geo_cidr_not_filtered_totalgeo_cidr_list_size{list="default|maltrail|whitelist"}geo_cidr_geo_block_by_country_total{country}geo_cidr_last_update_timestamp_seconds{component="blocklist|geodb"}geo_cidr_errors_total{component}
Testing
- Run
go test ./... -cover. - Tests use
httptestand a fake geo provider; no external network required. - CI-friendly: skip server-based tests with
-short,SKIP_SERVER_TESTS=1, orCI_RESTRICTED=1. These tests spin up anhttptestserver and perform client requests, which may be blocked in restricted sandboxes. Example:go test -short ./...orSKIP_SERVER_TESTS=1 go test ./.... A convenience targetmake test-ciis provided.
Examples
demos/docker-compose.yml: Traefik + whoami with local plugin.demos/kubernetes.yaml: Middleware CRD, ConfigMap, Service, and IngressRoute example.
CI
.gitlab-ci.ymlrunsgo testwith coverage and publishes artifacts.- In restricted runners, prefer
make test-cior setSKIP_SERVER_TESTS=1.
Notes
- This plugin serves metrics on the middleware path; ensure you exclude
/metricsfrom normal routing or place the middleware accordingly. - For GeoIP updates, provide
geoDBUpdateURLor manage the DB externally.