Context
A reverse proxy sits in front of Nginx, so the origin sees the proxy's network address. Forwarded headers can recover client context, but those headers are input supplied across a trust boundary. The real-IP configuration must identify which immediate senders are authorized to assert replacement addresses.
Prepare a diagram of actual proxy hops, their maintained address ranges and the header contract at each hop. Confirm whether clients can reach the origin directly. Check the Nginx build and installed module support with nginx -V. A logging change can also affect access rules and rate-limit keys, so involve the owners of those behaviors.
Establish the address contract
- Inspect the effective Nginx configuration with
nginx -Tthrough approved administrative access. Review only the relevant server and include blocks, and sanitize output before sharing because full configuration can contain sensitive values. Findset_real_ip_from,real_ip_headerandreal_ip_recursive, then compare their scope with the intended origin server. - Verify what the trusted upstream actually sends. Some environments use
X-Forwarded-For, others use a single address header or the PROXY protocol. These are different interfaces. PROXY protocol also needs listener support; selecting it as a header mechanism without matching transport configuration does not establish a working chain. - Test a harmless request through the approved proxy and compare the connection peer, selected client address and supplied chain. Nginx exposes the original connection address through real-IP variables where supported. Use temporary restricted diagnostics or safe log fields, preserving client privacy. The result should match a known test client, not simply look like a public address.
- Rehearse an untrusted-header test in a controlled environment. A request from outside trusted proxy ranges must not be allowed to choose its identity merely by adding the same header. If direct origin access is intentionally blocked, verify that boundary independently and test the configured trust behavior without opening broad temporary access.
An illustrative overbroad trust rule
In an illustrative application, the origin trusts replacement headers from every source. A direct request can then supply a chosen address that affects access logs and an IP-based policy. The correction is a maintained trusted-sender list and a tested proxy-header contract. Merely enabling recursive processing does not fix overbroad sender trust.
| Observation | Check | Interpretation |
|---|---|---|
| Every client appears as proxy | Module, header and trusted sender | Replacement not applied |
| Old or unexpected client selected | Proxy chain and recursion | Address-selection contract differs |
| Direct request controls identity | Sender trust scope | Spoofable assertion boundary |
| Correct logs, wrong policy behavior | Effective variables used by rules | Downstream configuration mismatch |
Correct and verify dependent behavior
Preserve the old configuration and modify only the relevant trust and header settings. Run nginx -t before an approved reload. Keep proxy address ranges maintained through the provider's supported source; an obsolete list can cause either missing replacements or unintended trust.
Verify known-client logging, untrusted-header handling and policies that depend on the resulting address. Include IPv6 paths where used. If multiple proxies remain, test the complete chain rather than one manually constructed header alone. Record what the origin considers the connection peer and the client identity.
Maintain the trust map
Monitor unexpected proxy addresses and abrupt changes in client-address distribution. Document header ownership, trusted-range updates and direct-origin access policy. Clouvenix server hardening can help review the interaction between origin trust and application controls.