The next task is to set a limit per one IP to our backend’s API:
- add requests limiter on the
/user/oauth/refresh_token
URI - set limit to 5 requests/minute from one IP
- if the limit is reached – return 429 Too Many Requests response
Will use NGINX ngx_http_limit_req_module
.
limit_req_zone
To make limiting works firs need to create a memory region to store IP addresses and requests from each.
Add it to the nginx.conf
, http {}
block:
...
limit_req_zone $binary_remote_addr zone=backend_oauth:10m rate=5r/m;
...
Here:
-
$binary_remote_addr
– a variable with a visitor’s IP -
zone=backend_oauth:10m
– memory zone named backend_oauth and 10 MB size ($binary_remote_addr
size can be found in thengx_stream_limit_conn_module
documentation) -
rate=5r/m
– 5 requests/minute limit
Also:
-
map $http_branch $app_branch
: see the NGINX: multi-branch deployment with Ansible, NGINX map and HTTP Headersmap $status $abnormal
: see the NGINX: access log – log all except 200 responsesset_real_ip_from
: see the NGINX: реальный IP в логах при работе за AWS Load Balancer (Rus)
limit_req
Next, in a virtual host’s config add a new location
where you want to apply limit and add limit_req
:
...
location ~ /v3/user/oauth/refresh_token/ {
limit_req zone=backend_oauth nodelay;
limit_req_status 429;
fastcgi_pass 127.0.0.1:9014;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param DOCUMENT_ROOT $root_path;
fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
fastcgi_intercept_errors on;
}
...
Check syntax, re-read configs:
root@bttrm-stage-app-2:/home/admin# nginx -t && systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Apache benchmark
Test it:
$ ab -n 100 -c 10 "https://stage.example.com/v3/user/oauth/refresh_token/"
Check logs:
root@bttrm-stage-app-2:/home/admin# tail -f /var/log/nginx/stage.example.com-access.log | grep 194.***.***.26
194.***.***.26 - - [08/Aug/2019:14:26:29 +0300] "GET /v3/user/oauth/refresh_token/ HTTP/1.1" 404 27 "-" "ApacheBench/2.3"
194.***.***.26 - - [08/Aug/2019:14:26:29 +0300] "GET /v3/user/oauth/refresh_token/ HTTP/1.1" 429 162 "-" "ApacheBench/2.3"
194.***.***.26 - - [08/Aug/2019:14:26:29 +0300] "GET /v3/user/oauth/refresh_token/ HTTP/1.1" 429 162 "-" "ApacheBench/2.3"
...
The 429 response was returned, all works.
NGINX, limit_req
and AWS ALB
Found a possible issue when using AWS ALB (but this was posted at 2014): with the $binary_remote_addr
limits may not works, if so – try to use $http_x_forwarded_for
instead.
Although in my current case everything was fine, maybe because of the я set_real_ip_from
(see the NGINX: реальный IP в логах при работе за AWS Load Balancer post, Rus).
Top comments (0)