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