Configuração de firewall

Quais portas o HeroCtl usa, quais precisam ficar abertas, e quais nunca deveriam ser expostas à internet.

Rede·9 min·

Um cluster HeroCtl saudável tem um conjunto pequeno e fixo de portas. Este documento mostra quais são, o que faz cada uma, e como configurar o firewall do sistema operacional para liberar exatamente o necessário, nem mais nem menos.

Portas em uso

PortaProtocoloFunçãoQuem precisa acessar
80TCPRoteador de ingress (HTTP)Internet inteira
443TCPRoteador de ingress (HTTPS)Internet inteira
8080TCPAPI do plano de controleOperadores e CLI, via VPN ou allowlist
8443TCPPainel web TLSOperadores, via VPN ou allowlist
4646TCPCoordenação interna entre nós (consenso)Apenas outros nós do cluster
4647TCPRPC entre coordenador e workersApenas outros nós do cluster
4648TCP+UDPGossip entre nósApenas outros nós do cluster

A regra geral é simples:

  • 80 e 443 abrem para o mundo. É o ponto de entrada das suas aplicações.
  • 8080 e 8443 nunca deveriam estar abertas para a internet pública.
  • 4646, 4647 e 4648 ficam restritas aos IPs internos do cluster.

Atenção: Expor 8080 sem allowlist é o erro de configuração mais comum em clusters novos. Qualquer pessoa com o token admin pode submeter jobs. Trate essa porta como SSH.

Topologia recomendada

                     internet
                        │
                  ┌─────┴─────┐
                  │  80, 443  │   ← qualquer origem
                  └─────┬─────┘
                        │
                ┌───────┴───────┐
                │   nós do      │
                │   cluster     │
                └───────┬───────┘
                        │
                  ┌─────┴─────┐
                  │ 4646-4648 │   ← apenas IPs internos
                  └───────────┘
                        │
                  ┌─────┴─────┐
                  │ 8080,8443 │   ← apenas VPN ou allowlist
                  └───────────┘

Ubuntu e Debian (ufw)

Configuração mínima para um nó servidor:

# regras default
sudo ufw default deny incoming
sudo ufw default allow outgoing

# acesso administrativo (ajuste o IP de origem)
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp comment 'SSH operador'
sudo ufw allow from 203.0.113.10 to any port 8080 proto tcp comment 'API'
sudo ufw allow from 203.0.113.10 to any port 8443 proto tcp comment 'Painel'

# tráfego público
sudo ufw allow 80/tcp comment 'Ingress HTTP'
sudo ufw allow 443/tcp comment 'Ingress HTTPS'

# comunicação interna entre nós (substitua pelos IPs reais)
for ip in 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4; do
  sudo ufw allow from $ip to any port 4646 proto tcp
  sudo ufw allow from $ip to any port 4647 proto tcp
  sudo ufw allow from $ip to any port 4648
done

sudo ufw enable
sudo ufw status numbered

Em nós que são apenas worker (sem painel exposto), pule as linhas 8080 e 8443.

RHEL, Fedora, AlmaLinux (firewalld)

# zonas separadas: pública para 80/443, interna para portas de cluster
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https

# zona internal recebe os IPs do cluster
sudo firewall-cmd --permanent --zone=internal --add-source=10.0.0.0/24
sudo firewall-cmd --permanent --zone=internal --add-port=4646/tcp
sudo firewall-cmd --permanent --zone=internal --add-port=4647/tcp
sudo firewall-cmd --permanent --zone=internal --add-port=4648/tcp
sudo firewall-cmd --permanent --zone=internal --add-port=4648/udp

# acesso admin: zone trusted com IP do operador
sudo firewall-cmd --permanent --zone=trusted --add-source=203.0.113.10
sudo firewall-cmd --permanent --zone=trusted --add-port=8080/tcp
sudo firewall-cmd --permanent --zone=trusted --add-port=8443/tcp

sudo firewall-cmd --reload
sudo firewall-cmd --list-all-zones

iptables direto

Se você prefere regras explícitas, ou usa um sistema sem ufw/firewalld:

# tráfego estabelecido
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT

# ingress público
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# admin restrito
iptables -A INPUT -p tcp -s 203.0.113.10 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s 203.0.113.10 --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp -s 203.0.113.10 --dport 8443 -j ACCEPT

# cluster interno (repita para cada IP)
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 4646 -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 4647 -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 4648 -j ACCEPT
iptables -A INPUT -p udp -s 10.0.0.0/24 --dport 4648 -j ACCEPT

# default deny
iptables -P INPUT DROP

# persistir
sudo netfilter-persistent save

Cloud firewall em camada de cima

Mesmo com ufw correto em cada nó, vale ativar o firewall do provedor de nuvem como segunda camada. Se o ufw cair por mudança errada, o cloud firewall continua segurando.

DigitalOcean Cloud Firewall

Crie uma firewall e atribua a todas as droplets do cluster:

DireçãoTipoOrigemPorta
InboundTCPAnywhere80, 443
InboundTCPIPs do operador22, 8080, 8443
InboundTCPTag heroctl-cluster4646, 4647, 4648
InboundUDPTag heroctl-cluster4648
OutboundAllAnywhereAll

Use tags em vez de IPs para 4646-4648 — quando você adiciona um nó novo com a tag, ele já entra na regra.

AWS Security Groups

Crie dois security groups:

  • heroctl-public: 80 e 443 de 0.0.0.0/0. Atribua a todos os nós.
  • heroctl-cluster: 4646-4648 com origem no próprio security group (self-reference). Para 8080 e 8443, source no security group da bastion.

Hetzner Cloud Firewall

Hetzner não tem self-reference. Use a rede privada do projeto e libere por CIDR:

allow tcp 80,443 from 0.0.0.0/0
allow tcp 4646,4647,4648 from 10.0.0.0/16
allow udp 4648 from 10.0.0.0/16
allow tcp 8080,8443 from <ip-do-operador>/32

Cloudflare na frente

Para proteção contra ataques volumétricos, colocar Cloudflare em modo proxy na frente do cluster funciona bem. Pontos de atenção:

  • Para emissão de certificado, use DNS-01 (não HTTP-01). O modo proxy quebra HTTP-01.
  • Restrinja 80 e 443 dos nós para aceitarem apenas os ranges de IP da Cloudflare. A lista oficial fica em https://www.cloudflare.com/ips-v4. Atualize via cron mensal.
  • Habilite "Full (strict)" no Cloudflare. Não use "Flexible" — isso faz a Cloudflare falar HTTP com seu cluster mesmo o usuário tendo HTTPS.

Bloqueando acesso administrativo

A regra mais importante deste documento. A porta 8080 não pode estar acessível pela internet pública. Três caminhos viáveis:

  1. VPN. WireGuard ou Tailscale entre máquinas dos operadores e o cluster. Bloqueia 8080 para qualquer origem fora da rede da VPN. Recomendado para times.
  2. Allowlist por IP fixo. Funciona para operador solo com IP residencial estável ou VPS bastion.
  3. SSH tunnel. ssh -L 8080:localhost:8080 servidor cada vez que for usar a CLI. Funciona, mas atrita.

A combinação que mais aparece em produção é VPN + cloud firewall. Operador entra na VPN, cloud firewall só libera 8080 para o range da VPN, e o ufw do nó faz a mesma coisa por dentro.

Validação

Depois de aplicar as regras, valide de fora:

# da sua máquina, sem VPN, contra um IP do cluster
nmap -p 80,443,8080,8443,4646,4647,4648 <ip-do-no>

Resultado correto: 80 e 443 abertas, todas as outras fechadas (closed ou filtered).

Próximos passos

#firewall#ufw#iptables#rede#seguranca