Sem tun0? Combine o IPsec descriptografado no nftables com meta ipsec
Um gateway baseado em políticas encaminha pacotes internos em texto claro que ainda chegam em eth0. Combine o caminho de segurança e o serviço, não uma interface ausente.
Você espera uma interface de túnel, procura por ela, e não há nada para combinar no firewall. Isso é normal para um gateway baseado em políticas: a troca criptografada chega na interface física, e o pacote interno descriptografado que depois é encaminhado também é observado chegando nessa mesma interface. Não há tun0 porque nada criou uma.
A requisição interna continua sendo um pacote distinto com sua própria origem, destino e serviço, e o kernel sabe de qual associação de segurança ele saiu. É esse conhecimento que uma regra de firewall pode combinar.
Dois pacotes, uma interface
Imagine a direção de entrada. Um pacote encapsulado em ESP ou UDP chega, o kernel encontra a política correspondente, descriptografa-o e entrega o pacote em texto claro ao caminho de encaminhamento. Uma regra que olha apenas o nome da interface não consegue distinguir esse pacote de qualquer outro tráfego que chegue pelo mesmo cabo.
O que o distingue é o contexto do caminho de segurança de entrada anexado ao pacote. O nftables o expõe como meta ipsec exists, que é verdadeiro quando o pacote chegou por um caminho de segurança IPsec. Combine-o com o pool de clientes, o destino e o serviço, e a regra fica específica o suficiente para ser segura.
Omitir o contexto é o erro comum, e é um erro de segurança, não estético. Uma regra que aceita qualquer coisa originada do pool de clientes aceita com a mesma facilidade um pacote falsificado da rede local, porque o endereço de origem não é prova de nada por si só. O contexto do caminho de segurança é a maneira mais barata de tornar a origem significativa. Escreva a regra com ele desde o início em vez de adicioná-lo depois de uma auditoria.
Escreva a regra de encaminhamento
Suponha um serviço de acesso remoto IPv4 autenticado com clientes em 10.90.0.0/24 e um destino aprovado em 203.0.113.40. Um fragmento de regra para esse fluxo tem esta aparência.
meta ipsec exists ip saddr 10.90.0.0/24 \
ip daddr 203.0.113.40 tcp dport 443 \
oifname "eth0" counter accept
Os endereços e a interface são exemplos a substituir. Coloque o equivalente revisado na política de encaminhamento antes da regra que, de outra forma, rejeitaria o fluxo, e não esvazie um conjunto de regras existente para instalá-lo; um gateway não é um experimento de sala limpa.
Vale a pena manter o termo oifname. Ele documenta a decisão de saída e impede que a regra corresponda em uma direção que você não pretendia, o que importa em um gateway com vários caminhos para a internet. Em uma máquina de testes com um único enlace ascendente o termo parece redundante, e é exatamente por isso que ele é removido antes de a máquina ganhar um segundo enlace.
As permissões para a troca externa são separadas. O caminho de entrada do gateway precisa das portas IKE e ESP ou de encapsulamento UDP que ele realmente usa, e essas permissões não autorizam nada sobre o pacote descriptografado lá dentro. Misturar as duas coisas é como um túnel em funcionamento acaba com um firewall que encaminha tudo.
O contexto de entrada não é o de saída
A mesma família de expressões cobre a outra direção com rt ipsec, que descreve a associação de segurança de saída que um pacote usará. Ela responde a outra pergunta: não de onde veio este pacote, mas se ele estará protegido no próximo trecho.
Essa distinção importa em um gateway que encerra um túnel e ao mesmo tempo encaminha para outro. Um pacote pode chegar descriptografado e ainda assim ter de sair criptografado, e uma aceitação escrita apenas para o contexto de entrada não diz nada sobre o requisito de saída. Se a política exige essa proteção, o conjunto de regras deveria expressá-la em vez de supor que o roteamento cuidará disso.
Mantenha as duas perguntas em regras separadas para que o leitor veja qual está sendo aplicada. Uma única regra engenhosa que verifica as duas é mais difícil de revisar e muito mais difícil de depurar quando uma de suas metades deixa de corresponder. Duas regras com contadores também dizem qual requisito está falhando, algo que uma regra combinada nunca fará.
NAT não é uma decisão do firewall
O tráfego para a internet a partir de um pool de clientes privado normalmente precisa de tradução de origem para que a resposta encontre o caminho de volta. Mas o tráfego selecionado para outra política IPsec de saída precisa manter sua isenção exigida, e mascarar cada origem privada sem pensar na próxima decisão de proteção quebra isso.
Uma aceitação dentro de uma cadeia NAT também não é uma permissão geral. NAT e filtragem têm tarefas diferentes, e uma cadeia NAT não examina cada pacote posterior de um fluxo estabelecido, e é exatamente por isso que contar com ela para segurança produz regras que parecem funcionar nos testes e falham sob carga.
O contrário também é verdadeiro e surpreende as pessoas: uma aceitação em algum lugar de uma cadeia base de filtragem não tem peso algum contra uma rejeição posterior em outra cadeia aplicável. A ordem e o escopo da cadeia decidem o resultado, não a presença de uma aceitação no arquivo.
Verifique o serviço interno exato
Teste o destino e a porta específicos que você autorizou, a partir de um cliente real, e confirme que a resposta volta. Depois teste algo que você não autorizou e verifique que não passa, porque uma regra ampla demais passa no primeiro teste tão bem quanto uma correta. Uma requisição que nunca sai do cliente também não é resultado de firewall, então leia os contadores para ver se o pacote foi avaliado. Dois testes e uma leitura de contador dirão mais do que uma tarde inteira lendo o conjunto de regras.
A referência do nftables documenta meta ipsec, rt ipsec e as expressões específicas de direção, e é o lugar para verificar a sintaxe em relação à versão instalada. E mantenha o escopo explícito: este é um exemplo IPv4, não diz nada sobre IPv6 e não transforma o encaminhamento arbitrário de portas públicas em parte do serviço VPN.