Skip to content

Feature Guide Geo Blocking

fuomag9 edited this page Sep 26, 2026 · 3 revisions

Feature Guide: Geo Blocking

Block or allow traffic to your proxy hosts based on the visitor's geographic location, network, or IP address.

Table of Contents

  1. Overview
  2. Prerequisites
  3. GeoIP Database Setup
  4. Configuring Geo Blocking
  5. Rule Types
  6. Allow vs. Block Rules
  7. Examples
  8. Troubleshooting

Overview

Geo blocking is powered by the caddy-blocker-plugin and MaxMind GeoLite2 databases. Rules are evaluated by Caddy on every request before it reaches your upstream service.

Supported rule types:

  • Country (ISO 3166-1 alpha-2 code, e.g. DE, US, FI)
  • Continent (AF, AN, AS, EU, NA, OC, SA)
  • ASN — Autonomous System Number (e.g. 24940 for Hetzner)
  • CIDR range (e.g. 203.0.113.0/24)
  • Exact IP address (e.g. 203.0.113.10)

Geo blocking is configured per proxy host, so you can have different rules for different services.


Prerequisites

  • MaxMind GeoLite2 Country and/or ASN databases
  • The geoipupdate Docker profile enabled (see setup below)

Country and continent rules require the Country DB. ASN rules require the ASN DB. CIDR and IP rules work without any database.


GeoIP Database Setup

1. Create a MaxMind account

Register for free at maxmind.com. No payment required for GeoLite2.

2. Generate a license key

In your MaxMind account portal:

  1. Go to My License Key
  2. Click Generate new license key
  3. Name it (e.g. caddy-proxy-manager)
  4. Note your Account ID and the generated License Key

3. Configure environment variables

Add to your .env file:

GEOIPUPDATE_ACCOUNT_ID=123456
GEOIPUPDATE_LICENSE_KEY=your_license_key_here

4. Start with the geoipupdate profile

docker compose --profile geoipupdate up -d

This starts the geoipupdate container which downloads and periodically refreshes the databases (every 72 hours by default). Databases are stored in the geoip-data Docker volume, which is mounted read-only into both the web and caddy containers.

5. Verify databases are available

In the Caddy Proxy Manager web UI, the geo blocking section of each proxy host will show which databases are available. You can also check the Settings page.


Configuring Geo Blocking

  1. Open Proxy Hosts and edit (or create) a proxy host
  2. Scroll to the Geo Blocking section
  3. Toggle Enable Geo Blocking on
  4. Add rules using the rule builder
  5. Click Save

Changes take effect immediately — Caddy configuration is updated in real time.

LAN Only (RFC1918) preset

The rule builder includes a LAN Only (RFC1918) preset button. Clicking it automatically populates the rules with allow entries for all private address ranges:

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16

This is useful when you want to restrict access to internal services to LAN clients only. Combined with appropriate block rules for public ranges, it provides a quick way to lock down an internal-only service.


Rule Types

Country

Block or allow based on the visitor's country.

Uses the MaxMind GeoLite2 Country database. Requires Country DB.

Format: ISO 3166-1 alpha-2 code (two uppercase letters)

Country Code
Germany DE
United States US
Finland FI
United Kingdom GB
France FR

Example: Block all requests from Germany → Rule: Block, Country, DE


Continent

Block or allow based on the visitor's continent. Useful for broad geographic restrictions.

Requires Country DB.

Continent Code
Africa AF
Antarctica AN
Asia AS
Europe EU
North America NA
Oceania OC
South America SA

Example: Block all traffic from Europe → Rule: Block, Continent, EU


ASN

Block or allow based on the visitor's Autonomous System Number. Useful for blocking specific hosting providers, VPN services, or ISPs.

Requires ASN DB.

Format: Numeric ASN without the AS prefix

Provider ASN
Hetzner 24940
Cloudflare 13335
DigitalOcean 14061
OVH 16276

Example: Block Hetzner servers → Rule: Block, ASN, 24940


CIDR

Block or allow an IP range in CIDR notation. Does not require any GeoIP database.

Format: x.x.x.x/prefix for IPv4, x:x::x/prefix for IPv6

Examples:

  • 203.0.113.0/24 — a /24 subnet (256 addresses)
  • 10.0.0.0/8 — private network
  • 2001:db8::/32 — IPv6 range

Example: Block a specific subnet → Rule: Block, CIDR, 203.0.113.0/24


IP

Block or allow a single exact IP address. Does not require any GeoIP database.

Format: x.x.x.x (IPv4) or full IPv6 address

Example: Allow a specific server IP → Rule: Allow, IP, 203.0.113.10


Allow vs. Block Rules

Allow rules take precedence over block rules.

This means you can create broad block rules and then punch specific exceptions through them.

Evaluation logic

For each incoming request, Caddy evaluates all rules:

  1. If any Allow rule matches → request is passed through
  2. If any Block rule matches (and no Allow rule matched) → request gets 403 Forbidden
  3. If no rules match → request is passed through

Common patterns

Block a country:

Block → Country → DE

Blocks all traffic from Germany.

Block a continent:

Block → Continent → EU

Blocks all traffic from Europe.

Block a continent, allow a specific country:

Block → Continent → EU
Allow → Country → FI

Blocks Europe but allows Finland through.

Block a hosting provider, allow your own server:

Block → ASN → 24940
Allow → IP → 1.2.3.4

Blocks Hetzner traffic except for your specific server IP.

Allow only one country (block everywhere else):

There is no "block all" rule type. To allow only one country, you need to block all other continents:

Block → Continent → AF
Block → Continent → AN
Block → Continent → AS
Block → Continent → EU
Block → Continent → NA
Block → Continent → OC
Block → Continent → SA
Allow → Country → US

This blocks all continents and then allows only the US through.


Examples

Example 1: Block a country

Goal: Block all traffic from Germany

Rules:

Block → Country → DE

Example 2: Block a hosting provider

Goal: Block all Hetzner servers (common source of bots/scanners)

Rules:

Block → ASN → 24940

Example 3: Block a region, allow your admin IP

Goal: Block all of Europe, but allow your home IP through

Rules:

Block → Continent → EU
Allow → IP → YOUR_HOME_IP

Example 4: Block a CIDR range

Goal: Block a specific IP range (e.g. a known malicious subnet)

Rules:

Block → CIDR → 203.0.113.0/24

Example 5: Allow only a specific country

Goal: Only allow traffic from Finland, block everything else

Rules:

Block → Continent → AF
Block → Continent → AN
Block → Continent → AS
Block → Continent → EU
Block → Continent → NA
Block → Continent → OC
Block → Continent → SA
Allow → Country → FI

Troubleshooting

Geo blocking section shows "Database not available"

The GeoLite2 databases are not mounted or haven't been downloaded yet.

Fix:

  1. Ensure GEOIPUPDATE_ACCOUNT_ID and GEOIPUPDATE_LICENSE_KEY are set in .env
  2. Start with the geoipupdate profile: docker compose --profile geoipupdate up -d
  3. Wait for the databases to download (check logs: docker compose logs geoipupdate)
  4. Verify the geoip-data volume is mounted: docker compose exec web ls /usr/share/GeoIP/

Rules not taking effect

Configuration is applied when you save. If changes don't take effect:

  1. Check Caddy logs: docker compose logs caddy
  2. Verify the proxy host was saved successfully (check the audit log)
  3. Restart Caddy: docker compose restart caddy

Visitors from allowed countries getting blocked

Check rule order and types:

  • Allow rules override block rules — ensure your allow rule type matches what you expect
  • Country and continent rules require the Country database — verify it's present
  • ASN rules require the ASN database — verify it's present

Blocked visitors getting through

  • CIDR and IP rules don't require databases — verify the format is correct
  • Country/continent/ASN lookups depend on database accuracy — MaxMind GeoLite2 is not 100% accurate

Related Documentation


Need help? Open an issue with your configuration details.

Clone this wiki locally