                               Filtering Bridges

  Alex Dupre

   <ale@FreeBSD.org>

   Revision: fafef270d2

   FreeBSD is a registered trademark of the FreeBSD Foundation.

   3Com and HomeConnect are registered trademarks of 3Com Corporation.

   Intel, Celeron, Centrino, Core, EtherExpress, i386, i486, Itanium,
   Pentium, and Xeon are trademarks or registered trademarks of Intel
   Corporation or its subsidiaries in the United States and other countries.

   Many of the designations used by manufacturers and sellers to distinguish
   their products are claimed as trademarks. Where those designations appear
   in this document, and the FreeBSD Project was aware of the trademark
   claim, the designations have been followed by the "(TM)" or the "(R)"
   symbol.

   2020-03-19 09:04:27 +0000 por Sergio Carlavilla Delgado.
   Resumen

   A menudo es util dividir una red fisica (por ejemplo una Ethernet) en dos
   segmentos separados sin tener que crear subredes y usar un router para
   vincularlas. El dispositivo que conecta las dos redes se llama bridge. Un
   sistema FreeBSD con dos interfaces de red es suficiente para actuar como
   bridge.

   Un bridge funciona escaneando las direcciones del nivel MAC (direcciones
   Ethernet) de los dispositivos conectados a cada una de sus interfaces de
   red y luego reenvia el trafico entre las dos redes solo si la fuente y el
   destino estan en diferentes segmentos. En muchos aspectos, un bridge es
   similar a un switch de Ethernet con solo dos puertos.

   [ Split HTML / Single HTML ]

     ----------------------------------------------------------------------

   Tabla de contenidos

   1. ?Por que utilizar un bridge que haga filtrado?

   2. Proceso de instalacion

   3. Preparacion final

   4. Habilitando el bridge

   5. Configurando el firewall

   6. Colaboradores

1. ?Por que utilizar un bridge que haga filtrado?

   Sucede con bastante frecuencia que, gracias a la reduccion del coste de
   las conexiones de banda ancha a Internet (xDSL) y a la reduccion de las
   direcciones IPv4 disponibles, muchas empresas estan conectadas a Internet
   las 24 horas del dia y con pocas (a veces ni siquiera dos) direcciones IP.
   A menudo en estas situaciones es necesario tener un firewall (tambien
   conocido como cortafuegos) que filtre el trafico entrante y saliente desde
   y hacia Internet, pero una solucion de filtrado de paquetes puede que no
   sea posible posible, ya sea por problemas de subredes, porque el router
   sea de propiedad del proveedor de servicios de internet (ISP), o porque no
   admite tales funcionalidades. En escenarios como estos se recomienda el
   uso de un brigde que realice el filtrado.

   Una buena solucion seria configurar un firewall basado en un bridge. Lo
   instalaremos entre el router xDSL y su hub/switch Ethernet, evitando asi
   problemas de numeracion IP.

2. Proceso de instalacion

   No es dificil anadir funcionalidades de brigde a un sistema FreeBSD. Desde
   la version 4.5 es posible cargar funcionalidades como modulos en lugar de
   tener que volver a compilar el kernel, lo cual simplifica mucho el
   procedimiento. En las siguientes subsecciones explicare ambas formas de
   instalacion.

  Importante:

   No siga ambas instrucciones: un procedimiento excluye el otro. Seleccione
   la mejor opcion de acuerdo a sus necesidades y habilidades.

   Antes de continuar asegurese de tener al menos dos tarjetas Ethernet que
   admitan el modo promiscuo tanto para la recepcion como para la
   transmision, ya que deben poder enviar paquetes Ethernet con cualquier
   direccion, no solo la suya. Ademas, para tener una buena tasa de
   transferencia, las tarjetas deben ser tarjetas del bus PCI. Las mejores
   opciones siguen siendo Intel EtherExpress(TM) Pro, seguida de la 3Com(R)
   3c9xx series. Para simplificar la configuracion del firewall, puede ser
   util tener dos tarjetas de diferentes fabricantes (con diferentes
   controladores) para distinguir claramente que interfaz esta conectada al
   router y cual a la red interna.

  2.1. Configuracion del kernel

   Si sigue este metodo es porque ha decidido utilizar el metodo de
   instalacion mas antiguo y tambien el que ha sido probado mas. Para
   empezar, debe agregar las siguientes lineas a su archivo de configuracion
   del kernel:

 options BRIDGE
 options IPFIREWALL
 options IPFIREWALL_VERBOSE

   La primera linea anade el soporte para el bridge, la segunda anade la
   compatibilidad con el firewall y la tercera se refiere a las funciones de
   logging del firewall.

   Ahora es necesario compilar e instalar el nuevo kernel. Puede encontrar
   instrucciones detalladas en la seccion compilar e instalar un kernel
   personalizado del manual de FreeBSD.

  2.2. Carga de modulos

   Si ha elegido usar el nuevo metodo de instalacion (mas simple), lo unico
   que debe hacer es anadir la siguiente linea a /boot/loader.conf :

 bridge_load="YES"

   Asi el modulo bridge.ko se cargara junto con el kernel durante el inicio
   del sistema. No es necesario anadir una linea similar para el modulo
   ipfw.ko, ya que se cargara automaticamente despues de la ejecucion de los
   pasos de la siguiente seccion.

3. Preparacion final

   Antes de reiniciar para cargar el nuevo kernel o los modulos requeridos
   (de acuerdo con el metodo de instalacion elegido anteriormente) debe
   realizar algunos cambios en el archivo de configuracion /etc/rc.conf. La
   regla predeterminada del firewall es rechazar todos los paquetes IP.
   Inicialmente configuraremos un firewall en modo open para verificar que
   funciona sin ningun problema en relacion con el filtrado de paquetes (en
   el caso de que vaya a ejecutar este procedimiento de forma remota dicha
   configuracion evitara que permanezca aislado de la red). Coloque estas
   lineas en el archivo /etc/rc.conf:

 firewall_enable="YES"
 firewall_type="open"
 firewall_quiet="YES"
 firewall_logging="YES"

   La primera linea activara el firewall (y cargara el modulo ipfw.ko si no
   esta compilado en el kernel), la segunda lo configurara en modo open (como
   se explica en el archivo /etc/rc.firewall), la tercera hara que no se
   muestren la carga de las reglas y la cuarta habilitara el soporte de
   logging.

   En cuanto a la configuracion de las interfaces de red la forma mas
   utilizada es asignar solo una IP a una de las tarjetas de red; el bridge
   funcionara igualmente, aunque ambas interfaces tengan una o no tengan
   ninguna IP configurada. En el ultimo caso (IP-less) la maquina bridge
   quedara aun mas oculta, ya que es inaccesible desde la red. Para
   configurarla, debe iniciar sesion desde la consola o mediante una tercera
   interfaz de red separada del bridge. A veces durante el inicio del sistema
   algunos programas requieren acceso a la red, por ejemplo para la
   resolucion del dominio. En este caso es necesario asignar una IP a la
   interfaz externa (la que esta conectada a Internet, donde se encuentra el
   servidor DNS) ya que el bridge se activara al final del procedimiento de
   arranque. Esto significa que la interfaz fxp0 (en nuestro caso) debe
   anadirse en la seccion ifconfig del archivo /etc/rc.conf, mientras que xl0
   no. Asignar una IP a ambas tarjetas de red no tiene mucho sentido, a menos
   que durante el procedimiento de inicio las aplicaciones tengan que acceder
   a servicios en ambos segmentos Ethernet.

   Hay otra cosa importante que hay que saber. Cuando se ejecuta IP over
   Ethernet, en realidad hay dos protocolos Ethernet en uso: uno es IP, el
   otro es ARP. ARP realiza la conversion de la direccion IP de un host a su
   direccion de Ethernet (capa MAC). Para permitir la comunicacion entre dos
   hosts separados por el bridge, es necesario que el bridge reenvie los
   paquetes ARP. Dicho protocolo no esta incluido en la capa IP, ya que solo
   existe con IP over Ethernet. El firewall de FreeBSD filtra exclusivamente
   en la capa IP y, por lo tanto, todos los paquetes no IP (ARP incluido) se
   reenvian sin ser filtrados, aunque el firewall este configurado para no
   permitir nada.

   Ahora es el momento de reiniciar el sistema y usarlo como antes: habra
   algunos mensajes nuevos sobre el bridge y el firewall, pero el bridge no
   se activara y el firewall, en el modo open, no bloqueara ninguna
   operacion.

   Si hay algun problema, debe solucionarlo ahora antes de continuar.

4. Habilitando el bridge

   En este momento para habilitar el bridge debe ejecutar los siguientes
   comandos (no olvide reemplazar los nombres de las dos interfaces de red
   fxp0 y xl0 por las suyas):

 # sysctl net.link.ether.bridge.config=fxp0:0,xl0:0
 # sysctl net.link.ether.bridge.ipfw=1
 # sysctl net.link.ether.bridge.enable=1

   La primera linea especifica que interfaces deben ser activadas por el
   bridge, la segunda habilitara el firewall en el bridge y finalmente la
   tercera habilitara el bridge.

   En este momento deberia poder insertar la maquina entre dos conjuntos de
   host sin comprometer ninguna capacidad de comunicacion entre ellos. Si ha
   funcionado, el siguiente paso es anadir lo siguiente
   net.link.ether.bridge.[blah]=[blah] al archivo /etc/sysctl.conf, para que
   se ejecute al inicio.

5. Configurando el firewall

   Ahora es el momento de crear su propio archivo de configuracion con las
   reglas personalizadas del firewall para proteger la red interna. Se
   encontrara con algunas complicaciones porque no todas las funcionalidades
   del firewall estan disponibles en los paquetes bridge. Hay ademas una
   diferencia entre los paquetes que estan en proceso de reenvio y los
   paquetes que esta recibiendo la maquina local. En general, los paquetes de
   entrada pasan por el firewall solo una vez, no dos veces, como suele ser
   el caso; en realidad se filtran solo despues de la recepcion, por lo que
   las reglas que usan out o xmit nunca coincidiran. Yo utilizo in via, que
   es una sintaxis mas antigua pero tiene sentido cuando la lees. Otra
   limitacion es que usted solo puede usar solo los comandos pass o reject
   para los paquetes filtrados por un bridge. Opciones mas complejas como
   divert, forward o reject no estan disponibles. Estas opciones pueden
   seguir utilizandose, pero solo en el trafico hacia o desde la propia
   maquina bridge (si tiene una direccion IP).

   El concepto de firewall con estado se incluyo por primera vez en FreeBSD
   4.0. Es una gran mejora para el trafico UDP, el cual generalmente es una
   solicitud de salida seguida poco despues por una respuesta con exactamente
   el mismo conjunto de direcciones IP y numeros de puerto (pero obviamente
   con origen y destino invertidos). Con los firewalls que no mantienen el
   estado no hay forma de lidiar con este tipo de trafico en una unica
   sesion. Pero con un firewall que puede "recordar" un paquete saliente de
   UDP y, durante los proximos minutos, permitir una respuesta el manejo de
   servicios UDP es trivial. El siguiente ejemplo muestra como hacerlo. Es
   posible hacer lo mismo con los paquetes TCP. Esto le permite evitar
   algunos ataques de denegacion de servicio y y otras maldades, pero tambien
   hace que su tabla de estado crezca rapidamente de tamano.

   Veamos una configuracion de ejemplo. Lo primero, tenga en cuenta que en la
   parte superior del archivo /etc/rc.firewall ya existen reglas
   predeterminadas para la interfaz de loopback lo0, por lo que no es
   necesario preocuparse de ellas. Las reglas personalizadas deben colocarse
   en un archivo separado (por ejemplo, /etc/rc.firewall.local) y cargarse al
   inicio del sistema, modificando la linea en el archivo /etc/rc.conf donde
   definimos el firewall en modo open:

 firewall_type="/etc/rc.firewall.local"

  Importante:

   Debe especificar la ruta completa, de lo contrario, no se cargara, con el
   riesgo de permanecer aislado de la red.

   Para nuestro ejemplo, imagine que tiene la interfaz fxp0 conectada hacia
   el exterior (Internet) y la xl0 hacia el interior (LAN). La maquina que
   haga de brigde tiene la IP 1.2.3.4 (su ISP no puede proporcionarle una
   direccion asi, pero para nuestro ejemplo nos sirve).

 # Cosas para las que tenemos que mantener el estado
 add check-state

 # Desechar todas las redes RFC 1918
 add drop all from 10.0.0.0/8 to any in via fxp0
 add drop all from 172.16.0.0/12 to any in via fxp0
 add drop all from 192.168.0.0/16 to any in via fxp0

 # Permitir que la maquina bridge diga lo que quiera
 # (si la maquina es IP-less no incluya estas lineas)
 add pass tcp from 1.2.3.4 to any setup keep-state
 add pass udp from 1.2.3.4 to any keep-state
 add pass ip from 1.2.3.4 to any

 # Permitir que los hosts internos digan lo que quieran
 add pass tcp from any to any in via xl0 setup keep-state
 add pass udp from any to any in via xl0 keep-state
 add pass ip from any to any in via xl0

 # Seccion TCP
 # Permitir SSH
 add pass tcp from any to any 22 in via fxp0 setup keep-state
 # Permitir SMTP solo hacia el servidor de correo
 add pass tcp from any to relay 25 in via fxp0 setup keep-state
 # Permitir transferencias de zona solo por el servidor de nombres esclavo [dns2.nic.it]
 add pass tcp from 193.205.245.8 to ns 53 in via fxp0 setup keep-state
 # Dejar pasar ident probes. Es mejor que esperar a que se agote el tiempo
 add pass tcp from any to any 113 in via fxp0 setup keep-state
 # Dejar paso al rango "quarantine"
 add pass tcp from any to any 49152-65535 in via fxp0 setup keep-state

 # Seccion UDP
 # Permitir DNS solo hacia el servidor de nombres
 add pass udp from any to ns 53 in via fxp0 keep-state
 # Dejar pasar el rango "quarantine"
 add pass udp from any to any 49152-65535 in via fxp0 keep-state

 # Seccion ICMP
 # Dejar paso a 'ping'
 add pass icmp from any to any icmptypes 8 keep-state
 # Dejar paso a los mensajes de error generados por 'traceroute'
 add pass icmp from any to any icmptypes 3
 add pass icmp from any to any icmptypes 11

 # Todo lo demas es sospechoso.
 add drop log all from any to any

   Aquellos de ustedes que hayan instalado firewalls antes notaran que faltan
   algunas cosas. En particular, no hay reglas contra la suplantacion de
   identidad, de hecho, no las anadimos:

 add deny all from 1.2.3.4/8 to any in via fxp0

   Es decir, descartar los paquetes que vienen del exterior diciendo
   pertenecer a nuestra red. Esto es algo que normalmente haria para
   asegurarse de que alguien no trata de evadir el filtrado de paquetes,
   generando paquetes corruptos que parecen ser de dentro de la red. El
   problema es que hay al menos un host en la interfaz externa que no desea
   ignorar: el router. Pero, por lo general, el ISP tiene reglas contra la
   suplantacion de identidad en su router, por lo que no tenemos que
   preocuparnos excesivamente.

   La ultima regla parece ser un duplicado exacto de la regla predeterminada,
   es decir, no dejar pasar nada que no este especificamente permitido. Pero
   hay una diferencia: todo trafico sospechoso sera registrado.

   Hay dos reglas para permitir el trafico SMTP y DNS hacia los servidores de
   correo y de nombres, si dispone de ellos. Obviamente todo el conjunto de
   reglas debe ser definido de acuerdo con sus preferencias personales; esto
   es solo un ejemplo especifico (el formato de la regla se describe con
   precision en la pagina del manual de ipfw(8)). Tenga en cuenta que para
   que el "relay" y el "ns" funcionen las busquedas del servicio de nombres
   deben funcionar antes de que el bridge este activado. Este es un ejemplo
   de como asegurarse de configurar la IP en la tarjeta de red correcta. Otra
   forma de hacer las cosas seria especificar la direccion IP en lugar del
   nombre del host (requerido si la maquina no tiene IP).

   Quienes esten acostumbrados a configurar firewalls probablemente tambien
   suelan usar una regla reset o forward para los paquetes ident (TCP puerto
   113). Por desgracia esta no es una opcion valida con el bridge, por lo
   tanto la mejor opcion es simplemente pasarlos a su destino. A menos que la
   maquina de destino este ejecutando un daemon ident es realmente
   inofensivo. La alternativa es eliminar las conexiones en el puerto 113, lo
   que creara algunos problemas con servicios como IRC (el probe del ident
   dara timeout).

   Lo unico raro que puede haber notado es que existe una regla para permitir
   que la maquina que hace de bridge hable y otra para los hosts internos.
   Recuerde que esto sucede porque los dos conjuntos de trafico tendran
   diferentes rutas a traves del kernel y del filtro de paquetes. La red
   interna pasara por el bridge, mientras que la maquina local utilizara el
   stack normal de IP para hablar. Por lo tanto, cada regla se ocupa de una
   cosa diferente. Las reglas in via fxp0 funcionan para ambas rutas. En
   general, si utiliza las reglas in via en todo el filtro, debe anadir una
   excepcion para los paquetes generados localmente, ya que no llegaron a
   traves de ninguna de nuestras interfaces.

6. Colaboradores

   Muchas partes de este articulo han sido obtenidas, actualizadas y
   adaptadas de un texto antiguo sobre el bridging, editado por Nick Sayer.
   Unas cuantas ideas muy inspiradoras vienen de una introduccion sobre el
   bridging que escribio Steve Peterson.

   Mi mas sincero agradecimiento a Luigi Rizzo por la implementacion del
   codigo de bridge en FreeBSD y por el tiempo que ha dedicado a responder
   todas mis preguntas.

   Un agradecimiento tambien a Tom Rhodes, quien reviso mi trabajo de
   traduccion del italiano (el idioma original de este articulo) al ingles.
