Pular para o conteúdo
● ONLINE

Redes Linux com BGP, PTT e IPTables: três desenhos de alta disponibilidade que realmente funcionam

Alta disponibilidade em Redes Linux com BGP, PTT e IPTables não começa com roteamento. Começa com uma decisão incômoda: o que você aceita perder quando um enlace cai, quando o upstream oscila ou quando um firewall para de responder. A resposta mais honesta é que HA de verdade quase nunca depende de uma única técnica. E é justamente por isso que eu desconfio de projetos que tentam resolver tudo com um único anúncio BGP ou com um cluster de firewall “milagroso”.

Na prática, Redes Linux com BGP, PTT e IPTables ficam muito mais sólidas quando você separa responsabilidades. Um desenho lida com roteamento. Outro com borda e troca de tráfego. Outro com estado de firewall e failover. Dá trabalho. Mas é o tipo de trabalho que evita aquele clássico incidente de madrugada em que o host segue pingando, só que ninguém passa tráfego útil.

Três alternativas que eu comparo em produção: BGP puro, PTT com upstream, e firewall stateful em par

Vou tratar aqui como comparação direta entre três alternativas reais de arquitetura:

  • Alternativa A — BGP puro com multihoming: você anuncia prefixos para dois ou mais vizinhos e deixa o roteamento tomar decisões.
  • Alternativa B — PTT como ponto de troca de tráfego + upstream de fallback: o tráfego local flui pelo IX/PTT, e o backup sai por operadora tradicional.
  • Alternativa C — IPTables em par ativo-passivo com VRRP: foco na borda de segurança e continuidade do NAT/filtragem quando um nó morre.

Essas abordagens não competem no vácuo. Em muitos ambientes, você combina as três. Mas a escolha da prioridade muda tudo: se sua dor é redundância de trânsito, BGP vem primeiro. Se sua dor é peering e latência local, PTT manda. Se sua dor é preservar estado de sessão e regras de borda, IPTables com VRRP resolve um pedaço específico do problema. E esse pedaço é grande.

Alternativa A: BGP puro com multihoming Linux

Esse é o desenho que muita gente romantiza e pouca gente implanta direito. O princípio é simples: o seu roteador Linux fala BGP com dois ou mais vizinhos, recebe rotas e anuncia seus prefixos. Quando um enlace cai, o protocolo converge. Quando um vizinho degrada, você aplica política e recorta o caminho. Parece elegante. E é. Só que a elegância cobra disciplina.

Num ambiente Linux, eu prefiro FRRouting (FRR) para BGP. O velho Quagga ficou para trás faz tempo. FRR integra bem com kernel routing table, suporta múltiplos peers, route-maps, communities e políticas que não viram uma sopa ilegível. Em host de borda, eu costumo separar o plano de roteamento do plano de dados com interfaces dedicadas, sysctl ajustado e monitoramento agressivo.

Exemplo de instalação em Debian/Ubuntu:

apt update
apt install -y frr frr-pythontools iproute2 jq tcpdump
systemctl enable frr
systemctl start frr

Arquivo /etc/frr/daemons ativando apenas o necessário:

zebra=yes
bgpd=yes
dbgpd=no
ospfd=no
ospf6d=no
ripd=no
isisd=no
pimd=no
ldpd=no
staticd=yes

Configuração mínima de BGP em /etc/frr/frr.conf:

frr defaults traditional
hostname edge01
service integrated-vtysh-config
log syslog informational!
router bgp 64512
 bgp router-id 198.51.100.2
 no bgp default ipv4-unicast
 neighbor 192.0.2.1 remote-as 64513
 neighbor 192.0.2.1 description UPSTREAM-A
 neighbor 192.0.2.5 remote-as 64514
 neighbor 192.0.2.5 description UPSTREAM-B
 !
 address-family ipv4 unicast
 network 203.0.113.0/24
 neighbor 192.0.2.1 activate
 neighbor 192.0.2.5 activate
 neighbor 192.0.2.1 route-map RM-OUT-UPA out
 neighbor 192.0.2.5 route-map RM-OUT-UPB out
 exit-address-family
!
ip prefix-list PL-OUT seq 10 permit 203.0.113.0/24
route-map RM-OUT-UPA permit 10
 match ip address prefix-list PL-OUT
 set community 64512:100 additive
route-map RM-OUT-UPB permit 10
 match ip address prefix-list PL-OUT
 set community 64512:200 additive

Esse trecho parece pequeno, mas já mostra o ponto central: política de anúncio. Não anuncie mais do que deveria. Não redistribua rota local sem filtro. Não deixe upstream ver rede privada. Parece banal; em incidente real, não é.

Vantagens reais do BGP puro:

  • Failover mais limpo entre links;
  • Controle fino de anúncio e preferência;
  • Escala melhor que scripts de rota estática;
  • Funciona bem com multihoming e crescimento gradual.

Desvantagens reais:

  • Exige disciplina de política e filtragem;
  • Convergência não é instantânea;
  • Sem monitoramento, você descobre problemas tarde;
  • Se o seu roteador Linux estiver mal ajustado, o kernel vira gargalo.

Eu não colocaria BGP puro em servidor sem separar funções. Um host que também roda banco, fila e aplicação não deveria anunciar rota pública diretamente. BGP em borda precisa de caixa dedicada ou VM dedicada com CPU e NIC previsíveis. E, se você precisar de performance séria, RSS, IRQ affinity e offload importam mais do que a maioria admite.

Alternativa B: PTT com upstream de fallback

Se o objetivo é reduzir latência e trânsito pago para destinos locais, o PTT entra como peça estratégica. Em redes brasileiras, isso muda o jogo para quem conversa muito com operadoras, ISPs, SaaS local e outros participantes do mesmo ponto de troca. Não é sobre glamour. É sobre caminho mais curto e tráfego melhor distribuído.

Em operação, o desenho costuma ficar assim: o tráfego para redes presentes no PTT sai pelo peering no IX, enquanto destinos fora do ecossistema seguem para o upstream. Aqui você não quer inventar moda dentro do Linux. Quer tabelas de roteamento coerentes, BGP bem filtrado e um plano de contingência claro para o caso de o IX ficar indisponível ou o switch fabric apresentar instabilidade.

Em alguns IXs brasileiros, o acesso físico ao datacenter exige rotina chata, e isso é bom sinal. Na prática, operar no PTT-SP em São Paulo costuma significar visita a data center e cross-connect sob controle rigoroso; a dinâmica física importa porque o ponto de troca não é um conceito abstrato. Quem já subiu porta em colocation na região da Barra Funda ou da Vila Olímpia sabe que janela de manutenção e logística de acesso impactam a operação tanto quanto um prefix-list mal escrito. A moral é simples: tratar PTT como “apenas mais um link” dá errado.

Um peer BGP em PTT geralmente precisa de filtros mais rígidos do que o upstream. Você quer aceitar apenas rotas válidas, com prefix-length coerente, e anunciar somente o que pertence ao seu AS ou aos seus clientes. Exemplo de route-map de entrada:

ip prefix-list PL-IN-PTT seq 10 permit 177.0.0.0/8 ge 24 le 24
ip prefix-list PL-IN-PTT seq 20 permit 179.0.0.0/8 ge 24 le 24
!
route-map RM-IN-PTT permit 10
 match ip address prefix-list PL-IN-PTT
 set local-preference 200
!
route-map RM-IN-PTT deny 100

O detalhe que pega muita gente é o local-preference. Ele define preferência interna. Se o PTT tem prioridade para destinos locais, você sobe o valor das rotas aprendidas ali. O upstream vira fallback com local-pref menor. Isso é mais limpo do que “brigar” com MED sem entender o comportamento dos vizinhos.

Se você opera com Linux no edge, monitore a tabela com:

vtysh -c 'show ip bgp summary'
vtysh -c 'show ip bgp'
ip route show table main
ip route get 8.8.8.8
watch -n 2 'ip -s link show dev eth1'

Vantagens reais do PTT com fallback:

  • Melhor latência para tráfego local;
  • Redução de custos de trânsito em rotas populares;
  • Arquitetura mais resiliente quando o upstream falha;
  • Política de roteamento controlada por comunidades e local-pref.

Desvantagens reais:

  • Dependência operacional do ecossistema do IX;
  • Mais peers, mais state, mais chance de erro de filtro;
  • Exige observabilidade decente para detectar flap e assimetria;
  • Peering mal configurado pode criar blackhole parcial muito rápido.

Eu gosto de PTT quando a empresa tem tráfego regional relevante. Não gosto quando alguém tenta usá-lo como desculpa para evitar engenharia de borda. IX melhora o caminho. Não substitui governança de rotas. Redes Linux com BGP, PTT e IPTables ficam mais robustas quando o PTT é usado como política de trânsito, não como gambiarra para esconder uma borda mal desenhada.

Alternativa C: IPTables em par ativo-passivo com VRRP

Agora entra a parte que muita gente ainda chama de “firewall”, mas que na prática é mais que isso: estado de conexão, NAT, inspeção e continuidade de sessão. Se você tem dois nós Linux na borda e quer failover sem reinventar a aplicação, um par ativo-passivo com VRRP e IPTables continua sendo uma solução objetiva. Não é a mais moderna para tudo. É a mais previsível para muita coisa.

Eu prefiro keepalived para VRRP. É estável, conhecido, automatizável e conversa bem com health checks. Em vez de depender de algo obscuro, você define um IP virtual flutuante, monitora link, gateway e serviço, e promove o nó saudável. Em host Linux, isso funciona muito bem para borda de NAT, VPN site-to-site, serviços expostos e até front de APIs internas.

Exemplo de /etc/keepalived/keepalived.conf:

vrrp_script chk_gateway {
 script "/usr/local/bin/check-gw.sh"
 interval 2
 weight -20
 fall 2
 rise 2
}

vrrp_instance VI_1 {
 state BACKUP
 interface eth0
 virtual_router_id 51
 priority 100
 advert_int 1
 authentication {
 auth_type PASS
 auth_pass S3nh4VRRP
 }
 virtual_ipaddress {
 203.0.113.10/24 dev eth0
 }
 track_script {
 chk_gateway
 }
}

Script de health check simples:

#!/usr/bin/env bash
set -euo pipefail
ping -c 2 -W 1 192.0.2.254 >/dev/null

Permissões:

chmod +x /usr/local/bin/check-gw.sh

Agora, a parte que eu considero inegociável: sincronização de estado. IPTables puro não sincroniza estado sozinho. Se você quer continuidade de conexões, precisa de conntrackd ou aceitar que as sessões vão cair no failover. Em serviços públicos sensíveis, cair uma sessão é aceitável? Às vezes sim. Em VPN corporativa ou acesso administrativo, não. Então use conntrack sincronizado.

Exemplo conceitual de conntrackd com sync via multicast ou unicast entre os nós:

Sync {
 Mode FTFW {
 DisableExternalCache Off
 }
 UDP {
 IPv4_address 192.0.2.11
 IPv4_Destination_Address 192.0.2.12
 Port 3780
 Interface eth1
 }
}

General {
 HashSize 65536
 HashLimit 262144
 Syslog on
 LockFile /var/lock/conntrackd.lock
 UNIX {
 Path /var/run/conntrackd.ctl
 }
}

Regras básicas com IPTables para um edge stateful:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 198.51.100.0/24 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth2 -o eth3 -j ACCEPT

Se você faz NAT, a dupla MASQUERADE/SNAT precisa ser pensada. Em borda fixa com IP público estável, eu prefiro SNAT porque é mais previsível e menos custoso que MASQUERADE. O MASQUERADE só faz sentido quando o IP muda com frequência. Em HA com VRRP, o IP virtual existe justamente para evitar isso.

Vantagens reais do par ativo-passivo com IPTables:

  • Comportamento previsível para NAT e firewall stateful;
  • Implementação conhecida por qualquer time Linux;
  • Failover rápido com VRRP;
  • Integra bem com monitoramento simples e automação declarativa.

Desvantagens reais:

  • Sem sync de estado, sessões caem no failover;
  • Não resolve roteamento externo sozinho;
  • Escala pior que policy routing mais elaborado;
  • IPTables legado exige cuidado se o ambiente migrou parte da lógica para nftables.

Quando BGP domina e quando ele só adiciona complexidade

Eu tenho uma opinião forte aqui: se você tem apenas um upstream, BGP muitas vezes é mais cerimônia do que utilidade. O kernel Linux já sabe apontar default route. Se o objetivo é só “ter redundância”, um segundo link com saúde checada e failover local pode resolver sem abrir sessão BGP com o mundo. O protocolo brilha quando você controla múltiplas rotas, múltiplos vizinhos e precisa influenciar o caminho. Fora disso, ele vira dívida operacional.

Em ambiente com ASN próprio, dois links e presença em PTT, BGP manda. Você consegue influenciar saída e entrada, anunciar prefixos só quando a borda está saudável e até remover anúncio com automação de infraestrutura. Um exemplo de integração com sistema de controle via API interna:

{
 "bgp": {
 "advertise_prefix": "203.0.113.0/24",
 "origin_as": 64512,
 "communities": ["64512:100", "64512:900"],
 "withdraw_on_fail": true
 }
}

Esse JSON poderia alimentar um controller simples que escreve a configuração do FRR e aplica vtysh com commit controlado. O ponto não é o formato. É o fluxo: estado da infraestrutura gera política de anúncio. Não o contrário.

O que eu automatizaria sem piedade: FRR, keepalived e firewall como código

Configuração manual de borda funciona até o dia em que o segundo nó precisa ser igual ao primeiro, só que sem erro humano. A resposta prática é tratar tudo como código. Eu gosto de Ansible para esse cenário porque ele encaixa bem em Linux infra tradicional e não força abstração desnecessária.

Trecho de playbook para instalar FRR e keepalived:

- hosts: edge
 become: true
 tasks:
 - name: Instala pacotes
 apt:
 name:
 - frr
 - keepalived
 - conntrackd
 - iptables
 - jq
 state: present
 update_cache: yes

 - name: Habilita serviços
 systemd:
 name: "{{ item }}"
 enabled: yes
 state: started
 loop:
 - frr
 - keepalived

Para regras de firewall, eu prefiro declarar a política em arquivos versionados e gerar o conjunto final em CI. Se o ambiente ainda usa iptables-restore, um arquivo persistente como este já resolve muito:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp --dport 22 -s 198.51.100.0/24 -j ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.10
COMMIT

Aplicação:

iptables-restore < /etc/iptables/rules.v4

Se você já está migrado para nftables, melhor ainda. Mas não force a migração só por estética. Use o que o time domina, desde que você tenha testes automatizados de sintaxe e um pipeline que valide a topologia antes do deploy. Um erro de regra de firewall em edge não é “incidente pequeno”. É corte de tráfego.

Três desenhos, três perfis de operação

Se eu tivesse que decidir com base no tipo de leitor, eu colocaria assim:

  • BGP puro: para quem opera ASN, múltiplos links e precisa controlar anúncio e preferência com precisão.
  • PTT + upstream: para quem quer reduzir latência regional e monetizar melhor o trânsito, sem perder fallback simples.
  • IPTables com VRRP: para quem quer continuidade de borda stateful, NAT e filtragem com failover previsível.

Mas a escolha madura não é “qual é o melhor”. É “qual parte do problema cada camada resolve”. BGP decide caminho. PTT melhora peering. IPTables controla tráfego e estado. Quando você encaixa isso direito, a borda Linux deixa de ser um amontoado de scripts e vira um sistema operável.

Eu gosto de testar essa pilha com quedas controladas: derrubar interface, matar processo do FRR, simular perda de peer, desligar o keepalived do master e observar convergência. Não em produção às cegas. Em janela controlada, com tcpdump aberto, logs no journald e olho na tabela de rotas. O comportamento real aparece ali, não no diagrama bonito.

Roteiro de validação antes de encostar na produção

Não há glamour em checklist. Há sobrevivência. Eu validaria assim:

# vizinhança BGP
vtysh -c 'show bgp ipv4 summary'

# rotas efetivas
ip route show
ip rule show

# saúde do VRRP
journalctl -u keepalived -f

# estado de conntrack
conntrack -L | head

# contadores do firewall
iptables -L -n -v

# captura de pacotes no enlace do peer
tcpdump -ni eth1 host 192.0.2.1 and port 179

Se o PTT participa da borda, eu também olho comunidades recebidas e anúncios enviados. Não confio em “está up” se não vi a tabela de fato. Sessão BGP estabelecida não significa rota útil. E rota útil não significa caminho simétrico. Essa diferença derruba aplicação, especialmente TLS com múltiplas conexões curtas ou qualquer coisa sensível a timeout.

Para equipes que preferem integração com CI, uma abordagem simples é validar sintaxe de configs antes do deploy. Exemplo de pipeline GitLab CI para FRR e firewall:

stages:
 - lint

lint_frr:
 stage: lint
 image: debian:12
 script:
 - apt-get update
 - apt-get install -y frr jq
 - vtysh -f frr.conf --test || true

lint_iptables:
 stage: lint
 image: debian:12
 script:
 - apt-get update
 - apt-get install -y iptables
 - iptables-restore --test < rules.v4

Esse tipo de validação pega erro bobo antes de virar indisponibilidade. E erro bobo em rede não perdoa.

Qual alternativa eu escolho em cada cenário

Se o seu ambiente é pequeno, com um único datacenter e link único, eu não colocaria BGP no centro da conversa. Eu escolheria IPTables com VRRP para continuidade local e deixaria a borda o mais simples possível. Menos peças. Menos falhas.

Se você tem presença em PTT, AS próprio e tráfego significativo dentro do Brasil, eu faria o oposto: BGP + PTT vira a espinha dorsal, e IPTables fica como camada de segurança e NAT. Essa combinação é a que mais vejo fazer sentido em operação séria.

Se o seu problema é serviço exposto com múltiplos caminhos, distribuição geográfica e política de anúncio refinada, BGP manda sem discussão. E se o seu problema é firewall stateful com troca rápida de nó, VRRP + conntrack continua sendo um desenho muito digno. Não é antigo. É operacional.

O detalhe que separa arquitetura boa de arquitetura frágil é simples: cada componente precisa ter um motivo claro para existir. Se você usa BGP porque “todo mundo usa”, você vai pagar com complexidade desnecessária. Se usa PTT sem filtros, você vai comprar problema. Se usa IPTables sem pensar em estado, o failover vira mentira.

Na prática, a borda Linux mais confiável que eu já vi não era a mais sofisticada. Era a mais disciplinada. FRR com política explícita. PTT com filtragem e preferência bem definidas. IPTables com regras curtas, auditáveis, persistidas como código. E testes de queda feitos antes do incidente, não depois.

Se esse conjunto cair numa madrugada qualquer, o que você quer enxergar primeiro é previsibilidade, não surpresa. E a previsibilidade vem exatamente dessa combinação: BGP para caminho, PTT para proximidade, IPTables para controle de sessão. É isso que sustenta Redes Linux com BGP, PTT e IPTables quando a operação para de ser teoria e começa a cobrar tempo real.