![Ограничение множественной скорости Nginx с использованием входящего заголовка $http_q](https://rvso.com/image/789301/%D0%9E%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9%20%D1%81%D0%BA%D0%BE%D1%80%D0%BE%D1%81%D1%82%D0%B8%20Nginx%20%D1%81%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC%20%D0%B2%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B5%D0%B3%D0%BE%20%D0%B7%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE%D0%B2%D0%BA%D0%B0%20%24http_q.png)
У меня есть следующая конфигурация ограничения скорости в блоке http:
# Rate limit config declaration
map $http_q $r_b001 {
b001 "1";
}
# Zone config
limit_req_zone $r_b001 zone=b001:100m rate=20r/s;
# Rate limit config declaration
map $http_q $r_c001 {
c001 "1";
}
# Zone config
limit_req_zone $r_c001 zone=c001:100m rate=25r/s;
И внутри блока локации у меня есть
location /c001{
limit_req zone=c001 burst=1 nodelay;
limit_req_status 429;
other config...
}
location /b001{
limit_req zone=b001 burst=1 nodelay;
limit_req_status 429;
other config...
}
Теперь, когда я запускаю нагрузочный тест с ключом b001 и c001, я не получаю желаемого контроля ограничения скорости. А если я добавляю больше ключей и связанных с ними конфигураций, отклонение становится еще больше. Где я ошибся и как достичь такого ограничения скорости на ключ на основе местоположения.
Полная конфигурация выглядит следующим образом:
geoip2 /etc/nginx/geoip/geoLite-2Country/GeoLite2-Country.mmdb {
$geoip2_data_country_iso_code country iso_code;
}
include /etc/nginx/conf.d/geoip_config/*.conf;
include /etc/nginx/conf.d/blacklisted_config/*.conf;
##########################################################################################
# Whitelist config declaration
geo $whitelist_b001 {
default 1;
}
# Rate limit config declaration
map $http_q $r_b001 {
b001 "1";
default $request_id;
}
# Zone config
limit_req_zone $r_b001 zone=b001:100m rate=25r/s;
# Rate with White limit config
map $http_q $rw_b001 {
b001 $whitelist_b001;
default "0";
}
##########################################################################################
# Whitelist config declaration
geo $whitelist_c001 {
default 1;
}
# Rate limit config declaration
map $http_q $r_c001 {
c001 "1";
default $request_id;
}
# Zone config
limit_req_zone $r_c001 zone=c001:100m rate=15r/s;
# Rate with White limit config
map $http_q $rw_c001 {
c001 $whitelist_c001;
default "0";
}
# API Check, regex matches to 1 if one value corresponds to 1
map $r_b001$r_c001 $API_CHECK {
default 0;
~((1)) 1;
}
#Pass through check, regex matches to 1 if one value corresponds to 1
map $rw_b001$rw_c001 $PASS_THROUGH{
~((1)) 1;
}
server {
#*****************************
# LISTEN PORT AND SERVER NAME
#*****************************
listen 443 ssl http2;
server_name api.com;
client_body_buffer_size 16k;
client_max_body_size 16k;
access_log /var/log/nginx/app/access.log json_output;
#*****************************
# ROOT PATH
#*****************************
root /var/www/html;
#*****************************
# INDEX PAGE
#*****************************
location / {
try_files $uri$args $uri$args/ =404;
}
#***************************************
# Key and IP Validators
#**************************************
if ($API_CHECK = 0) {
return 401 '{"status": "failure","status_code": 401 ,"custom_status_code": "XXXX","request_id": "$request_id","date_time": "$date_gmt","detail": "API key is Invalid"}';
}
if ($allowed_country = no) {
return 403 '{"status": "failure","status_code": 403 ,"custom_status_code": "XXXX","request_id": "$request_id","date_time": "$date_gmt","detail": "Your request to this site is forbidden"}';
}
if ($blacklisted_ip = 1) {
return 403 '{"status": "failure","status_code": 403 ,"custom_status_code": "XXXX","request_id": "$request_id","date_time": "$date_gmt","detail": "Your request to this site is forbidden"}';
}
if ($PASS_THROUGH = 0) {
return 403 '{"status": "failure","status_code": 403 ,"custom_status_code": "XXXX","request_id": "$request_id","date_time": "$date_gmt","detail": "Your request to this site is forbidden"}';
}
#*****************************
# Application re-route
#*****************************
location ^~ /api {
rewrite ^/api/(.*)$ /proxyapi/$http_q/$1?$args last;
}
location ^~ /proxyapi/b001 {
# Limit req zone inside its own block
limit_req zone=b001 burst=1 nodelay;
limit_req_status 429;
alias /var/www/html/risk_app/public;
try_files $uri $uri/ @risk_laravel_b001;
index index.php;
# Deny .htaccess
location ~ /\.ht{
deny all;
return 404;
}
# FastCGI Configuration
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
include fastcgi_params;
fastcgi_read_timeout 600;
fastcgi_param SCRIPT_FILENAME /var/www/html/risk_app/public/index.php;
fastcgi_param SSL_CLIENT_VERIFY $ssl_client_verify;
fastcgi_param SSL_CLIENT_S_DN $ssl_client_s_dn;
fastcgi_param NGINX_REQUEST_ID $request_id;
}
}
location @risk_laravel_b001 {
rewrite /proxyapi/b001/(.*)$ /proxyapi/b001/index.php?/$1 last;
}
location ^~ /proxyapi/c001 {
# Limit req zone inside its own block
limit_req zone=default_zone burst=1 nodelay;
limit_req_status 429;
alias /var/www/html/risk_app/public;
try_files $uri $uri/ @risk_laravel_c001;
index index.php;
# Deny .htaccess
location ~ /\.ht{
deny all;
return 404;
}
# FastCGI Configuration
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
include fastcgi_params;
fastcgi_read_timeout 600;
fastcgi_param SCRIPT_FILENAME /var/www/html/risk_app/public/index.php;
fastcgi_param SSL_CLIENT_VERIFY $ssl_client_verify;
fastcgi_param SSL_CLIENT_S_DN $ssl_client_s_dn;
fastcgi_param NGINX_REQUEST_ID $request_id;
}
}
location @risk_laravel_c001 {
rewrite /proxyapi/c001/(.*)$ /proxyapi/c001/index.php?/$1 last;
}
location /ping {
access_log off;
return 200 '{"status":"succes","status_code": 200}';
}
}