NGINX GeoIP2 Country Access Control Prompt
Add country- or ASN-based access control and routing to NGINX with the ngx_http_geoip2 module — allow/deny by country, route regional traffic, and set headers — while correctly resolving the real client IP behind a CDN or load balancer.
- Target user
- Engineers adding geo access rules to an NGINX edge
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior edge engineer who adds GeoIP2-based access control and routing to NGINX. You know GeoIP is probabilistic and that it must run on the true client IP, not the proxy's.
I will provide:
- `nginx -V` output (to confirm the `ngx_http_geoip2` module is present): [PASTE]
- Where my MaxMind GeoLite2/GeoIP2 database file lives, and how it's updated: [PATH + PROCESS]
- Whether NGINX is behind a CDN/load balancer, and the trusted proxy ranges: [DESCRIBE]
- The policy I want (deny listed countries, allow only listed countries, route by region, tag with headers): [DESCRIBE]
- Any IPs/paths that must ALWAYS be allowed regardless of geo (health checks, admin, monitoring): [LIST]
Design the geo config:
1. **Real client IP first** — if behind a proxy, `set_real_ip_from <ranges>` + `real_ip_header X-Forwarded-For` (or CF-Connecting-IP) so GeoIP2 sees the true client. Emphasize this must come before the geoip2 lookup.
2. **GeoIP2 lookup** — a `geoip2 <db> { $geoip2_country_code source=$remote_addr country iso_code; }` block (and ASN if relevant), producing variables for use in maps.
3. **Policy via map** — a `map $geoip2_country_code $allowed { ... }` implementing allow-list or deny-list logic, with a sane default. Show both patterns and recommend one for MY case.
4. **Enforcement + escape hatches** — deny with a clear status (`403` or a custom page) when `$allowed` is false, but ALWAYS bypass for the allow-listed IPs/paths I listed (health checks, admin). Never let geo rules block monitoring.
5. **Regional routing (optional)** — if I want routing rather than blocking, map country/region to different upstreams or backends.
6. **Observability** — add `$geoip2_country_code` to the access log so you can audit who was blocked and catch database mistakes.
Output: (a) the full `http`/`server` config, commented, with the real-IP-before-lookup ordering called out; (b) the always-allow bypass for critical IPs/paths; (c) how to test — `curl` with a spoofed `X-Forwarded-For` from a known-country IP and what to expect; (d) a note on keeping the MaxMind DB updated; (e) `nginx -t` verification. Apply only after `nginx -t` passes and reload.
Run this prompt with AI
Test it, get an AI-improved version, or compare models — live in the Prompt Workspace. No copy-paste.
Why this prompt works
GeoIP access control breaks in two predictable ways. First, behind a CDN or load balancer NGINX geolocates the proxy’s IP unless you restore the real client IP with real_ip before the lookup — so the whole world resolves to one country. The prompt makes real-IP-first ordering explicit, which is the single most common cause of “my geo block does nothing” or “it blocks everyone.”
Second, teams hard-lock legitimate users and, worse, their own health checks and monitoring. GeoIP databases misplace VPN and mobile users routinely, so the prompt bakes in an always-allow bypass for critical IPs and paths and insists on an appeal/allow-list path — treating geo as one signal, not a security perimeter.
Logging $geoip2_country_code and testing with a spoofed X-Forwarded-For gives you an auditable, reproducible way to confirm the policy and catch a stale database before it blocks real revenue.
Related prompts
-
NGINX CORS & Preflight Proxy Prompt
Get correct, secure CORS handling in NGINX for a reverse-proxied API — OPTIONS preflight, Access-Control-* headers, credentials, and per-origin allow-listing — without the classic duplicate-header and wildcard-with-credentials footguns.
-
NGINX Slowloris & Timeout Hardening Prompt
Harden NGINX against slow-client and connection-exhaustion attacks — client/header/body timeouts, connection and request-rate limits, and buffer caps — tuned so real slow mobile clients aren't collateral damage.
-
NGINX auth_request Subrequest SSO Prompt
Design a correct `auth_request` gateway that offloads authentication to an external SSO/auth service — forwarding the right headers, handling 401/403 vs 5xx distinctly, and passing identity back to your app — instead of a fragile snippet that leaks unauthenticated traffic on the auth service's bad day.
-
NGINX Real Client IP Behind a Load Balancer Prompt
Recover the true client IP when NGINX sits behind an L7 load balancer or CDN — configure real_ip / X-Forwarded-For or PROXY protocol with trusted-proxy scoping — so rate limits, geo rules, and access logs stop keying on the load balancer's address.
More NGINX prompts & error guides
Browse every NGINX prompt and troubleshooting guide in one place.
Reading prompts? Get all 500 in one free PDF
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.