Las instrucciones para hacer un cortafuegos realmente SIMPLE y la vez funcional (statefull firewall) con ipfw; sensillamente “no existen”, al menos No de manera oficial. El cortafuegos ejemplificado en el handbook es bastante ortodoxo y no muestra la flexibilidad de ipfw.
Para empezar, el módulo debe ser cargado en el kernel, así que inicializaremos ipfw como si fuera un demonio más del sistema. Esto quiere decir que lo añadiremos al /etc/rc.conf
1 2 |
|
Te recomiendo reiniciar ahora; para que todo se cargue correctamente.
La documentación oficial aclara que los firewall pueden ser (además) del tipo: open, client, simple, closed o UNKNOWN. Sin embargo, en mi opinión estas configuraciones prefabricadas, no son suficiente para un servidor (por ejemplo proxy).
Para mantener la armonía chea y anticuada de freebsd; colocamos el cortafuegos en el etc/ que está bajo /usr/local/. Ten en cuenta que casi todas las aplicaciones que instales, tendrán su /etc ahí.
Reiniciar ipfw no es tan jamón como un usuario de iptables haría. Hacer un flush de las reglas, significa quedarse trancado y perder la conexión por ssh. Para reiniciar el cortafuegos, deberás tener un script que haga flush y además, reiniciar el servicio. Este scriptsito me lo hice para la faena de toquetear el cortafuegos
1 2 3 4 5 |
|
La documentación oficial (y otras muchas) indican que cada regla se cree enumerada y que bebes mantener esta numeración manualmente. Sin embargo, esto no es estrictamente necesario. Cada regla incrementará el número de manera implícita.
La mecánica de ipfw es más sencilla que cualquier firewall de linux en mi opinión.
ipfw add accion argumento
Si ya conoces ufw, te darás cuenta de que es una copia bastante mala de ipfw, sobre todo; teniendo cuenta que ipfw es un firewall en sí, mientras que ufw, es un stack que genera instrucciones de iptables.
Algo de lo que linux se ha alejado mucho es el teorema de KISS, pero en BSD, que es unix ortodoxo, mantiene la simpleza como pilar. De esta manera, una acción allow, en su forma más simple, es casi lenguaje natural.
ipfw add allow all from 10.99 to me
O sea, permite todo lo que venga de 10.0.0.1 para mi. Pero podemos hacer algo más discriminatorio.
ipfw add allow tcp from 10.0.0.99 to 10.0.0.1 dst-port 22 in via xn0
Permite el tráfico tcp de 10.99 para 10.1 que valla para el puerto 22 en sentido entrante (in) por la interfaz (via) xn0
¿Te la llevaste? Jamón de pollo! ¿Verdad?
Veamos pues un ipfw.rules bien básico. La interfaz lo0 (lo con un cero) es el localhost. La interfaz xn0 es la WAN y xn1 es la LAN.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Veamos algunas características de este cortafuegos…
Como ven, no arranca haciendo flush como los de iptables. De hecho, hacer flush como primera linea puede causarte problemas muy serios. Por otro parte, reiniciar el cortafuegos sin hacer flush, provoca que se dupliquen las reglas.
La salida, por definición, está bloqueada. La última regla; autoriza la salida del tráfico. ¿Por qué la última? ¿Por qué no al principio? Pues por si hacemos un pipe de salida. Aveces regular el ancho de banda de salida, es más útil que regular el de entrada. Por ejemplo, si queremos moderar la cantidad de tráfico que un servidor web exporta. Más adelante veremos dummynet y los pipe.
En iptables, hacemos DROP cuando queremos desechar paquetes. En ipfw usamos deny, aunque también puedes usar drop que es sinónimo de deny. El cortafuego lo sustituirá por deny. Lo puedes ver al usar: ipfw show
Note que “from me” para ipfw, significa un paquete que provenga de cualquiera de las ip que tiene configurada el servidor. En este caso, la interfaz xn0 debe tener alguna de la red 192.168.1.0/24 así que me será dicha ip.
Una característica de ipfw bien peligrosa es que tiene muchas cosas implícitas. Como lo de la numeración. Cuando digo implícita me refrito a que si no las pones, ipfw las asume. Fíjate bien como se maneja el tema de los puertos en la siguientes reglas.
1 2 3 4 5 6 |
|
En la primera regla, declaramos “me 3128”, esto significa “para mi ip por el puerto 3128”. Realmente ipfw lo reescribe (puedes verlo con “show”) y pondrá la cláusula dst-port al igual que la siguiente linea, detrás de me viene la cláusula dst-port seguida por el puerto. Pero si no la pones, se asume como implícita. En poca palabras:
“to me 3128” y “to me dst-port 3128” es exactamente lo mismo.
Otro tema que le retraquetea el mango; es la gestión del ancho de vianda. Porque tc de iproute (en linux) es un asco. Pero si conocemos ipfw, sabremos que maneja el ancho de vianda de una menera muy peculiar; usando un módulo llamado dummynet. No esperes ver la palabra “dummynet” escrita en el cortafuegos. En fin; analiza este ejemplo:
1 2 |
|
Se crea el pipe número 1, con un ancho de banda de 128 KyloBytes. En la regla de arriba, se dijo que todo el tráfico de la interfaz xn0, proveniente de el servidor hacia la red 192.168.1.0/24 y en sentido saliente; será a 128K. O sea, modificamos el ancho de banda que sale del servidor, lo cual es bastante útil para un servidor web o ftp.
En el caso de un servidor proxy, no vale la pena modificar el ancho de banda de salida, ya que las páginas son enviadas al cliente una vez bajadas y si ya nos hicimos el arakiri de bajarla: ¿Pa que demorarlas más? Para un servidor proxy usamos una regla bidireccional. O sea, creamos el pipe 1 y el pipe 2 con igual o diferente ancho de banda y aplicamos una regla pa afuera y otra pa adentro.
Tenga en cuenta que el las conexiones HDSL tiene más ancho de vianda pa abajo que pa arriba. Osea, que salida a la WAN (el router) debe ser más estrecha que salida a la LAN.
En un servidor de correo sí sería útil regular la entrada, ya que hay gente que manda elefantes por el puerto 25. Sobre todo en redes conmutadas o muy lentas. También sería útil moderar la entrada en un servidor que involucre subida de ficheros, por ejemplo, una nube, un servidor de carpetas compartidas.
Ah! por cierto:
Si crearas un pipe y le dijeras que 3 ip, lo usan, el ancho de vianda sería compartido para esas 3 ip. O sea
1 2 3 4 |
|
En este caso, 10, 11 y 12, tienen un total de 128KB/s, si 10 acapara todo el ancho de banda (los 128) entonces 11 y 12 tendrán unos bellos timeout como respuesta. Piensa en todo lo que puedes hacer con eso.
OJO CON EL ÓRDEN!!!
Esa regla machea la salida. Si la colocaras debajo de la regla que permite todo hacia afuera, simplemente, no pinchará porque no machea. Coge por la regla de salida y nunca va al pipe. Como diría los yumas “rule of thumbs”
Las reglas que envían el tráfico al pipe, debes ponerlas arriba de la regla “destino final” del paquete.
De esta manera el paquete va al pipe y luego regresa al cortafuegos. O sea, intenta poner siempre los pipe arriba y el cortafuegos abajo