Forwarding real remote IP to proxied server with nginx

To hide my website IP I proxied the main server with nginx on another VPS. I am trying to send the visitor real IP to my website and here is my config in conf.d folder:

proxy_cache_path  /etc/nginx/cacheddata  levels=1:2   keys_zone=staticfilecache:180m  max_size=500m;
proxy_temp_path /etc/nginx/cacheddata/temp;
proxy_connect_timeout 30;
proxy_read_timeout 120;
proxy_send_timeout 120;

#IMPORTANT - this sets the basic cache key that's used in the static file cache.
proxy_cache_key "$scheme://$host$request_uri";

upstream wordpressapache {
        #The upstream apache server. You can have many of these and weight them accordingly,
        #allowing nginx to function as a caching load balancer 
        server 127.0.0.1:8080 weight=1 fail_timeout=120s;
}
server {
      listen 80;
      server_name XXXXXX.com;
      access_log off;
      error_log off;
    set_real_ip_from 0.0.0.0/0;
    real_ip_header X-Real-IP;
    real_ip_recursive on;

# gzip compression options
  gzip on;
  gzip_http_version 1.0;
  gzip_comp_level 6;
  gzip_min_length 0;
  gzip_buffers 16 8k;
  gzip_proxied any;
  gzip_types text/plain text/css text/xml text/javascript application/xml application/xml+rss application/javascript application/json;
  gzip_disable "MSIE [1-6]\.";
  gzip_vary on;


      location / {
      proxy_pass http://XXXXXX/;
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass_request_headers on;
      proxy_max_temp_file_size 0;
      client_max_body_size 10m;
      client_body_buffer_size 128k;
      proxy_connect_timeout 90;
      proxy_send_timeout 90;
      proxy_read_timeout 90;
      proxy_buffer_size 4k;
      proxy_buffers 4 32k;
      proxy_busy_buffers_size 64k;
      proxy_temp_file_write_size 64k;
   }
} 

And created a simple php page with this code on the proxied server:

<? echo $_SERVER["REMOTE_ADDR"]; ?>

When I open the page it displays the nginx server IP instead of my IP. Did I do anything wrong?


Solution 1:

Forwarding real remote IP from nginx to apache actually requires mod_remoteip module installed & enabled in httpd.conf on the apache side.

Your current nginx configuration is fine, it has required proxy_set_header options in the server block:

server {
    ...
    proxy_set_header    X-Real-IP        $remote_addr;
    proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
    ...
}

On the apache side you should enable the required module with:

LoadModule remoteip_module modules/mod_remoteip.so

and set this directives:

RemoteIPHeader X-Real-IP
RemoteIPInternalProxy 127.0.0.1

replace 127.0.0.1 with your nginx IP if needed...

Solution 2:

You need to configure these options at the actual server where your web site is running at:

set_real_ip_from 0.0.0.0/0;
real_ip_header X-Real-IP;
real_ip_recursive on;

You need to use the IP address of your proxy server in set_real_ip_from directive, so that only that server's X-Real-IP header is allowed.

These directives tell nginx that it should use the IP address listed in the HTTP header instead of the IP address of the TCP connection source as the source IP of the connection.

Then, in your proxy server you need to make sure it sets the X-Real-IP header with the value of client IP address, like your configuration already sets it.

In summary, in proxy server you set the header, and in the main server you tell web server to use the header.