I have a set of Nginx servers behind an Amazon ELB load balancer. I am using set_real_ip (from the HttpRealIpModule) so that I can access the originating client IP address on these servers (for passing through to php-fpm and for use in the HttpGeoIPModule).

It seems that set_real_ip_from in the nginx configuration can only accept an IP address. However, with regard to ELB machines Amazon say:

Note: Because the set of IP addresses associated with a LoadBalancer can change over time, you should never create an "A" record with any specific IP address. If you want to use a friendly DNS name for your LoadBalancer instead of the name generated by the Elastic Load Balancing service, you should create a CNAME record for the LoadBalancer DNS name, or use Amazon Route 53 to create a hosted zone. For more information, see the Using Domain Names With Elastic Load Balancing

But if I need to input an IP address I can't use a CNAME (either amazon's or my own). Is there a solution to this problem?

up vote 36 down vote accepted

If you can guarantee that all requests will be coming from ELB (I'm not familiar with it), you could try:

real_ip_header X-Forwarded-For;
set_real_ip_from 0.0.0.0/0;

That should tell nginx to trust an X-Forwarded-For header from anyone. The downside is that if anyone directly accesses your server, they would be able to spoof an X-Forwarded-For header and nginx would use the wrong client ip address.

  • 2
    Thanks - I didn't realise I could add an IP range there... I'll check if there is a more specific range that the ELB could be on (I think 10.0.0.1/8 would work although there may be something more specific) – vitch Nov 16 '11 at 17:32
  • I added a follow up question to find out if anyone knows the valid range: serverfault.com/questions/331697/… – vitch Nov 16 '11 at 18:52
  • If it's a VPC ALB, your range(s) is(are) the same as your subnet ranges of which the LB is a part. – talonx Sep 12 at 7:22

Today's best practice is to use VPC, so, then, you will know the exact CIDR for your ELB. Then, you can add something like this to your Nginx configuration file:

real_ip_header X-Forwarded-For;
set_real_ip_from 10.0.0.0/8;
  • Seeing as the question is from 2011 it's possible that option wasn't available then. I just include all possible private networks since outside users won't get to them easily. – Jordan Reiter Jun 22 '16 at 20:14

Use the VPC CIDR for set_real_ip_from You can find it in Amazon console under VPC => Your VPC (replace <your VPC CIDR here> with it):

real_ip_header X-Forwarded-For;
set_real_ip_from <your VPC CIDR here>;

Setting the trusted range to 0.0.0.0/0 on Amazon ELB is for sure going to get you into trouble. You can guarantee that the requests comes from the ELB if you can configure the security group for your nginx server, but the original request will originate from any possible source (Amazon ELBs are public interfaces).

A simple test will reveal this:

curl --header "X-Forwarded-For: 1.2.3.4" "http://your-elb-dns-address/"

The logs on your nginx server will then show 1.2.3.4 as the real IP, which is a spoofed one. See IP Range for internal private IP of Amazon ELB for better answers.

  • 3
    This would only be an issue if you set real_ip_recursive on, which isn't the default, and didn't even exist when I originally answered the question. – kolbyjack May 9 '14 at 11:41

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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