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?
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'.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With