limit_req is not working with dynamically extracted user address
Maxim Dounin
mdounin at mdounin.ru
Fri Mar 18 14:21:32 UTC 2016
Hello!
On Fri, Mar 18, 2016 at 09:45:58AM -0400, malish8632 wrote:
> Hi, if our HTTP block looks like below where we find IP from X-Forwarded-For
> using perl module it looks like zone and limit_req are not using correct
> variable $user_real_ip or it is reset right after logging.
>
> The nginx_access_log shows the first logged field correctly as $user_real_ip
> - which is first element of comma separated IP addresses in X-Forwarded-For
> header from different hopes. User request comes thorough several different
> CDN and DDOS services.
>
> But when limit_req kicks in it would take for some reason last element in
> same header X-Forwarded-For which of course not our intention.
>
> Can you help understand why and what we are doing wrong?
How did you found that limit_req uses a wrong element?
Note:
> 2016/03/17 17:44:15 [error] 19382#0: *8 limiting requests, excess: 5.613 by
> zone "one", client: 333.101.98.188, server: www.my.com, request: "GET
> /our/api/here HTTP/1.1", host: "www.my.com"
The "client: 333.101.98.188" is the client address as automatically
logged by nginx for all error messages (also known as $remote_addr).
It's not related to the limit string used by limit_req.
[...]
> perl_set $user_real_ip '
>
> sub {
> my $r = shift;
> my $str = $r->header_in("X-Forwarded-For");
> my @fields = split /,/, $str;
> my $real_ip = $fields[0];
> return $real_ip;
> }
>
> ';
Note well: this can be easily tricked by clients using a fake
address in initial X-Forwarded-For header. You may want to use
the realip module instead, it allows to trust only known proxies,
see here:
http://nginx.org/en/docs/http/ngx_http_realip_module.html
--
Maxim Dounin
http://nginx.org/
More information about the nginx
mailing list