2

I recently set up a NodeBalancer in front of a Rails 3.2.12 app. The app is served by nginx and Unicorn.

All seems to work fine, but I get a lot of errors such as these that I didn't get when I only had 1 server.

IP spoofing attack?!HTTP_CLIENT_IP="10.16.81.184"HTTP_X_FORWARDED_FOR="136.160.88.153, 192.168.255.5"
actionpack (3.2.12) lib/action_dispatch/middleware/remote_ip.rb:55:in `calculate_ip'

Here is my nginx configuration for the app.

upstream unicorn {
server unix:/tmp/unicorn.ahotu-calendars.sock fail_timeout=0;
}

server {
listen 80 default deferred;
root /home/deployer/apps/appdirectory/current/public;
if (-f $document_root/system/maintenance.html) {
return 503;
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /system/maintenance.html last;
break;
}

location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}

try_files $uri/index.html $uri @unicorn;
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}

error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}

Did I do something wrong in the config file?

Thank you.

w5m
  • 151
  • 8
jlfenaux
  • 283
  • 1
  • 4
  • 8

1 Answers1

2

To prevent clients from forging a proxy's headers, both X-Forwarded-For and Client-Ip have to equal to not raise this kind of error.

Simply set the Client-Ip header in your nginx config:

As for the IP addresses in your log:

  • 192.168.255.5 probably is NodeBalancer's internal IP
    (examples in Linode Library show 192.168.0.0/16 subnet as usual; that should be static - or at least keep inside the subnet)
  • 136.160.88.153 is the real remote address you want to know
  • 10.16.81.184 is some other, unknown IP address - maybe another proxy added it earlier
    (does it appear on each request or is it sometimes empty?)

I'm sorry, I somehow came to believe (your) nginx would be running on the NodeBalancer.
Use the HttpRealIpModule like this:

# trust connections from internal addresses
set_real_ip_from 192.168.0.0/16;
real_ip_header X-Forwarded-For;

Or, at least make sure to pass the original X-Forwarded-For header to Rails instead of nginx's modified one, and unset the Client-Ip (whereever it may come from):

proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_set_header Client-Ip "";
Lukas
  • 984
  • 5
  • 14
  • With this technique, I loose the IP of the client. In my logs, all I get is the NodeBalancer's internal IP. I ended up removing the ip_spoofing_check in the rails app. Thanks – jlfenaux Mar 22 '13 at 10:00
  • Edited my answer some days ago... maybe the question still matters for you. – Lukas Mar 27 '13 at 23:32