20

I need to store visitors' IP address to our database and here's the way I am trying to do that:

@ip = request.remote_ip
@ip = request.env['REMOTE_ADDR']

But in both cases, the @ip variable stored the value 127.0.0.1, even when I deploy the app to Amazon EC2 instance.

When I check http://www.whatismyip.com/, it shows my IP as 109.175.XXX.X.

Thus, why does the ruby variable always display the 127.0.0.1 address? How do I get the real IP?


EDIT: Here's the output of following:

request.env['HTTP_X_FORWARDED_FOR'] => 
request.remote_ip => 127.0.0.1
request.env['REMOTE_ADDR'] => 127.0.0.1
request.ip => 127.0.0.1

I thought that the problem is just on my side, but I sent links to 3 of my friends and all of them see the same IP, just 127.0.0.1.

I am solving this issue the whole day and still no success.

Thank you

atw
  • 5,428
  • 10
  • 39
  • 63
user984621
  • 46,344
  • 73
  • 224
  • 412
  • maybe your app is behind a [reverse proxy](http://en.wikipedia.org/wiki/Reverse_proxy) ? – m_x Oct 11 '13 at 11:42
  • how do the "visitor" visits your server? When you use EC2 instance how do you send the request to the server? – Makis Tsantekidis Oct 11 '13 at 11:42
  • Simply, I have opened my website in browser and reloaded the page, because I wanted to see there the changed IP - but there's still the same as the one on localhost - 127.0.0.1 – user984621 Oct 11 '13 at 11:45
  • 1
    @Afsane.F You might have better luck opening a new question and providing as much detail as possible. Narrowing down the questions scope and providing more details and data could really help. – Tom Jan 28 '19 at 20:50

3 Answers3

24

When you visit a site locally you're coming from the local IP address, ie 127.0.0.1.

What you're doing is the correct way to the visitors IP address, and the result you're seeing is as expected.

You want to use

@ip = request.remote_ip

because that takes into account most cases of reverse proxies and other situations you might encounter where request.env['REMOTE_ADDR'] might be nil or the address of the local proxy.

If you indeed do have a reverse proxy in front of your application server (and you probably do), you need to make sure it sets the proper headers when forwarding the requests. As a minimum the X-Forwarded-For header should be set.

Sample nginx configuration

If you're using nginx as a reverse proxy in front of your Rails application (ie using proxy_pass), you need to configure it to add the proper headers to the request it sends. In the case of X-Forwarded-For that is done using:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

You might want to also configure the following to have nginx forward the requested hostname and protocols:

# enable this if you forward HTTPS traffic to Rails,
# this helps Rack set the proper URL scheme for doing redirects:
proxy_set_header X-Forwarded-Proto $scheme;

# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;
Jakob S
  • 19,575
  • 3
  • 40
  • 38
  • thank you for your reply. But truth be told, I still don't understand why I'm receiving **127.0.0.1** on Amazon EC2. I tested it also with `request.remote_ip` command. Why is in the production mode on EC2 displayed **127.0.0.1** instead of **109.175.XXX.X**? – user984621 Oct 11 '13 at 13:22
  • Without knowing your setup, it's hard to say. Most likely you're hitting some proxying webserver that forwards the requests to whatever you're serving Rails via (Unicorn, Thin, Webrick). That proxy is local to your app, and if it doesn't set the expected headers, request.remote_ip won't pick up the original IP. – Jakob S Oct 11 '13 at 14:12
  • It it help, I am running on Unicorn. (I don't know about the proxy) – user984621 Oct 11 '13 at 14:13
  • So you are hitting the Unicorn process directly? You don't have Apache or Nginx in there somewhere? Or perhaps some Amazon load balancer? – Jakob S Oct 11 '13 at 14:16
  • @JakobS I have the same problem but the difference is that I'm using nginx. Do u know how I can get the visitors ip ? – Afsanefda Jan 28 '19 at 11:19
  • @Afsane.F Can you post your nginx configuration ? – ray Jan 29 '19 at 07:28
  • 1
    If you're using `request.remote_ip` on the Rails side, you're already doing it right. However, nginx needs to be configured to forward the actual remote IP address, I've updated my answer with details for exactly that. – Jakob S Jan 29 '19 at 12:12
6

x-forwarded-for. x-forwarded-for (XFF) is a standard proxy header which indicates the IP addresses that a request has flowed through on its way from the client to the server.

In my nginx server configuration I had,

proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

I was getting client remote IP as below,

request.env['HTTP_X_FORWARDED_FOR'] || request.remote_ip

Note: It can be wrong IP address if client is sitting behind proxy.

ray
  • 5,454
  • 1
  • 18
  • 40
0

Note that if you are using AWS with any of their supplied Load Balancers, you may have to configure those load balancers appropriately in order to get them to forward the client IP.

Normally Stack Overflow does not like answers that are just a link, but in this case, since the question is very old and we do not the details to answer the specific question, and because the kind of load balancers AWS offers and the way to configure them keeps changing, I will just post a link to the AWS Knowledge Base instructions for forwarding the client IP address through a load balancer.

You can have similar issues if you are using a Content Delivery Network (CDN) to deliver data, in which case you need to contact your CDN provider for instructions.

@Jakob S correctly explains how to configure nginx to pass the X-Forwarded-For header, which is the current de facto standard, but the X- prefix means it is explicitly non-standard under the relevant HTTP spec. Eventually you may want to support the Forwarded header, which is specified in RFC 7239 but as of now (January 2019) it has not been widely adopted and is not worth switching to due to the lack of widespread support.

Community
  • 1
  • 1
Old Pro
  • 24,624
  • 7
  • 58
  • 106