¿Cómo usar nft en Linux Bridge para bloquear el acceso a cierta dirección IP?

¿Cómo usar nft en Linux Bridge para bloquear el acceso a cierta dirección IP?

Tengo una caja de Ubuntu con un puente br0definido. El puente se ha eth0conectado al servicio de Internet y eth1al puerto de red de una PC. El puente funciona como se esperaba y pasa todo el tráfico entre eth0y eth1.

Quiero implementar una regla que bloquee el acceso a ciertas direcciones IP externas (por ejemplo, 1.1.1.1) desde la PC. Supongo nftque es la forma de hacer esto. ¿Cómo escribo una regla para que nada pueda pasar br0desde/hacia 1.1.1.1?

El propósito aquí es poder simular ciertas fallas para realizar pruebas.

Respuesta1

Esto se hace usandonftables'familia puente.

nftablesproporciona la familia de puentes como reemplazo deebtables.

Crea una tabla en elpuentefamilia:

# nft add table bridge t

Crea una cadena para filtrar fotogramas reenviados:

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

Cree una regla para evitar que los paquetes IPeth1para llegar a 1.1.1.1:

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

Eso es todo para un firewall sin estado.


DesdeNúcleo de Linux 5.3 nftablestambién tiene soporte para cortafuegos con estado directo en elpuentecamino:

Agregue soporte de seguimiento de conexión nativo para el puente. Antes de este conjunto de parches, la única posibilidad para la gente de hacer filtrado de estado era usar la br_netfiltercapa de emulación, este es un paso adelante para desaprobarlo [...]

Esto permite aislar fácilmente el sistema en una sola dirección. Por ejemplo para permitir:

  • acceso entrante a la PC con SSH
  • acceso saliente desde el PC: el PC a utilizarsilbidoy DNS ( tha continuación representa ambosTCPyudp)
  • ARP (sin el cual no hay conectividad IPv4)
  • todo lo necesariotráfico de respuesta(como primera regla por razones de rendimiento)
  • y nada más

uno podría 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

Ciertamente es posible cierta factorización y se debe considerar (por ejemplo: mediante el uso de conjuntos yconcatenaciones).


Todos los ejemplos anteriores no afectarán la caja de Ubuntu en sí, que aún puede alcanzar y ser alcanzada por ambos lados. Para afectar el tráfico desde la PC a la caja de Ubuntu (o respectivamente desde la caja de Ubuntu a la PC), se puede aplicar el mismo tipo de reglas en una cadena que se conectaaporte(resp.producción) en lugar deadelante.


Nota:

Elbr_netfilterEl módulo no debe cargarse (habilitando de forma predeterminada la propiedad sysctl net.bridge.bridge-nf-call-iptables = 1) para evitar interacciones inesperadas entre nativos.puentereglas yIPreglas familiares que también afectannftablestan bien comoiptables. Eso significabr_netfilterSe debe evitar ejecutar Docker o Kubernetes (los 2 usuarios habituales de ) en el mismo sistema.al realizar experimentos de red (pero aún es posible con cuidado adicional, por ejemplo: adaptandoestas preguntas y respuestas de UL SE).

Haber br_netfiltercargado (y net.bridge.bridge-nf-call-iptables = 1) le inducirá a pensar que la forma normal de realizar las operaciones sería filtrar en elIPfamilia en elfiltrar/adelantegancho. Ese no es el caso normal ynftablescarece de características adicionales que aprovechen esto, comoiptables'physdevmódulo de coincidencia: en cambio, el objetivo siempre ha sido hacer esto de forma nativa en elpuentefamilia y no depender de ella br_netfilter.

Respuesta2

Si su host Linux se ejecuta como enrutador, también deberá configurar ip_forwarding.

Para responder a tu pregunta, puedes usar nftables como este:

#!/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
   } 

}

y ejecute esto con nft -f /path/to/your/nft.file

Sin embargo, esto es un poco inútil (sé que estás aprendiendo nftables, no te lo tomes demasiado a la ligera). La mejor práctica es descartar todo y permitir solo lo necesario, de modo que no se elimine el tráfico específico, sino que se permita el tráfico específico.

La documentación de Red Hat 8 me pareció muy buena para nftables, tal vez puedas aprender de ella tanto como yo:

documentación de rhel 8 nftables

información relacionada