6

On an existing nginx reverse proxy, I need to pass the client IP to a server (from nginx to the frontend served in NG-Engine, and from this to the backend), I tried a lot of sites, but the server is just receiving 127.0.0.1. Extra info (added after Michael Hampton question), our Virtual Machines infrastructure:

  1. Client browser (another VM or remote desktop)
  2. (VM1) nginx reverse proxy (it works, HTTPS layer I added at least)
  3. (VM1) NgEngine serving the homemade frontend
  4. (VM1) RESTful API served by a Java/Spring homemade backend (running in IntelliJ idea)
  5. (VM2..x) other servers feeding the backend with data (out of the question)

I checked doc, tried here (including removing the X-Real-IP header, as they suggest in this other question). I tried also to add:

set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For

My nginx has real_ip module (output of nginx -V below), and this is my nginx.conf... What I am doing wrong?

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
  worker_connections 768;
  # multi_accept on;
}

http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 65;
  types_hash_max_size 2048;
  # server_tokens off;

  server_names_hash_bucket_size 64;
  # server_name_in_redirect off;

  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
  ssl_prefer_server_ciphers on;

  gzip on;
  gzip_disable "msie6";

  server {
    listen 443 ssl;
    server_name          test-server;
    ssl_certificate      /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key  /etc/nginx/ssl/nginx.key;

    add_header              Strict-Transport-Security  "max-age=63072000; includeSubdomains; preload" always;
    add_header              X-Frame-Options            SAMEORIGIN;
    add_header              X-Content-Type-Options     nosniff;

    # allow nginx to start regardless of upstream endpoint state by using intermediary variable
    set                     $UPSTREAM_SERVICE          10.10.10.15:8080;

    location  / {
      proxy_pass               http://localhost:6789
      proxy_http_version       1.1;

      proxy_buffering          off;
      proxy_buffer_size        128k;
      proxy_busy_buffers_size  256k;
      proxy_buffers            4                   256k;
      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_set_header         X-Forwarded-Proto   $scheme;
      proxy_set_header         Upgrade             $http_upgrade;
      proxy_set_header         Connection          $http_connection;

    }
  }
}

Output of nginx -V:

nginx version: nginx/1.14.0 (Ubuntu)
built with OpenSSL 1.1.0g  2 Nov 2017
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-mcUg8N/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_flv_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_secure_link_module --with-http_sub_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-headers-more-filter --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-cache-purge --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-ndk --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-echo --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-fancyindex --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/nchan --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-lua --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/rtmp --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-uploadprogress --add-dy
namic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-upstream-fair --add-dynamic-module=/build/nginx-mcUg8N/nginx-1.14.0/debian/modules/http-subs-filter

Thank you very much and best regards

2
  • What is in front of nginx? Jul 9, 2018 at 0:44
  • Thanks: true, I forgot that (it is not my part, I even didn't know it before finding info to answer you): It is NgEngine What we have: it is a development and testing infrastructure, with the following components: client browser (VM/remote desktop) -- (VM1) nginx reverse proxy (it works, HTTPS layer I added at least) -- (VM1) NgEngine serving the homemade frontend -- (VM1) RESTful API served by a Java/Spring homemade backend (running in IntelliJ idea) -- (VM2..x) other servers feeding the backend with data (out of the question). Thanks
    – xCovelus
    Jul 9, 2018 at 7:41

2 Answers 2

5

On an existing nginx reverse proxy, I need to pass the client IP to a server (both running in the same OS), I tried a lot of sites, but the server is just receiving 127.0.0.1.

As a reverse proxy, your back-end server will always receive connection from your nginx process, which, depends on your *_pass directive, will contain your nginx's IP address (in your case, 127.0.0.1).

As such, you may not fetch client IP by checking client address, you'll only get your front-end server IP address.

In reverse proxy and load balancing, uh, business, we have several ways to extract client IP from reverse proxy on the backend:

  1. Non-standard de-facto X-Forwarded-For HTTP request header, contains all the proxies passed and requesting client IP address(es).
  2. Forwarded HTTP request header, is a new standardized way to replace X-Forwarded-For, also contains IP addresses for all proxies passed and requesting client.
  3. X-Real-IP HTTP request header, or any custom HTTP request header, to arbitrarily contain client IP address.

Check your back-end application if they support any of these headers.


My nginx has real_ip module

ngx_http_realip_module isn't used for this case. It is used if nginx is behind a proxy so that it could validate and fetch real client IP address and store it in a specified variable.

1
  • something I did not know is proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; had to be set under location / {} block. When I had it at http level (?) it did not do anything.
    – Rafa
    2 days ago
0

Thanks to both comments I had a clearer idea about how to find out the solution. I was specially helpful the comment from mforsetti:

Check your back-end application if they support any of these headers.

And also:

[..], we have several ways to extract client IP from reverse proxy on the backend: [..]

Using HttpServletRequest (request):

request.getRemoteAddr();

was (and still) is giving me the proxy IP. So, I decided to try manually to get the right header:

request.getHeader("X-Forwarded-For");

And that was giving me exactly the client IP.

Thanks a lot for your help, without it, I would not be able to solve this.

1
  • 1
    Please be warned that if you read the links I put on the answer, you'll see that X-Forwarded-For may contain IP addresses of the proxies your client used as well as your client IP address, so you need to filter those first.
    – mforsetti
    Jul 12, 2018 at 15:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.