Welcome! Log In Create A New Profile

Advanced

Geo check behind load balancer

Posted by chris098 
Geo check behind load balancer
November 27, 2009 05:20PM
I have a number of nginx servers running on EC2 behind Amazon's "Elastic Load Balancer".

I want to find the country of the original requester.

My "geo" line originally looked like this:

[code]
geo $country {
...
}
proxy_set_header COUNTRY $country;
[/code]

That worked perfectly outside the load balancer, but with the load balancer, the remote_addr is just the local IP of the load balancer. To compensate, I adjusted the geo line to look like this:

[code]
geo $http_x_forwarded_for $country {
...
}
proxy_set_header COUNTRY $country;
[/code]

Unfortunately, http_x_forwarded_for occasionally contains TWO ip addresses, separated by a comma. For example, "62.161.123.123, 10.123.123.123"

It is the first ip address, 62.161.123.123 (in this case) that I want to perform the geo check on.

How can I parse out the original IP and use that for the geo check?
Re: Geo check behind load balancer
November 30, 2009 04:17PM
For anyone experiencing this problem in the future, I was able to use some embedded perl to parse the XFF string for the client's IP address

[code]
perl_set $client_ip '
sub {
my $r = shift;
my $xff = $r->header_in("x-forwarded-for");
if (!$xff) {
return $r->remote_addr;
} else {
if ($xff =~ /([0-9\.]+).*/) {
return $1;
} else {
return $xff;
}
}
}
';

geo $client_ip $country {
default no;
...
[/code]
Re: Geo check behind load balancer
February 23, 2011 04:33AM
Don't mean to resurrect a very old thread but I ran into a similar issue recently and came across a different solution, so I though I would share!

Similarly we are running a number Amazon EC2 machines behind an AWS Elastic Load Balancer. We wanted to use the HttpLimitReqModule in order limit the number of requests for a given session i.e. stop a DOS attack.

Because we were running behind the load balancer the remote address was always that of Amazons load balancer, i.e. something in the range 10.0.0.0/8

As pointed out by Chris above, x-forwarded-for may be a comma separated list of IPs you cannot just use the x-forwarded-for string. You can use the above perl module script to extract the last IP from x-forwarded-for but there is an easier way.

Nginx has another module, HttpRealIpModule, it allows you to extract the remote addr from x-forwarded-for once you provide an IP(s) of your trusted proxy.

In order to work behind Amazons load balancer you set the trusted proxy to that of Amazons internal range

All you have to do is add the following to your nginx conf:

set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;

Now the $remote_addr variable will the set to that of the user and not the load balancer.

Hope this helps anyone else who runs into this problem.
Re: Geo check behind load balancer
August 10, 2011 11:47AM
Just to follow up from my last post.. sometimes ELB will bounce you from 2 internal IPs, both within the 10.0.0.0/8 range.
I think it happens when you have instances that are spread across multiple AZs.

It appears that HttpRealIpModule does not handle multiple trusted proxies correctly and only seems to work with one trusted proxy.
It looks like someone has run into this issue before, http://forum.nginx.org/read.php?2,154968,154996 - I've filled a bug report
Re: Geo check behind load balancer
August 19, 2011 08:09PM
ciaran: Just wanted to confirm that your solution worked great for me also. Thanks
Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 69
Record Number of Users: 7 on March 06, 2014
Record Number of Guests: 229 on August 01, 2014
Powered by nginx    Powered by FreeBSD    PHP Powered    Powered by Percona     ipv6 ready