Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails shows IP as 127.0.0.1 when accessed from private NIC, but Nginx shows the correct IP. Public IP gets forwarded fine

We are running a Rails application on Unicorn + Nginx. The server has two NICs that we use. eth0 handles requests for the public internet, and eth2 handles requests from our private network.

When a request comes through eth0, the nginx logs show the public IP, and the Rails logs also show this IP. However, when a request comes through eth2, the nginx logs show the private IP correctly (e.g. 192.168.5.134), but the Rails logs show 127.0.0.1.

So it seems like public requests on eth0 get their X-Forwarded-For header set correctly, but this isn't happening for requests on eth2.

Our nginx config is pretty basic:

upstream example.com {
  server unix://var/www/example.com/shared/sockets/unicorn.socket fail_timeout=0;
}

...

server {
  listen 443 ssl;
  ...

  location @example.com  {
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real_IP $remote_Addr;
    proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    if ($host ~* "^(.+)\.example.com$") {
      set $subdomain $1;
    }

    proxy_pass http://example.com;
  }

Any ideas?

like image 653
ndbroadbent Avatar asked Nov 09 '13 01:11

ndbroadbent


1 Answers

The issue was that Rails thinks any 192.168.x.x address is a private address, so strips them from the X-Forwarded_For header.

# IP addresses that are "trusted proxies" that can be stripped from
# the comma-delimited list in the X-Forwarded-For header. See also:
# http://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces
TRUSTED_PROXIES = %r{
  ^127\.0\.0\.1$                | # localhost
  ^(10                          | # private IP 10.x.x.x
    172\.(1[6-9]|2[0-9]|3[0-1]) | # private IP in the range 172.16.0.0 .. 172.31.255.255
    192\.168                      # private IP 192.168.x.x
   )\.
}x

See the relevant Rails source here and here.

One solution is to add this to your config/application.rb:

config.action_dispatch.trusted_proxies = /^127\.0\.0\.1$/ # localhost

That way, IPs on your local network will not be replaced by '127.0.0.1'.

like image 131
ndbroadbent Avatar answered Sep 28 '22 15:09

ndbroadbent