Rewrite e Rate Limiting
Aula 4 de 6
Rewrite e Redirecionamentos
Diretiva rewrite
# Sintaxe: rewrite regex substituição [flag];
# Redirecionamento simples
rewrite ^/old-page$ /new-page permanent; # 301
rewrite ^/temp$ /other redirect; # 302
# Redirecionamento de domínio
server {
listen 80;
server_name old-domain.com www.old-domain.com;
rewrite ^(.*)$ http://new-domain.com$1 permanent;
}
# Remover prefixo de URL
rewrite ^/products/(.*)$ /item?id=$1 last;
# Redirecionar para HTTPS com rewrite
server {
listen 80;
server_name site.com;
rewrite ^(.*)$ https://site.com$1 permanent;
}
Flags do rewrite
| Flag | Significado |
|---|---|
last | Finaliza o processamento de rewrites na location atual |
break | Finaliza o processamento de rewrites sem validar novas locations |
redirect | Redirecionamento temporário (302) |
permanent | Redirecionamento permanente (301) |
Diretiva return (preferível ao rewrite)
# return é mais eficiente que rewrite para redirecionamentos simples
# Redirecionamentos
return 301 http://new-domain.com$request_uri;
return 302 /temp-page.html;
# Respostas diretas
return 200 "OK";
return 404;
return 403 "Acesso negado";
# Redirecionar HTTP para HTTPS (forma mais eficiente)
server {
listen 80;
server_name site.com;
return 301 https://site.com$request_uri;
}
# Redirecionar www para sem www
server {
listen 80;
server_name www.site.com;
return 301 $scheme://site.com$request_uri;
}
# Redirecionar com preservação de query string
server {
listen 80;
server_name site.com;
return 301 https://site.com$request_uri?$query_string;
}
try_files com Named Locations
# Named location (prefixo @)
server {
root /var/www/site;
location / {
try_files $uri $uri/ @app;
}
location @app {
proxy_pass http://backend:3000;
}
location /admin {
try_files $uri $uri/ @admin_fallback;
}
location @admin_fallback {
proxy_pass http://admin-backend:4000;
}
}
Exemplos Práticos de Rewrite
server {
listen 80;
server_name blog.exemplo.com;
# SEO: remover trailing slash
rewrite ^/(.+)/$ /$1 permanent;
# SEO: URL amigável
rewrite ^/post/([0-9]+)/(.*)$ /article.php?id=$1&slug=$2 last;
# Redirecionar páginas antigas
location /about-us {
return 301 /sobre;
}
location /category {
rewrite ^/category/(.*)$ /categoria/$1 permanent;
}
# Bloquear hotlinking
location ~ \.(jpg|jpeg|png|gif)$ {
valid_referers none blocked site.com *.site.com;
if ($invalid_referer) {
return 403;
}
}
# Forçar download de certos arquivos
location ~ \.(pdf|doc)$ {
add_header Content-Disposition "attachment";
}
}
Rate Limiting
limit_req_zone e limit_req
# No bloco http (nginx.conf)
# Define a zona de rate limiting
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=general_limit:10m rate=100r/s;
# Também pode usar $server_name como chave
limit_req_zone $server_name zone=site_limit:10m rate=1000r/s;
# Rate por URI
limit_req_zone $binary_remote_addr$uri zone=uri_limit:10m rate=10r/s;
server {
# Aplicar rate limiting global
location / {
limit_req zone=general_limit burst=200 nodelay;
}
# Rate limit restrito para API
location /api/ {
limit_req zone=api_limit burst=50 nodelay;
proxy_pass http://api_backend;
}
# Rate limit severo para login
location /login {
limit_req zone=login_limit burst=3;
limit_req_status 429;
proxy_pass http://auth_backend;
}
# Rate limit por URI
location /search {
limit_req zone=uri_limit burst=10 nodelay;
proxy_pass http://search_backend;
}
}
Burst e Nodelay
# Sem burst: excesso é rejeitado imediatamente
location /api/ {
limit_req zone=api_limit;
}
# Com burst: permite picos acima da taxa
# 30 req/s com burst=20 permite até 50 req/s por curto período
location /api/ {
limit_req zone=api_limit burst=20;
}
# Com burst e nodelay: processa o burst imediatamente
# em vez de enfileirar
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
}
# Status personalizado para rate limit
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
# Retorna header informativo
add_header Retry-After 5 always;
}
limit_conn_zone (Conexões Simultâneas)
# No bloco http
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn_zone $server_name zone=server:10m;
server {
# Limitar conexões por IP
location /downloads/ {
limit_conn addr 2;
limit_conn_status 503;
}
# Limitar conexões por servidor
location / {
limit_conn server 100;
}
# Limitar conexões por IP + nível de zona adicional
location /stream/ {
limit_conn addr 1;
limit_conn_log_level warn;
}
}
Geo, Allow e Deny
Bloqueio por Geolocalização
# No bloco http - baixar banco GeoIP
# sudo apt install libnginx-mod-http-geoip
geoip_country /usr/share/GeoIP/GeoIP.dat;
server {
location / {
# Bloquear países específicos
if ($geoip_country_code ~ (CN|RU|KP)) {
return 403;
}
}
}
Allow e Deny por IP
location /admin {
# Restringir acesso a IPs internos
allow 127.0.0.1;
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
}
location /internal-api {
allow 10.0.0.0/8;
allow 172.16.0.0/12;
deny all;
}
location /status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
Mapa geo para Regras Condicionais
# No bloco http
geo $blocked_country {
default 0;
CN 1;
RU 1;
KP 1;
IR 1;
}
geo $is_internal {
default 0;
10.0.0.0/8 1;
172.16.0.0/12 1;
192.168.0.0/16 1;
127.0.0.0/8 1;
}
server {
location / {
if ($blocked_country) {
return 403;
}
}
location /admin {
if ($is_internal) {
proxy_pass http://admin_backend;
}
return 403;
}
}
Lab: Proteção contra Abuso com Rate Limiting
Configure proteção completa contra abuso usando rate limiting, restrição de IP e redirecionamentos.
# 1. Criar aplicação de teste
sudo mkdir -p /var/www/rate-limited
cat << 'HTML' | sudo tee /var/www/rate-limited/index.html
<!DOCTYPE html>
<html>
<head><title>Protegido</title></head>
<body>
<h1>Site Protegido</h1>
<ul>
<li><a href="/api/">API (30 req/s)</a></li>
<li><a href="/login">Login (5 req/min)</a></li>
<li><a href="/downloads/">Downloads (2 conexões/IP)</a></li>
<li><a href="/admin">Admin (IP interno)</a></li>
</ul>
</body>
</html>
HTML
# 2. Criar configuração com rate limiting
cat << 'NGINX' | sudo tee /etc/nginx/sites-available/rate-limited-site
limit_req_zone $binary_remote_addr zone=general:10m rate=50r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_conn_zone $binary_remote_addr zone=download:10m;
server {
listen 80;
server_name rate-limited.local;
root /var/www/rate-limited;
index index.html;
# Rate limit geral
location / {
limit_req zone=general burst=100 nodelay;
try_files $uri $uri/ =404;
}
# API com rate limit médio
location /api/ {
limit_req zone=api burst=50 nodelay;
limit_req_status 429;
add_header Retry-After 1 always;
proxy_pass http://127.0.0.1:3000;
}
# Login com rate limit severo
location /login {
limit_req zone=login burst=3;
limit_req_status 429;
add_header Retry-After 60 always;
proxy_pass http://127.0.0.1:3000;
}
# Downloads com limite de conexões simultâneas
location /downloads/ {
limit_conn download 2;
limit_conn_status 503;
alias /var/www/rate-limited/downloads/;
autoindex on;
}
# Admin apenas para IPs internos
location /admin {
allow 127.0.0.1;
allow 192.168.0.0/16;
deny all;
}
# Redirecionamentos
location /old-page {
return 301 /new-page;
}
location ~ ^/product/([0-9]+)$ {
return 301 /item?id=$1;
}
access_log /var/log/nginx/rate-limited-access.log;
error_log /var/log/nginx/rate-limited-error.log;
}
NGINX
# 3. Habilitar e aplicar
sudo ln -sf /etc/nginx/sites-available/rate-limited-site /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
# 4. Testar rate limiting
echo "Testando requisições normais..."
curl -s -o /dev/null -w "%{http_code}" http://rate-limited.local/
echo -e "\n\nTestando rate limit (muitas requisições)..."
for i in {1..60}; do
curl -s -o /dev/null -w "%{http_code} " http://rate-limited.local/api/ &
done
wait
echo -e "\n\nTestando restrição de IP..."
curl -s -o /dev/null -w "%{http_code}" http://rate-limited.local/admin/
echo -e "\n\nTestando redirect..."
curl -I http://rate-limited.local/old-page 2>&1 | grep Location
Rate limiting é sua primeira linha de defesa contra abuso. Use combinado com allow/deny, geo blocking e redirects. Sempre defina bursts adequados para não impactar usuários legítimos e use nodelay para evitar filas desnecessárias.