This plugin was forked from nscuro/traefik-plugin-geoblock: traefik plugin to whitelist requests based on geolocation and remains compatible with the original plugin.
A Traefik plugin that allows or blocks requests based on IP geolocation using IP2Location database.
š This project includes IP2Location LITE data available from
lite.ip2location.com
.
It is possible to install the plugin locally or to install it through Traefik Plugins.
Create or modify your Traefik static configuration
experimental:localPlugins:geoblock:moduleName: github.com/david-garcia-garcia/traefik-geoblock
You should clone the plugin into the container, i.e
# Create the directory for the pluginsRUN set -eux; \mkdir -p /plugins-local/src/github.com/david-garcia-garciaRUN set -eux && git clone https://github.com/david-garcia-garcia/traefik-geoblock /plugins-local/src/github.com/david-garcia-garcia/traefik-geoblock --branch v1.0.1 --single-branch
Add to your Traefik static configuration:
experimental:plugins:geoblock:moduleName: github.com/david-garcia-garcia/traefik-geoblockversion: v1.0.1
version: "3.7"services:traefik:image: traefik:latestvolumes:- /var/run/docker.sock:/var/run/docker.sock- ./traefik.yml:/etc/traefik/traefik.yml- ./dynamic-config.yml:/etc/traefik/dynamic-config.yml- ./IP2LOCATION-LITE-DB1.IPV6.BIN:/plugins-storage/IP2LOCATION-LITE-DB1.IPV6.BINports:- "80:80"- "443:443"whoami:image: traefik/whoamilabels:- "traefik.enable=true"- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"- "traefik.http.routers.whoami.middlewares=geoblock@file"
http:middlewares:geoblock:plugin:geoblock:#-------------------------------# Core Settings#-------------------------------enabled: true # Enable/disable the plugin entirelydefaultAllow: false # Default behavior when no rules match (false = block)#-------------------------------# Database Configuration#-------------------------------databaseFilePath: "/plugins-local/src/github.com/david-garcia-garcia/traefik-geoblock/IP2LOCATION-LITE-DB1.IPV6.BIN"# Can be:# - Full path: /path/to/IP2LOCATION-LITE-DB1.IPV6.BIN# - Directory: /path/to/ (will search for IP2LOCATION-LITE-DB1.IPV6.BIN recursively). Use /plugins-storage/sources/ if you are installing from plugin repository.# - Empty: uses embedded database assuming it is installed in /plugins-local/src/github.com/david-garcia-garcia/traefik-geoblock/#-------------------------------# Country-based Rules (ISO 3166-1 alpha-2 format)#-------------------------------allowedCountries: # Whitelist of countries to allow- "US" # United States- "CA" # Canada- "GB" # United KingdomblockedCountries: # Blacklist of countries to block- "RU" # Russia- "CN" # China#-------------------------------# Network Rules#-------------------------------allowPrivate: true # Allow requests from private/internal networks (marked as "PRIVATE")allowedIPBlocks: # CIDR ranges to always allow (highest priority)- "192.168.0.0/16"- "10.0.0.0/8"- "2001:db8::/32"blockedIPBlocks: # CIDR ranges to always block- "203.0.113.0/24"# More specific ranges (longer prefix) take precedence#-------------------------------# Bypass Configuration#-------------------------------bypassHeaders: # Headers that skip geoblocking entirelyX-Internal-Request: "true"X-Skip-Geoblock: "1"#-------------------------------# Error Handling and ban#-------------------------------banIfError: true # Block requests if IP lookup failsdisallowedStatusCode: 403 # HTTP status code for blocked requests. If you are using banHtmlFilePath make sure to set this to a valid code (such as NOT 204).banHtmlFilePath: "/plugins-local/src/github.com/david-garcia-garcia/traefik-geoblock/geoblockban.html"# Can be:# - Full path: /path/to/geoblockban.html# - Directory: /path/to/ (will search for geoblockban.html recursively). Use /plugins-storage/sources/ if you are installing from plugin repository.# - Empty: returns only status code# Template variables available: {{.IP}} and {{.Country}}#-------------------------------# Logging Configuration#-------------------------------logLevel: "info" # Available: debug, info, warn, errorlogFormat: "json" # Available: json, textlogPath: "/var/log/geoblock.log" # Empty for Traefik's standard outputlogBannedRequests: true # Log blocked requests. They will be logged at info level.#-------------------------------# Database Auto-Update Settings#-------------------------------databaseAutoUpdate: true# Enable automatic database updates. Updates are asynchronous and triggere during middleware startup. The updated database will be used when the middleware starts again.# Make sure you whitelist in your FW domains ["download.ip2location.com", "www.ip2location.com"]databaseAutoUpdateDir: "/data/ip2database"# Directory to store updated databases. This must be a persitent volme in the traefik pod.databaseAutoUpdateToken: "" # IP2Location download token (if using premium)databaseAutoUpdateCode: "DB1" # Database product code to download (if using premium)
The plugin processes requests in the following order:
If any IP in the chain is blocked, the request is denied.
When using JSON logging, the following fields are included in the log entries:
time
: Timestamp of the request in ISO 8601 formatlevel
: Log level (debug, info, warn, error)msg
: Log message describing the actionplugin
: Plugin identifierip
: The IP address that triggered the actionip_chain
: Full chain of IP addresses from X-Forwarded-For headercountry
: Country code or "PRIVATE" for internal networkshost
: Request host headermethod
: HTTP method usedphase
: Processing phase where the action occurred:
ip_allow_private
: Private network checkip_block
: IP block rules checkcountry_block
: Country rules checkdefault
: Default allow/deny rulepath
: Request pathExample log entry:
{"time": "2025-03-01T19:24:04.414051815Z","level": "INFO","msg": "blocked request","plugin": "geoblock@docker","ip": "172.18.0.1","ip_chain": "","country": "PRIVATE","host": "localhost:8000","method": "GET","phase": "ip_allow_private","path": "/bar"}
š This project is licensed under the Apache License 2.0 - see the LICENSE file for details.