{"id":13582127,"url":"https://github.com/PascalMinder/geoblock","last_synced_at":"2025-04-06T13:32:50.461Z","repository":{"id":42386591,"uuid":"346829555","full_name":"PascalMinder/geoblock","owner":"PascalMinder","description":"Traefik middleware plugin - Deny requests based on country of origin","archived":false,"fork":false,"pushed_at":"2025-02-11T11:08:52.000Z","size":94,"stargazers_count":121,"open_issues_count":6,"forks_count":11,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-11T12:23:48.091Z","etag":null,"topics":["traefik-plugin"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PascalMinder.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-11T20:32:46.000Z","updated_at":"2025-02-11T12:06:32.000Z","dependencies_parsed_at":"2024-04-18T14:01:36.014Z","dependency_job_id":"2c49e0c5-7a99-4851-8af0-10cbbe47b39c","html_url":"https://github.com/PascalMinder/geoblock","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PascalMinder%2Fgeoblock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PascalMinder%2Fgeoblock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PascalMinder%2Fgeoblock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PascalMinder%2Fgeoblock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PascalMinder","download_url":"https://codeload.github.com/PascalMinder/geoblock/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247488844,"owners_count":20947014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["traefik-plugin"],"created_at":"2024-08-01T15:02:26.536Z","updated_at":"2025-04-06T13:32:50.434Z","avatar_url":"https://github.com/PascalMinder.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# GeoBlock\n\nSimple plugin for [Traefik](https://github.com/containous/traefik) to block or allow requests based on their country of origin. Uses [GeoJs.io](https://www.geojs.io/).\n\n## Configuration\n\nIt is possible to install the [plugin locally](https://traefik.io/blog/using-private-plugins-in-traefik-proxy-2-5/) or to install it through [Traefik Pilot](https://pilot.traefik.io/plugins).\n\n### Configuration as local plugin\n\nDepending 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](https://hub.docker.com/_/traefik/).\n\nDownload 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:\n\n#### `docker-compose.yml`\n\n````yml\nversion: \"3.7\"\n\nservices:\n  traefik:\n    image: traefik\n\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n      - /docker/config/traefik/traefik.yml:/etc/traefik/traefik.yml\n      - /docker/config/traefik/dynamic-configuration.yml:/etc/traefik/dynamic-configuration.yml\n      - /docker/config/traefik/plugin/geoblock:/plugins-local/src/github.com/PascalMinder/geoblock/\n\n    ports:\n      - \"80:80\"\n\n  hello:\n    image: containous/whoami\n    labels:\n      - traefik.enable=true\n      - traefik.http.routers.hello.entrypoints=http\n      - traefik.http.routers.hello.rule=Host(`hello.localhost`)\n      - traefik.http.services.hello.loadbalancer.server.port=80\n      - traefik.http.routers.hello.middlewares=my-plugin@file\n````\n\nTo 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.\n\n````yml\nlog:\n  level: INFO\n\nexperimental:\n  localPlugins:\n    geoblock:\n      moduleName: github.com/PascalMinder/geoblock\n````\n\n#### `dynamic-configuration.yml`\n\n````yml\nhttp:\n  middlewares:\n    geoblock-ch:\n      plugin:\n        geoblock:\n          silentStartUp: false\n          allowLocalRequests: true\n          logLocalRequests: false\n          logAllowedRequests: false\n          logApiRequests: true\n          api: \"https://get.geojs.io/v1/ip/country/{ip}\"\n          apiTimeoutMs: 750                                 # optional\n          cacheSize: 15\n          forceMonthlyUpdate: true\n          allowUnknownCountries: false\n          unknownCountryApiResponse: \"nil\"\n          countries:\n            - CH\n````\n\n### Traefik Plugin registry\n\nThis procedure will install the plugin via the [Traefik Plugin registry](https://plugins.traefik.io/install).\n\nAdd the following to your `traefik-config.yml`\n\n```yml\nexperimental:\n  plugins:\n    geoblock:\n      moduleName: \"github.com/PascalMinder/geoblock\"\n      version: \"v0.2.5\"\n\n# other stuff you might have in your traefik-config\nentryPoints:\n  http:\n    address: \":80\"\n  https:\n    address: \":443\"\n\nproviders:\n  docker:\n    endpoint: \"unix:///var/run/docker.sock\"\n    exposedByDefault: false\n  file:\n    filename: \"/etc/traefik/dynamic-configuration.yml\"\n```\n\nIn your dynamic configuration add the following:\n\n```yml\nhttp:\n  middlewares:\n    my-GeoBlock:\n      plugin:\n        geoblock:\n          silentStartUp: false\n          allowLocalRequests: true\n          logLocalRequests: false\n          logAllowedRequests: false\n          logApiRequests: false\n          api: \"https://get.geojs.io/v1/ip/country/{ip}\"\n          apiTimeoutMs: 500\n          cacheSize: 25\n          forceMonthlyUpdate: true\n          allowUnknownCountries: false\n          unknownCountryApiResponse: \"nil\"\n          countries:\n            - CH\n```\n\nAnd some example docker file for traefik:\n\n```yml\nversion: \"3\"\nnetworks:\n  proxy:\n    external: true # specifies that this network has been created outside of Compose, raises an error if it doesn’t exist\nservices:\n  traefik:\n    image: traefik:latest\n    container_name: traefik\n    restart: unless-stopped\n    security_opt:\n      - no-new-privileges:true\n    networks:\n      proxy:\n        aliases:\n          - traefik\n    ports:\n      - 80:80\n      - 443:443\n    volumes:\n      - \"/etc/timezone:/etc/timezone:ro\"\n      - \"/etc/localtime:/etc/localtime:ro\"\n      - \"/var/run/docker.sock:/var/run/docker.sock:ro\"\n      - \"/a/docker/config/traefik/data/traefik.yml:/etc/traefik/traefik.yml:ro\"\n      - \"/a/docker/config/traefik/data/dynamic-configuration.yml:/etc/traefik/dynamic-configuration.yml\"\n```\n\nThis configuration might not work. It's just to give you an idea how to configure it.\n\n## Full plugin sample configuration\n\n- `allowLocalRequests`: If set to true, will not block request from [Private IP Ranges](https://de.wikipedia.org/wiki/Private_IP-Adresse)\n- `logLocalRequests`: If set to true, will log every connection from any IP in the private IP range\n- `api`: API URI used for querying the country associated with the connecting IP\n- `countries`: list of allowed countries\n- `blackListMode`: set to `false` so the plugin is running in `whitelist mode`\n\n````yml\nmy-GeoBlock:\n    plugin:\n        GeoBlock:\n            silentStartUp: false\n            allowLocalRequests: false\n            logLocalRequests: false\n            logAllowedRequests: false\n            logApiRequests: false\n            api: \"https://get.geojs.io/v1/ip/country/{ip}\"\n            apiTimeoutMs: 750                                 # optional\n            cacheSize: 15\n            forceMonthlyUpdate: false\n            allowUnknownCountries: false\n            unknownCountryApiResponse: \"nil\"\n            blackListMode: false\n            addCountryHeader: false\n            countries:\n                - AF # Afghanistan\n                - AL # Albania\n                - DZ # Algeria\n                - AS # American Samoa\n                - AD # Andorra\n                - AO # Angola\n                - AI # Anguilla\n                - AQ # Antarctica\n                - AG # Antigua and Barbuda\n                - AR # Argentina\n                - AM # Armenia\n                - AW # Aruba\n                - AU # Australia\n                - AT # Austria\n                - AZ # Azerbaijan\n                - BS # Bahamas (the)\n                - BH # Bahrain\n                - BD # Bangladesh\n                - BB # Barbados\n                - BY # Belarus\n                - BE # Belgium\n                - BZ # Belize\n                - BJ # Benin\n                - BM # Bermuda\n                - BT # Bhutan\n                - BO # Bolivia (Plurinational State of)\n                - BQ # Bonaire, Sint Eustatius and Saba\n                - BA # Bosnia and Herzegovina\n                - BW # Botswana\n                - BV # Bouvet Island\n                - BR # Brazil\n                - IO # British Indian Ocean Territory (the)\n                - BN # Brunei Darussalam\n                - BG # Bulgaria\n                - BF # Burkina Faso\n                - BI # Burundi\n                - CV # Cabo Verde\n                - KH # Cambodia\n                - CM # Cameroon\n                - CA # Canada\n                - KY # Cayman Islands (the)\n                - CF # Central African Republic (the)\n                - TD # Chad\n                - CL # Chile\n                - CN # China\n                - CX # Christmas Island\n                - CC # Cocos (Keeling) Islands (the)\n                - CO # Colombia\n                - KM # Comoros (the)\n                - CD # Congo (the Democratic Republic of the)\n                - CG # Congo (the)\n                - CK # Cook Islands (the)\n                - CR # Costa Rica\n                - HR # Croatia\n                - CU # Cuba\n                - CW # Curaçao\n                - CY # Cyprus\n                - CZ # Czechia\n                - CI # Côte d'Ivoire\n                - DK # Denmark\n                - DJ # Djibouti\n                - DM # Dominica\n                - DO # Dominican Republic (the)\n                - EC # Ecuador\n                - EG # Egypt\n                - SV # El Salvador\n                - GQ # Equatorial Guinea\n                - ER # Eritrea\n                - EE # Estonia\n                - SZ # Eswatini\n                - ET # Ethiopia\n                - FK # Falkland Islands (the) [Malvinas]\n                - FO # Faroe Islands (the)\n                - FJ # Fiji\n                - FI # Finland\n                - FR # France\n                - GF # French Guiana\n                - PF # French Polynesia\n                - TF # French Southern Territories (the)\n                - GA # Gabon\n                - GM # Gambia (the)\n                - GE # Georgia\n                - DE # Germany\n                - GH # Ghana\n                - GI # Gibraltar\n                - GR # Greece\n                - GL # Greenland\n                - GD # Grenada\n                - GP # Guadeloupe\n                - GU # Guam\n                - GT # Guatemala\n                - GG # Guernsey\n                - GN # Guinea\n                - GW # Guinea-Bissau\n                - GY # Guyana\n                - HT # Haiti\n                - HM # Heard Island and McDonald Islands\n                - VA # Holy See (the)\n                - HN # Honduras\n                - HK # Hong Kong\n                - HU # Hungary\n                - IS # Iceland\n                - IN # India\n                - ID # Indonesia\n                - IR # Iran (Islamic Republic of)\n                - IQ # Iraq\n                - IE # Ireland\n                - IM # Isle of Man\n                - IL # Israel\n                - IT # Italy\n                - JM # Jamaica\n                - JP # Japan\n                - JE # Jersey\n                - JO # Jordan\n                - KZ # Kazakhstan\n                - KE # Kenya\n                - KI # Kiribati\n                - KP # Korea (the Democratic People's Republic of)\n                - KR # Korea (the Republic of)\n                - KW # Kuwait\n                - KG # Kyrgyzstan\n                - LA # Lao People's Democratic Republic (the)\n                - LV # Latvia\n                - LB # Lebanon\n                - LS # Lesotho\n                - LR # Liberia\n                - LY # Libya\n                - LI # Liechtenstein\n                - LT # Lithuania\n                - LU # Luxembourg\n                - MO # Macao\n                - MG # Madagascar\n                - MW # Malawi\n                - MY # Malaysia\n                - MV # Maldives\n                - ML # Mali\n                - MT # Malta\n                - MH # Marshall Islands (the)\n                - MQ # Martinique\n                - MR # Mauritania\n                - MU # Mauritius\n                - YT # Mayotte\n                - MX # Mexico\n                - FM # Micronesia (Federated States of)\n                - MD # Moldova (the Republic of)\n                - MC # Monaco\n                - MN # Mongolia\n                - ME # Montenegro\n                - MS # Montserrat\n                - MA # Morocco\n                - MZ # Mozambique\n                - MM # Myanmar\n                - NA # Namibia\n                - NR # Nauru\n                - NP # Nepal\n                - NL # Netherlands (the)\n                - NC # New Caledonia\n                - NZ # New Zealand\n                - NI # Nicaragua\n                - NE # Niger (the)\n                - NG # Nigeria\n                - NU # Niue\n                - NF # Norfolk Island\n                - MP # Northern Mariana Islands (the)\n                - NO # Norway\n                - OM # Oman\n                - PK # Pakistan\n                - PW # Palau\n                - PS # Palestine, State of\n                - PA # Panama\n                - PG # Papua New Guinea\n                - PY # Paraguay\n                - PE # Peru\n                - PH # Philippines (the)\n                - PN # Pitcairn\n                - PL # Poland\n                - PT # Portugal\n                - PR # Puerto Rico\n                - QA # Qatar\n                - MK # Republic of North Macedonia\n                - RO # Romania\n                - RU # Russian Federation (the)\n                - RW # Rwanda\n                - RE # Réunion\n                - BL # Saint Barthélemy\n                - SH # Saint Helena, Ascension and Tristan da Cunha\n                - KN # Saint Kitts and Nevis\n                - LC # Saint Lucia\n                - MF # Saint Martin (French part)\n                - PM # Saint Pierre and Miquelon\n                - VC # Saint Vincent and the Grenadines\n                - WS # Samoa\n                - SM # San Marino\n                - ST # Sao Tome and Principe\n                - SA # Saudi Arabia\n                - SN # Senegal\n                - RS # Serbia\n                - SC # Seychelles\n                - SL # Sierra Leone\n                - SG # Singapore\n                - SX # Sint Maarten (Dutch part)\n                - SK # Slovakia\n                - SI # Slovenia\n                - SB # Solomon Islands\n                - SO # Somalia\n                - ZA # South Africa\n                - GS # South Georgia and the South Sandwich Islands\n                - SS # South Sudan\n                - ES # Spain\n                - LK # Sri Lanka\n                - SD # Sudan (the)\n                - SR # Suriname\n                - SJ # Svalbard and Jan Mayen\n                - SE # Sweden\n                - CH # Switzerland\n                - SY # Syrian Arab Republic\n                - TW # Taiwan (Province of China)\n                - TJ # Tajikistan\n                - TZ # Tanzania, United Republic of\n                - TH # Thailand\n                - TL # Timor-Leste\n                - TG # Togo\n                - TK # Tokelau\n                - TO # Tonga\n                - TT # Trinidad and Tobago\n                - TN # Tunisia\n                - TR # Turkey\n                - TM # Turkmenistan\n                - TC # Turks and Caicos Islands (the)\n                - TV # Tuvalu\n                - UG # Uganda\n                - UA # Ukraine\n                - AE # United Arab Emirates (the)\n                - GB # United Kingdom of Great Britain and Northern Ireland (the)\n                - UM # United States Minor Outlying Islands (the)\n                - US # United States of America (the)\n                - UY # Uruguay\n                - UZ # Uzbekistan\n                - VU # Vanuatu\n                - VE # Venezuela (Bolivarian Republic of)\n                - VN # Viet Nam\n                - VG # Virgin Islands (British)\n                - VI # Virgin Islands (U.S.)\n                - WF # Wallis and Futuna\n                - EH # Western Sahara\n                - YE # Yemen\n                - ZM # Zambia\n                - ZW # Zimbabwe\n                - AX # Åland Islands\n````\n\n## Configuration options\n\n### Silent start-up: `silentStartUp`\n\nIf set to true, the configuration is not written to the output upon the start-up of the plugin.\n\n### Allow local requests: `allowLocalRequests`\n\nIf set to true, will not block request from [Private IP Ranges](https://en.wikipedia.org/wiki/Private_network).\n\n### Log local requests: `logLocalRequests`\n\nIf set to true, will show a log message when some one accesses the service over a private ip address.\n\n### Log allowed requests `logAllowedRequests`\n\nIf set to true, will show a log message with the IP and the country of origin if a request is allowed.\n\n### Log API requests `logApiRequests`\n\nIf set to true, will show a log message for every API hit.\n\n### API `api`\n\nDefines the API URL for the IP to Country resolution. The IP to fetch can be added with `{ip}` to the URL.\n\n### API Timeout `apiTimeoutMs`\n\nTimeout for the call to the api uri.\n\n### Ignore the API timeout error `ignoreAPITimeout`\n\nIf the `ignoreAPITimeout` option is set to `true`, a request is allowed even if the API could not be reached.\n\n### Set custom HTTP header field to retrieve the country code from `ipGeolocationHttpHeaderField`\n\nAllow setting the name of a custom HTTP header field to retrieve the country code from. E.g. `cf-ipcountry` for Cloudflare.\n\n### Cache size `cacheSize`\n\nDefines the max size of the [LRU](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)) (least recently used) cache.\n\n### Force monthly update `forceMonthlyUpdate`\n\nEven if an IP stays in the cache for a period of a month (about 30 x 24 hours), it must be fetch again after a month.\n\n### Allow unknown countries `allowUnknownCountries`\n\nSome IP addresses have no country associated with them. If this option is set to true, all IPs with no associated country are also allowed.  \n\n### Unknown country api response `unknownCountryApiResponse`\n\nThe API uri can be customized. This options allows to customize the response string of the API when a IP with no associated country is requested.\n\n### Black list mode `blackListMode`\n\nWhen set to `true` the filter logic is inverted, i.e. requests originating from countries listed in the [`countries`](#countries-countries) list are **blocked**. Default: `false`.\n\n### Countries `countries`\n\nA list of country codes from which connections to the service should be allowed. Logic can be inverted by using the [`blackListMode`](#black-list-mode-blacklistmode).\n\n### Allowed IP addresses `allowedIPAddresses`\n\nA list of explicitly allowed IP addresses or IP address ranges. IP addresses and ranges added to this list will always be allowed.\n\n```yaml\nallowedIPAddresses:\n  - 192.0.2.10          # single IPv4 address\n  - 203.0.113.0/24      # IPv4 range in CIDR format  \n  - 2001:db8:1234:/48   # IPv6 range in CIDR format\n```\n\n### Add Header to request with Country Code: `addCountryHeader`\n\nIf set to `true`, adds the X-IPCountry header to the HTTP request header. The header contains the two letter country code returned by cache or API request.\n\n### Customize denied request status code `httpStatusCodeDeniedRequest`\n\nAllows customizing the HTTP status code returned if the request was denied.\n\n### Define a custom log file `logFilePath`\n\nAllows to define a target for the logs of the middleware. The path must look like the following: `logFilePath: \"/log/geoblock.log\"`. Make sure the folder is writeable.\n\n### Define a custom log file `XForwardedForReverseProxy`\n\nBasically tells GeoBlock to only allow/deny a request based on the first IP address in the X-ForwardedFor HTTP header. This is useful for servers behind e.g. a Cloudflare proxy.\n\n### Define a custom log file `redirectUrlIfDenied`\n\nAllows returning a HTTP 301 status code, which indicates that the requested resource has been moved. The URL which can be specified is used to redirect the client to. So instead of \"blocking\" the client, the client will be redirected to the configured URL.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPascalMinder%2Fgeoblock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPascalMinder%2Fgeoblock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPascalMinder%2Fgeoblock/lists"}