SkillAgentSearch skills...

Geoblock

Traefik middleware plugin - Deny requests based on country of origin

Install / Use

/learn @PascalMinder/Geoblock
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

GeoBlock

Simple plugin for Traefik to block or allow requests based on their country of origin. Uses GeoJs.io.

Configuration

It is possible to install the plugin locally or to install it through Traefik Pilot.

Configuration as local plugin

Depending on your setup, the installation steps might differ from the one described here. This example assumes that your Traefik instance runs in a Docker container and uses the official image.

Download the latest release of the plugin and save it to a location the Traefik container can reach. Below is an example of a possible setup. Notice how the plugin source is mapped into the container (/plugin/geoblock:/plugins-local/src/github.com/PascalMinder/geoblock/) via a volume bind mount:

docker-compose.yml

version: "3.7"

services:
  traefik:
    image: traefik

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /docker/config/traefik/traefik.yml:/etc/traefik/traefik.yml
      - /docker/config/traefik/dynamic-configuration.yml:/etc/traefik/dynamic-configuration.yml
      - /docker/config/traefik/plugin/geoblock:/plugins-local/src/github.com/PascalMinder/geoblock/

    ports:
      - "80:80"

  hello:
    image: containous/whoami
    labels:
      - traefik.enable=true
      - traefik.http.routers.hello.entrypoints=http
      - traefik.http.routers.hello.rule=Host(`hello.localhost`)
      - traefik.http.services.hello.loadbalancer.server.port=80
      - traefik.http.routers.hello.middlewares=my-plugin@file

To complete the setup, the Traefik configuration must be extended with the plugin. For this you must create the traefik.yml and the dynamic-configuration.yml` files if not present already.

log:
  level: INFO

experimental:
  localPlugins:
    geoblock:
      moduleName: github.com/PascalMinder/geoblock

dynamic-configuration.yml

http:
  middlewares:
    geoblock-ch:
      plugin:
        geoblock:
          silentStartUp: false
          allowLocalRequests: true
          logLocalRequests: false
          logAllowedRequests: false
          logApiRequests: true
          api: "https://get.geojs.io/v1/ip/country/{ip}"
          apiTimeoutMs: 750 # optional
          cacheSize: 15
          forceMonthlyUpdate: true
          allowUnknownCountries: false
          unknownCountryApiResponse: "nil"
          countries:
            - CH
          excludedPathPatterns:
            - "^[^/]+/health$"
            - "^[^/]+/status$"

Traefik Plugin registry

This procedure will install the plugin via the Traefik Plugin registry.

Add the following to your traefik-config.yml

experimental:
  plugins:
    geoblock:
      moduleName: "github.com/PascalMinder/geoblock"
      version: "v0.3.3"

# other stuff you might have in your traefik-config
entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    filename: "/etc/traefik/dynamic-configuration.yml"

In your dynamic configuration add the following:

http:
  middlewares:
    my-GeoBlock:
      plugin:
        geoblock:
          silentStartUp: false
          allowLocalRequests: true
          logLocalRequests: false
          logAllowedRequests: false
          logApiRequests: false
          api: "https://get.geojs.io/v1/ip/country/{ip}"
          apiTimeoutMs: 500
          cacheSize: 25
          forceMonthlyUpdate: true
          allowUnknownCountries: false
          unknownCountryApiResponse: "nil"
          countries:
            - CH
          excludedPathPatterns:
            - "^[^/]+/health$"
            - "^[^/]+/status$"

And some example docker file for traefik:

version: "3"
networks:
  proxy:
    external: true # specifies that this network has been created outside of Compose, raises an error if it doesn’t exist
services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      proxy:
        aliases:
          - traefik
    ports:
      - 80:80
      - 443:443
    volumes:
      - "/etc/timezone:/etc/timezone:ro"
      - "/etc/localtime:/etc/localtime:ro"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/a/docker/config/traefik/data/traefik.yml:/etc/traefik/traefik.yml:ro"
      - "/a/docker/config/traefik/data/dynamic-configuration.yml:/etc/traefik/dynamic-configuration.yml"

This configuration might not work. It's just to give you an idea how to configure it.

Full plugin sample configuration

  • allowLocalRequests: If set to true, will not block request from Private IP Ranges
  • logLocalRequests: If set to true, will log every connection from any IP in the private IP range
  • api: API URI used for querying the country associated with the connecting IP
  • countries: list of allowed countries
  • blackListMode: set to false so the plugin is running in whitelist mode
my-GeoBlock:
  plugin:
    GeoBlock:
      silentStartUp: false
      allowLocalRequests: false
      logLocalRequests: false
      logAllowedRequests: false
      logApiRequests: false
      api: "https://get.geojs.io/v1/ip/country/{ip}"
      apiTimeoutMs: 750 # optional
      cacheSize: 15
      forceMonthlyUpdate: false
      allowUnknownCountries: false
      unknownCountryApiResponse: "nil"
      blackListMode: false
      addCountryHeader: false
      excludedPathPatterns:
        - "^[^/]+/health$"
        - "^[^/]+/status$"
      countries:
        - AF # Afghanistan
        - AL # Albania
        - DZ # Algeria
        - AS # American Samoa
        - AD # Andorra
        - AO # Angola
        - AI # Anguilla
        - AQ # Antarctica
        - AG # Antigua and Barbuda
        - AR # Argentina
        - AM # Armenia
        - AW # Aruba
        - AU # Australia
        - AT # Austria
        - AZ # Azerbaijan
        - BS # Bahamas (the)
        - BH # Bahrain
        - BD # Bangladesh
        - BB # Barbados
        - BY # Belarus
        - BE # Belgium
        - BZ # Belize
        - BJ # Benin
        - BM # Bermuda
        - BT # Bhutan
        - BO # Bolivia (Plurinational State of)
        - BQ # Bonaire, Sint Eustatius and Saba
        - BA # Bosnia and Herzegovina
        - BW # Botswana
        - BV # Bouvet Island
        - BR # Brazil
        - IO # British Indian Ocean Territory (the)
        - BN # Brunei Darussalam
        - BG # Bulgaria
        - BF # Burkina Faso
        - BI # Burundi
        - CV # Cabo Verde
        - KH # Cambodia
        - CM # Cameroon
        - CA # Canada
        - KY # Cayman Islands (the)
        - CF # Central African Republic (the)
        - TD # Chad
        - CL # Chile
        - CN # China
        - CX # Christmas Island
        - CC # Cocos (Keeling) Islands (the)
        - CO # Colombia
        - KM # Comoros (the)
        - CD # Congo (the Democratic Republic of the)
        - CG # Congo (the)
        - CK # Cook Islands (the)
        - CR # Costa Rica
        - HR # Croatia
        - CU # Cuba
        - CW # Curaçao
        - CY # Cyprus
        - CZ # Czechia
        - CI # Côte d'Ivoire
        - DK # Denmark
        - DJ # Djibouti
        - DM # Dominica
        - DO # Dominican Republic (the)
        - EC # Ecuador
        - EG # Egypt
        - SV # El Salvador
        - GQ # Equatorial Guinea
        - ER # Eritrea
        - EE # Estonia
        - SZ # Eswatini
        - ET # Ethiopia
        - FK # Falkland Islands (the) [Malvinas]
        - FO # Faroe Islands (the)
        - FJ # Fiji
        - FI # Finland
        - FR # France
        - GF # French Guiana
        - PF # French Polynesia
        - TF # French Southern Territories (the)
        - GA # Gabon
        - GM # Gambia (the)
        - GE # Georgia
        - DE # Germany
        - GH # Ghana
        - GI # Gibraltar
        - GR # Greece
        - GL # Greenland
        - GD # Grenada
        - GP # Guadeloupe
        - GU # Guam
        - GT # Guatemala
        - GG # Guernsey
        - GN # Guinea
        - GW # Guinea-Bissau
        - GY # Guyana
        - HT # Haiti
        - HM # Heard Island and McDonald Islands
        - VA # Holy See (the)
        - HN # Honduras
        - HK # Hong Kong
        - HU # Hungary
        - IS # Iceland
        - IN # India
        - ID # Indonesia
        - IR # Iran (Islamic Republic of)
        - IQ # Iraq
        - IE # Ireland
        - IM # Isle of Man
        - IL # Israel
        - IT # Italy
        - JM # Jamaica
        - JP # Japan
        - JE # Jersey
        - JO # Jordan
        - KZ # Kazakhstan
        - KE # Kenya
        - KI # Kiribati
        - KP # Korea (the Democratic People's Republic of)
        - KR # Korea (the Republic of)
        - KW # Kuwait
        - KG # Kyrgyzstan
        - LA # Lao People's Democratic Republic (the)
        - LV # Latvia
        - LB # Lebanon
        - LS # Lesotho
        - LR # Liberia
        - LY # Libya
        - LI # Liechtenstein
        - LT # Lithuania
        - LU # Luxembourg
        - MO # Macao
        - MG # Madagascar
        - MW # Malawi
        - MY # Malaysia
        - MV # Maldives
        - ML # Mali
        - MT # Malta
        - MH # Marshall Islands (the)
        - MQ # Martinique
        - MR # Mauritania
        - MU # Mauritius
        - YT # Mayotte
        - MX # Mexico
        - FM # Micronesia (Federated States of)
        - MD # Moldova (the Republic of)
        - MC # Monaco
        - MN # Mongolia
        - ME # Montenegro
        - MS # Montserrat
        - MA # Morocco
        - MZ # Mozambique
        - MM # Myanmar
        - NA
View on GitHub
GitHub Stars302
CategoryDevelopment
Updated5d ago
Forks19

Languages

Go

Security Score

80/100

Audited on Mar 31, 2026

No findings