El SysAdmin del 3er Mundo

todo lo que expliqué mientras nadie prestaba atención

ipfw simple y conciso

| Comments

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

“/etc/rc.conf”
1
2
 firewall_enable="YES"
 firewall_type="/usr/local/etc/ipfw.rules"

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

“/usr/local/bin/reiniciar_ipfw.sh”
1
2
3
4
5
 #!/bin/csh
 service ipfw stop
 ipfw -q flush
 service ipfw start
 ipfw show

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.

“ipfw.rules”
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
 # lo permitimos todo pa afuera
 ipfw -q add allow all from any to any out keep-state

 # permite todo por el localhost
 ipfw -q add allow all from any to any via lo0

 # las conexiones que ya estén iniciadas, pásalas
 # compara eso con el de iptables
 ipfw -q add allow tcp from any to any established

 # permite que te hagan ping desde la LAN 
 # pero no mucho icmp para que no hagan flood
 ipfw pipe 1 config bw 30KBytes
 ipfw -q add pipe 1 icmp from 192.168.1.0/24 to me in via xn1
 ipfw -q add allow  icmp from 192.168.1.0/24 to me in via xn1

 # permite que accedan al proxy desde la LAN
 ipfw -q add allow tcp from 192.168.1.0/24 to me 3128 via xn1

 # permite el servidor web pero solo deade la WAN
 # en este caso "me" será la ip de la WAN
 ipfw -q add allow tcp from any to me dst-port 80 via xn0

 # descarta el resto de los paquetes ENTRANTES
 # esta regla casi nunca es necesaria, ya que
 # suele ser implícita, o sea, drop por defecto
 ipfw -q add drop all from any to any

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.

“ipfw dst-port”
1
2
3
4
5
6
 # permite que accedan al proxy desde la LAN
 ipfw -q add allow tcp from 192.168.1.0/24 to me 3128 via xn1

 # permite el servidor web pero solo deade la WAN
 # en este caso "me" será la ip de la WAN
 ipfw -q add allow tcp from any to me dst-port 80 via xn0

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:

“ipfw y dummynet”
1
2
 ipfw add pipe 1 ip from me to 192.168.1.0/24 out via xn0
 ipfw pipe 1 config bw 128KBytes

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

“ipfw y dummynet”
1
2
3
4
 ipfw add pipe 1 ip from me to 192.168.1.10/24 out via xn0
 ipfw add pipe 1 ip from me to 192.168.1.11/24 out via xn0
 ipfw add pipe 1 ip from me to 192.168.1.12/24 out via xn0
 ipfw pipe 1 config bw 128KBytes

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

Si este artículo te resultó interesante, considere donar 0.07 BTC: 1Kg4gu3e7u8HUw8bj5NbBciRg6Y56kuFCU

Comments