[nginx] Using User-Agent & IP address to rate limit
lorenanicole
nginx-forum at nginx.us
Mon Jul 28 15:35:51 UTC 2014
Nginx novice here - after spending some time both here, reading through
other community forums, and trial and error I'm looking for confirmation on
my current Nginx config and/or suggestions on a better Nginx config. The end
goal is to use both the IP address and User-Agent to rate limit requests
being proxied to an external API. Currently the config sets zones with their
respective rate limits and bursts using the IP address as the key. Inside
the main location directive the User-Agent is read and based on the
User-Agent the URI is rewritten to the location with the appropriate zone.
http {
include mime.types;
default_type application/octet-stream;
limit_req_zone $binary_remote_addr zone=one:10m rate=136r/s;
limit_req_zone $binary_remote_addr zone=two:10m rate=150r/s;
limit_req_zone $binary_remote_addr zone=three:10m rate=160r/s;
limit_req_zone $binary_remote_addr zone=four:10m rate=30r/m;
sendfile on;
keepalive_timeout 65;
server {
listen 443;
server_name localhost;
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
proxy_ssl_session_reuse off;
large_client_header_buffers 4 32K;
location /java {
limit_req zone=one burst=140;
log_format java '$remote_addr - $remote_user [$time_local]'
'"$request" | STATUS: $status | BODY BYTES: $body_bytes_sent |'
'"$http_referer" "$http_user_agent"| GET PARAMS: $args | REQ BODY:
$request_body';
access_log /var/log/nginx-access.log java;
proxy_pass https://example.com/;
}
location /python {
limit_req zone=two burst=140;
#echo "You made it here with: " $request_body "and this: " $args
"and this: " $uri "and this: " $1;
log_format python '$remote_addr - $remote_user [$time_local]'
'"$request" | STATUS: $status | BODY BYTES: $body_bytes_sent |'
'"$http_referer" "$http_user_agent"| GET PARAMS: $args | REQ BODY:
$request_body';
access_log /var/log/nginx-access.log python;
proxy_pass https://example.com/;
}
location /etc {
limit_req zone=four burst=1;
log_format etc '$remote_addr - $remote_user [$time_local]'
'"$request" | STATUS: $status | BODY BYTES: $body_bytes_sent |'
'"$http_referer" "$http_user_agent"| GET PARAMS: $args | REQ BODY:
$request_body';
access_log /var/log/nginx-access.log etc;
proxy_pass https://example.com/;
}
location / {
root html;
index index.html index.htm;
if ($http_user_agent = Java/1.6.0_65) {
rewrite ^(.*)$ /java$uri last;
}
if ($http_user_agent = python) {
rewrite ^(.*)$ /python$uri last;
}
if ($http_user_agent = "") {
rewrite ^(.*)$ /etc$uri last;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
The concern here is if there is a way to redirect the rewritten uri without
having to break out and start processing the request again (argument last)?
Additionally, is the setting of zone's using the IP address as the key the
proper way to control these different rate limiting and burst thresholds?
Posted at Nginx Forum: http://forum.nginx.org/read.php?2,252085,252085#msg-252085
More information about the nginx
mailing list