Introduction
Understanding a client’s real IP address is crucial for server administration, security, and analytics. When an NGINX server sits behind a reverse proxy or load balancer, obtaining the client’s original IP address can be challenging. In this tutorial, we’ll dive into how we can use NGINX directive like X-REAL-IP
and X-FORWARDED-FOR
to retrieve a client’s real IP address.
Each header definition
X-REAL-IP: Is a non-standard header commonly used to determine a client’s real IP address. This header is added by some proxies to indicate the source/client IP address, regardless of how many layers of proxy are in between.
X-FORWARDED-FOR: Is a de-facto standard header for identifying the originating IP address of a client connecting through an HTTP proxy or load balancer.
Configuring nginx to log real IP
To make NGINX log the correct client IP address, you need to set it up to trust the proxy in front of it. This is done using the set_real_ip_from and the real_ip_header directives in your configuration.
set_real_ip_from 192.168.1.0/24; # Your proxy's subnet
real_ip_header X-Real-IP;
You would add those lines to the respective location block, server block, or http block depending on the scope you want them to have.
Log Format Configuration
To see these changes reflected in the logs, include $remote_addr or the custom variable $http_x_real_ip you might set up in the log_format directive:
log_format main '$remote_addr - $remote_user [$time_local] "$request" ';
After making these changes, restart NGINX for the changes to take effect:
sudo systemctl restart nginx
Dealing with Multiple IP Addresses in X-FORWARDED-FOR
The X-FORWARDED-FOR can contain multiple IP addresses if the request has passed through multiple proxies. NGINX has the real_ip_recursive
directive to deal with this situation.
real_ip_header X-Forwarded-For;
real_ip_recursive on;
This ensures NGINX uses the last non-trusted IP address in the X-FORWARDED-FOR list.
Working with Real IP in Application Code
In application code, such as PHP, node.js, or Python, use the server variables to access these headers and thus the real IP:
PHP:
$real_ip = $_SERVER['HTTP_X_REAL_IP'] OR $_SERVER['REMOTE_ADDR'];
Node.js with Express:
const realIp = req.headers['x-real-ip'] || req.connection.remoteAddress;
Python with Flask:
real_ip = request.headers.get('X-Real-IP') or request.remote_addr
Security Considerations
It is critical to only trust proxies that you control. Trusting arbitrary proxies can allow an attacker to spoof an IP address. So, make sure to keep your set_real_ip_from
configurations accurate to your infrastructure.
Conclusion
By following this tutorial, you have improved your understanding of NGINX’s X-REAL-IP
and X-FORWARDED-FOR
headers. You can now configure NGINX to log and use a client’s real IP address effectively, which enhances the ability to track and analyze traffic accurately, implement security measures and troubleshooting.