Como usar o NFT no Linux Bridge para bloquear o acesso a determinado endereço IP?

Como usar o NFT no Linux Bridge para bloquear o acesso a determinado endereço IP?

Eu tenho uma caixa Ubuntu com uma ponte br0definida. A ponte foi eth0conectada ao serviço de Internet e eth1à porta de rede de um PC. A ponte está funcionando conforme esperado e passando todo o tráfego entre eth0e eth1.

Quero estabelecer uma regra que bloqueie o acesso a determinados endereços IP externos (por exemplo, 1.1.1.1) do PC. Presumo nftque seja a maneira de fazer isso. Como escrevo uma regra para que nada possa passar br0de/para 1.1.1.1.

O objetivo aqui é poder simular certas falhas para teste.

Responder1

Isso é feito usandonftáveis'família da ponte.

nftáveisfornece a família bridge como um substituto paratabelas de débito.

Crie uma tabela nopontefamília:

# nft add table bridge t

Crie uma cadeia para filtrar quadros encaminhados:

# nft add chain bridge t c '{ type filter hook forward priority 0; policy accept; }'

Crie uma regra para impedir que pacotes IP sejameth1para chegar a 1.1.1.1:

# nft add rule bridge t c iif eth1 ether type ip ip daddr 1.1.1.1 drop

É isso para um firewall sem estado.


DesdeKernel Linux 5.3 nftáveistambém tem suporte para firewall com estado direto nopontecaminho:

Adicione suporte nativo de rastreamento de conexão para a ponte. Antes deste conjunto de patches, a única chance para as pessoas fazerem filtragem com estado é usar a br_netfiltercamada de emulação, este é um passo à frente para descontinuar [...]

Isto permite isolar facilmente o sistema em uma única direção. Por exemplo, para permitir:

  • acesso de entrada ao PC com SSH
  • acesso de saída do PC: o PC a ser usadopingare DNS ( thabaixo significa ambostcpeUDP)
  • ARP (sem o qual não há conectividade IPv4)
  • tudo necessáriotráfego de resposta(como primeira regra por motivos de desempenho)
  • e nada mais

alguém poderia usar:

# nft add rule bridge t c ct state related,established accept
# nft add rule bridge t c oif eth1 ether type ip tcp dport 22 accept
# nft add rule bridge t c iif eth1 ether type ip meta l4proto {tcp, udp} th dport 53 accept
# nft add rule bridge t c iif eth1 ether type ip icmp type echo-request accept
# nft add rule bridge t c ether type arp accept
# nft add rule bridge t c drop

Alguma fatoração é certamente possível e deve ser considerada (por exemplo: usando conjuntos econcatenações).


Todos os exemplos acima não afetarão a própria caixa do Ubuntu, que ainda pode alcançar e ser alcançada por ambos os lados. Para afetar o tráfego do PC para a caixa do Ubuntu (ou respectivamente da caixa do Ubuntu para o PC), o mesmo tipo de regras pode ser feito em uma cadeia conectadaentrada(resp.saída) em vez deavançar.


Observação:

Obr_netfiltermódulo não deve ser carregado (habilitando por padrão a propriedade sysctl net.bridge.bridge-nf-call-iptables = 1) para evitar interações inesperadas entre nativosponteregras eIPregras familiares que também afetamnftáveistão bem quantotabelas de ip. Que significaexecutar Docker ou Kubernetes (os 2 usuários habituais br_netfilter) no mesmo sistema deve ser evitadoao fazer experimentos de rede (mas ainda é possível com cuidados adicionais, por exemplo: adaptandoesta pergunta/resposta da UL SE).

Ter br_netfiltercarregado (e net.bridge.bridge-nf-call-iptables = 1) irá induzi-lo a pensar que a forma normal de operações seria filtrar noIPfamília nofiltro/avançargancho. Esse não é o caso normal, enftáveisnão possui recursos adicionais que aproveitem isso, comotabelas de ip'physdevmódulo match: em vez disso, o objetivo sempre foi fazer isso nativamente nopontefamília e não confiar br_netfilter.

Responder2

Se o seu host Linux estiver rodando como um roteador, você também precisará configurar o ip_forwarding.

Para responder sua pergunta, você poderia usar nftables assim:

#!/usr/bin/nft 

flush ruleset

table inet my_table {
   chain INPUT {
      iifname br0 saddr 1.1.1.1 drop
      iifname br0 daddr 1.1.1.1 drop
   }

chain FORWARD {
      iifname br0 saddr 1.1.1.1 drop
      iifname br0 daddr 1.1.1.1 drop
   } 

}

e execute isso com nft -f /path/to/your/nft.file

Isso é um pouco inútil (eu sei que você está aprendendo nftables, não leve isso muito a sério). A melhor prática é descartar tudo e permitir apenas o que é necessário, não descartando tráfego específico, mas permitindo tráfego específico.

Achei a documentação do red hat 8 muito boa para nftables, talvez você possa aprender com ela tanto quanto eu:

documentação do rhel 8 nftables

informação relacionada