Apache Rewrite Rules para NGINX Rewrite Rules

Aplicando as regras dos servidores Apache para servidores NGINX


Autor: Réulison Silva Publicado em: Maio 19, 2021

Irei comentar como converter as regras do servidor Apache HTTP para a sintaxe NGINX. Você precisa converter para as regras de reescrita do NGINX ao colocá-lo na frente de seus servidores Apache para assumir o controle como proxy reverso ou load balance, ou quando substituir os servidores Apache por servidores NGINX. Lembre-se de que o NGINX não oferece suporte a arquivos de configuração por diretório (arquivos .htaccess do Apache), portanto, é necessário convertê-los separadamente.

Assumiremos que você está familiarizado com as regras do Apache e como o NGINX processa URLs.

Convertendo a regra que adiciona o www

Esta regra do Apache adiciona o prefixo www a URL:

RewriteCond %{HTTP_HOST} exemplo.org
RewriteRule (.*)         http://www.exemplo.org$1

A seguinte configuração do NGINX é a conversão correta. O primeiro server corresponde às solicitações do servidor para exemplo.org e as redireciona permanentemente para www.exemplo.org. O segundo server corresponde a URL reescrita (e todas as outras solicitações para www.exemplo.org) pelo servidor.

# USE ESSE EXEMPLO
server {
    listen      80;
    server_name exemplo.org;
    return      301 http://www.exemplo.org$request_uri;
}
 
server {
    listen      80;
    server_name www.exemplo.org;
    # ...
}

O seguinte pode parecer uma maneira natural de converter a regra do Apache em uma regra do NGINX, mas não recomendamos. Em comparação com a conversão recomendada, ela requer dois estágios extras de processamento: O NGINX deve primeiro verificar a condição if e, em seguida, avaliar a expressão regular na diretiva rewrite (simples assim).

# NÃO RECOMENDADO
server {
    listen      80;
    server_name www.exemplo.org exemplo.org;
    if ($http_host = exemplo.org) {
        rewrite (.*) http://www.exemplo.org$1;
    }
    # ...
}

Convertendo uma regra “não é” ou !

Esta regra do Apache corresponde a URLs que não são “exemplo.com e não www.exemplo.com” (você pode chamar isso de lógica inversa) e os reescreve em www.exemplo.com:

RewriteCond %{HTTP_HOST} !exemplo.com
RewriteCond %{HTTP_HOST} !www.exemplo.com
RewriteRule (.*)         http://www.exemplo.com$1

Para a conversão NGINX, definimos explicitamente um server que combina as versões “positivas” das diretivas Apache RewriteCond (ou seja, corresponde a URLs que começam com exemplo.com ou www.exemplo.com) e o outro server que corresponde ao que agora é melhor caracterizado como “todo o resto”.

server {
    listen      80;
    server_name exemplo.com www.exemplo.com;
    # ...
}
 
server {
    listen      80 default_server;
    server_name _;
    return      301 http://www.exemplo.com$request_uri;
}

WordPress.org possui um arquivo .htaccess padrão com as seguintes diretivas do Apache que permitem links permanentes “mais bonitos” do ponto de vista dos visitantes:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Aqui está o equivalente do NGINX:

location / {
    try_files $uri $uri/ /index.php?$args;
}

Em breve escrevo mais sobre como habilitar permalinks bonitos para WordPress com NGINX, assine minha newsletter.

Criando regras que encaminham solicitações dinâmicas para um App Server

Os administradores de servidores costumam usar o Apache Rewrite para servir recursos estáticos diretamente, se eles existirem, e encaminhar solicitações dinâmicas para um servidor de aplicações.

DocumentRoot /var/www/myapp.com/current/public
 
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ %{DOCUMENT_ROOT}/system/maintenance.html [L]
 
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)$ $1 [QSA,L]
 
RewriteCond %{REQUEST_FILENAME}/index.html -f
RewriteRule ^(.*)$ $1/index.html [QSA,L]
 
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [QSA,L]
 
RewriteRule ^/(.*)$ balancer://app-server_cluster%{REQUEST_URI} [P,QSA,L]

Especificamente, as regras acima executam as seguintes funções:

  • A diretiva DocumentRoot especifica o diretório do disco local onde o conteúdo é armazenado.

  • O primeiro bloco de regras detecta se o arquivo /system/maintenance.html existe - é uma prática comum entre os administradores de servidores criar este arquivo como um sinal de que o site está temporariamente indisponível devido à manutenção. Se o arquivo existir, ele será servido independentemente do arquivo solicitado (efetivamente, a regra reescreve todas as solicitações para maintenance.html). Presumivelmente, a reescrita resulta no envio de uma notificação de manutenção ao navegador.

  • Os próximos três blocos atendem a esses recursos estáticos, se existirem:

    • O arquivo solicitado;
    • O arquivo index.html no diretório nomeado no final da URL;
    • Qualquer arquivo com a extensão .html;
  • A regra final entra em ação se nenhum dos três tipos de arquivo existir. Ele passa a solicitação para um cluster de servidore de aplicações.

Esta é a conversão para NGINX. A diretiva root corresponde à diretiva Apache DocumentRoot. A diretiva try_files substitui as regras restantes, usando um location chamado @app-server_cluster como a reescrita final e definindo um location correspondente que envia solicitações de proxy ao servidor de aplicações:

location / {
    root       /var/www/myapp.com/current/public;
 
    try_files /system/maintenance.html
              $uri $uri/index.html $uri.html
              @app-server_cluster;
}
 
location @app-server_cluster {
    proxy_pass http://app-server;
}

Dúvidas? Comentários abaixo.