Temos vários servidores de back-end na forma de instâncias do EC2 com base em uma sub-rede privada na AWS VPC que precisam se comunicar com uma API de terceiros. Essa API está limitando as solicitações que podemos enviar com base no endereço IP de origem e, ao dimensionar nossa configuração, começamos a atingir os limites do IP do gateway NAT usado para todo o tráfego de saída.
Assim, quero configurar um proxy para tráfego de saída com vários EIPs anexados. Para testar, estou usando atualmente uma instância do Amazon Linux 2 com 2 ENIs com 2 EIPs anexados cada. Os servidores de back-end abrem um túnel SSH para o proxy de saída e mapeiam a API de terceiros para uma porta local, uma entrada no arquivo hosts dos servidores redireciona todo o tráfego para esse nome de host para localhost e essa configuração está funcionando bem em geral, mas o tráfego de saída do proxy está sempre usando apenas o primeiro EIP associado.
Então minha configuração fica assim:
ENI1: eth0
private IP1: 10.0.11.81
private IP2: 10.0.11.82
ENI2: eth1
private IP3: 10.0.11.52
private IP4: 10.0.11.53
original route table:
default via 10.0.11.1 dev eth0
default via 10.0.11.1 dev eth1 metric 10001
10.0.11.0/24 dev eth0 proto kernel scope link src 10.0.11.81
10.0.11.0/24 dev eth1 proto kernel scope link src 10.0.11.52
169.254.169.254 dev eth0
Agora quero poder especificar qual servidor de back-end usa qual EIP ao chamar a API por meio do proxy de saída. Minha primeira tentativa foi a seguinte:
- configurar 4 usuários diferentes no host proxy
- adicione regras iptable para cada usuário assim:
iptables -t nat -m owner --uid-owner user1 -A POSTROUTING -j SNAT --to IP1
etc. - isso funciona para os 2 IPs que estão conectados ao ENI primário (ou seja, eth0 na máquina), mas não funciona para os 2 IPs associados ao segundo ENI (eth1)
- adicionar
-o eth1
à declaração também não funcionou
Minha próxima tentativa foi criar tabelas de roteamento personalizadas para cada endereço IP e combiná-las com as regras de política:
- crie uma tabela de rotas personalizada, ou seja, para IP3:
default via 10.0.11.1 dev eth1
10.0.11.0/24 dev eth1 proto static scope link src 10.0.11.52
169.254.169.254 dev eth1 scope link
- crie a regra iptables para marcar o tráfego originário do user3:
-A OUTPUT -m owner --uid-owner 1003 -j MARK --set-xmark 0x3/0xffffffff
- crie regra para utilizar a tabela de rotas personalizada para todos os pacotes marcados com 3:
32763: from all fwmark 0x3 lookup ip3
- isso novamente não funciona. pacotes são tratados de forma diferente. todos os usuários podem se comunicar com o mundo, exceto user3 no exemplo acima.
O que estou fazendo errado? Há algo trivial que estou perdendo ou toda a minha abordagem está fadada ao fracasso? Estou muito aberto a sugestões, tanto para fazer essa configuração funcionar quanto para abordagens alternativas ...
Muito obrigado antecipadamente!
Entre em contato com a organização que executa a API e explique a situação. Criar um relacionamento comercial é um bom começo para resolver o problema.
Implemente o IPv6 para reduzir a complexidade técnica. A AWS fornecerá um /64 por sub-rede de espaço público, permitindo a comunicação direta entre suas instâncias e a API. O endereço exclusivo por instância torna aparente que você realmente está expandindo. Solicitar que suas redes tenham uma cota maior se torna mais fácil, pois todas estão no /56 de sua VPC.
Afinal, eu mesmo encontrei uma solução e a documentei aqui: Melhor maneira de rotear o tráfego com base no usuário conectado por meio de uma rota redundante específica?
Apenas no caso de alguém tropeçar nisso no futuro.