Voltar ao Blog
SegurançaVPSDockerCloudflare

Endurecendo uma VPS: Firewall, Docker e Proxy na Ordem Certa

20 de maio de 2026·11 min de leitura

A Ordem da Defesa Importa Mais que o Inventário

A maioria dos servidores comprometidos não cai por falta de ferramenta — cai porque a postura defensiva foi montada depois de o serviço já estar em pé, na primeira tentativa de mitigar um incidente. Quando o atacante já está dentro do laço, qualquer configuração nova vira corrida.

Uma VPS endurecida desde o boot inverte o jogo: a sequência correta é firewall e kernel primeiro, runtime de contêiner depois, proxy reverso por último. Cada camada herda a postura da camada de baixo. Pular a base significa que o resto está apoiado em ar.

"Segurança não é o que você sabe — é o que você configura."

1. Firewall no Boot, Antes do Docker Existir

Em uma instalação típica de Ubuntu ou Debian, habilitar ufw com política default deny incoming e liberar apenas SSH é trivial. O detalhe que derruba a maioria das VPS aparece depois: ao instalar o Docker, o daemon manipula iptables diretamente e insere regras na chain DOCKER, anteriores às regras criadas pelo UFW.

O efeito prático: ao publicar uma porta com -p 5432:5432, o Postgres fica acessível na internet mesmo com o UFW "negando" aquela porta. O UFW está ativo, a regra existe — mas o pacote nunca chega até ela.

  • Binde explícito em localhost: ao publicar portas para serviços internos, prefixe o host — -p 127.0.0.1:5432:5432. Sem o IP, o bind é em 0.0.0.0.
  • Chain DOCKER-USER: o Docker reserva essa chain justamente para regras administrativas que precisam executar antes do roteamento de contêineres. É o ponto correto para inserir um DROP seletivo de origem.

2. Pinning de Versão do Proxy Reverso

Stacks como Coolify, Caprover ou setups manuais com Watchtower tendem a manter o proxy reverso (geralmente Traefik) sempre atualizado. A intenção é boa — patches de segurança aplicados sem intervenção. O problema é que o componente de borda é justamente o que não pode falhar em silêncio.

Uma release com regressão no Traefik não derruba apenas um serviço: ela tira do ar todos os domínios que dependem do roteamento. E descobrir isso no meio de um pico de tráfego é descobrir tarde.

  • Tag fixa, nunca latest: fixe a versão minor exata em uso (por exemplo traefik:v3.1.5) e suba uma versão por vez, validando em homologação antes de promover.
  • Auto-update desligado no proxy: em Coolify, desabilite a atualização automática especificamente para o serviço do proxy. Os serviços de aplicação podem manter o comportamento default; a borda, não.

3. O IP Real do Servidor Não Pode Vazar

Posicionar a aplicação atrás do Cloudflare só protege enquanto o IP de origem permanece desconhecido. Se o atacante descobre o IP real, ele simplesmente pula a camada — manda tráfego direto para o servidor e ignora o proxy.

Os vetores de vazamento são previsíveis e a maior parte é histórica:

  • DNS histórico: serviços como SecurityTrails, DNSlytics e o Censys preservam registros A/AAAA antigos. Se em algum momento o domínio apontou direto para o IP, antes do Cloudflare entrar na frente, esse registro continua público.
  • Subdomínios não-proxiados: um direct.dominio.com com a nuvem cinza (DNS-only) entrega o IP em uma consulta trivial.
  • E-mails enviados pela aplicação: cabeçalhos Received de SMTP, links de tracking e webhooks de saída revelam o IP de origem se enviados diretamente pela VPS em vez de um provedor de e-mail externo.

A mitigação tem duas pernas. A primeira é rotacionar o IP — emitir um IP novo e descomissionar o antigo. A segunda, mais durável, é configurar o firewall para aceitar tráfego HTTP/HTTPS apenas dos ranges publicados pelo Cloudflare. Mesmo que o IP volte a vazar, o servidor responde só ao proxy.

4. Cloudflare Under Attack Mode Como Botão Real

O Under Attack Mode exibe um desafio JavaScript antes de qualquer request alcançar a origem. Bots simples, scripts em Python e ferramentas de carga não conseguem renderizar o JS — são bloqueados na borda. Usuários reais pagam um atraso de poucos segundos.

O recurso só protege se estiver acessível no momento certo. Duas posturas concretas:

01

Regra automática por threshold

Configure uma regra em WAF / Rate Limiting que dispare Managed Challenge ou JS Challenge quando o tráfego ultrapassar a baseline. O objetivo não é bloquear pico legítimo — é cortar o pico anômalo antes que ele justifique intervenção manual.
02

UAM como ação de incident response

Mantenha um runbook curto que descreva onde está o toggle, quais domínios cobrir e como reverter. Sob estresse, ninguém procura menu — a documentação precisa ser executável em 30 segundos.

5. SYN Cookies: Defesa no Kernel Contra SYN Flood

Um ataque SYN flood explora o handshake do TCP. O atacante envia um SYN, o servidor responde com SYN-ACK e aloca uma entrada na fila de conexões pendentes esperando o ACK final. O ACK nunca chega. A fila enche. Conexões legítimas começam a ser recusadas.

SYN cookies invertem essa dinâmica. Quando a fila está sob pressão, o kernel codifica o estado da conexão dentro do número de sequência inicial do SYN-ACK — derivado da tupla IP/porta mais uma chave secreta — e não aloca nada. Se o ACK legítimo voltar, o servidor recalcula o cookie, confirma a integridade e reconstrói o estado. Se não voltar, não há recurso desperdiçado.

Habilitar é uma linha em /etc/sysctl.conf:

  • net.ipv4.tcp_syncookies = 1 — ativa o mecanismo somente sob pressão na fila, sem custo no caminho normal.
  • net.ipv4.tcp_max_syn_backlog — aumenta a fila de meio estabelecimento antes do cookie entrar em ação.

6. File Descriptors no Contêiner

Cada conexão TCP, cada arquivo aberto, cada socket em estado transiente consome um file descriptor. O default herdado pelo contêiner costuma ser baixo — 1024 em muitas imagens — e basta um proxy sob carga moderada, um banco com pool grande ou um servidor de websocket para esbarrar nesse teto.

O sintoma é confuso: o serviço responde lento, retorna erros intermitentes de too many open files, e a métrica de CPU/RAM continua tranquila. Ajustar é declarativo:

  • CLI: --ulimit nofile=65536:65536 no docker run.
  • Compose: bloco ulimits.nofile com soft e hard definidos explicitamente no serviço.
  • Validação: dentro do contêiner, cat /proc/self/limits mostra o valor efetivo — confirmar o que foi aplicado evita supor.

7. Alertas Que Disparam, Não Dashboards Que Decoram

O ponto frágil mais comum em VPS pequenas não é a ausência de métricas — é a ausência de alertas acionáveis. Gráficos bonitos no Grafana só ajudam se alguém estiver olhando. Um alerta no celular chega quando o servidor ainda dá para salvar.

Quatro sinais cobrem a maior parte dos cenários de degradação:

  • RSS do processo do proxy: subida abrupta de memória residente do Traefik/Nginx normalmente antecede colapso por minutos.
  • Contagem de processos do host: crescimento monotônico indica fork bomb ou loop em healthcheck que não está sendo coletado.
  • Conexões em SYN_RECV: é a assinatura direta de SYN flood — alertar quando o número passar de uma baseline conhecida torna o ataque visível antes do SSH cair.
  • Requests por segundo no proxy: diferenciar pico orgânico de pico anômalo só é possível com baseline histórica. Sem isso, qualquer pico parece igual.

Stacks adequadas para começo de operação: Netdata entrega alertas configurados a partir da instalação; Prometheus + Alertmanager oferece flexibilidade quando o volume justifica o esforço de operar a stack.

Em resumo: Endurecer uma VPS é um conjunto pequeno e finito de configurações que custa uma tarde no início do projeto e poupa horas de incidente depois. A diferença entre um servidor que aguenta e um que cai não está na ferramenta escolhida — está em qual camada foi configurada antes, e em qual alerta dispara cedo o suficiente para a defesa ainda ter caminho.

Voltar ao Blog