limit_req is not working with dynamically extracted user address

malish8632 nginx-forum at forum.nginx.org
Fri Mar 18 13:45:58 UTC 2016


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?

Also to note we are using 1.6.2 version. We tried to upgrade it to 1.8
version but it didn't help.

Thanks,

Sergey

Example of nginx_access_log and following nginx_error_log
-------------------------------------------------------------------------------------
555.182.61.171 - - - www.my.com - [17/Mar/2016:17:44:15 -0400] "GET
/our/api/here HTTP/1.1" 503 270 0.000 "-" "Java/1.8.0_51" "555.182.61.171,
333.101.98.188" - 


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"
-------------------------------------------------------------------------------------


HTTP block
---------------------------------------------
http {
    include       /etc/nginx/mime.types;
    include       /etc/nginx/proxy.conf;
    index         index.html index.htm index.php;

....
    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;
        }

    ';
         
    log_format  main  '$user_real_ip - $remote_addr - $remote_user - $host -
[$time_local] "$request" '
                      '$status $body_bytes_sent $request_time
"$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"
$http_cf_ray';

    sendfile        on;

    keepalive_timeout  20;

    limit_req_zone $user_real_ip zone=one:50m rate=1r/s;
	
    include /etc/nginx/conf.d/*.conf;
}



www.conf location
-------------------------------
    location /xxxx/ {
		
		limit_req zone=one burst=5 nodelay;
.....

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,265461,265461#msg-265461



More information about the nginx mailing list