Uma regra pode manter um pool VPN admitido longe de um intervalo de destino sem perturbar mais nada do que o gateway faz. A regra em si é curta; as partes que decidem se funciona são o hook onde ela vive e a sua posição na cadeia. Errar essas duas produz um firewall que parece correto e se comporta de forma inconsistente. Comece pelo que o pacote faz quando a regra o vê.

O que a regra realmente compara

A regra compara três coisas ao mesmo tempo: uma interface de entrada, um prefixo de origem e um prefixo de destino. As três devem ser verdadeiras antes de o drop ser aplicado, e é isso que a mantém estreita. Lê-la como uma única expressão é mais fácil do que como três políticas separadas.

A correspondência de interface é o que distingue o tráfego encaminhado dos clientes das conexões do próprio gateway. Sem ela, uma regra que nomeasse apenas o pool de origem também afetaria pacotes que o próprio gateway gera a partir desse endereço, se alguma vez o fizer. O prefixo de origem limita a política aos clientes admitidos, e o prefixo de destino limita-a a um único intervalo. Leia a regra como uma interseção e não como uma lista.

Anote os três valores antes de editar qualquer coisa: o nome da interface do túnel, o pool que o servidor distribui e o prefixo que pretende negar. Um erro de digitação em qualquer um deles produz uma regra que é analisada limpidamente e não protege nada. Guarde esses três valores no registo de alterações ao lado da regra.

O hook decide a quem a regra se aplica

Uma cadeia netfilter está ligada a um hook, e o hook decide quais pacotes a cadeia chega a ver. O hook forward vê o tráfego encaminhado através do gateway, que é exatamente o tráfego de cliente para destino. Todo o resto da cadeia aponta para outro público.

O hook input vê o tráfego endereçado ao próprio gateway, pelo que uma regra ali colocada governa o acesso aos seus próprios serviços e não o trânsito. O hook output vê o tráfego que o gateway origina, o que é o oposto do que uma política de pool de clientes precisa. Os nomes das cadeias são etiquetas arbitrárias escolhidas por quem escreveu o conjunto de regras, por isso não deduza o hook a partir do nome. Verifique onde a cadeia está ligada antes de assumir o que ela pode comparar.

HookTraffic it seesRight for this policy
inputAddressed to the gatewayNo, that is the host's own services
forwardRouted through the gatewayYes, for client-to-destination traffic
outputGenerated by the gatewayNo, that is the opposite direction

Ler a ligação é uma verificação de uma linha que impede que uma regra acabe numa cadeia que nunca vê o pacote.

Coloque a regra antes da aceitação ampla

As regras são avaliadas por ordem e o primeiro veredicto vence. Uma aceitação ampla mais acima na cadeia termina a avaliação para os pacotes que corresponde, pelo que um drop acrescentado depois nunca é executado para eles. Essa regra de ordem é toda a razão pela qual uma regra de aspeto correto pode não ter efeito.

Insira a regra antes da aceitação em vez de a acrescentar no fim. Se a cadeia já contém uma aceitação geral para a interface do túnel, a nova regra tem de a preceder, caso contrário é apenas decorativa. Verifique a ordem resultante e não o ficheiro que editou, porque um conjunto de regras montado a partir de vários ficheiros pode não corresponder a nenhum deles. Depois confirme com um pacote de teste do pool.

sudo nft list chain inet filter forward
sudo nft insert rule inet filter forward iifname "tun0" ip saddr 10.90.0.0/24 ip daddr 198.51.100.0/24 drop
sudo nft -c -f /etc/nftables.conf

O terceiro comando analisa o ficheiro sem o aplicar, o que apanha erros de sintaxe antes de se tornarem uma interrupção. Aplique-o com um plano de reversão, porque uma regra errada numa cadeia forward pode cortar o túnel por onde trabalha.

Os fluxos existentes não se importam com a sua nova regra

Uma entrada de conntrack criada antes de a regra existir continua a corresponder à aceitação anterior. É por isso que um novo drop às vezes parece funcionar para ligações novas e não fazer nada pela que está a ser testada.

Leia a correspondência de estado no topo da cadeia. Se aceitar tráfego established e related antes da sua regra, cada fluxo já em curso continua a fluir até se fechar. Normalmente é o comportamento que quer para uma regra de emergência, e é confuso quando espera um corte imediato. Decida que efeito quer antes de implementar. Um teste que reutilize uma ligação aberta contar-lhe-á uma história errada.

sudo conntrack -L -s 10.90.0.14 -d 198.51.100.20
sudo nft list ruleset | grep -n -A3 'ct state'

O primeiro comando mostra se existe um fluxo, e o segundo mostra se uma regra de estado precoce continua a aceitá-lo. Ambos são só de leitura e seguros durante um incidente.

O que esta regra não é

A regra não é uma lista negra de domínios, uma política IPv6 nem uma restrição a uma conta de aplicação individual.

Cada uma dessas coisas precisa do seu próprio mecanismo. Um bloqueio de domínio tem de resolver nomes, o que um filtro de pacotes não faz. O tráfego IPv6 precisa da sua própria correspondência, porque uma expressão ip não diz nada sobre pacotes ip6. Uma restrição ao nível da aplicação pertence ao serviço ou a um proxy autenticado, não a uma correspondência de prefixo. Manter esses requisitos separados é o que evita pedir a uma regra estreita que faça quatro trabalhos.

O contrato que esta regra entrega é preciso: o tráfego de um pool admitido para um prefixo de destino é negado, enquanto o tráfego não relacionado do gateway mantém a sua política existente. Escreva essa frase ao lado da regra, e a próxima pessoa saberá para que servia.

Artigos relacionados