Sem Agente · Sem Instalação

Hardening Nginx: Guia Completo de Segurança

Hardening do Nginx: O Guia para Amplificar sua Segurança (com tudo que pode dar errado se você não fizer) Cada linha de configuração padrão do Nginx que você ignora é uma porta entreaberta. Este guia mostra exatamente o que cada uma significa na prática — e como fechar, uma por uma.

Hardening do Nginx: O Guia para Amplificar sua Segurança (com tudo que pode dar errado se você não fizer)

Cada linha de configuração padrão do Nginx que você ignora é uma porta entreaberta. Este guia mostra exatamente o que cada uma significa na prática — e como fechar, uma por uma.

Introdução

O Nginx nasceu em 2004 com uma proposta diferente do Apache: ser leve, rápido e lidar com milhares de conexões simultâneas sem suar. Em 20 anos virou o servidor web mais usado do mundo entre os sites do top 1 milhão. E, exatamente como o Apache, sua configuração padrão é projetada para funcionar em qualquer lugar — não para ser segura em qualquer lugar.

A boa notícia é que o Nginx tem uma configuração mais enxuta e centralizada que o Apache. A má notícia é que justamente por isso, quando algo está errado, está errado em todos os sites de uma vez.

Este guia segue a mesma lógica do post anterior sobre Apache: para cada item, explicamos o que a configuração padrão faz, o que um atacante consegue fazer com isso (com cenários reais), e como corrigir com configuração pronta pra copiar.

1. server_tokens: o Nginx também grita sua versão

O que acontece por padrão

Toda resposta do Nginx inclui um header Server assim:

Server: nginx/1.24.0

E em páginas de erro, aparece um rodapé igualmente revelador.

O que isso causa

  1. Atacante varre a internet com Shodan, Censys ou um script
  2. Filtra por "nginx/1.24.0" — encontra todas as CVEs daquela versão
  3. Filtra exploits prontos no Exploit-DB, Metasploit, GitHub
  4. Se a sua versão tem vulnerabilidade não corrigida, o ataque começa em segundos

Agravante específico do Nginx: muita gente roda versões compiladas com módulos de terceiros (Brotli, ModSecurity, RTMP) que ficam pra trás nas atualizações.

A correção

http {
    server_tokens off;
}

Para esconder completamente o header (não apenas a versão), use o módulo headers-more:

more_clear_headers Server;
more_set_headers "Server: webserver";

2. fastcgiparam SERVERSOFTWARE: o vazamento via PHP

O que acontece por padrão

Quando o Nginx passa requisições pro PHP-FPM, envia automaticamente uma variável SERVERSOFTWARE com a versão do Nginx. Combinado com exposephp = On, vaza versão dos dois.

O que isso causa

Mesmo problema do item anterior, em estéreo. Atacante descobre versão do Nginx e do PHP com uma única requisição.

A correção

No php.ini:

expose_php = Off

No bloco PHP do Nginx:

location ~ \.php$ {
    fastcgi_param SERVER_SOFTWARE "webserver";
    fastcgi_hide_header X-Powered-By;
}

A diretiva fastcgihideheader impede que headers vindos do upstream sejam repassados ao cliente. Use sempre.

3. Métodos HTTP perigosos

O que acontece por padrão

O Nginx aceita qualquer método HTTP que o cliente enviar e repassa pra aplicação backend.

O que isso causa

  • API mal protegida que aceita DELETE /api/users/123 sem autenticação adequada
  • Aplicação Node/Python com rota PUT aberta por engano
  • WebDAV mal configurado em outro componente
  • Scanners de compliance marcando como vulnerabilidade

A correção

server {
    if ($request_method !~ ^(GET|HEAD|POST)$) {
        return 405;
    }
}

Para APIs REST que precisam de PUT, DELETE, PATCH:

if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|PATCH|OPTIONS)$) {
    return 405;
}

4. Strict-Transport-Security (HSTS)

O que acontece por padrão

O Nginx não envia HSTS. Mesmo em sites HTTPS-only, o navegador faz o primeiro request via HTTP até receber redirect.

O que isso causa

SSL Stripping: atacante em Wi-Fi público intercepta o primeiro request HTTP, mantém conexão HTTP com a vítima e HTTPS com o servidor real. A vítima nunca vê o cadeado, mas digita senha mesmo assim.

Com HSTS, o navegador se recusa a falar HTTP com o domínio depois da primeira visita. O ataque para de funcionar.

A correção

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

AVISO CRÍTICO sobre always: sem esse sufixo, o header só é enviado em respostas de sucesso e redirect, não em respostas de erro. Com always, é enviado em todas. Use sempre always em headers de segurança no Nginx.

Aviso sobre HSTS em si: uma vez aplicado com max-age longo, o navegador trava o domínio em HTTPS. Se o certificado vencer, usuários ficam sem acesso. Comece com max-age=300 (5 minutos), valide tudo, depois aumente.

5. X-Frame-Options: clickjacking

O que acontece por padrão

Sem esse header, qualquer site pode embutir o seu dentro de um iframe.

O que isso causa

Clickjacking: atacante cria site qualquer (sorteio, jogo) que carrega seu painel admin dentro de iframe invisível, com botões falsos sobrepostos. A vítima — logada em outra aba do seu sistema — clica em "ganhar prêmio" e na verdade clica em "excluir conta" no seu painel.

A correção

add_header X-Frame-Options "SAMEORIGIN" always;

6. X-Content-Type-Options: MIME sniffing

O que acontece por padrão

Quando recebe arquivo com Content-Type ambíguo, o navegador tenta adivinhar o tipo real olhando o conteúdo (MIME sniffing).

O que isso causa

Atacante envia foto.png com conteúdo HTML/JavaScript dentro. Você valida só a extensão. Quando outra vítima acessa, o navegador olha o conteúdo, pensa "isso é HTML" e executa. XSS armazenado sem nem precisar burlar filtro.

A correção

add_header X-Content-Type-Options "nosniff" always;

7. Referrer-Policy

O que acontece por padrão

Quando usuário clica em link externo, o navegador envia ao destino a URL completa de origem.

O que isso causa

Suponha URLs como:

https://meusistema.com/admin/usuarios?token=eyJhbGciOi...
https://meusistema.com/reset-senha?key=abc123
https://meuhospital.com/paciente/joao-silva-cpf-12345/exames

Qualquer link externo (ou imagem de outro domínio, ou pixel de tracking) faz a URL inteira vazar pro destino. Tokens, IDs, dados sensíveis. Sistemas de saúde americanos vazaram identificadores de pacientes pro Facebook por causa exatamente disso.

A correção

add_header Referrer-Policy "strict-origin-when-cross-origin" always;

URL completa em links internos, só o domínio em links externos via HTTPS, nada quando saindo de HTTPS pra HTTP.

8. Permissions-Policy

O que acontece por padrão

Sem esse header, qualquer página do site pode pedir acesso a câmera, microfone, geolocalização, USB, sensores.

O que isso causa

Imagine um XSS no site corporativo. Atacante injeta:

navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  .then(stream => transmiteParaServidorDoAtacante(stream))

A vítima vê popup de "permitir câmera?" e como confia no site, clica em permitir. Webcam e microfone do diretor financeiro transmitindo ao vivo.

A correção

add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()" always;

9. Content-Security-Policy: a defesa moderna contra XSS

O que acontece por padrão

Sem CSP, o navegador executa qualquer JavaScript que aparecer na página, de qualquer origem.

O que isso causa

XSS está há mais de 20 anos no top 10 da OWASP. Sem CSP, qualquer falha vira execução de JavaScript arbitrário com acesso a cookies e sessão. Com CSP bem configurada, mesmo que o XSS exista, o navegador se recusa a executar o script malicioso.

A correção

add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'" always;

CSP é o header mais difícil de configurar. A política acima quebra sites que usam Google Analytics, Google Fonts, jQuery via CDN, etc. Sempre teste primeiro com Content-Security-Policy-Report-Only, que reporta violações sem bloquear.

10. Cross-Origin headers (COOP, CORP, COEP)

O que acontece por padrão

Sem esses headers, sua janela compartilha processo com outras janelas e recursos podem ser carregados por qualquer origem.

O que isso causa

Após Spectre e Meltdown (2018), descobriu-se que JavaScript podia ler memória de outros processos via side channels da CPU. A defesa: isolar processos por origem.

A correção

add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;
# add_header Cross-Origin-Embedder-Policy "require-corp" always;

Aviso COEP: require-corp quebra recursos de terceiros que não enviam CORP. Se embute YouTube, Maps, fontes externas, deixe COEP comentado.

11. Listagem de diretórios e arquivos sensíveis

O que acontece por padrão

Por padrão, o Nginx não lista diretórios — vitória default. Mas o módulo está disponível e muita gente habilita "só pra testar" e esquece. E mais grave: o Nginx não tem .htaccess, então tudo precisa vir do conf.

O que isso causa

Listagem já vazou backups de banco, código fonte (.git/), uploads privados, documentos confidenciais. Mesmo sem listagem, acesso direto a .env, .git/config, wp-config.php.bak é trivial pra scanners.

A correção

# Bloqueia arquivos e pastas começando com ponto
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
    return 404;
}

# Exceção para Let's Encrypt
location ^~ /.well-known/ {
    allow all;
}

# Bloqueia extensões perigosas
location ~* \.(bak|backup|swp|old|sql|sql\.gz|tar|tar\.gz|zip|log|env|ini|conf|config|yml|yaml|lock)$ {
    deny all;
    access_log off;
    log_not_found off;
    return 404;
}

# Bloqueia arquivos específicos
location ~* (composer\.(json|lock)|package(-lock)?\.json|wp-config\.php|configuration\.php|web\.config)$ {
    deny all;
    access_log off;
    log_not_found off;
    return 404;
}

Por que return 404 em vez de 403? 403 confirma ao atacante que o arquivo existe ali. 404 finge que não existe. Defesa em profundidade.

12. Execução de PHP em pastas de upload

O que acontece por padrão

Se você tem location ~ \.php$ genérico, ele executa PHP em qualquer caminho terminado em .php — incluindo /uploads/shell.php.

O que isso causa

Combine com qualquer falha de upload — validação fraca, MIME forjado — e você tem upload de webshell. Atacante envia shell.php, acessa, e tem execução de comandos com o usuário do PHP-FPM. Padrão de comprometimento mais comum em WordPress, Joomla, Drupal há 15 anos.

A correção

location ^~ /uploads/ {
    location ~* \.(php|phtml|php3|php4|php5|pht|phar)$ {
        deny all;
        return 404;
    }
}

O ^~ garante prioridade sobre regex locations, evitando que o PHP global pegue arquivos dentro de uploads.

13. SSL/TLS: enterrando TLS 1.0 e 1.1

O que acontece por padrão

Em muitas distros, Nginx vem com TLS 1.0 e 1.1 habilitados. Esses protocolos têm vulnerabilidades conhecidas (BEAST, FREAK, POODLE) e foram oficialmente descontinuados pelo IETF em 2021 (RFC 8996).

O que isso causa

POODLE, BEAST, FREAK, downgrade attacks. PCI-DSS exige TLS 1.2+. Browsers modernos já mostram aviso de "conexão não segura" pra TLS 1.0/1.1.

A correção

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_ecdh_curve X25519:secp384r1:secp256r1;
ssl_session_timeout 1d;
ssl_session_cache shared:NginxSSL:50m;
ssl_session_tickets off;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/seudominio.com.br/chain.pem;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;

Use o Mozilla SSL Configuration Generator para gerar configurações sob medida.

14. clientmaxbody_size e timeouts (anti-Slowloris)

O que acontece por padrão

Padrão do Nginx é 1MB pra body. Razoável, mas muita gente aumenta pra "100M" ou "0" (ilimitado) sem pensar quando bate erro 413.

O que isso causa

Atacante manda requisições gigantes pra exaurir banda, memória e disco temporário. Repetindo, derruba o servidor.

Pior: timeouts longos (padrão) deixam o servidor vulnerável a Slowloris — ataque onde cliente abre conexões e envia bytes lentamente pra travar workers. Um único atacante derruba o Nginx com script Python de 20 linhas.

A correção

http {
    client_max_body_size 2m;
    client_body_buffer_size 128k;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;
    
    # Timeouts curtos = anti-Slowloris
    client_body_timeout 12;
    client_header_timeout 12;
    keepalive_timeout 15;
    send_timeout 10;
}

# Aumente apenas em locations específicas:
location /api/upload {
    client_max_body_size 50m;
}

15. Rate limiting

O que acontece por padrão

Sem limite. Atacante manda na velocidade que conseguir.

O que isso causa

  • Brute force em login — 10.000 senhas por segundo no /login
  • Brute force em API — enumeração de IDs sequenciais
  • Scraping agressivo — bot baixa o site inteiro em segundos
  • DoS por endpoint caro — atacante chama endpoint pesado repetidamente

A correção

http {
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
    limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;
    
    server {
        limit_conn conn_per_ip 20;
        
        location /login {
            limit_req zone=login burst=3 nodelay;
        }
        
        location /api/ {
            limit_req zone=api burst=20 nodelay;
        }
    }
}

16. proxyhideheader: vazamento via aplicação backend

O que acontece por padrão

Quando o Nginx é proxy reverso, repassa os headers que a aplicação envia. E aplicações adoram vazar:

X-Powered-By: Express
X-AspNet-Version: 4.0.30319
X-Runtime: 0.123456
X-Generator: Drupal 9
X-Drupal-Cache: HIT

O que isso causa

Atacante descobre versão exata do framework e busca CVEs. Headers como X-Drupal-Cache revelam estrutura interna.

A correção

proxy_hide_header X-Powered-By;
proxy_hide_header X-AspNet-Version;
proxy_hide_header X-AspNetMvc-Version;
proxy_hide_header X-Runtime;
proxy_hide_header X-Generator;
proxy_hide_header X-Drupal-Cache;
proxy_hide_header X-Drupal-Dynamic-Cache;
proxy_hide_header Server;

fastcgi_hide_header X-Powered-By;

Use generosamente. É uma das melhores ferramentas do Nginx.

Configuração final: tudo junto

Salve em /etc/nginx/snippets/security-hardening.conf:

# ============================================================
#  SECURITY HARDENING - Nginx
#  Inclua nos servers com:
#    include snippets/security-hardening.conf;
# ============================================================

# --- Headers de segurança HTTP (sempre 'always'!) ---
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
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=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;

# --- Bloqueio de métodos HTTP perigosos ---
if ($request_method !~ ^(GET|HEAD|POST)$) {
    return 405;
}

# --- Esconde headers vazados pelo upstream ---
proxy_hide_header X-Powered-By;
proxy_hide_header X-AspNet-Version;
proxy_hide_header X-AspNetMvc-Version;
proxy_hide_header X-Runtime;
proxy_hide_header X-Generator;
proxy_hide_header X-Drupal-Cache;
proxy_hide_header X-Drupal-Dynamic-Cache;
fastcgi_hide_header X-Powered-By;

# --- Bloqueio de arquivos e pastas começando com ponto ---
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
    return 404;
}

location ^~ /.well-known/ {
    allow all;
}

# --- Bloqueio de arquivos sensíveis por extensão ---
location ~* \.(bak|backup|swp|old|sql|sql\.gz|tar|tar\.gz|zip|log|env|ini|conf|config|yml|yaml|lock)$ {
    deny all;
    access_log off;
    log_not_found off;
    return 404;
}

# --- Bloqueio de arquivos sensíveis por nome ---
location ~* (composer\.(json|lock)|package(-lock)?\.json|wp-config\.php|configuration\.php|web\.config)$ {
    deny all;
    access_log off;
    log_not_found off;
    return 404;
}

# --- Pasta de uploads sem execução de PHP ---
location ^~ /uploads/ {
    location ~* \.(php|phtml|php3|php4|php5|pht|phar)$ {
        deny all;
        return 404;
    }
}

autoindex off;

E o nginx.conf global:

http {
    server_tokens off;
    
    # Limites de tamanho
    client_max_body_size 2m;
    client_body_buffer_size 128k;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;
    
    # Timeouts (anti-Slowloris)
    client_body_timeout 12;
    client_header_timeout 12;
    keepalive_timeout 15;
    send_timeout 10;
    
    # Rate limiting
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
    limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;
    
    # SSL/TLS
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_ecdh_curve X25519:secp384r1:secp256r1;
    ssl_session_timeout 1d;
    ssl_session_cache shared:NginxSSL:50m;
    ssl_session_tickets off;
}

Server HTTPS completo de exemplo:

server {
    listen 80;
    listen [::]:80;
    server_name seudominio.com.br www.seudominio.com.br;
    
    location ^~ /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
    }
    
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    
    server_name seudominio.com.br www.seudominio.com.br;
    root /var/www/html;
    index index.php index.html;
    
    ssl_certificate     /etc/letsencrypt/live/seudominio.com.br/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/seudominio.com.br/privkey.pem;
    
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/seudominio.com.br/chain.pem;
    resolver 1.1.1.1 8.8.8.8 valid=300s;
    resolver_timeout 5s;
    
    include snippets/security-hardening.conf;
    
    limit_conn conn_per_ip 20;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SERVER_SOFTWARE "webserver";
        include fastcgi_params;
        fastcgi_hide_header X-Powered-By;
    }
    
    location = /login {
        limit_req zone=login burst=3 nodelay;
        try_files $uri /index.php?$query_string;
    }
    
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        try_files $uri /index.php?$query_string;
    }
}

Validando

sudo nginx -t
sudo systemctl reload nginx
curl -I https://seudominio.com.br

Ferramentas: securityheaders.com, ssllabs.com/ssltest, Mozilla Observatory, e SentinelHub para monitoramento contínuo.

Checklist final

  • [ ] server_tokens off
  • [ ] expose_php = Off no php.ini
  • [ ] fastcgiparam SERVERSOFTWARE sobrescrito
  • [ ] fastcgihideheader X-Powered-By
  • [ ] HSTS com always (testado com max-age curto antes!)
  • [ ] X-Frame-Options aplicado
  • [ ] X-Content-Type-Options aplicado
  • [ ] Referrer-Policy aplicada
  • [ ] Permissions-Policy aplicada
  • [ ] CSP definida (testada em report-only primeiro!)
  • [ ] COOP/CORP aplicados
  • [ ] Métodos HTTP perigosos bloqueados
  • [ ] Pastas/arquivos com . bloqueados (com exceção .well-known)
  • [ ] Arquivos sensíveis bloqueados por extensão e nome
  • [ ] PHP desabilitado em pastas de upload com ^~
  • [ ] autoindex off em todos os locations
  • [ ] TLS 1.0 e 1.1 desabilitados
  • [ ] Cifras modernas configuradas
  • [ ] OCSP Stapling habilitado
  • [ ] clientmaxbody_size definido (não 0!)
  • [ ] Timeouts curtos (anti-Slowloris)
  • [ ] Rate limiting em login e API
  • [ ] proxyhideheader para vazamentos comuns
  • [ ] Site testou A+ em securityheaders.com
  • [ ] Site testou A+ em ssllabs.com
  • [ ] Monitoramento contínuo ativo

Apache vs Nginx: as diferenças que importam pra segurança

Se você leu o post sobre Apache também, vale destacar onde os dois divergem na hora de fazer hardening:

O Nginx é mais centralizado. Não tem .htaccess, então toda configuração precisa estar no conf principal. Melhor pra segurança (menos pegadinhas espalhadas), mas exige acesso ao servidor.

O always é uma armadilha do Nginx. Headers sem always não aparecem em respostas de erro. É a pegadinha mais comum em hardening de Nginx — você acha que tudo está perfeito até alguém testar uma página 404 e descobrir que metade dos headers sumiu.

O Nginx tem rate limiting nativo e excelente. Sintaxe muito mais simples que o Apache.

O proxyhideheader é um superpoder. Especialmente importante porque o Nginx é o servidor mais comum como proxy reverso pra aplicações modernas (Node, Python, Go).

Listagem de diretórios é desabilitada por padrão. Diferente do Apache. Vitória default.

A polêmica do if. No Nginx, if dentro de location pode causar comportamentos inesperados em alguns cenários (vale a pena ler o famoso "If is Evil" na wiki oficial). Para filtros simples como o de método HTTP que mostrei aqui, é seguro.

Considerações finais

Hardening continua sendo um processo, não um evento. Você aplicou tudo isso hoje? Ótimo. Mas amanhã alguém vai instalar um plugin que sobrescreve uma config, alguém vai mexer no CSP pra adicionar um analytics e esquecer de testar, alguém vai colocar clientmaxbody_size 0 "só pra ver se resolve o erro do upload".

A única forma realista de manter um servidor seguro a longo prazo é monitorar continuamente. Algo precisa estar olhando, todos os dias, se nada mudou pra pior — se um header sumiu, se uma porta nova abriu, se o certificado vai vencer, se uma versão nova tem CVE crítica.

É exatamente pra isso que existe o SentinelHub: scanner contínuo de segurança web, com alertas em tempo real, descrições em português, relatórios prontos pra mostrar pra diretoria, e detecção de tudo que esses dois posts cobriram.

Achou útil? Compartilha com o sysadmin da sua empresa. Achou que ele deveria ter feito isso ontem? Provavelmente sim.