Skip to content
DevOps AI ToolKit
Newsletter
All prompts
AI for NGINX Difficulty: Advanced ClaudeChatGPTCursor

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.

Target user
Engineers running NGINX behind an ALB/ELB, GCLB, Cloudflare, or another proxy
Difficulty
Advanced
Tools
Claude, ChatGPT, Cursor

The prompt

You are a senior NGINX engineer who fixes "everything looks like it comes from the load balancer" incidents. You understand the `ngx_http_realip_module`, the difference between `X-Forwarded-For` and PROXY protocol, and why trusting a client-supplied header without scoping it to trusted proxies is a spoofing vulnerability.

I will provide:
- What sits in front of NGINX: [ALB/ELB / GCLB / Cloudflare / another NGINX / HAProxy]
- How the front layer forwards the client IP: [X-Forwarded-For header / PROXY protocol v1 or v2 / X-Real-IP]
- The proxy/CDN source IP ranges (or that they are dynamic): [CIDRS OR "dynamic, published list"]
- What is currently broken: [logs show LB IP / rate limiting hits everyone / geo rules wrong]
- Whether TLS terminates at the LB or at NGINX: [DESCRIBE]

Produce the fix:

1. **Choose the mechanism** — recommend header-based `real_ip` (`X-Forwarded-For`/`X-Real-IP`) vs PROXY protocol based on what the front layer actually sends, and explain the trade-off (PROXY protocol survives non-HTTP and can't be spoofed by clients; XFF is simpler but must be trusted carefully).

2. **Scope trust tightly** — configure `set_real_ip_from` for **only** the load balancer / CDN CIDRs, plus `real_ip_header` and `real_ip_recursive on;` where a chain of proxies is involved. Explain exactly why an unscoped `set_real_ip_from 0.0.0.0/0;` lets any client forge their IP and bypass rate limits and allow-lists.

3. **PROXY protocol path** — if used, show `listen ... proxy_protocol;` and `set_real_ip_from` for the LB, and warn that once `proxy_protocol` is enabled the port will reject any connection that does not speak it (so a health check hitting it directly will fail).

4. **Propagate downstream** — set `proxy_set_header X-Real-IP $remote_addr;` and `X-Forwarded-For $proxy_add_x_forwarded_for;` correctly for upstreams behind this NGINX, and fix the log format to record `$remote_addr` now that it reflects the real client.

5. **Verify** — give a concrete test (curl through the LB with a spoofed `X-Forwarded-For`) proving that a client outside the trusted CIDRs cannot override `$remote_addr`.

Output: (a) the complete commented config (server/listen + real_ip directives + log_format), (b) a table of each directive and the spoofing or logging failure it addresses, (c) the verification commands, and (d) the `nginx -t` line. Validate with `nginx -t` and reload; do not enable `proxy_protocol` on a live listener without confirming the front layer sends it.

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

The symptom is always the same and always confusing: every request in the access log, every rate-limit bucket, and every geo decision suddenly keys on one or two IPs — the load balancer’s. The instinct is to trust X-Forwarded-For and move on, which quietly introduces a spoofing hole, because a header a client can set is a header a client can lie about. This prompt forces the one decision that makes the fix safe: which upstream addresses are allowed to assert a client IP.

By requiring set_real_ip_from to be scoped to the actual proxy CIDRs — and by explicitly naming the 0.0.0.0/0 anti-pattern — the prompt turns “recover the real IP” into “recover the real IP without letting anyone forge it.” That distinction is the entire security value; an unscoped real_ip config is arguably worse than none, because it launders spoofed headers into a trusted $remote_addr.

It also handles the two operational traps people hit the hard way: enabling PROXY protocol on a listener and then watching health checks and direct hits fail because they don’t speak it, and forgetting to update the log format so the “fix” appears not to work. The mandatory spoof-a-header verification step means the engineer ships something they’ve actually proven, not something that merely looks right.

Related prompts

More NGINX prompts & error guides

Browse every NGINX prompt and troubleshooting guide in one place.

Free download · 368-page PDF

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.