Servidores Web: Apache2 e Nginx no Debian 13
Nesta seção de tutoriais, os servidores web abordados são o Apache2 e o Nginx. Ambos são amplamente empregados no mercado corporativo, permitindo atender desde hospedagens virtuais dinâmicas com módulos avançados até balanceamento de carga e proxy reverso de altíssimo desempenho.
A escolha do servidor web depende do perfil da sua carga de trabalho e dos requisitos de infraestrutura:
Apache2 (HTTP Server)
Poderoso, flexível e modular. Utiliza arquitetura orientada a processos e threads através de MPMs (Multi-Processing Modules: mpm_event, mpm_worker e mpm_prefork).
- Pontos Fortes: Amplo ecossistema de módulos nativos (
mod_security,mod_dav,mod_auth_pam,mod_ldap), suporte a arquivos.htaccesspor diretório. - Ideal para: Hospedagens compartilhadas, aplicações corporativas com autenticação heterogênea e controle descentralizado.
Nginx (Engine X)
Arquitetura assíncrona orientada a eventos (event-driven) baseada na chamada epoll do kernel Linux.
- Pontos Fortes: Consumo de memória extremamente baixo e previsível sob milhares de conexões simultâneas (C10K), altíssima performance para conteúdo estático e excelente atuação como Reverse Proxy e Load Balancer.
- Ideal para: APIs REST, microserviços, frontends de alto tráfego e terminação SSL ágil.
Clique em qualquer item para expandir ou consulte o menu lateral "Full Screen Overlay" para navegação direta:
Instalação dos pacotes oficiais, arquitetura de MPMs e validação de serviço.
Hospedagem baseada em nomes (Name-based Virtual Hosting) e resolução por cabeçalho Host.
Criptografia assimétrica, certificados digitais, cifras seguras e HSTS.
Publicação descentralizada em ~/public_html/ e controle de privilégios de arquivos.
Execução de scripts via Common Gateway Interface (RFC 3875) com mod_cgid.
Módulo embarcado libapache2-mod-php e suas implicações com mpm_prefork.
Arquitetura desacoplada com mpm_event e fastcgi_proxy via socket Unix.
Controle de acesso por senha criptografada em htpasswd com algoritmo bcrypt.
Compartilhamento colaborativo via HTTP (RFC 4918) com travas mod_dav_fs.
Validação contra credenciais locais do Linux sem duplicação de contas.
Integração corporativa com diretórios OpenLDAP ou Microsoft Active Directory.
Multiplexação de conexões, compressão HPACK e ALPN para alto desempenho.
Proxy reverso e balanceador de carga em camada 7 com mod_proxy_balancer.
Firewall de aplicação web com regras OWASP CRS contra SQLi, XSS e explorações.
Limitação de vazão de banda por conexão e proteção contra exaustão de link.
Execução persistente de interpretador Perl em memória eliminando ciclo de compilação.
Execução de aplicações Python WSGI (Flask/Django) em modo daemon corporativo.
Análise de tráfego, sessões e crawlers a partir do formato Combined Log.
Implantação de CMS com pilha LAMP, reescrita de URLs amigáveis e banco MariaDB.
Base de conhecimento wiki autohospedada, isolamento de uploads e integridade UTF-8.
Fundamentação Teórica
O Apache HTTP Server (Apache2) é estruturado em uma arquitetura modular extensível. Seu núcleo gerencia o ciclo de vida da conexão de rede e a máquina de estados HTTP através de MPMs (Multi-Processing Modules):
- mpm_event (Padrão no Debian 13): Arquitetura orientada a eventos e threads assíncronas. Uma thread dedicada gerencia conexões em estado Keep-Alive (utilizando a chamada
epolldo Linux), liberando as threads de trabalho para atender novas requisições imediatas. - mpm_worker: Modelo híbrido multi-processo e multi-thread, eficiente, porém sem tratamento assíncrono para conexões inativas.
- mpm_prefork: Modelo tradicional isolado em processos individuais (sem threads). Obrigatório apenas quando são utilizadas bibliotecas externas não-thread-safe.
No Debian, a configuração é segregada nos diretórios mods-available/, sites-available/ e conf-available/, ativados por links simbólicos gerados pelos comandos utilitários a2enmod, a2ensite e a2enconf.
ServerTokens Prod e ServerSignature Off em /etc/apache2/conf-available/security.conf para ocultar a versão exata do servidor em cabeçalhos HTTP.
Roteiro Prático & Configuração
# 1. Atualizar índices de pacotes e instalar o Apache2 sudo apt update && sudo apt install -y apache2 apache2-utils # 2. Habilitar inicialização no boot e iniciar o serviço sudo systemctl enable --now apache2 # 3. Liberar portas no firewall UFW (ou nftables) sudo ufw allow in "Apache Full"
Validação e Teste
# Checar integridade dos arquivos de configuração e status do daemon sudo apache2ctl configtest sudo systemctl status apache2 --no-pager curl -I http://localhost
Fundamentação Teórica
O recurso de Hospedagem Virtual Baseada em Nome (Name-based Virtual Hosting) permite que um único endereço IP e instância do Apache atendam a centenas de domínios distintos. A distinção entre sites ocorre pela inspeção obrigatória do cabeçalho Host: enviado pelo cliente (definido na RFC 7230 / HTTP/1.1).
O algoritmo de roteamento do Apache avalia a correspondência exata de ServerName e, secundariamente, de ServerAlias. O bloco <Directory> define a barreira de segurança de execução e listagem (Options) e se arquivos de configuração distribuídos (AllowOverride) podem sobrescrever diretivas.
Roteiro Prático & Configuração
# 1. Criar estrutura de diretórios para o domínio lab.local sudo mkdir -p /var/www/lab.local/public_html sudo chown -R www-data:www-data /var/www/lab.local/public_html sudo chmod -R 755 /var/www/lab.local # 2. Criar página estática inicial echo '<h1>Servidor Web Lab.local no Debian 13</h1>' | sudo tee /var/www/lab.local/public_html/index.html # 3. Criar arquivo de VirtualHost em sites-available sudo tee /etc/apache2/sites-available/lab.local.conf << 'EOF' <VirtualHost *:80> ServerName lab.local ServerAlias www.lab.local ServerAdmin admin@lab.local DocumentRoot /var/www/lab.local/public_html <Directory /var/www/lab.local/public_html> Options -Indexes +FollowSymLinks AllowOverride None Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/lab.local_error.log CustomLog ${APACHE_LOG_DIR}/lab.local_access.log combined </VirtualHost> EOF # 4. Ativar o novo site e recarregar graciosamente o serviço sudo a2ensite lab.local.conf sudo systemctl reload apache2
Validação e Teste
# Simulação de requisição com injeção do cabeçalho Host curl -H "Host: lab.local" http://localhost
Fundamentação Teórica
A proteção de dados em trânsito baseia-se no protocolo Transport Layer Security (TLS 1.2 e TLS 1.3). Durante o TLS Handshake, cliente e servidor negociam parâmetros criptográficos, autenticam o servidor via certificados digitais X.509 e trocam segredos simétricos através de curvas elípticas (ECDHE) com propriedade de Perfect Forward Secrecy (PFS).
Com o Server Name Indication (SNI), o cliente informa o nome de domínio antes da negociação da chave, permitindo múltiplos certificados SSL em um mesmo endereço IP.
Roteiro Prático & Configuração
# 1. Habilitar os módulos necessários sudo a2enmod ssl headers rewrite # 2. Gerar par de chaves e certificado autoassinado para testes locais sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/ssl/private/apache-selfsigned.key \ -out /etc/ssl/certs/apache-selfsigned.crt \ -subj "/C=BR/ST=Amazonas/L=Manaus/O=STI/CN=lab.local" # 3. Configurar VirtualHost SSL na porta 443 sudo tee /etc/apache2/sites-available/lab.local-ssl.conf << 'EOF' <VirtualHost *:443> ServerName lab.local DocumentRoot /var/www/lab.local/public_html SSLEngine on SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key # Hardening de Protocolos e Cifras (Desativar SSLv3, TLS 1.0 e TLS 1.1) SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite HIGH:!aNULL:!MD5:!3DES # Cabeçalho HSTS (Strict-Transport-Security) Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" ErrorLog ${APACHE_LOG_DIR}/lab.local_ssl_error.log CustomLog ${APACHE_LOG_DIR}/lab.local_ssl_access.log combined </VirtualHost> EOF # 4. Ativar o site SSL e recarregar o Apache sudo a2ensite lab.local-ssl.conf sudo systemctl reload apache2
Validação e Teste
# Inspecionar certificado e versão TLS negociada via linha de comando openssl s_client -connect localhost:443 -servername lab.local < /dev/null 2>&1 | grep -E "Protocol|Cipher|CN"
Fundamentação Teórica
O módulo mod_userdir traduz requisições com a sintaxe /~usuario/ diretamente para o diretório local /home/usuario/public_html. Trata-se de uma solução tradicional para publicação autônoma em universidades, centros de pesquisa e intranets de TI.
Aspecto de Segurança Crítico: O processo do Apache roda sob o usuário www-data. Para que o Apache consiga atravessar até public_html sem expor outros arquivos do usuário, o diretório home deve ter permissão de execução (chmod 711), e o public_html deve ter permissão de leitura (chmod 755).
Roteiro Prático & Configuração
# 1. Habilitar o módulo userdir sudo a2enmod userdir # 2. Criar a pasta no perfil do usuário de teste (ex: aluno) mkdir -p ~/public_html echo "<h2>Home page pessoal de $USER no Debian 13</h2>" > ~/public_html/index.html # 3. Ajustar permissões POSIX de travessia chmod 711 ~ chmod 755 ~/public_html chmod 644 ~/public_html/index.html # 4. Recarregar o Apache sudo systemctl reload apache2
Validação e Teste
# Testar requisição direta com curl curl -s http://localhost/~$USER/
Fundamentação Teórica
O padrão Common Gateway Interface (CGI, RFC 3875) especifica a interface entre o servidor HTTP e programas executáveis externos. O Apache invoca o executável via chamada de sistema fork/exec, injetando os dados da requisição em variáveis de ambiente (como QUERY_STRING, REQUEST_METHOD e HTTP_USER_AGENT) e coletando a saída padrão (stdout).
Em MPMs multithread como o mpm_event, utiliza-se o módulo mod_cgid, que mantém um processo daemon separado para gerenciar os forks, prevenindo vazamentos de descritores de arquivos entre threads de rede.
Roteiro Prático & Configuração
# 1. Habilitar o módulo CGI para ambientes multithread sudo a2enmod cgid # 2. Criar um script CGI em Python 3 em /usr/lib/cgi-bin/ sudo tee /usr/lib/cgi-bin/info.py << 'EOF' #!/usr/bin/env python3 import os import datetime print("Content-Type: text/html; charset=utf-8\n") print("<html><body>") print("<h1>Execução CGI Nativa (Python 3)</h1>") print(f"<p><strong>Data/Hora do Servidor:</strong> {datetime.datetime.now()}</p>") print(f"<p><strong>Método HTTP:</strong> {os.environ.get('REQUEST_METHOD', 'N/A')}</p>") print(f"<p><strong>Remote IP:</strong> {os.environ.get('REMOTE_ADDR', 'N/A')}</p>") print("</body></html>") EOF # 3. Tornar o script executável e recarregar o Apache sudo chmod +x /usr/lib/cgi-bin/info.py sudo systemctl reload apache2
Validação e Teste
# Executar requisição HTTP para o script CGI curl -s http://localhost/cgi-bin/info.py
Fundamentação Teórica
O mod_php embute o motor de interpretação Zend Engine diretamente dentro dos processos de atendimento do Apache. Isso significa que não há comunicação de rede ou IPC entre o web server e o PHP, reduzindo a latência em requisições monolíticas legadas.
Restrição Arquitetural Severa: Diversas bibliotecas C legadas vinculadas ao PHP não são reentrantes nem thread-safe. Por isso, a utilização do libapache2-mod-php obriga o uso do módulo de multiprocessamento mpm_prefork. Cada requisição ocupa um processo completo de 30-50 MB de RAM, inviabilizando altas taxas de concorrência.
Roteiro Prático & Configuração
# 1. Instalar o módulo mod_php e utilitários sudo apt install -y libapache2-mod-php php # 2. Desativar mpm_event e ativar mpm_prefork (requisito do mod_php) sudo a2dismod mpm_event sudo a2enmod mpm_prefork sudo a2enmod php* # 3. Criar arquivo de teste echo '<?php phpinfo(); ?>' | sudo tee /var/www/html/info.php sudo systemctl restart apache2
Validação e Teste
# Verificar MPM ativo e execução do interpretador apache2ctl -M | grep -E "mpm|php" curl -s http://localhost/info.php | grep -i "Zend Engine"
Fundamentação Teórica
A arquitetura moderna recomendada para PHP em servidores de produção desacopla o servidor web do interpretador. O Apache atua exclusivamente como servidor HTTP assíncrono (usando mpm_event) e repassa requisições .php via protocolo binário FastCGI para o serviço PHP-FPM (FastCGI Process Manager).
A comunicação via Unix Domain Socket (ex: /run/php/php8.4-fpm.sock) opera diretamente no buffer de memória do kernel, sem a sobrecarga de pilha de rede TCP/IP, proporcionando baixa latência e contenção de vazamento de memória com pools dinâmicos de workers.
Roteiro Prático & Configuração
# 1. Instalar PHP-FPM e extensões recomendadas sudo apt install -y php-fpm libapache2-mod-fcgid # 2. Desativar mod_php e migrar para mpm_event sudo a2dismod php* sudo a2dismod mpm_prefork sudo a2enmod mpm_event proxy proxy_fcgi setenvif # 3. Ativar a configuração FPM padrão do Debian PHP_CONF=$(ls /etc/apache2/conf-available/ | grep -E "php.*-fpm.conf" | head -n 1) sudo a2enconf ${PHP_CONF%.conf} # 4. Reiniciar o serviço Apache2 sudo systemctl restart apache2
Validação e Teste
# Checar processo PHP-FPM e cabeçalhos HTTP retornados systemctl status php*-fpm --no-pager curl -I http://localhost/info.php
Fundamentação Teórica
Definida na RFC 7617, a autenticação básica HTTP é um mecanismo sem estado (stateless). Quando um cliente requisita um recurso protegido, o servidor retorna o código de status 401 Unauthorized com o cabeçalho de desafio WWW-Authenticate: Basic realm="Restrito".
O cliente codifica usuário e senha em Base64 e reenvia no cabeçalho Authorization: Basic <token>. Como o Base64 é reversível, o uso conjunto com SSL/TLS (HTTPS) é mandatório para evitar interceptação de credenciais.
Roteiro Prático & Configuração
# 1. Criar o arquivo de senhas protegido com hash moderno (bcrypt -B) sudo htpasswd -B -c /etc/apache2/.htpasswd admin sudo chown root:www-data /etc/apache2/.htpasswd sudo chmod 640 /etc/apache2/.htpasswd # 2. Proteger um diretório específico no VirtualHost sudo mkdir -p /var/www/html/restrito echo '<h1>Área Administrativa Confidencial</h1>' | sudo tee /var/www/html/restrito/index.html sudo tee /etc/apache2/conf-available/area-restrita.conf << 'EOF' <Directory /var/www/html/restrito> AuthType Basic AuthName "Acesso Restrito - Credenciais Necessarias" AuthUserFile /etc/apache2/.htpasswd Require valid-user </Directory> EOF sudo a2enconf area-restrita sudo systemctl reload apache2
Validação e Teste
# Teste sem credenciais (espera 401) e com credenciais (espera 200) curl -I http://localhost/restrito/ curl -u admin:senha http://localhost/restrito/
Fundamentação Teórica
O protocolo WebDAV (RFC 4918) adiciona capacidades de edição e gerenciamento colaborativo de arquivos ao protocolo HTTP. Introduz novos métodos HTTP:
PROPFIND/PROPPATCH: Leitura e alteração de metadados de arquivos.MKCOL: Criação de coleções (diretórios remotos).LOCK/UNLOCK: Controle de concorrência com bloqueio exclusivo ou compartilhado.
O Apache gerencia as travas através do módulo mod_dav_fs, persistindo estados de concorrência em uma base binária configurada na diretiva DavLockDB.
Roteiro Prático & Configuração
# 1. Habilitar módulos WebDAV sudo a2enmod dav dav_fs # 2. Configurar a DavLockDB e diretório compartilhado sudo mkdir -p /var/lib/apache2/ sudo mkdir -p /var/www/webdav sudo chown -R www-data:www-data /var/www/webdav /var/lib/apache2 sudo tee /etc/apache2/conf-available/webdav.conf << 'EOF' DavLockDB /var/lib/apache2/DavLock Alias /webdav /var/www/webdav <Directory /var/www/webdav> Dav On Options Indexes AuthType Basic AuthName "WebDAV Storage" AuthUserFile /etc/apache2/.htpasswd Require valid-user </Directory> EOF # 3. Ativar configuração e recarregar sudo a2enconf webdav sudo systemctl restart apache2
Validação e Teste
# Criar diretório remoto via requisição MKCOL curl -X MKCOL -u admin:senha http://localhost/webdav/novo_diretorio curl -T /etc/issue -u admin:senha http://localhost/webdav/issue_upload.txt
Fundamentação Teórica
O Pluggable Authentication Modules (PAM) é o arcabouço central de autenticação do Linux. Ao integrá-lo ao Apache, as contas de usuários locais criadas no sistema operacional (definidas em /etc/passwd e /etc/shadow) podem ser usadas para acesso web.
Desafio de Privilégios: O processo do Apache (usuário www-data) não possui privilégios para ler o arquivo /etc/shadow diretamente. A arquitetura segura utiliza o utilitário auxiliar pwauth (com flag setuid root restrita) integrado ao módulo mod_authnz_external.
Roteiro Prático & Configuração
# 1. Instalar utilitário pwauth e módulo de autenticação externa sudo apt install -y pwauth libapache2-mod-authnz-external sudo a2enmod authnz_external # 2. Configurar o provider externo de autenticação PAM sudo tee /etc/apache2/conf-available/auth-pam.conf << 'EOF' AddExternalAuth pwauth /usr/sbin/pwauth SetExternalAuthMethod pwauth pipe <Directory /var/www/html/pam-protegido> AuthType Basic AuthName "Autenticacao Local do Sistema (PAM)" AuthBasicProvider external AuthExternal pwauth Require valid-user </Directory> EOF # 3. Criar diretório e recarregar Apache sudo mkdir -p /var/www/html/pam-protegido echo '<h1>Autenticado com Sucesso via Conta Linux PAM</h1>' | sudo tee /var/www/html/pam-protegido/index.html sudo a2enconf auth-pam sudo systemctl reload apache2
Validação e Teste
# Testar autenticação com usuário e senha do sistema operacional curl -u aluno:senha123 http://localhost/pam-protegido/
Fundamentação Teórica
O LDAP (Lightweight Directory Access Protocol) centraliza identidades e privilégios em infraestruturas corporativas (como OpenLDAP, FreeIPA ou Microsoft Active Directory). O módulo mod_authnz_ldap realiza um fluxo em dois passos:
- Search / Bind de Serviço: O Apache conecta-se ao servidor de catálogo com uma conta de serviço (
AuthLDAPBindDN) e localiza o DN (Distinguished Name) do usuário com base no atributo informado (ex:sAMAccountNameouuid). - User Bind: O Apache tenta realizar uma nova autenticação (bind) utilizando o DN localizado e a senha digitada pelo usuário. Se for aceita, o acesso é validado.
Roteiro Prático & Configuração
# 1. Habilitar módulos LDAP no Apache sudo a2enmod ldap authnz_ldap # 2. Configurar o bloco de autenticação LDAP em um diretório sudo tee /etc/apache2/conf-available/auth-ldap.conf << 'EOF' <Directory /var/www/html/corporativo> AuthType Basic AuthName "Dominio Corporativo LDAP" AuthBasicProvider ldap # URL LDAP: Servidor, BaseDN, Atributo, Escopo, Filtro AuthLDAPURL "ldap://192.168.1.10:389/dc=empresa,dc=lan?sAMAccountName?sub?(objectClass=user)" NONE AuthLDAPBindDN "cn=svc_apache,ou=Servicos,dc=empresa,dc=lan" AuthLDAPBindPassword "SenhaSegura123!" # Restringir a qualquer usuário autenticado ou a um grupo específico Require valid-user # Require ldap-group cn=Tecnologia,ou=Grupos,dc=empresa,dc=lan </Directory> EOF # 3. Ativar e recarregar serviço sudo mkdir -p /var/www/html/corporativo sudo a2enconf auth-ldap sudo systemctl reload apache2
Validação e Teste
# Inspecionar handshake e logs de busca LDAP durante a autenticação sudo tail -f /var/log/apache2/error.log
Fundamentação Teórica
O HTTP/2 (RFC 7540) substitui o modelo textual sequencial do HTTP/1.1 por um formato binário estruturado em frames e streams. Permite a multiplexação completa: centenas de requisições e respostas são transmitidas simultaneamente sobre uma única conexão TCP compartilhada, sem o bloqueio Head-of-Line (HoL) da camada de aplicação.
Conta ainda com compressão de cabeçalhos HPACK (RFC 7541). Por exigência dos navegadores, opera quase exclusivamente sobre TLS (HTTPS) com negociação ALPN (Application-Layer Protocol Negotiation) e requer o MPM assíncrono mpm_event.
Roteiro Prático & Configuração
# 1. Habilitar o módulo http2 sudo a2enmod http2 # 2. Configurar a diretiva Protocols globalmente ou no VirtualHost sudo tee /etc/apache2/conf-available/http2.conf << 'EOF' # Priorizar HTTP/2 e manter fallback para HTTP/1.1 Protocols h2 h2c http/1.1 H2Direct on H2ModernTLSOnly on EOF # 3. Ativar configuração e reiniciar sudo a2enconf http2 sudo systemctl restart apache2
Validação e Teste
# Validar negociação do protocolo via curl curl -I --http2 -k -s https://localhost/ | grep -E "HTTP/|server"
Fundamentação Teórica
O Proxy Reverso atua como um intermediário na borda da rede: recebe requisições de clientes externos e as despacha para clusters ou nós de backend em redes privadas. Isso esconde a topologia interna, centraliza a terminação SSL e possibilita balanceamento de carga de alta disponibilidade.
O mod_proxy_balancer distribui o tráfego usando algoritmos especializados:
byrequests: Distribuição uniforme baseada no número de requisições (Round-Robin ponderado).bytraffic: Distribuição baseada no volume de bytes trafegados.bybusyness: Envia requisições ao nó que tiver o menor número de conexões ativas simultâneas.
Roteiro Prático & Configuração
# 1. Habilitar módulos de proxy e balanceamento sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests lbmethod_bytraffic status # 2. Configurar o balanceador de carga no VirtualHost sudo tee /etc/apache2/conf-available/proxy-balancer.conf << 'EOF' ProxyPreserveHost On <Proxy balancer://meucluster> BalancerMember http://192.168.56.10:80 loadfactor=5 BalancerMember http://192.168.56.11:80 loadfactor=5 ProxySet lbmethod=byrequests </Proxy> ProxyPass /app balancer://meucluster/ ProxyPassReverse /app balancer://meucluster/ EOF # 3. Ativar e reiniciar sudo a2enconf proxy-balancer sudo systemctl restart apache2
Validação e Teste
# Validar repasse de requisições para o backend curl -I http://localhost/app
Fundamentação Teórica
O ModSecurity (mod_security2) opera como um firewall de aplicação na Camada 7 (Aplicação). Ele inspeciona o fluxo bidirecional de mensagens HTTP (cabeçalhos, método, URI, corpo de requisições POST e respostas do servidor), decodificando formatos complexos (JSON, XML, URL-encoded, multipart) antes que alcancem o backend.
Em conjunto com o OWASP ModSecurity Core Rule Set (CRS), bloqueia ativamente ataques do OWASP Top 10, incluindo Injeções de SQL (SQLi), Cross-Site Scripting (XSS), Inclusão Remota de Arquivo (RFI/LFI) e explorações de Deserialização.
Roteiro Prático & Configuração
# 1. Instalar o mod_security e conjunto de regras OWASP CRS sudo apt install -y libapache2-mod-security2 modsecurity-crs # 2. Habilitar o motor de regras no arquivo de configuração sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf # 3. Ativar o módulo e reiniciar o Apache sudo a2enmod security2 sudo systemctl restart apache2
Validação e Teste
# Simulação de tentativa de injeção SQL maliciosa (deve retornar HTTP 403 Forbidden) curl -I "http://localhost/?id=1'%20OR%20'1'='1" sudo tail -n 20 /var/log/apache2/modsec_audit.log
Fundamentação Teórica
O módulo mod_ratelimit fornece um filtro de saída (Output Filter) projetado para regular a taxa de transmissão de banda de dados enviada aos clientes. É fundamental para evitar que downloads concorrentes de arquivos volumosos (como imagens ISO, backups ou vídeos) monopolizem a largura de banda do servidor e degradem o atendimento a requisições dinâmicas prioritárias.
A taxa é definida em KBytes por segundo (KB/s) através da variável de ambiente rate-limit.
Roteiro Prático & Configuração
# 1. Habilitar o módulo ratelimit sudo a2enmod ratelimit # 2. Configurar limite de taxa para diretório de downloads (ex: 500 KB/s) sudo mkdir -p /var/www/html/downloads sudo dd if=/dev/urandom of=/var/www/html/downloads/amostra.bin bs=1M count=10 sudo tee /etc/apache2/conf-available/ratelimit.conf << 'EOF' <Location /downloads> SetOutputFilter RATE_LIMIT SetEnv rate-limit 500 </Location> EOF # 3. Ativar a configuração e recarregar o Apache sudo a2enconf ratelimit sudo systemctl reload apache2
Validação e Teste
# Testar velocidade do download e conferir taxa mantida a ~500 KB/s curl -o /dev/null http://localhost/downloads/amostra.bin
Fundamentação Teórica
O mod_perl integra o interpretador da linguagem Perl diretamente no núcleo do servidor Apache. Ao contrário do CGI tradicional (que dispara um novo processo por requisição), o mod_perl compila o código Perl em bytecode na primeira execução e o retém em memória RAM compartilhada.
Permite ainda a manipulação completa das fases do ciclo de vida da requisição HTTP do Apache (autenticação, reescrita de URI, geração de cabeçalhos e logging) através de módulos Perl puros (como ModPerl::Registry).
Roteiro Prático & Configuração
# 1. Instalar o módulo mod_perl no Debian 13 sudo apt install -y libapache2-mod-perl2 sudo a2enmod perl # 2. Configurar o diretório de execução Perl Registry sudo mkdir -p /var/www/perl sudo tee /etc/apache2/conf-available/perl.conf << 'EOF' Alias /perl/ /var/www/perl/ <Directory /var/www/perl> SetHandler perl-script PerlResponseHandler ModPerl::Registry PerlOptions +ParseHeaders Options +ExecCGI Require all granted </Directory> EOF # 3. Criar script de teste com persistência de estado em memória sudo tee /var/www/perl/teste.pl << 'EOF' #!/usr/bin/perl use strict; use warnings; our $contador; $contador++; print "Content-type: text/html\n\n"; print "<h1>Ambiente mod_perl no Debian 13</h1>"; print "<p>Esta requisição foi atendida pelo interpretador persistente.</p>"; print "<p>Contador persistente no processo filho: <strong>$contador</strong></p>"; EOF sudo chmod +x /var/www/perl/teste.pl sudo a2enconf perl sudo systemctl restart apache2
Validação e Teste
# Executar requisições consecutivas para observar incremento do contador em memória curl -s http://localhost/perl/teste.pl curl -s http://localhost/perl/teste.pl
Fundamentação Teórica
A especificação Web Server Gateway Interface (WSGI, PEP 3333) é o padrão universal para comunicação entre servidores web e aplicações web desenvolvidas em Python (como Flask, Django e FastAPI).
O mod_wsgi suporta dois modos operacionais:
- Embedded Mode: O código Python executa diretamente dentro das threads de atendimento do Apache (pouco recomendado em produção).
- Daemon Mode (Padrão Corporativo): O Apache despacha requisições para um conjunto isolado de processos em segundo plano gerenciados pelo daemon WSGI. Garante isolamento de memória, permissões dedicadas de usuário/grupo e permite reinicializar a aplicação atualizando o arquivo
.wsgi(hot-reload via comandotouch) sem reiniciar o servidor web.
Roteiro Prático & Configuração
# 1. Instalar o módulo mod_wsgi para Python 3 e pacote venv sudo apt install -y libapache2-mod-wsgi-py3 python3-venv sudo a2enmod wsgi # 2. Criar ambiente virtual e script da aplicação WSGI sudo mkdir -p /var/www/python_app sudo python3 -m venv /var/www/python_app/venv sudo tee /var/www/python_app/app.wsgi << 'EOF' import sys sys.path.insert(0, '/var/www/python_app') def application(environ, start_response): status = '200 OK' output = b'Ambiente Python WSGI corporativo ativo no Apache2 (Debian 13)!' response_headers = [('Content-type', 'text/plain; charset=utf-8'), ('Content-Length', str(len(output)))] start_response(status, response_headers) return [output] EOF # 3. Configurar VirtualHost em Modo Daemon sudo tee /etc/apache2/conf-available/python-wsgi.conf << 'EOF' WSGIDaemonProcess python_app user=www-data group=www-data threads=5 python-home=/var/www/python_app/venv WSGIScriptAlias /python /var/www/python_app/app.wsgi <Directory /var/www/python_app> WSGIProcessGroup python_app WSGIApplicationGroup %{GLOBAL} Require all granted </Directory> EOF sudo chown -R www-data:www-data /var/www/python_app sudo a2enconf python-wsgi sudo systemctl restart apache2
Validação e Teste
# Testar invocação do endpoint Python WSGI curl -s http://localhost/python
Fundamentação Teórica
O AWStats (Advanced Web Statistics) é uma ferramenta open-source de auditoria e geração gráfica de métricas de acesso. Diferente de scripts JavaScript de frontend (como Google Analytics), o AWStats analisa diretamente os arquivos de log do servidor (access.log).
Identifica requisições diretas de robôs de busca (crawlers e spiders), ataques automatizados de varredura, códigos de erro HTTP (404, 500), consumo de banda por extensão de arquivo e tempos de resposta, operando perfeitamente em redes fechadas (intranets).
Roteiro Prático & Configuração
# 1. Instalar o pacote AWStats e habilitar cgi sudo apt install -y awstats sudo a2enmod cgi # 2. Configurar perfil do site no AWStats sudo cp /etc/awstats/awstats.conf /etc/awstats/awstats.lab.local.conf sudo sed -i 's|^LogFile=.*|LogFile="/var/log/apache2/access.log"|' /etc/awstats/awstats.lab.local.conf sudo sed -i 's|^SiteDomain=.*|SiteDomain="lab.local"|' /etc/awstats/awstats.lab.local.conf sudo sed -i 's|^LogFormat=.*|LogFormat=1|' /etc/awstats/awstats.lab.local.conf # 3. Configurar acesso restrito ao painel web do AWStats sudo tee /etc/apache2/conf-available/awstats-access.conf << 'EOF' Alias /awstatsclasses/ "/usr/share/awstats/lib/" Alias /awstats-icon/ "/usr/share/awstats/icon/" ScriptAlias /awstats/ "/usr/lib/cgi-bin/" <Directory "/usr/lib/cgi-bin"> Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch AuthType Basic AuthName "Painel Administrativo de Estatisticas" AuthUserFile /etc/apache2/.htpasswd Require valid-user </Directory> EOF # 4. Atualizar estatísticas e ativar conf sudo /usr/lib/cgi-bin/awstats.pl -config=lab.local -update sudo a2enconf awstats-access sudo systemctl reload apache2
Validação e Teste
# Testar invocação do script AWStats via terminal curl -u admin:senha "http://localhost/awstats/awstats.pl?config=lab.local" | grep -i "AWStats"
Fundamentação Teórica
O WordPress é o sistema gerenciador de conteúdo mais utilizado na web, operando sobre a clássica pilha LAMP (Linux, Apache, MariaDB/MySQL, PHP). No nível do Apache, sua principal dependência é o módulo mod_rewrite.
O WordPress utiliza o padrão de projeto Front Controller: todas as requisições para posts e categorias são reescritas internamente para o script index.php através de regras distribuídas em arquivo .htaccess, exigindo a diretiva AllowOverride All no VirtualHost.
Roteiro Prático & Configuração
# 1. Habilitar mod_rewrite e instalar extensões PHP para WordPress sudo a2enmod rewrite sudo apt install -y mariadb-server php-mysql php-curl php-gd php-mbstring php-xml php-zip # 2. Criar banco de dados e usuário no MariaDB sudo mysql -e "CREATE DATABASE wp_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" sudo mysql -e "CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'SenhaForteWP@2026';" sudo mysql -e "GRANT ALL ON wp_db.* TO 'wp_user'@'localhost'; FLUSH PRIVILEGES;" # 3. Baixar código do WordPress e configurar diretório sudo mkdir -p /var/www/wordpress cd /tmp && wget -q https://wordpress.org/latest.tar.gz sudo tar -xzf latest.tar.gz -C /var/www/ sudo chown -R www-data:www-data /var/www/wordpress sudo find /var/www/wordpress -type d -exec chmod 755 {} \; sudo find /var/www/wordpress -type f -exec chmod 644 {} \; # 4. Configurar VirtualHost com suporte a .htaccess (AllowOverride All) sudo tee /etc/apache2/sites-available/wordpress.conf << 'EOF' <VirtualHost *:80> ServerName blog.lab.local DocumentRoot /var/www/wordpress <Directory /var/www/wordpress> Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/wordpress_error.log CustomLog ${APACHE_LOG_DIR}/wordpress_access.log combined </VirtualHost> EOF sudo a2ensite wordpress.conf sudo systemctl reload apache2
Validação e Teste
# Testar resposta inicial do instalador do WordPress curl -H "Host: blog.lab.local" http://localhost/wp-admin/install.php | grep -i "WordPress"
Fundamentação Teórica
O MediaWiki é o mecanismo wiki colaborativo de alta escala que sustenta a Wikipedia e amplas bases de documentação técnica corporativa. Exige suporte robusto a transações relacionais em UTF-8 (MariaDB com charset utf8mb4) e renderização gráfica de diagramas e equações via ImageMagick.
Blindagem de Segurança Obrigatória: O diretório de anexos e mídias (/var/www/mediawiki/images/) deve ter a execução de scripts PHP explicitamente desativada para prevenir ataques de Remote Code Execution (RCE) decorrentes de uploads maliciosos.
Roteiro Prático & Configuração
# 1. Instalar dependências e utilitário ImageMagick sudo apt install -y php-intl php-mbstring php-xml php-gd imagemagick # 2. Criar banco de dados dedicado no MariaDB sudo mysql -e "CREATE DATABASE wiki_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" sudo mysql -e "CREATE USER 'wiki_user'@'localhost' IDENTIFIED BY 'SenhaForteWiki@2026';" sudo mysql -e "GRANT ALL ON wiki_db.* TO 'wiki_user'@'localhost'; FLUSH PRIVILEGES;" # 3. Baixar versão estável e configurar permissões sudo mkdir -p /var/www/mediawiki cd /tmp && wget -q https://releases.wikimedia.org/mediawiki/1.42/mediawiki-1.42.0.tar.gz sudo tar -xzf mediawiki-*.tar.gz -C /var/www/mediawiki --strip-components=1 sudo chown -R www-data:www-data /var/www/mediawiki # 4. Configurar VirtualHost com blindagem do diretório /images sudo tee /etc/apache2/sites-available/mediawiki.conf << 'EOF' <VirtualHost *:80> ServerName wiki.lab.local DocumentRoot /var/www/mediawiki <Directory /var/www/mediawiki> Options -Indexes +FollowSymLinks AllowOverride None Require all granted </Directory> # Hardening: Bloquear execução de scripts no diretório de uploads <Directory /var/www/mediawiki/images> AllowOverride None <FilesMatch "\.(php|php5|phtml|pl|py|cgi)$"> Require all denied </FilesMatch> </Directory> ErrorLog ${APACHE_LOG_DIR}/mediawiki_error.log CustomLog ${APACHE_LOG_DIR}/mediawiki_access.log combined </VirtualHost> EOF sudo a2ensite mediawiki.conf sudo systemctl reload apache2
Validação e Teste
# Testar acesso inicial ao configurador web do MediaWiki curl -H "Host: wiki.lab.local" http://localhost/index.php | grep -i "MediaWiki"
Navegação rápida pelos tópicos ou utilize o menu lateral Full Screen Overlay para acesso direto:
Instalação dos pacotes oficiais, arquitetura Master/Worker, modelo epoll e otimizações de I/O de kernel.
Configuração de server { ... }, ordem de precedência de location e fallback defensivo com try_files.
Criptografia TLS 1.3/1.2, curvas elípticas ECDHE, cache de sessão em RAM compartilhada e OCSP Stapling.
Comunicação binária FastCGI via Unix Domain Socket, gestão de buffers e blindagem contra injeção em uploads.
Desafio e resposta RFC 7617, senhas protegidas com bcrypt e combinação com listas de controle de acesso (ACLs de IP).
Encaminhamento de tráfego com proxy_pass, repasse de cabeçalhos X-Real-IP e X-Forwarded-For e absorção de buffers.
Balanceamento em camada 7 no bloco upstream (Round-Robin, least_conn, ip_hash) e checagens passivas de saúde.
Multiplexação de conexões, cabeçalhos HPACK e implantação do HTTP/3 nativo sobre UDP com cabeçalho Alt-Svc.
Algoritmo Leaky Bucket em zonas de memória compartilhada, controle de rajadas (burst/nodelay) e resposta 429.
Inclusão de CSP, X-Frame-Options, X-Content-Type-Options, supressão de versão e bloqueio de buffers excessivos.
Cache de páginas dinâmicas em disco/RAM, cabeçalhos X-Cache-Status e bypass automático para usuários logados.
Validação de sub-requisições HTTP para integração com provedores de SSO, Authelia, Keycloak e LDAP.
Habilitar operações HTTP de arquivos remotos (PUT, DELETE, MKCOL, MOVE) via ngx_http_dav_module.
Balanceamento em camada 4 com o bloco stream { ... } para bancos MariaDB, PostgreSQL e consultas DNS.
Integração desacoplada com Gunicorn e Uvicorn via Unix Sockets, isolamento de processos e arquivos estáticos.
Proxy reverso para microsserviços Node.js com túneis bidirecionais WebSockets (Upgrade / Connection).
Web Application Firewall inspecionando tráfego HTTP com regras OWASP CRS contra ataques web em camada 7.
Observabilidade em tempo real com stub_status, exportação para Prometheus e métricas de conexões ativas.
Configuração de permalinks sem .htaccess, proteção do wp-config.php e aceleração de cache FastCGI.
Roteamento de permalinks amigáveis /wiki/, bloqueio estrito de execução PHP em uploads e suporte a OPcache.
Fundamentação Teórica
O NGINX utiliza uma arquitetura assíncrona orientada a eventos (event-driven) que resolve com extrema eficiência o desafio C10K/C100K (atendimento a mais de 10.000 conexões simultâneas por máquina). Ao contrário de servidores baseados em threads ou processos por conexão, o NGINX emprega um modelo Master-Worker:
- Processo Master: Executa com privilégios de superusuário (
root). É responsável por ler e validar arquivos de configuração, abrir portas de rede privilegiadas (TCP 80 e 443) e gerenciar os processos filhos (Workers), permitindo recarregamento a quente (graceful reload) sem perda de pacotes. - Processos Workers: Executam como usuário sem privilégios (
www-data). Cada Worker roda em um loop de eventos de thread única (single-threaded event loop), utilizando a chamada de sistema de I/O multiplexadoepolldo Linux para monitorar milhares de sockets de rede de forma não-bloqueante.
As chamadas de sistema sendfile, tcp_nopush e tcp_nodelay operam transferência direta de blocos do sistema de arquivos para os buffers de rede no espaço do kernel (zero-copy I/O), maximizando o throughput de arquivos estáticos.
worker_processes auto; no /etc/nginx/nginx.conf para que o NGINX atribua automaticamente um Worker para cada núcleo de CPU da máquina.
Roteiro Prático & Configuração
# 1. Atualizar índices e instalar o NGINX oficial do Debian 13 sudo apt update && sudo apt install -y nginx # 2. Ajustar parâmetros essenciais no core /etc/nginx/nginx.conf sudo tee /etc/nginx/conf.d/tuning.conf << 'EOF' # Otimização de concorrência e buffers client_body_buffer_size 128k; client_header_buffer_size 1k; client_max_body_size 16m; large_client_header_buffers 4 8k; # Timeouts defensivos contra conexões lentas client_body_timeout 12; client_header_timeout 12; keepalive_timeout 65; send_timeout 10; EOF # 3. Habilitar e iniciar o daemon systemd sudo systemctl enable --now nginx # 4. Liberar tráfego no firewall UFW sudo ufw allow in "Nginx Full"
Validação e Teste
# Checar sintaxe e status do daemon NGINX sudo nginx -t sudo systemctl status nginx --no-pager curl -I http://localhost
Fundamentação Teórica
No NGINX, hospedagens virtuais são implementadas através de blocos server { ... } (comumente chamados de Server Blocks). O NGINX avalia o cabeçalho HTTP Host: para direcionar a requisição ao bloco com o server_name correspondente.
Ordem de Casamento de Diretivas Location:
=: Casamento exato. Interrompe a busca imediatamente ao encontrar correspondência (ex:location = /favicon.ico).^~: Prefixo não-regex. Se for o maior prefixo coincidente, ignora quaisquer expressões regulares subsequentes.~e~*: Expressões regulares case-sensitive e case-insensitive, avaliadas na ordem física em que aparecem no arquivo.- Prefixo mais longo genérico (ex:
location /).
O uso da diretiva defensiva try_files $uri $uri/ =404; garante que arquivos e diretórios existentes sejam entregues diretamente, retornando código 404 em vez de expor listagens de diretório indesejadas.
Roteiro Prático & Configuração
# 1. Criar a raiz de documentos para o domínio lab-nginx.lan sudo mkdir -p /var/www/lab-nginx.lan/html sudo chown -R www-data:www-data /var/www/lab-nginx.lan sudo chmod -R 755 /var/www/lab-nginx.lan # 2. Criar página inicial echo '<h1>Server Block NGINX Ativo no Debian 13</h1>' | sudo tee /var/www/lab-nginx.lan/html/index.html # 3. Criar arquivo de Server Block em sites-available sudo tee /etc/nginx/sites-available/lab-nginx.lan.conf << 'EOF' server { listen 80; listen [::]:80; server_name lab-nginx.lan www.lab-nginx.lan; root /var/www/lab-nginx.lan/html; index index.html index.htm; location / { try_files $uri $uri/ =404; } # Desativar logs de arquivos de suporte para economizar disco location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; } access_log /var/log/nginx/lab-nginx.lan_access.log; error_log /var/log/nginx/lab-nginx.lan_error.log; } EOF # 4. Habilitar site via link simbólico e recarregar NGINX sudo ln -sf /etc/nginx/sites-available/lab-nginx.lan.conf /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Validar resolução simulando cabeçalho Host curl -H "Host: lab-nginx.lan" http://localhost
Fundamentação Teórica
A configuração de HTTPS no NGINX deve seguir as diretrizes rigorosas da IETF e da Mozilla (Modern / Intermediate Profile). Isso exige a desativação de protocolos legados vulneráveis (SSLv3, TLS 1.0, TLS 1.1) em favor de TLS 1.2 e TLS 1.3, associados a algoritmos de chave assimétrica ECDHE com curvas elípticas seguras (X25519, P-256).
Eficiência Operacional com NGINX:
ssl_session_cache shared:SSL:10m;: Aloca uma região de memória compartilhada de 10 MB compartilhada entre todos os processos Workers. Cada megabyte retém cerca de 4.000 sessões, reduzindo handshakes caros de CPU em até 80%.ssl_stapling on;: Envia o comprovante de validade assinado pela CA diretamente na resposta TLS, evitando consultas síncronas de revogação por parte dos navegadores.
Roteiro Prático & Configuração
# 1. Instalar Certbot e módulo NGINX sudo apt install -y certbot python3-certbot-nginx openssl # 2. Criar configuração global de parâmetros TLS seguros sudo tee /etc/nginx/conf.d/ssl_params.conf << 'EOF' ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"; ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 1.1.1.1 8.8.8.8 valid=300s; resolver_timeout 5s; EOF # 3. Gerar certificado autoassinado para homologação local sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/ssl/private/nginx-selfsigned.key \ -out /etc/ssl/certs/nginx-selfsigned.crt \ -subj "/C=BR/ST=Amazonas/L=Manaus/O=STI/CN=lab-nginx.lan" # 4. Atualizar o Server Block com terminação SSL e redirecionamento 80 -> 443 sudo tee /etc/nginx/sites-available/lab-nginx.lan.conf << 'EOF' server { listen 80; listen [::]:80; server_name lab-nginx.lan www.lab-nginx.lan; return 301 https://$host$request_uri; } server { listen 443 ssl; listen [::]:443 ssl; server_name lab-nginx.lan www.lab-nginx.lan; root /var/www/lab-nginx.lan/html; index index.html; ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; location / { try_files $uri $uri/ =404; } } EOF sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Validar versão TLS negociada e integridade da conexão openssl s_client -connect localhost:443 -servername lab-nginx.lan < /dev/null 2>&1 | grep -E "Protocol|Cipher"
Fundamentação Teórica
O NGINX não possui módulo de script embutido no core (ao contrário do mod_php do Apache). Essa decisão arquitetural previne que códigos PHP com vazamento de memória ou erros de execução afetem o loop assíncrono de eventos do servidor web.
O NGINX comunica-se com o PHP-FPM (FastCGI Process Manager) através do protocolo binário FastCGI, preferencialmente utilizando Unix Domain Sockets (como /run/php/php8.4-fpm.sock). A alocação adequada das diretivas fastcgi_buffers e fastcgi_buffer_size permite absorver a resposta gerada pelo PHP em memória RAM sem a necessidade de gravar buffers temporários em disco (I/O de arquivo).
Roteiro Prático & Configuração
# 1. Instalar o PHP-FPM no Debian 13 sudo apt install -y php-fpm php-cli php-mysql # 2. Localizar o socket Unix em execução PHP_SOCK=$(ls /run/php/php*-fpm.sock | head -n 1) # 3. Adicionar o bloco de tratamento FastCGI no Server Block sudo tee /etc/nginx/snippets/fastcgi-php.conf << EOF location ~ \.php$ { try_files \$fastcgi_script_name =404; fastcgi_split_path_info ^(.+\.php)(/.+)\$; fastcgi_pass unix:$PHP_SOCK; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; # Buffering de alta vazão fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; fastcgi_connect_timeout 60s; fastcgi_send_timeout 60s; fastcgi_read_timeout 60s; } EOF # 4. Criar script de teste PHP e recarregar NGINX echo '<?php phpinfo(); ?>' | sudo tee /var/www/lab-nginx.lan/html/info.php sudo sed -i '/location \/ {/i \ include snippets/fastcgi-php.conf;' /etc/nginx/sites-available/lab-nginx.lan.conf sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Validar interpretação do script PHP curl -k -s https://localhost/info.php | grep -i "Server API"
Fundamentação Teórica
O módulo ngx_http_auth_basic_module protege rotas do servidor web solicitando credenciais de usuário conforme a RFC 7617. O servidor desafia o cliente não autenticado com o código de resposta 401 Unauthorized.
Segurança e Integração de Rede: O arquivo de senhas do NGINX deve ser criptografado com o algoritmo bcrypt (ou MD5 apr1). É possível combinar autenticação básica com listas de controle de IP através da diretiva satisfy any (liberando administradores da rede interna sem senha e exigindo autenticação apenas de conexões externas).
Roteiro Prático & Configuração
# 1. Instalar utilitário htpasswd sudo apt install -y apache2-utils # 2. Gerar base de credenciais criptografadas em bcrypt (-B) sudo htpasswd -B -c /etc/nginx/.htpasswd admin sudo chown root:www-data /etc/nginx/.htpasswd sudo chmod 640 /etc/nginx/.htpasswd # 3. Proteger rota restrita no Server Block sudo mkdir -p /var/www/lab-nginx.lan/html/admin echo '<h1>Console Restrito de Gerenciamento</h1>' | sudo tee /var/www/lab-nginx.lan/html/admin/index.html sudo tee -a /etc/nginx/sites-available/lab-nginx.lan.conf << 'EOF' # Bloco administrativo restrito location ^~ /admin/ { auth_basic "Acesso Administrativo Restrito"; auth_basic_user_file /etc/nginx/.htpasswd; try_files $uri $uri/ =404; } EOF sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Teste sem credencial (401) e com credencial válida (200) curl -k -I https://localhost/admin/ curl -k -u admin:senha https://localhost/admin/
Fundamentação Teórica
Ao operar como Proxy Reverso, o NGINX atua como a única porta de entrada exposta à Internet pública. Ele encerra a conexão de rede do cliente, aplica camadas de segurança (WAF, SSL, Rate Limit) e abre uma nova conexão interna com os servidores da camada de aplicação (Node.js, Flask, Spring, etc.).
Preservação de Contexto e Buffering:
- Os cabeçalhos
X-Real-IP,X-Forwarded-ForeX-Forwarded-Protosão injetados pelo NGINX para que o backend conheça o IP e protocolo original do visitante. - Com
proxy_buffering on;, o NGINX lê a resposta do backend o mais rápido possível e libera a thread da aplicação, transmitindo os dados no ritmo da conexão do cliente externo.
Roteiro Prático & Configuração
# 1. Criar arquivo de configuração de proxy reverso sudo tee /etc/nginx/sites-available/proxy-app.conf << 'EOF' server { listen 80; server_name app.lab-nginx.lan; location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; # Repasse de cabeçalhos de contexto proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Buffering de resposta proxy_buffering on; proxy_buffers 8 16k; proxy_buffer_size 32k; # Timeouts de conexão com o backend proxy_connect_timeout 60s; proxy_read_timeout 60s; proxy_send_timeout 60s; } } EOF # 2. Ativar site e recarregar serviço sudo ln -sf /etc/nginx/sites-available/proxy-app.conf /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Validar repasse de requisição para a aplicação interna curl -H "Host: app.lab-nginx.lan" http://localhost/
Fundamentação Teórica
O balanceamento de carga HTTP em Camada 7 é centralizado no bloco upstream dentro do contexto http. O NGINX implementa diferentes estratégias de roteamento:
- Round-Robin (Padrão): Distribuição cíclica proporcional aos pesos atribuídos (
weight=N). - Least Connections (
least_conn): Encaminha para o nó com menor quantidade de conexões ativas simultâneas. - IP Hash (
ip_hash): Garante persistência de sessão vinculando os 3 primeiros octetos do IPv4 do cliente ao mesmo servidor de destino. - Generic Hash (
hash $request_uri consistent): Utiliza algoritmo de hash consistente (ketama) para roteamento determinístico, maximizando acertos de cache local dos nós.
Os nós podem ser sinalizados com max_fails e fail_timeout para exclusão passiva automática de servidores inoperantes, além de marcações backup e down.
Roteiro Prático & Configuração
# 1. Configurar cluster de servidores no bloco upstream sudo tee /etc/nginx/conf.d/load_balancer.conf << 'EOF' upstream cluster_backends { least_conn; server 192.168.56.10:80 weight=3 max_fails=2 fail_timeout=10s; server 192.168.56.11:80 weight=2 max_fails=2 fail_timeout=10s; server 192.168.56.12:80 backup; keepalive 32; } server { listen 80; server_name cluster.lab-nginx.lan; location / { proxy_pass http://cluster_backends; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } EOF # 2. Testar configuração e recarregar o NGINX sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Testar balanceamento disparando requisições sequenciais for i in {1..8}; do curl -s -H "Host: cluster.lab-nginx.lan" http://localhost/; echo "---"; done
Fundamentação Teórica
A evolução dos protocolos de aplicação transforma a experiência e a latência de transferência web:
- HTTP/2 (RFC 7540): Multiplexa dezenas de fluxos bidirecionais de dados sob uma única conexão TCP persistente com compressão de cabeçalho HPACK. Elimina bloqueio HoL da camada de aplicação.
- HTTP/3 (RFC 9000): Migra a camada de transporte de TCP para QUIC sobre UDP (porta 443). Elimina totalmente o bloqueio Head-of-Line em nível de pacote (a perda de um segmento afeta apenas aquele fluxo de dados individual), oferece migração transparente de conexões em redes móveis e realiza handshake criptográfico TLS 1.3 integrado em 0-RTT/1-RTT.
Roteiro Prático & Configuração
# 1. Configurar Server Block com suporte simultâneo a HTTP/2 e HTTP/3/QUIC sudo tee /etc/nginx/sites-available/quic-http3.conf << 'EOF' server { # Escuta TCP com TLS e HTTP/2 listen 443 ssl; listen [::]:443 ssl; http2 on; # Escuta UDP para QUIC / HTTP/3 listen 443 quic reuseport; listen [::]:443 quic reuseport; server_name speed.lab-nginx.lan; root /var/www/lab-nginx.lan/html; ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key; ssl_protocols TLSv1.2 TLSv1.3; # Anunciar disponibilidade de HTTP/3 para os navegadores clientes add_header Alt-Svc 'h3=":443"; ma=86400'; add_header X-Protocol $server_protocol always; location / { try_files $uri $uri/ =404; } } EOF # 2. Habilitar site e liberar porta UDP no firewall sudo ln -sf /etc/nginx/sites-available/quic-http3.conf /etc/nginx/sites-enabled/ sudo ufw allow 443/udp sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Inspecionar cabeçalho Alt-Svc e protocolo negociado curl -k -I --http2 https://localhost/ | grep -i "alt-svc"
Fundamentação Teórica
O controle de taxa de requisições no NGINX é fundamentado no algoritmo Leaky Bucket (balde furado). Ele estabelece um fluxo constante de saída e retém requisições excedentes em um buffer temporário de rajada.
Estrutura de Memória e Parâmetros:
limit_req_zone: Cria uma zona de memória compartilhada para rastrear clientes. Utiliza a variável$binary_remote_addr(que compacta cada endereço IPv4 em apenas 4 bytes e IPv6 em 16 bytes), permitindo que uma zona de 10 MB rastreie mais de 160.000 clientes simultâneos.rate=5r/s: Taxa média tolerada por cliente.burst=10: Capacidade do balde para absorver picos instantâneos.nodelay: Processa requisições dentro do limite da rajada imediatamente, sem enfileiramento artificial, descartando o excesso com código HTTP 429.
Roteiro Prático & Configuração
# 1. Definir zonas globais de controle de requisição e conexão sudo tee /etc/nginx/conf.d/ratelimit.conf << 'EOF' # Zona por IP com taxa máxima de 5 requisições por segundo limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s; # Zona de conexões simultâneas máximas por IP limit_conn_zone $binary_remote_addr zone=conn_limit:10m; # Código HTTP padronizado de erro (Too Many Requests) limit_req_status 429; limit_conn_status 429; EOF # 2. Aplicar restrição em endpoints críticos de login ou API sudo tee -a /etc/nginx/sites-available/lab-nginx.lan.conf << 'EOF' location /login/ { limit_req zone=api_limit burst=10 nodelay; limit_conn conn_limit 5; try_files $uri $uri/ =404; } EOF # 3. Recarregar o NGINX sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Simulação de rajada com teste de estresse (deve retornar HTTP 429) sudo apt install -y apache2-utils ab -n 25 -c 5 http://localhost/login/
Fundamentação Teórica
O Hardening do NGINX fecha portas de ataque na camada de aplicação e impede que o navegador cliente execute comportamentos inseguros:
server_tokens off;: Oculta a versão exata do software em páginas de erro e cabeçalhosServer: nginx.X-Frame-Options: SAMEORIGIN: Previne ataques de Clickjacking que tentam renderizar a aplicação dentro de um iframe invisível.X-Content-Type-Options: nosniff: Impede que o navegador infira tipos MIME diferentes dos declarados pelo servidor.Content-Security-Policy (CSP): Define fontes estritamente autorizadas para scripts, folhas de estilo e imagens, mitigando ataques de XSS.- Bloqueio de arquivos ocultos: Nega requisições para diretórios versionados (
.git) e arquivos de ambiente (.env).
Roteiro Prático & Configuração
# 1. Criar arquivo modular com cabeçalhos de segurança sudo tee /etc/nginx/conf.d/security_hardening.conf << 'EOF' # Ocultar versão do software server_tokens off; # Cabeçalhos de Proteção do Navegador add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always; add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; # Bloqueio preventivo de arquivos e diretórios ocultos (.git, .env) location ~ /\.(?!well-known).* { deny all; access_log off; log_not_found off; } EOF # 2. Validar sintaxe e aplicar sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Inspecionar cabeçalhos de resposta com curl curl -I http://localhost/ | grep -iE "server|x-frame|content-type|referrer"
Fundamentação Teórica
O FastCGI Microcaching permite que o NGINX armazene em disco/RAM o resultado de páginas HTML dinâmicas geradas pelo PHP-FPM por breves intervalos (de 1 segundo a vários minutos). Em picos de tráfego, em vez de disparar 5.000 requisições simultâneas para o PHP e o banco de dados, o NGINX atende 4.999 diretamente do seu cache (HIT).
O cabeçalho X-Cache-Status informa o resultado da busca: HIT (entregue do cache), MISS (gerado pelo backend e cacheado) ou BYPASS (quando há cookies de sessão ativa ou métodos POST).
Roteiro Prático & Configuração
# 1. Criar diretório de cache do FastCGI sudo mkdir -p /var/cache/nginx/fastcgi sudo chown -R www-data:www-data /var/cache/nginx/fastcgi # 2. Configurar a zona de microcache no contexto http sudo tee /etc/nginx/conf.d/fastcgi_cache.conf << 'EOF' fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=MICROCACHE:100m inactive=60m max_size=1g; fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_use_stale error timeout invalid_header updating http_500; fastcgi_ignore_headers Cache-Control Expires Set-Cookie; EOF # 3. Aplicar no Server Block com regras de bypass para sessões ativas sudo tee /etc/nginx/snippets/cache-bypass.conf << 'EOF' set $skip_cache 0; # Nunca cachear requisições POST ou com query strings if ($request_method = POST) { set $skip_cache 1; } if ($query_string != "") { set $skip_cache 1; } # Não cachear se o usuário estiver autenticado if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|logged_in") { set $skip_cache 1; } EOF sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Realizar duas requisições consecutivas para validar HIT no cache curl -k -I https://localhost/info.php | grep -i "X-Cache-Status" curl -k -I https://localhost/info.php | grep -i "X-Cache-Status"
Fundamentação Teórica
O módulo ngx_http_auth_request_module viabiliza a implementação de autenticação centralizada corporativa (SSO, OAuth2, Authelia, Keycloak). Antes de liberar qualquer requisição para a aplicação interna, o NGINX dispara uma sub-requisição interna em segundo plano para o serviço de autenticação.
Se o endpoint de validação retornar código 2xx OK, o NGINX prossegue com o atendimento original. Se retornar 401 ou 403, o NGINX interrompe a conexão e redireciona o usuário para o portal de login corporativo.
Roteiro Prático & Configuração
# 1. Configurar rota protegida por sub-requisição sudo tee /etc/nginx/conf.d/sso_auth.conf << 'EOF' server { listen 80; server_name intranet.lab-nginx.lan; location /privado/ { auth_request /auth-verify; error_page 401 = @redireciona_login; root /var/www/lab-nginx.lan/html; try_files $uri $uri/ =404; } # Endpoint de verificação interna (não acessível diretamente pelo cliente) location = /auth-verify { internal; proxy_pass http://127.0.0.1:9091/api/verify; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Original-URI $request_uri; } # Redirecionamento amigável para o portal de login location @redireciona_login { return 302 https://auth.lab-nginx.lan/login?destino=$request_uri; } } EOF # 2. Recarregar o NGINX sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Validar interceptação e redirecionamento de requisição sem token curl -I -H "Host: intranet.lab-nginx.lan" http://localhost/privado/
Fundamentação Teórica
O módulo compilado ngx_http_dav_module provê suporte ao padrão WebDAV (RFC 4918), transformando o NGINX em um repositório remoto para publicação e edição colaborativa de arquivos através do protocolo HTTP.
Suporta nativamente os métodos de alteração PUT, DELETE, MKCOL (criação de diretórios), COPY e MOVE. Recomenda-se associar autenticação básica ou mutual TLS (mTLS) para blindar operações de escrita contra invasões.
Roteiro Prático & Configuração
# 1. Criar pasta compartilhada WebDAV com permissões sudo mkdir -p /var/www/webdav_nginx /var/cache/nginx/client_temp sudo chown -R www-data:www-data /var/www/webdav_nginx /var/cache/nginx/client_temp # 2. Configurar o bloco WebDAV sudo tee /etc/nginx/conf.d/webdav.conf << 'EOF' server { listen 80; server_name dav.lab-nginx.lan; location / { root /var/www/webdav_nginx; client_body_temp_path /var/cache/nginx/client_temp; # Métodos autorizados dav_methods PUT DELETE MKCOL COPY MOVE; create_full_put_path on; dav_access user:rw group:rw all:r; # Proteção com autenticação básica auth_basic "WebDAV NGINX Storage"; auth_basic_user_file /etc/nginx/.htpasswd; } } EOF # 3. Recarregar o NGINX sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Testar upload de arquivo com método HTTP PUT curl -u admin:senha -T /etc/issue -H "Host: dav.lab-nginx.lan" http://localhost/upload_test.txt curl -u admin:senha -X DELETE -H "Host: dav.lab-nginx.lan" http://localhost/upload_test.txt
Fundamentação Teórica
Além de servidores web HTTP, o NGINX atua como um roteador e balanceador de carga de altíssimo desempenho na Camada 4 (Transporte) através do módulo ngx_stream_core_module. Configurado fora do bloco http (no bloco de nível raiz stream { ... }), ele não processa cabeçalhos de aplicação nem realiza parsing de URLs.
Isso permite balancear bancos de dados relacionais (MariaDB/MySQL porta 3306, PostgreSQL porta 5432), consultas de resolução DNS (UDP porta 53) e tráfego LDAP, reduzindo latência com conexões TCP brutas.
Roteiro Prático & Configuração
# 1. Configurar o bloco stream no /etc/nginx/nginx.conf sudo tee -a /etc/nginx/nginx.conf << 'EOF' # Balanceamento de Carga Camada 4 (TCP/UDP) stream { upstream mysql_cluster { least_conn; server 192.168.56.20:3306 max_fails=3 fail_timeout=10s; server 192.168.56.21:3306 max_fails=3 fail_timeout=10s; } server { listen 3307; proxy_pass mysql_cluster; proxy_connect_timeout 5s; proxy_timeout 1h; } } EOF # 2. Validar sintaxe e recarregar serviço sudo nginx -t && sudo systemctl restart nginx
Validação e Teste
# Inspecionar porta TCP 3307 em escuta pelo NGINX ss -tulpn | grep 3307
Fundamentação Teórica
Para hospedar aplicações Python (Flask, Django, FastAPI), o NGINX opera como o frontend público de proxy reverso conectado ao servidor de aplicação (como Gunicorn para WSGI ou Uvicorn para ASGI) através de um Unix Domain Socket local.
O Gunicorn gerencia os processos de interpretação Python (pré-alocando workers), enquanto o NGINX entrega arquivos estáticos diretamente do disco com sendfile, aplica compactação gzip/brotli e lida com terminação SSL, poupando a CPU dos processos Python.
Roteiro Prático & Configuração
# 1. Instalar Python 3 venv e criar ambiente isolado sudo apt install -y python3-venv python3-pip sudo mkdir -p /var/www/pyapp && cd /var/www/pyapp sudo python3 -m venv venv sudo ./venv/bin/pip install flask gunicorn # 2. Criar aplicação Flask minimalista sudo tee /var/www/pyapp/wsgi.py << 'EOF' from flask import Flask app = Flask(__name__) @app.route("/") def index(): return "Aplicação Python Flask servida via NGINX e Gunicorn no Debian 13!" if __name__ == "__main__": app.run() EOF # 3. Criar serviço systemd para o daemon do Gunicorn sudo tee /etc/systemd/system/pyapp.service << 'EOF' [Unit] Description=Gunicorn instance to serve pyapp After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/var/www/pyapp ExecStart=/var/www/pyapp/venv/bin/gunicorn --workers 3 --bind unix:/var/www/pyapp/pyapp.sock -m 007 wsgi:app [Install] WantedBy=multi-user.target EOF # 4. Configurar Server Block do NGINX sudo tee /etc/nginx/conf.d/pyapp.conf << 'EOF' server { listen 80; server_name python.lab-nginx.lan; location / { proxy_pass http://unix:/var/www/pyapp/pyapp.sock; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } EOF sudo systemctl daemon-reload && sudo systemctl enable --now pyapp sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Validar resposta da aplicação Python curl -H "Host: python.lab-nginx.lan" http://localhost/
Fundamentação Teórica
Aplicações interativas em tempo real desenvolvidas em Node.js demandam suporte ao protocolo WebSocket (RFC 6455). A conexão inicia através de um handshake HTTP com o cabeçalho Upgrade: websocket, que é promovido a uma conexão TCP bidirecional contínua.
O NGINX deve ser configurado com as diretivas proxy_set_header Upgrade $http_upgrade; e proxy_set_header Connection $connection_upgrade;, além de timeouts estendidos (proxy_read_timeout 86400s;) para prevenir desconexões involuntárias de clientes conectados ao chat ou dashboards em tempo real.
Roteiro Prático & Configuração
# 1. Configurar o mapeamento de cabeçalho de Upgrade no contexto http sudo tee /etc/nginx/conf.d/websocket_map.conf << 'EOF' map $http_upgrade $connection_upgrade { default upgrade; '' close; } EOF # 2. Configurar Server Block com proxy para Node.js e WebSockets sudo tee /etc/nginx/conf.d/nodejs_app.conf << 'EOF' server { listen 80; server_name node.lab-nginx.lan; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; # Suporte a WebSockets proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Timeouts para conexões contínuas proxy_read_timeout 86400s; proxy_send_timeout 86400s; } } EOF # 3. Recarregar NGINX sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Checar suporte a WebSocket enviando cabeçalho de teste de Upgrade curl -I -H "Host: node.lab-nginx.lan" -H "Upgrade: websocket" -H "Connection: Upgrade" http://localhost/
Fundamentação Teórica
A proteção em Camada 7 contra o OWASP Top 10 (Injeção de SQL, XSS, Remote Code Execution, Path Traversal) é garantida no NGINX através do conector ModSecurity (libmodsecurity3) ou do moderno motor nativo Coraza WAF.
Diferente de firewalls de rede (que operam em IPs e portas), o WAF inspeciona o payload textual da requisição, decodifica entidades URL-encoded e aplica o OWASP Core Rule Set (CRS v4) com base em pontuação de anomalias (Anomaly Scoring Mode), bloqueando a requisição antes que ela atinja os servidores de backend.
Roteiro Prático & Configuração
# 1. Instalar bibliotecas do ModSecurity e conjunto de regras OWASP sudo apt install -y libmodsecurity3 modsecurity-crs # 2. Configurar o arquivo principal do ModSecurity sudo mkdir -p /etc/nginx/modsec sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/nginx/modsec/modsecurity.conf # 3. Incluir as regras do OWASP CRS sudo tee /etc/nginx/modsec/main.conf << 'EOF' Include /etc/nginx/modsec/modsecurity.conf Include /usr/share/modsecurity-crs/crs-setup.conf Include /usr/share/modsecurity-crs/rules/*.conf EOF # 4. Habilitar o WAF no Server Block do NGINX sudo sed -i '/server_name/a \ modsecurity on; modsecurity_rules_file /etc/nginx/modsec/main.conf;' /etc/nginx/sites-available/lab-nginx.lan.conf sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Disparar simulação de injeção SQL para verificar bloqueio HTTP 403 curl -I "http://localhost/?search='UNION%20SELECT%201,2,3--"
Fundamentação Teórica
Para observabilidade em produção, o módulo ngx_http_stub_status_module expõe em tempo real os contadores atômicos de desempenho do NGINX:
Active connections: Total de conexões clientes atualmente abertas (incluindo estados de leitura, escrita e espera).server accepts handled requests: Número total de conexões TCP aceitas, tratadas com sucesso e total de requisições HTTP processadas.Reading: Conexões nas quais o NGINX está lendo os cabeçalhos do cliente.Writing: Conexões nas quais o NGINX está transmitindo respostas de volta ao cliente.Waiting: Conexões inativas aguardando nova requisição (Keep-Alive).
Essas métricas são expostas ao Prometheus através do exportador nginx-prometheus-exporter para exibição em dashboards no Grafana.
Roteiro Prático & Configuração
# 1. Configurar endpoint restrito de métricas no NGINX sudo tee /etc/nginx/conf.d/stub_status.conf << 'EOF' server { listen 127.0.0.1:8081; server_name 127.0.0.1; location = /stub_status { stub_status; allow 127.0.0.1; deny all; access_log off; } } EOF # 2. Instalar o exportador oficial de métricas do Prometheus sudo apt install -y prometheus-nginx-exporter # 3. Configurar o daemon do exportador apontando para o endpoint local sudo sed -i 's|ARGS=.*|ARGS="-nginx.scrape-uri=http://127.0.0.1:8081/stub_status"|' /etc/default/prometheus-nginx-exporter sudo systemctl restart prometheus-nginx-exporter sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Inspecionar saída bruta do stub_status e métricas no formato Prometheus curl -s http://127.0.0.1:8081/stub_status curl -s http://127.0.0.1:9113/metrics | grep nginx_connections
Fundamentação Teórica
O WordPress não depende de arquivos descentralizados .htaccess no NGINX. Toda a reescrita de permalinks amigáveis é resolvida nativamente em memória pela diretiva try_files $uri $uri/ /index.php?$args;, que atua como o Front Controller.
Blindagem de Arquitetura: A configuração segura do WordPress no NGINX exige o bloqueio explícito de arquivos de sistema (como wp-config.php) e a proibição absoluta de execução de interpretadores PHP no diretório público de uploads (/wp-content/uploads/), neutralizando ataques de upload malicioso de webshells.
Roteiro Prático & Configuração
# 1. Criar banco de dados dedicado no MariaDB sudo mysql -e "CREATE DATABASE wp_nginx DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" sudo mysql -e "CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'SenhaForteWP@2026';" sudo mysql -e "GRANT ALL ON wp_nginx.* TO 'wp_user'@'localhost'; FLUSH PRIVILEGES;" # 2. Configurar Server Block otimizado para WordPress sudo tee /etc/nginx/sites-available/wordpress-nginx.conf << 'EOF' server { listen 80; server_name blog-nginx.lab.local; root /var/www/wordpress; index index.php index.html; location / { try_files $uri $uri/ /index.php?$args; } # Bloquear execução direta de scripts na pasta de uploads location ~* /(?:uploads|files)/.*\.php$ { deny all; } # Bloquear leitura de arquivos sensíveis location = /wp-config.php { deny all; } location = /xmlrpc.php { deny all; } # Cache agressivo de assets estáticos location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ { expires max; log_not_found off; access_log off; } # Processamento PHP via socket Unix location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/run/php/php8.4-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } EOF # 3. Habilitar site e recarregar NGINX sudo ln -sf /etc/nginx/sites-available/wordpress-nginx.conf /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Testar rota inicial do WordPress curl -I -H "Host: blog-nginx.lab.local" http://localhost/wp-login.php
Fundamentação Teórica
O MediaWiki adota a convenção de URLs curtas e amigáveis no padrão /wiki/Nome_do_Artigo, que internamente é encaminhada para o script principal /w/index.php?title=$1. O NGINX executa essa conversão em velocidade de barramento sem sobrecarga de rotas.
Defesa em Profundidade: O diretório /images/ (utilizado para upload de anexos e mídias por editores da wiki) deve ter a execução de arquivos com extensões executáveis (.php, .phtml, .pl, .py) estritamente bloqueada, impedindo a exploração de Remote Code Execution (RCE) via upload.
Roteiro Prático & Configuração
# 1. Configurar Server Block completo para o MediaWiki sudo tee /etc/nginx/sites-available/mediawiki-nginx.conf << 'EOF' server { listen 80; server_name wiki-nginx.lab.local; root /var/www/mediawiki; index index.php; # Reescrever URLs limpas /wiki/Artigo location /wiki/ { rewrite ^/wiki/(.*)$ /index.php?title=$1&$args; } location / { try_files $uri $uri/ /index.php?$args; } # Bloqueio de execução de scripts no diretório de imagens location ^~ /images/ { location ~ \.(php|php5|phtml|pl|py|cgi)$ { deny all; } } # Tratamento de scripts PHP location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/run/php/php8.4-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } EOF # 2. Ativar site e recarregar o NGINX sudo ln -sf /etc/nginx/sites-available/mediawiki-nginx.conf /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx
Validação e Teste
# Validar resolução e cabeçalho de resposta do MediaWiki curl -I -H "Host: wiki-nginx.lab.local" http://localhost/wiki/Pagina_principal