Manter o endereço do cliente VPN até a aplicação faz com que cada linha de registro e cada entrada da lista de permissões signifiquem a mesma coisa. Reescrevê-lo na borda da nuvem torna a tabela de rotas mais simples e os registros menos úteis. Nenhuma das escolhas está errada por si só, e o argumento que a decide raramente é sobre desempenho. Três condições a resolvem: se a aplicação precisa saber qual pessoa se conectou, se a malha da nuvem aceitará a origem que você pretende enviar e quem aceitará assumir a rota de retorno depois.

Três condições a decidem

Comece pelo requisito da aplicação, não pelo diagrama de rede. Se a autorização ou a auditoria dependem do endereço individual do cliente, preservá-lo é um requisito funcional e traduzi-lo é uma regressão. Se a aplicação só precisa saber que o tráfego chegou pelo caminho de acesso remoto, um endereço traduzido é suficiente e muito mais barato de operar.

A segunda condição é mecânica. Uma rede virtual não confia automaticamente num pacote que afirma um endereço que não foi atribuído à interface emissora. A maioria das malhas de nuvem impõe isso, de formas e com nomes diferentes, e um projeto que o ignora parecerá correto no diagrama e descartará em silêncio em produção.

A terceira é organizacional. Preservar as origens significa que a tabela de rotas da sub-rede da aplicação precisa apontar de volta para o gateway para o prefixo do cliente, e cada equipe que adicionar uma sub-rede depois precisa manter essa rota consistente. É um custo pequeno uma vez e recorrente em dezenas de contas. Decida quem o paga antes de prometer o comportamento.

Uma rota não é permissão para falsificar

Adicionar uma rota de retorno diz à sua sub-rede para onde as respostas devem ir. Não diz à malha que a instância que encaminha esses pacotes tem permissão para emiti-los com uma origem estrangeira. Na AWS o controle relevante é a verificação de origem e destino, e ela é visível por instância:

aws ec2 describe-instances --instance-ids i-0a1b2c3d4e5f60718 \
  --query "Reservations[].Instances[].SourceDestCheck"
aws ec2 modify-instance-attribute --instance-id i-0a1b2c3d4e5f60718 \
  --no-source-dest-check

Desative-a apenas para a instância cujo trabalho documentado é o encaminhamento, e para nada mais. Cada VM de aplicação que mantém a verificação ativa é uma máquina menos que pode ser usada para emitir tráfego com uma origem emprestada. Se a sua plataforma não for AWS, procure a configuração equivalente de anti-falsificação ou de endereços permitidos em vez de supor que o comportamento se transfere.

Uma captura de pacotes rápida resolve a questão mais rápido do que ler o console. Se as respostas saem e o cliente nunca as vê, é a malha que descarta a origem falsificada, e não a aplicação que falha.

O que a tradução compra e quanto custa

Reescrever a origem no gateway elimina o problema do caminho de volta. A aplicação vê um endereço que já sabe como alcançar, e o prefixo do cliente nunca precisa aparecer numa tabela de rotas da nuvem. No Linux a regra é uma linha, e vale a pena escrever a versão mais estreita que você conseguir:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 172.20.8.0/24 -o ens5 -j SNAT --to-source 10.40.3.10

Observe o que a aplicação agora registra: 10.40.3.10 para cada usuário, em cada conexão, para sempre. Qualquer lista de endereços permitidos construída sobre esse valor agora concede acesso a toda a população de acesso remoto, e qualquer revisão de incidente precisa voltar ao gateway para responder quem era.

A solução não é abandonar a tradução, é parar de fingir que o endereço é uma identidade. Carregue a identidade do cliente num campo autenticado, registre-a no gateway junto com a tupla traduzida e deixe a aplicação juntar por ela. Sem a chave de junção, a tradução converte um problema de rede num problema forense permanente.

O relé é uma interface diferente

Um proxy reverso à frente da aplicação contorna por completo a questão do caminho roteado. O proxy abre a própria conexão de backend, então o prefixo do cliente nunca precisa ser roteável dentro da rede virtual, e a aplicação pode receber a identidade num cabeçalho que o proxy define.

Esse cabeçalho só é confiável quando o backend o aceita do proxy e de nada mais. Em termos de nginx isso significa nomear explicitamente o par confiável em vez de acreditar em qualquer coisa que chegue:

set_real_ip_from 10.40.3.10;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

Qualquer cliente que consiga alcançar o backend diretamente pode falsificar o mesmo cabeçalho, portanto o backend precisa ser inalcançável exceto pelo proxy. Isso é um fato de firewall, não uma opinião de configuração, e é a suposição que as pessoas pulam ao copiar o trecho.

O relé também muda o que você compra. Você ganha uma identidade em nível de aplicação e um lugar natural para registrá-la; abre mão da generalidade, porque cada novo protocolo precisa do seu próprio suporte de proxy. Para serviços HTTP essa troca costuma ser boa, e para qualquer coisa que não seja HTTP normalmente não está disponível de forma alguma.

Anote o que cada fronteira vê

Escolha o que escolher, a revisão de projeto deve terminar com uma tabela que nomeie o endereço de origem e a identidade demonstrável em cada salto. Sem ela, o primeiro incidente produz três equipes que descrevem cada uma um cliente diferente.

BoundarySource the next hop seesWhat is actually proven
Client to gateway172.20.8.14A certificate or credential was presented
Gateway to app subnet, preserved172.20.8.14The same session, if the return route exists
Gateway to app subnet, translated10.40.3.10Only that traffic came through the gateway
Proxy to backend10.40.3.10 plus a headerThe proxy asserted an identity it authenticated

Depois escolha. Preserve quando a autorização da aplicação depender de fato do endereço do cliente e você puder assumir a rota. Traduza quando não for o caso e você puder carregar a identidade fora de banda, e use as orientações da AWS para instâncias de encaminhamento para as configurações de encaminhamento específicas da plataforma. Recorra a um relé quando o serviço falar HTTP e você quiser que a identidade deixe de ser um endereço.

Artigos relacionados