Os load balancers que a gente conhece são destinos. O cliente resolve um nome no DNS, recebe um IP, abre uma conexão com o load balancer, e o load balancer abre outra conexão com algum servidor atrás dele. Ele é o fim de uma conexão e o começo de outra.
O Gateway Load Balancer não é nada disso. Nenhuma aplicação aponta para ele. Ele não aparece em DNS nenhum. Você nunca abre uma conexão com ele. Ele é um desvio no caminho, declarado numa tabela de rotas, e o tráfego que passa por ele sequer fica sabendo que passou.
Ele existe para resolver um problema bem específico: colocar um firewall de terceiros no meio do caminho do seu tráfego, sem que esse firewall vire um ponto único de falha e sem mentir sobre quem é a origem e o destino de cada pacote.
Se a mecânica geral de load balancer ainda não está fresca, ela está em Load balancer: o que é e como a lógica dele funciona por dentro. Este post assume aquele.
Antes de tudo: o que é um appliance virtual
Não dá para entender o GWLB sem entender o que ele carrega nas costas.
Por trinta anos, firewall foi uma caixa física. Você comprava um Palo Alto, um FortiGate, um Check Point, parafusava no rack e passava cabos de rede por ele. Todo o tráfego atravessava aquela caixa, e ela bloqueava o que não devia passar. O nome genérico dessa categoria é middlebox: um equipamento que fica no meio do caminho fazendo alguma coisa com os pacotes que passam.
Na nuvem não existe rack. Não há onde plugar cabo.
Então os fabricantes fizeram o óbvio: pegaram o mesmo sistema operacional que rodava dentro da caixa e empacotaram como uma imagem de máquina virtual.
| Caixa física | Appliance virtual |
|---|---|
| Palo Alto PA-series | VM-Series (AMI) |
| FortiGate | FortiGate-VM |
| Check Point | CloudGuard Network |
| F5 BIG-IP | BIG-IP VE |
Isso é um appliance virtual: uma caixa de segurança física, transformada numa instância EC2.
E repare que é um produto pronto, não software que você instala. Você não sobe um Ubuntu vazio e configura um firewall nele. Você sobe a AMI do fabricante e ela inicia já sendo um firewall, com o console próprio dele, a mesma sintaxe de regras da caixa física, e normalmente sem nem te dar um shell de propósito geral. Atualizar é trocar a imagem, não rodar apt upgrade.
O que isso resolve, e por que empresas grandes insistem nesse caminho em vez de usar só o que a AWS oferece:
- Profundidade. Security group é filtro de camada 4 com estado. AWS Network Firewall roda regras Suricata. Nenhum dos dois faz identificação de milhares de aplicações, decriptação de TLS com a CA da empresa, sandbox de arquivo ou DLP. Se o requisito de segurança cita uma capacidade que só o fabricante tem, o appliance é como ela entra na AWS.
- Continuidade, que é o motivo real na maioria dos casos. Um banco tem quinze anos de regras escritas naquele fabricante, um time certificado nele, um processo de auditoria construído em cima dos logs dele e um documento de conformidade que cita o produto pelo nome. Reescrever tudo isso em termos nativos da AWS é um projeto de anos com risco real. Rodar o mesmo firewall que já se conhece, agora como EC2, custa infinitamente menos atrito.
E o que isso custa. Aqui está a parte que importa para o resto do post: um appliance virtual é uma instância EC2. Tudo o que era bom na caixa física, o hardware dedicado, a redundância de fábrica, o fato de ela ficar inerte no rack, sumiu. O que sobrou é uma VM que pode morrer, que tem teto de throughput ditado pelo tipo de instância, e que, no momento em que você a coloca no caminho do tráfego, vira um gargalo do qual tudo depende.
O problema: como se insere isso no caminho
Antes do GWLB, em 2020, existiam duas saídas, e as duas eram ruins.
Rota apontando para uma ENI. A tabela de rotas diz 0.0.0.0/0 -> eni-abc123. Funciona, e é uma instância só. Não escala, e se ela morrer o tráfego cai num buraco negro até alguma Lambda reescrever a tabela de rotas. Failover medido em dezenas de segundos. O motivo dessa fragilidade é o mesmo discutido em ENI: uma ENI é um objeto preso a uma AZ e a uma instância por vez.
Fazer o appliance atuar como proxy ou NAT. Ele termina a conexão e abre outra. Funciona, mas agora todo pacote que o appliance e o destino enxergam tem o IP de origem errado. Suas regras de segurança, seus logs e a lógica de IP do cliente na aplicação passam todos a mentir. E IP de origem é exatamente o insumo do qual uma política de firewall depende.
O GWLB é a terceira saída: escala horizontal, com health check, e transparente. O appliance vê o IP real do cliente e o IP real do destino. O destino vê o IP real do cliente. Como se não houvesse nada no caminho.
A lógica: por que encapsular é obrigatório
Essa é a parte que vale internalizar, porque todo o resto decorre dela.
Um pacote que chega no GWLB é endereçado a outra pessoa. O cliente 10.0.1.5 está falando com 54.x.x.x. O IP do appliance não aparece em lugar nenhum desse pacote.
Então o GWLB tem uma contradição para resolver: precisa entregar o pacote a um appliance sem alterar o pacote, porque alterar o pacote destrói justamente a razão de ele existir.
A única saída é um túnel. O GWLB embrulha o pacote original, intacto, dentro de um pacote novo endereçado ao appliance:
externo: srcIP=GWLB dstIP=appliance UDP dport=6081
├── cabeçalho GENEVE (VNI + opções TLV)
└── pacote original: srcIP=10.0.1.5 dstIP=54.x.x.x TCP 443 ...O protocolo é o GENEVE (RFC 8926), sobre UDP na porta 6081. Duas propriedades fizeram dele a escolha certa:
- Ele é agnóstico ao conteúdo. O GWLB não precisa de um listener por porta como o ALB e o NLB. TCP, UDP, ICMP, ESP, qualquer coisa sobre IP é encapsulada do mesmo jeito. É por isso que a configuração de listener do GWLB é essencialmente inexistente.
- Ele tem opções TLV extensíveis. A AWS enfia metadado ali dentro: o ID do endpoint, o ID do attachment e um cookie de fluxo. É assim que o appliance consegue distinguir tráfego vindo de VPCs diferentes e aplicar política diferente para cada um, sem que nada disso apareça no pacote do cliente.
O preço do embrulho é 68 bytes de overhead, e isso vira problema operacional de verdade mais adiante.
As duas peças
O GWLB é composto de dois objetos que vivem em lugares diferentes:
- O GWLB propriamente dito, na VPC de segurança, junto com os appliances no target group.
- O GWLB Endpoint (GWLBe), na VPC consumidora, que é o objeto que você coloca na tabela de rotas.
Os dois são ligados por um VPC Endpoint Service, a mesma máquina do PrivateLink usada com NLB. Essa escolha não é detalhe de implementação, é o que define o modelo de propriedade: o time de segurança é dono da VPC de appliances e publica um serviço; os times de aplicação apenas criam um endpoint e adicionam uma linha na tabela de rotas. Nenhum dos dois lados precisa acesso à conta do outro.
O caminho de um pacote
VPC consumidora │ VPC de segurança
│
cliente 10.0.1.5 │
│ │
│ tabela de rotas: 0.0.0.0/0 -> vpce-gwlb
▼ │
┌────────┐ GENEVE / UDP 6081 │ ┌────────┐ ┌──────────────┐
│ GWLBe │ ════════════════════════════▶│ GWLB │───▶│ appliance A │
└────────┘ │ └────────┘ │ ├──────────────┤
▲ ▲ volta pelo mesmo túnel │ ▲ └─▶│ appliance B │
│ ╚════════════════════════════════════════════ └──────────────┘
▼ │ (desencapsula, inspeciona, reencapsula)
IGW / destino original │Passo a passo:
- Uma entrada de tabela de rotas manda o pacote para o GWLBe em vez do próximo salto natural. Pode ser a tabela de rotas da subnet, a edge association do Internet Gateway ou a do Virtual Private Gateway.
- O GWLBe encaminha para o GWLB pela conexão de PrivateLink.
- O GWLB escolhe um alvo por hash de fluxo e encapsula o pacote original em GENEVE.
- O appliance recebe na UDP 6081, desencapsula, inspeciona o pacote real e aplica a política.
- Se permitiu, ele reencapsula e devolve pelo mesmo túnel. Se negou, simplesmente descarta, e não há nada para devolver.
- O GWLB desencapsula e entrega o pacote de volta ao GWLBe, que o solta para continuar em direção ao destino original.
O passo 5 é onde o GWLB se separa de todos os outros load balancers. O alvo aqui não gera uma resposta. Ele devolve o mesmo pacote que recebeu. O appliance é um passa-tudo, e isso precisa ter sido construído de propósito: ele tem que falar GENEVE e tem que devolver pelo túnel. É por isso que se usa AMI de fabricante e não qualquer EC2.
E é por isso também que o modelo mental correto é desvio, não encaminhamento. Depois da inspeção, o pacote volta para o mesmo endpoint de onde saiu e retoma a rota em que já estava. O GWLB não entrega nada às suas instâncias de aplicação. Ele não sabe que elas existem. Quem entrega é o ALB, ou a tabela de rotas, ou o Internet Gateway, e nada disso passa pelo GWLB.
ALB e NLB respondem "qual dos meus servidores atende essa requisição?". GWLB responde "qual dos meus inspetores olha esse pacote antes dele seguir para onde já ia?".
Aderência de fluxo, o que faz tudo funcionar ou quebrar
Um firewall com estado é inútil se o SYN cai no appliance A e o ACK cai no appliance B. O segundo enxerga um ACK de uma conexão que ele nunca viu nascer, e descarta. Então o GWLB gruda cada fluxo num alvo:
| Modo | Hash sobre | Quando |
|---|---|---|
| 5-tuple (padrão) | IP origem, IP destino, porta origem, porta destino, protocolo | TCP e UDP. Obrigatório com appliance mode no TGW. |
| 3-tuple | IP origem, IP destino, protocolo | Tráfego que não é TCP nem UDP, ou configurado explicitamente |
| 2-tuple | IP origem, IP destino | Configurado explicitamente, aderência mais grossa |
É o mesmo hash de camada 4 que sustenta o NLB. A diferença é que o GWLB garante também que as duas direções do fluxo caiam no mesmo appliance, e é essa garantia que permite ao firewall manter estado.
Roteamento assimétrico e o appliance mode
O GWLB só consegue garantir simetria dentro do escopo dele. Quando entra Transit Gateway na história, o TGW escolhe a AZ de cada direção de forma independente, e você ganha o clássico:
ida: VPC A ─▶ TGW ─▶ inspeção AZ-a ─▶ VPC B (firewall a vê o SYN)
volta: VPC B ─▶ TGW ─▶ inspeção AZ-b ─▶ VPC A (firewall b vê o ACK e descarta)A correção é ligar o appliance mode no attachment do TGW. Com ele ativo, o TGW calcula o hash do fluxo uma vez e mantém as duas direções na mesma ENI da VPC de inspeção pelo tempo de vida do fluxo. Sem appliance mode, a alternativa histórica era fazer SNAT no appliance para forçar o retorno, o que reintroduz exatamente a mentira de IP de origem que o GWLB tinha eliminado.
Ligue o appliance mode. É de longe a causa mais comum de incidente com GWLB.
Ligado a isso: o GWLBe é um objeto zonal, e cross-zone load balancing vem desligado por padrão. Mais barato e com menos latência, porque o tráfego não atravessa AZ, mas significa que os appliances de uma AZ só atendem o endpoint daquela AZ. Crie um GWLBe por AZ.
Os padrões que você vai encontrar
1. Inspeção distribuída. Um GWLBe em cada VPC, appliances centralizados. Na entrada, a edge association do IGW manda o tráfego para o GWLBe antes dele chegar no ALB. Na saída, a tabela de rotas da subnet manda 0.0.0.0/0 para o GWLBe antes do NAT Gateway. Não precisa de Transit Gateway, tem a menor latência, e custa mais endpoints.
2. Inspeção centralizada com Transit Gateway. Uma VPC de inspeção com o GWLB e o auto scaling group de appliances. As tabelas de rotas do TGW forçam o tráfego entre VPCs e para on-premises a passar por ela. É a arquitetura de referência do whitepaper de multi-VPC da AWS e onde empresas grandes acabam parando. Exige appliance mode.
3. Saída centralizada. A VPC de inspeção tem o GWLB e o NAT Gateway. Todo tráfego de saída de todas as contas é inspecionado e sai por um conjunto único e auditado de IPs. Popular em setor regulado, porque "toda saída passa por um firewall e sai por estes IPs" é um controle que se demonstra para auditoria em uma frase.
4. Uso que não é segurança. O GWLB é uma primitiva genérica de "desviar pacotes para uma frota". Também se usa para captura de pacotes e analytics de rede, IDS com Suricata ou Zeek, e appliances próprios escritos em casa, desde que falem GENEVE.
As pegadinhas
- MTU. O GENEVE soma 68 bytes. Atravessando um IGW o teto é 1500, então um pacote interno de 1500 fragmenta ou é descartado. Pelo TGW o teto é 8500. Na prática isso aparece como "requisição pequena funciona, upload grande trava", que é o sintoma clássico de PMTUD quebrado.
- O health check não prova o caminho de dados. O GWLB sonda o appliance por HTTP, HTTPS ou TCP numa porta própria, não pelo túnel GENEVE. Um alvo saudável não significa que a inspeção está funcionando.
- Custo em camadas. Hora de GWLB, mais GLCU (Gateway Load Balancer Capacity Units), mais hora de GWLBe por endpoint e por AZ, mais processamento de dados dos dois lados. Arquiteturas distribuídas multiplicam endpoints rápido.
- Depurar fica mais difícil. O desvio é transparente, então um pacote descartado parece falha silenciosa de rede para o time de aplicação. O log do appliance vira a fonte da verdade, e ele fica em outra conta e em outro console.
- Dois planos de controle. AWS de um lado, console do fabricante do outro. Isso é custo operacional permanente, não custo de setup.
Onde ele se encaixa na família
| ALB | NLB | GWLB | |
|---|---|---|---|
| Camada | 7 | 4 | 3 + 4 |
| Como o tráfego chega | DNS | DNS | Tabela de rotas |
| É um destino? | Sim | Sim | Não, é um desvio |
| O que balanceia | Requisições | Conexões | Fluxos de pacotes |
| Tipo de alvo | Servidores da aplicação | Servidores da aplicação | Appliances de inspeção |
| Preserva IP de origem | No X-Forwarded-For |
Sim | Sim, integralmente |
| Configura listener por porta | Sim | Sim | Não, aceita todo IP |
O modelo mental
O GWLB é um desvio no roteamento com balanceamento embutido. Ele existe porque inspecionar tráfego exige duas coisas que são contraditórias entre si: o pacote precisa chegar num appliance cujo IP não está no pacote, e o pacote não pode ser alterado. Encapsular é a única forma de satisfazer as duas ao mesmo tempo, e todo o resto do produto, o GENEVE, o hairpin, a aderência de 5-tuple, o appliance mode, é consequência direta dessa escolha.
Dito de outro jeito, dividindo responsabilidade:
appliance virtual = a função (firewall, IDS, DPI)
GWLB = como colocar N deles no caminho, com segurançaOs fabricantes resolveram "como eu rodo meu firewall na nuvem". Faltava resolver "como eu coloco dez deles no caminho, escalo, monitoro saúde e faço failover em segundos, sem NAT e sem perder os IPs originais". Essa metade era a que faltava.
Vale notar que a Azure lançou o próprio Gateway Load Balancer com desenho praticamente idêntico, trocando GENEVE por VXLAN e a tabela de rotas por encadeamento a um frontend IP. Quando duas nuvens chegam independentemente na mesma primitiva, é sinal forte de que a abstração está certa.
Como isso se conecta com o resto
Este post fecha um arco. Em Load balancer a pergunta era "para qual servidor mando essa requisição". Aqui a pergunta mudou de natureza: não é mais sobre entregar, é sobre interceptar antes de entregar, e por isso o objeto deixou de ser um destino e virou uma entrada de rota.
A tabela de rotas que faz o desvio é a mesma discutida em CIDR e subnets na VPC, e a razão de o failover por ENI não bastar, que é o buraco original que o GWLB preenche, está em ENI. A separação entre o que o GWLB enxerga (IP e porta) e o que ele não enxerga (o conteúdo) é a mesma divisão de camadas de Modelo OSI e TCP/IP, com um detalhe curioso: o GWLB não enxerga o conteúdo, mas entrega o conteúdo inteiro para quem enxerga.
Referências
- AWS. What is a Gateway Load Balancer?. Documentação oficial, com o detalhamento de GENEVE, aderência de fluxo e health checks.
- AWS. Introducing AWS Gateway Load Balancer. O anúncio de lançamento, útil por explicar o problema que motivou o produto.
- AWS. Centralized inspection architecture with GWLB and Transit Gateway. O padrão de inspeção centralizada em detalhe, incluindo appliance mode.
- AWS. Using GWLB with Transit Gateway for centralized network security. Capítulo do whitepaper de infraestrutura multi-VPC.
- AWS. VPC Routing Enhancements and GWLB Deployment Patterns. Os padrões de inserção via tabela de rotas, incluindo edge association.
- IETF. RFC 8926: Geneve, Generic Network Virtualization Encapsulation. A especificação do protocolo de encapsulamento.
- AWS. Access virtual appliances through AWS PrivateLink. Como o endpoint service liga a VPC consumidora à VPC de segurança.