---
title: "Proteger aplicação web contra ataques: defesa em camadas"
description: "Firewall, proxy com rate limiting, WAF, login forte, atualizações e logs: como proteger um site ou API em VPS, camada por camada, com exemplos em Nginx."
url: "https://streethosting.com.br/guias/infraestrutura/proteger-aplicacao-web-ataques"
category: "infraestrutura"
slug: "proteger-aplicacao-web-ataques"
datePublished: "2026-09-28"
dateModified: "2026-09-28"
author: "Equipe StreetHosting"
difficulty: "intermediario"
language: "pt-BR"
keywords:
  - "proteger aplicacao web ataques"
  - "seguranca aplicacao web vps"
  - "rate limiting nginx"
  - "cabecalhos de seguranca nginx"
  - "proteger api contra ataques"
  - "owasp top 10 na pratica"
---

# Como blindar um site ou uma API em VPS, camada por camada

Nenhuma ferramenta sozinha protege uma aplicação web. Este guia organiza as defesas em camadas, da porta de rede ao log, e mostra o que configurar primeiro em uma VPS com Nginx.

> **Resposta rápida**
>
> Para **proteger uma aplicação web contra ataques**, empilhe defesas que se cobrem: firewall expondo só 80, 443 e SSH; proxy reverso com TLS, rate limiting e cabeçalhos de segurança; WAF para filtrar injeções; autenticação com 2FA e sessões seguras; sistema, runtime e dependências atualizados; e logs com alerta para perceber o que passou. Cada camada assume que a anterior pode falhar.

## As camadas e o que cada uma barra

A maior parte dos ataques contra sites em VPS não é pessoal. Robôs varrem faixas inteiras de IP procurando arquivo .env esquecido na pasta pública, painel de login do WordPress, phpMyAdmin, plugin desatualizado e banco de dados aberto. Uma parte menor é direcionada: teste de senhas vazadas no seu login, abuso de API, enxurrada de requisições para derrubar o serviço. Nenhuma ferramenta cobre tudo isso, por isso a defesa é montada em camadas.

| Camada | O que barra | Ferramenta típica na VPS |
| --- | --- | --- |
| Rede | Porta esquecida aberta, banco exposto, varredura | UFW e AntiDDoS do provedor |
| Borda e proxy | Excesso de requisições, upload gigante, versão exposta | Nginx com TLS, limites e cabeçalhos |
| Filtro de conteúdo | Injeção de SQL, XSS, exploração de falha conhecida | WAF com OWASP CRS ou WAF de CDN |
| Identidade | Senha vazada, sequestro de sessão, painel exposto | 2FA, cookies seguros, VPN para administração |
| Código e dependências | Falha conhecida em biblioteca, tema ou plugin | Atualização e auditoria de pacotes |
| Observação | Ataque que passou pelas outras camadas | Logs, Fail2Ban e alertas |

Para uma equipe pequena, a ordem de prioridade é pelo custo contra o impacto: fechar portas, ligar TLS e atualizar, endurecer o login, limitar requisições, organizar logs e, por último, ajustar um WAF. As três primeiras levam uma tarde e resolvem a maior parte do risco.

## Rede: expor só o necessário

Uma aplicação web precisa das portas 80 e 443 abertas para o público e da porta do SSH para você. Todo o resto, como PostgreSQL na 5432, MySQL na 3306, Redis na 6379 e a porta interna da aplicação (3000, 8000, 8080), deve escutar só em 127.0.0.1 ou em rede privada. Descubra o que está escutando para fora com:

```
sudo ss -tlnp
```

Qualquer serviço interno ligado em 0.0.0.0 ou em um asterisco está aceitando conexão de qualquer lugar. Corrija em dois lugares: no próprio serviço, mudando o endereço de escuta, e no firewall, negando a porta. Se uma das camadas falhar, a outra segura. O passo a passo das regras está no guia de [firewall UFW na VPS Ubuntu](https://streethosting.com.br/guias/vps/firewall-ufw-vps-ubuntu), incluindo a armadilha do Docker, que publica portas por fora do UFW.

Painéis administrativos (phpMyAdmin, Portainer, editor do n8n, dashboards de métricas) não precisam estar na internet. Acesse por um túnel SSH, como `ssh -L 8080:127.0.0.1:8080 usuario@IP_DA_VPS`, ou por uma [VPN com WireGuard](https://streethosting.com.br/guias/vps/proteger-vps-wireguard-vpn). Um painel que não aparece em nenhuma varredura não recebe tentativa de login.

Duas situações fogem do que o firewall da VPS resolve. O DDoS volumétrico precisa ser filtrado antes de chegar ao servidor, na rede do provedor. E se o site fica atrás de uma CDN, a origem deve aceitar 80 e 443 só das faixas de IP da CDN; caso contrário, quem descobrir o IP real da VPS contorna toda a proteção da borda. Nesse cenário, configure o Nginx para recuperar o IP verdadeiro do visitante com `set_real_ip_from` e `real_ip_header`, senão os limites por IP vão tratar todos os visitantes como se fossem a própria CDN.

## Proxy reverso: TLS, limites e cabeçalhos

Coloque o Nginx na frente da aplicação, seja ela Node.js, Python ou PHP, e deixe a aplicação escutando só localmente. O Nginx termina o TLS, como mostra o guia de [certificado SSL com Let's Encrypt e Nginx](https://streethosting.com.br/guias/vps/certificado-ssl-vps-lets-encrypt-nginx), e passa a ser o lugar certo para impor limite de tamanho, tempo e frequência. Um arquivo em `/etc/nginx/conf.d/` é lido dentro do bloco http no Ubuntu:

```
# /etc/nginx/conf.d/seguranca.conf
server_tokens off;
client_max_body_size 10m;
client_body_timeout 15s;
client_header_timeout 15s;

limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=20r/s;
limit_conn_zone $binary_remote_addr zone=porip:10m;
limit_req_status 429;
limit_conn_status 429;
```

E dentro do bloco server do site:

```
location = /login {
    limit_req zone=login burst=5 nodelay;
    proxy_pass http://127.0.0.1:3000;
}

location /api/ {
    limit_req zone=api burst=40 nodelay;
    limit_conn porip 20;
    proxy_pass http://127.0.0.1:3000;
}

location ~ /\.(?!well-known) {
    deny all;
}

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
```

- **Login a 10 por minuto:** um pedido a cada seis segundos por IP, com folga de cinco para quem erra a senha uma vez. Um robô testando senhas cai para algumas centenas de tentativas por dia.
- **Status 429:** o padrão do Nginx é 503, que confunde com servidor fora do ar. O 429 diz ao cliente e ao seu monitoramento que é limite de frequência.
- **Arquivos ocultos:** a regra com deny all bloqueia .env, .git e similares, mas deixa passar a pasta `.well-known`, que o Let's Encrypt usa para validar o domínio.
- **Cabeçalhos:** HSTS força HTTPS no navegador, nosniff impede que um arquivo seja interpretado como outro tipo e o `X-Frame-Options` evita que o site seja embutido em página de terceiros para enganar cliques.

> **Atenção**
>
> No Nginx, um add_header dentro de um location substitui todos os que vieram do bloco server. Se algum location tiver cabeçalho próprio, repita ali os de segurança. E só ligue o HSTS com includeSubDomains depois de confirmar que todos os subdomínios respondem em HTTPS. Valide sempre com `sudo nginx -t` antes do reload.

O cabeçalho mais forte contra XSS é o Content Security Policy, mas ele depende de cada aplicação. Comece com a versão só de relatório, que avisa sem bloquear, e aperte aos poucos.

## WAF: filtrar o conteúdo

O firewall olha portas e o proxy olha volume. O WAF lê o conteúdo: URL, parâmetros, cabeçalhos e corpo da requisição, procurando padrões de injeção de SQL, XSS, inclusão de arquivo e exploração de falhas conhecidas. Na VPS, o caminho comum é o ModSecurity com o OWASP Core Rule Set dentro do Nginx; na borda, o WAF de uma CDN faz o mesmo antes de o tráfego chegar à sua máquina.

O maior valor do WAF é ganhar tempo: quando sai uma falha grave em um plugin, as regras bloqueiam a exploração em massa enquanto você aplica a atualização. Ele não corrige erro de lógica, não impede que um usuário acesse o pedido de outro se a aplicação não checar permissão e gera falso positivo se ligado direto em modo de bloqueio. Como escolher, instalar e calibrar está em [o que é WAF e quando usar](https://streethosting.com.br/guias/infraestrutura/o-que-e-waf-firewall-aplicacao). Para enxurradas de requisições que imitam usuários reais, leia também sobre [DDoS de camada 7](https://streethosting.com.br/guias/infraestrutura/ddos-camada-7-l7-aplicacao).

## Autenticação, sessões e painel

Login é o ponto mais atacado de qualquer aplicação, e boa parte das invasões não quebra nada: entra com uma senha vazada de outro site. As medidas abaixo valem para sistema próprio e para painel de CMS.

- **Senhas guardadas com hash lento:** Argon2id ou bcrypt, nunca MD5 ou SHA simples. Frameworks como Laravel e Django já fazem isso por padrão; o erro costuma aparecer em sistema escrito do zero.
- **2FA para quem administra:** um aplicativo de código temporário nas contas com poder de apagar dados, no mínimo.
- **Limite por conta, além do limite por IP:** teste de senhas vazadas vem de milhares de IPs diferentes. Atrasar ou travar a conta depois de várias falhas fecha o que o limite por IP deixa passar. A mensagem de erro deve ser a mesma para usuário inexistente e senha errada.
- **Sessão bem configurada:** cookie com Secure, HttpOnly e SameSite, identificador de sessão renovado no login e expiração por inatividade. Formulários com proteção contra CSRF.
- **Painel fora do alcance público:** restrinja o caminho administrativo por IP no Nginx, com `allow 203.0.113.10; deny all;` dentro do location, ou deixe o painel acessível só pela VPN.
- **Permissão checada no servidor:** cada requisição precisa confirmar que aquele usuário pode ver aquele recurso. Falha de controle de acesso aparece no topo do OWASP Top 10 justamente porque WAF nenhum enxerga esse erro.
- **Tokens de API com escopo e validade:** nunca na query string, onde acabam gravados em log, e com CORS liberado só para as origens que você controla.

## Atualizações, dependências e segredos

A maioria dos comprometimentos em massa explora falhas que já tinham correção publicada. Existem três níveis de atualização, e cada um tem ritmo próprio. O sistema operacional pode andar sozinho com as [atualizações automáticas de segurança do Ubuntu](https://streethosting.com.br/guias/vps/atualizacoes-automaticas-seguranca-ubuntu). O runtime (Node.js, PHP, Python) precisa estar em uma versão ainda suportada. E as dependências da aplicação pedem auditoria periódica:

```
npm audit --omit=dev
composer audit
pip-audit
docker compose pull && docker compose up -d
```

O `pip-audit` é instalado à parte, com pip, dentro do ambiente virtual do projeto. A última linha vale para quem roda em containers: a imagem só recebe correção quando você baixa a versão nova e recria o container.

- [ ] Arquivo .env fora da pasta pública, com permissão 600 e fora do Git
- [ ] Usuário do banco com acesso só ao banco da aplicação
- [ ] Consultas parametrizadas ou ORM, nunca texto do usuário colado no SQL
- [ ] Upload validado pelo conteúdo, com limite de tamanho e fora de pasta executável
- [ ] Modo de depuração desligado em produção
- [ ] Plugins, temas e rotas de teste que não são usados removidos

Um teste rápido mostra se o servidor entrega o que não devia. Os dois comandos abaixo devem responder 403 ou 404:

```
curl -s -o /dev/null -w "%{http_code}\n" https://seu-dominio.com.br/.env
curl -s -o /dev/null -w "%{http_code}\n" https://seu-dominio.com.br/.git/config
```

## Logs, alertas e resposta

Sem log, você descobre o ataque pelo cliente. Registre tentativas de login com IP, ações administrativas, respostas 4xx e 5xx, bloqueios por limite e bloqueios do WAF. O Nginx grava em `/var/log/nginx/` e a aplicação, se rodar como serviço systemd, aparece no `journalctl -u nome-do-servico`. Duas consultas resolvem muita dúvida no formato padrão de log do Nginx:

```
# IPs que mais fizeram requisições
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

# quantas respostas 401, 403 e 429
sudo awk '$9 ~ /^(401|403|429)$/' /var/log/nginx/access.log | wc -l
```

O passo seguinte é automatizar a reação. O [Fail2Ban na VPS](https://streethosting.com.br/guias/vps/configurar-fail2ban-ssh-vps) lê o log de erro do Nginx e bane IPs que estouram o limite de requisições repetidamente ou que varrem caminhos típicos de robô. Alertas de pico de erro e de serviço fora do ar fecham o ciclo.

> **Dica**
>
> Se algo passar, siga uma ordem: preserve os logs antes de limpar qualquer coisa, troque senhas, chaves de API e segredos do .env, corrija a falha e, na dúvida sobre a integridade, restaure de um backup limpo. Quando houver dado pessoal envolvido, a LGPD exige comunicar a ANPD e os titulares se o incidente puder causar risco ou dano relevante.

## Onde hospedar com essas camadas

Hospedagem compartilhada não deixa você mexer no firewall, nos limites do Nginx, em módulo de WAF nem no Fail2Ban. Uma VPS com root deixa, e em troca a configuração passa a ser sua. A camada que você não consegue montar sozinho é a do DDoS volumétrico, porque ela precisa agir antes do tráfego chegar à máquina.

As [VPS da StreetHosting](https://streethosting.com.br/vps) são KVM com acesso root, datacenter em São Paulo e AntiDDoS incluso na rede, o que cobre essa camada. Para uma API pequena com Nginx e banco, a VPS Xeon de 4 vCPU e 6 GB sai por R$ 57,00 por mês. Um site com WAF, aplicação e banco na mesma máquina fica confortável na VPS Ryzen 9 9950X de 4 vCPU, 8 GB DDR5 e 80 GB NVMe, por R$ 114,00, já que as regras do WAF consomem CPU a cada requisição. Os planos de entrada começam em R$ 23,00 na linha Xeon e R$ 39,00 na Ryzen.

## Perguntas frequentes

### Qual a primeira coisa a fazer para proteger uma aplicação web?

Fechar o que não precisa estar exposto e atualizar o que está. Deixe abertas só as portas 80, 443 e a do SSH, faça banco de dados e painéis escutarem apenas localmente e aplique as atualizações pendentes. Essas duas medidas cortam a maior parte dos ataques automatizados.

### Rate limiting atrapalha usuários legítimos?

Pode atrapalhar se o limite for apertado demais, principalmente quando muitas pessoas saem pelo mesmo IP, como em empresas, escolas e redes móveis com CGNAT. Use limites rígidos só em pontos sensíveis, como login e recuperação de senha, e limites folgados no resto do site.

### Preciso de WAF se já tenho firewall?

São coisas diferentes. O firewall decide quais portas aceitam conexão, e a porta 443 precisa ficar aberta para o site funcionar. O WAF inspeciona o conteúdo que passa por ela e barra padrões de ataque. Para sites com formulários, login e plugins, vale ter os dois.

### HTTPS protege o site contra ataques?

Protege o caminho, não o destino. O TLS impede que alguém leia ou altere os dados entre o visitante e o servidor, mas uma injeção de SQL chega criptografada do mesmo jeito. Ele é obrigatório, só que resolve uma camada só.

### Como saber se meu site já foi atacado?

Olhe os logs do Nginx e da aplicação em busca de picos de erros 401, 403 e 500, acessos a caminhos que não existem no seu site e logins de IPs ou horários incomuns. Arquivos alterados sem deploy e processos desconhecidos consumindo CPU são sinais fortes de comprometimento.

## Guias relacionados

- [O que é WAF e quando usar em sites e APIs](https://streethosting.com.br/guias/infraestrutura/o-que-e-waf-firewall-aplicacao.md)
- [Firewall de rede e firewall de aplicação: qual a diferença](https://streethosting.com.br/guias/infraestrutura/firewall-rede-vs-aplicacao-diferenca.md)
- [UFW na VPS Ubuntu: regras de firewall sem perder o SSH](https://streethosting.com.br/guias/vps/firewall-ufw-vps-ubuntu.md)
- [Configurar Fail2Ban na VPS: SSH, Nginx e reincidentes](https://streethosting.com.br/guias/vps/configurar-fail2ban-ssh-vps.md)
- [DDoS de camada 7: o que é o ataque de aplicação e como mitigar](https://streethosting.com.br/guias/infraestrutura/ddos-camada-7-l7-aplicacao.md)

## Produtos citados

- https://streethosting.com.br/vps
- https://streethosting.com.br/vps/ryzen
- https://streethosting.com.br/vps/xeon

## Dados estruturados

```json
[
  {
    "@context": "https://schema.org",
    "@type": [
      "Article",
      "TechArticle"
    ],
    "headline": "Como blindar um site ou uma API em VPS, camada por camada",
    "name": "Proteger aplicação web contra ataques: defesa em camadas",
    "abstract": "Nenhuma ferramenta sozinha protege uma aplicação web. Este guia organiza as defesas em camadas, da porta de rede ao log, e mostra o que configurar primeiro em uma VPS com Nginx.",
    "description": "Firewall, proxy com rate limiting, WAF, login forte, atualizações e logs: como proteger um site ou API em VPS, camada por camada, com exemplos em Nginx.",
    "datePublished": "2026-09-28",
    "dateModified": "2026-09-28",
    "author": {
      "@type": "Organization",
      "name": "Equipe StreetHosting"
    },
    "publisher": {
      "@type": "Organization",
      "name": "StreetHosting",
      "url": "https://streethosting.com.br"
    },
    "inLanguage": "pt-BR",
    "mainEntityOfPage": {
      "@type": "WebPage",
      "@id": "https://streethosting.com.br/guias/infraestrutura/proteger-aplicacao-web-ataques"
    }
  },
  {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    "mainEntity": [
      {
        "@type": "Question",
        "name": "Qual a primeira coisa a fazer para proteger uma aplicação web?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Fechar o que não precisa estar exposto e atualizar o que está. Deixe abertas só as portas 80, 443 e a do SSH, faça banco de dados e painéis escutarem apenas localmente e aplique as atualizações pendentes. Essas duas medidas cortam a maior parte dos ataques automatizados."
        }
      },
      {
        "@type": "Question",
        "name": "Rate limiting atrapalha usuários legítimos?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Pode atrapalhar se o limite for apertado demais, principalmente quando muitas pessoas saem pelo mesmo IP, como em empresas, escolas e redes móveis com CGNAT. Use limites rígidos só em pontos sensíveis, como login e recuperação de senha, e limites folgados no resto do site."
        }
      },
      {
        "@type": "Question",
        "name": "Preciso de WAF se já tenho firewall?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "São coisas diferentes. O firewall decide quais portas aceitam conexão, e a porta 443 precisa ficar aberta para o site funcionar. O WAF inspeciona o conteúdo que passa por ela e barra padrões de ataque. Para sites com formulários, login e plugins, vale ter os dois."
        }
      },
      {
        "@type": "Question",
        "name": "HTTPS protege o site contra ataques?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Protege o caminho, não o destino. O TLS impede que alguém leia ou altere os dados entre o visitante e o servidor, mas uma injeção de SQL chega criptografada do mesmo jeito. Ele é obrigatório, só que resolve uma camada só."
        }
      },
      {
        "@type": "Question",
        "name": "Como saber se meu site já foi atacado?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Olhe os logs do Nginx e da aplicação em busca de picos de erros 401, 403 e 500, acessos a caminhos que não existem no seu site e logins de IPs ou horários incomuns. Arquivos alterados sem deploy e processos desconhecidos consumindo CPU são sinais fortes de comprometimento."
        }
      }
    ]
  }
]
```
