Dois engenheiros com o mesmo gateway OpenBSD muitas vezes dão-lhe dois conjuntos de regras diferentes para alcançar uma rede remota, e ambos podem ser defendidos. A escolha entre tradução de origem e uma rota de retorno não é de todo uma questão de sintaxe. Tudo depende do que o lado remoto já sabe sobre 192.168.88.0/24 e do que precisa de guardar nos registos. Se errar nisto, a linha nat-to parecerá perfeitamente correta enquanto as respostas desaparecem no gateway predefinido remoto.

O encaminhamento e a reescrita respondem a perguntas diferentes

A tabela de encaminhamento decide que 172.20.0.0/16 é alcançável por tun0, e essa decisão acontece antes de qualquer tradução do pf ser consultada. A tradução de origem altera depois o cabeçalho do pacote para que o extremo remoto veja o endereço do túnel do gateway em vez de um anfitrião da LAN. Nenhum dos mecanismos substitui o outro: uma regra nat não pode fazer aparecer uma rota, e uma rota não pode convencer um router remoto que nunca ouviu falar da sua sub-rede privada. Quando o lado remoto não tem caminho de retorno, as respostas são descartadas ou encaminhadas para o seu gateway predefinido, e nenhum ajuste de regras resolve isso.

Dito de forma simples, o encaminhamento responde a para onde vai o tráfego e a tradução responde de onde ele parece vir. Mantenha ambos em caixas mentais separadas enquanto desenha o conjunto de regras.

Três condições que decidem

Faça três perguntas por ordem e o desenho escolhe-se quase sempre sozinho. A rede remota tem uma rota estática que aponta para o endereço do túnel para 192.168.88.0/24, ou o administrador dela controla os routers nesse caminho? Se sim, deixe os endereços da LAN viajar sem alterações e ignore a tradução por completo. Precisa de visibilidade por cliente do lado remoto, seja para política de acesso ou para uma pista de auditoria? Se sim, preservar a origem vale o trabalho de encaminhamento. O endereço do túnel é suficientemente estável para ser escrito numa rota remota, ou muda entre reconexões?

Se qualquer resposta for não ou desconhecida, nat-to é a opção pragmática, e é também a reversível. Uma regra de tradução sai numa única linha assim que o lado remoto acrescenta uma rota adequada. Uma rota de retorno que nunca foi instalada custa-lhe um tópico de suporte sempre que alguém pergunta porque é que o túnel só funciona num sentido.

Colocar o fragmento para que o pf o avalie de facto

O fragmento abaixo assume que a LAN é 192.168.88.0/24, a rede remota é 172.20.0.0/16 e a interface do túnel é tun0. Nada nele escolhe um próximo salto. Apenas reescreve a origem nos pacotes que já estão a sair pelo túnel.

match out on tun0 inet from 192.168.88.0/24 to 172.20.0.0/16 nat-to (tun0)
pass in on em0 inet from 192.168.88.0/24 to any keep state

Dois detalhes nessa primeira linha carregam a maior parte do peso. Os parênteses à volta de tun0 dizem ao pf para ler o endereço da interface sempre que constrói uma entrada de estado, o que importa quando o túnel é renumerado após uma reconexão. A palavra match significa que a regra reescreve e depois deixa cair, por isso uma regra pass separada ainda tem de admitir o fluxo. A interface nomeada na linha match também tem de ser a que a tabela de encaminhamento escolhe, senão o pf avalia a regra num caminho de saída diferente do que o pacote realmente toma.

Não se esqueça do lado do kernel. O encaminhamento IPv4 tem de estar ativo, e as regras pass com estado para túnel e LAN têm de existir antes de tudo isto fazer sentido. A secção PF NAT das FAQ do OpenBSD é a referência certa para a ordem das palavras-chave aqui.

Verifique o conjunto de regras antes de confiar no tráfego

Verifique primeiro a sintaxe com pfctl -nf /etc/pf.conf, que analisa o ficheiro sem o carregar. Depois carregue a política e releia o que o kernel tem realmente, porque uma regra analisada corretamente pode ainda ficar tapada ou ligada à interface errada. O pfctl -sn imprime as regras de tradução na sua forma carregada, e o pfctl -sr imprime as regras de filtro pela ordem de avaliação.

Depois observe o cabo. No gateway, tcpdump -ni tun0 'host 172.20.0.10' mostra se o endereço de origem que sai do túnel é o do túnel ou o do anfitrião da LAN. Um netstat -rn -f inet rápido confirma em que interface o destino se resolve. Assim que o tráfego flui, o pfctl -ss lista as entradas de estado; se um fluxo não produziu estado, o pacote nunca encontrou uma regra que o criasse.

Se o lado do túnel parecer correto e as respostas continuarem a não chegar, pare de editar o pf. A falha restante está no router remoto, onde a resposta é enviada para um endereço privado que esse lado não consegue alcançar.

Quando a tradução custa mais do que poupa

A tradução esconde clientes, e às vezes é exatamente a troca errada. Sub-redes sobrepostas são um caso: se o lado remoto também usa 192.168.88.0/24 internamente, apresentar os anfitriões da LAN como o gateway torna a colisão pior em vez de melhor. Políticas IPsec que selecionam tráfego por par de endereços são outro, porque a base de dados de política de segurança é comparada antes da tradução e nunca vê o pacote reescrito. Qualquer implementação que fatura, limita ou audita por utilizador também perde a identidade de que precisa no momento em que a origem colapsa num único endereço.

Os derivados portáteis do pf são uma armadilha à parte. Os produtos que geram os seus próprios ficheiros de regras esperam que o NAT seja configurado através da sua interface, e os fragmentos editados à mão são substituídos no recarregamento seguinte. Conjuntos de regras copiados de guias escritos antes de a palavra-chave match existir não carregam num kernel atual, por isso porte a sintaxe e leia o erro em vez de adivinhar.

A regra de decisão que sobrevive ao contacto com redes reais é curta: instale uma rota de retorno quando puder, traduza quando não puder, e anote qual das três condições o levou a essa escolha. Essa nota poupa uma tarde à pessoa seguinte.

Artigos relacionados