Blog / Linux/ Nginx ngx_http_realip_module: Installation, Configuration, and Real Client IP Retrieval

Nginx ngx_http_realip_module: Installation, Configuration, and Real Client IP Retrieval

Overview of ngx_http_realip_module

The ngx_http_realip_module is a core Nginx module designed to extract the original client's real IP address from HTTP headers set by proxy servers (like CDNs or load balancers) when Nginx sits behind a reverse proxy.

Without this module, Nginx access logs and backend applications (e.g., PHP via $_SERVER['REMOTE_ADDR']) will record the IP of the last proxy server, not the end user. This affects access statistics, security auditing, and geo-restriction features.

Installation and Verification

Most precompiled Nginx packages include this module. Verify with:

nginx -V 2>&1 | grep -o http_realip_module

If http_realip_module is printed, it's available. For custom compilation, add --with-http_realip_module to ./configure.

Basic Configuration and Use Cases

Single Reverse Proxy

Architecture: Client (IP: 123.123.123.123) → Proxy (IP: 10.10.10.10) → Backend Nginx.

Without realip, backend logs show 10.10.10.10. To get the real client IP, add this to the http, server, or location context:

set_real_ip_from 10.10.10.10;
real_ip_header X-Forwarded-For;
  • set_real_ip_from: Defines trusted proxy IPs or CIDR ranges.
  • real_ip_header: Specifies the HTTP header containing the real IP (e.g., X-Forwarded-For or X-Real-IP).

After configuration, Nginx uses the first IP from X-Forwarded-For (123.123.123.123) as the real client IP, overwriting the $remote_addr variable.

Multiple Proxies and real_ip_recursive

Complex architecture: Client → Proxy1 (192.168.1.10) → Proxy2 (10.10.10.10) → Backend Nginx.

The X-Forwarded-For header received may be: 123.123.123.123, 192.168.1.10, 10.10.10.10.

With basic config:

set_real_ip_from 10.10.10.10;
real_ip_header X-Forwarded-For;
# real_ip_recursive is off by default

Nginx incorrectly takes the last IP (10.10.10.10). To fix, enable real_ip_recursive and list all trusted proxies:

set_real_ip_from 10.10.10.10;
set_real_ip_from 192.168.1.10;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
  • real_ip_recursive off (default): Uses the last IP in the specified header.
  • real_ip_recursive on: Traverses the header from right to left, skipping IPs in set_real_ip_from, and selects the first untrusted IP as the real client IP.

In the example, Nginx checks: 10.10.10.10 (trusted, skip) → 192.168.1.10 (trusted, skip) → 123.123.123.123 (untrusted, selected).

Configuration Example and Verification

Full example for nginx.conf:

# Define trusted proxy IP ranges
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
# Specify the HTTP header containing the real IP
real_ip_header X-Forwarded-For;
# Enable recursive search for multi‑proxy chains
real_ip_recursive on;

Reload Nginx: nginx -s reload.

Verify by checking access logs. Ensure the $remote_addr variable shows the real client IP. Example log format:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;

Important Notes and Common Issues

  • Security: Only add trusted proxy IPs to set_real_ip_from. Misconfiguration allows IP spoofing via forged headers.
  • Header Selection: Coordinate with upstream proxies on which header to use (commonly X-Forwarded-For or X-Real-IP).
  • Variable Override: The module modifies $remote_addr, affecting all features relying on it (e.g., rate limiting, access control).
  • PROXY Protocol: For proxies using PROXY protocol (common in TCP/UDP), use listen ... proxy_protocol; and real_ip_header proxy_protocol; instead.

Proper configuration ensures your logs and security policies are based on accurate end‑user IPs, even behind complex proxy networks.

Post a Comment

Your email will not be published. Required fields are marked with *.