martes, 13 de diciembre de 2011

Una guía de PF para principiantes (OpenBSD packet filter)

Bien, hace varios días publicamos un trabajo salido del penúltimo número de la revista BSDmag que trataba una comparación entre FreeBSD y Ubuntu Server. Les dije entonces que el susodicho número incluida una guía básica para configurar un cortafuegos con el filtro de paquetes de OpenBSD PF y que pretendíamos traerlo a este sitio, pues aquí les va (por cierto, no se en que paró aquel asunto de las puertas traseras en Ipsec  alguien dijo "la vida es ávida y desmemoriada"...). El artículo refiere al archivo de configuración usado en OpenBSD, pero es lo mismo para con FreeBSD (el autor dice que lo probó en PC-BSD, ergo, es lo mismo). Nuevamente, si les interesan estos tópicos (y dominan el idioma) les recomiendo la suscripción. La traducción hoy es de Jorge, esperamos les resulte útil, así pues, provecho!

Una guía de PF para principiantes (OpenBSD packet filter)
OpenBSD, FreeSDB y PC-BSD utilizan un cortafuegos incorporado llamado "packet filter" (PF para abreviar). Este artículo tiene la intención de que los principiantes asimilen un conocimiento básico de como utilizar PF en OpenBSD. Varios conceptos intermedios y avanzados han sido intencionalmente omitidos.

Lo que aprenderán.... 
  • Una comprensión básica de un archivo /etc/pf.conf para seguridad básica
Conocimientos previos necesarios....
  • Habilidad para utilizar la línea de comando en OpenBSD
  • Algún conocimiento sobre números de puertos TCP y UDP 
Esta guía puede aplicarse a otros sistemas operativos * BSD, aunque no lo probé en todos. He probado  PC-BSD, lo que significa que estas instrucciones también sirven para FreeBSD. Temas más avanzados pueden ser específicos de OpenBSD. Ni NetBSD ni Dragonfly BSD usan PF. 
Me parece que la documentación de OpenBSD a menudo lanza demasiada información para los principiantes desde el primer momento. La guía de usuarios de PF no es la excepción. Lo siguiente es un conjunto simplificado de esas instrucciones. La sintaxis básica que los novatos deben conocer es esta:

action [direction] [quick] [on interface] [af] [proto protocol] \ [from src_addr] [to dst_port]

He omitido intencionalmente opciones más "oscuras" o avanzadas. 

action: Puede ser block o pass, o sea, permite o no el tráfico. Se explica por sí mismo. 
direction: Puede ser IN o OUT (entrada o salida).
quick: Si un paquete coincide con una regla específica marcada como quick, la regla se considera como la última regla coincidente y por tanto se ejecuta la acción.  
interface: Se explica por sí misma. En VMware  vic0. 
af: Puede ser  inet  para IPv4 ó inet6 para IPv6. 
proto: TCP, UDP, ICMP o ICMP6. 

Puede utilizar directiva "all" en algunos lugares, pero no vamos a hablar esto mas que para las dos últimas líneas del archivo /etc/pf.conf. En la mayoría de los casos, ud deseará especificar  lo que está permitido, y luego bloquear  todo lo demás. Para ello, hacemos un uso liberal de la palabra "quick". Para el tráfico entrante, digamos que sólo quiere permitir SSH y HTTP. Añada las siguientes reglas: 

pass in quick on vic0 proto tcp to port 22
pass in quick on vic0 proto tcp to port 80

Tenga  en cuenta que simplemente excluimos las directivas que no necesitamos. En este caso, no es necesario especificar la versión del protocolo IP o de donde viene el tráfico porque quiero permitir el tráfico en ambas versiones de IP y desde cualquier lugar. 
Ahora, permitir los pings es un poco más complicado. ICMP es una bestia diferente a TCP o UDP. Tenemos que especificar la palabra clave "all"  que significa desde cualquier lugar, a cualquier puerto. También debemos especificar el tipo de paquete ICMP (echoreq): 

pass in quick inet proto icmp all icmp-type echoreq 

También vamos a permitir sólo cierto tráfico de salida. Esto podría protegerle en caso de que un usuario no autorizado intente utilizar una aplicación que ud no quiere que utilice. Para este ejemplo, permitiremos que nuestro servidor utilize: 

• FTP (para comandos como pkg _ add
• SSH (acceso remoto a otros servidores SSH) 
• SNMP (para que sendmail pueda enviarnos notificaciones) 
• DNS (para que nuestro servidor pueda resolver nombres de host) 
• HTTP (para usar comandos como wget
• Ping 

Aquí están las reglas: 

pass out quick on vic0 proto tcp to port 20 # Usado por FTP en modo PASV  
pass out quick on vic0 proto tcp to port 21
pass out quick on vic0 proto tcp to port 22
pass out quick on vic0 proto tcp to port 25
pass out quick on vic0 proto udp to port 53
pass out quick on vic0 proto tcp to port 80
pass out quick on vic0 proto tcp to port 443
pass out quick inet proto icmp all icmp-type echoreq 

Para bloquear todo el tráfico que no hallamos permitido anteriormente, simplemente  agregamos más líneas al final del archivo: 

block out all
block in all 

Ahora vemos la importancia de la Directiva "quick". Con ella, el filtro de paquetes aplica las reglas para el tráfico coincidente (pass).  Sin ella, el filtro de paquetes continúa buscando coincidencias hasta el final del conjunto de reglas. Dado que las directivas "block out all" y "block in all" coinciden con todo el tráfico, estaremos bloqueando todo aquello que no incluya "quick". ¿Podríamos haber evitado todo este asunto con "quick" tan solo colocando las líneas de bloqueo en la parte superior? Probablemente. Acabo de descubrir que usando "quick", y colocando entonces las directivas de bloqueo al final de la configuración hace el archivo de configuración fácil de leer y entender. Ahora simplemente ejecute  pfctl -f /etc/pf.conf para recargar y probar las reglas. 

¿Qué pasa cuando algo sale mal? 
Si usted piensa que las reglas del firewall están causando problemas, entonces comente las dos reglas de bloqueo al final del fichero /etc/pf.conf.

Utilize  pfctl -f /etc/pf.conf para recargar las reglas, y vea si eso arregla las cosas. El comando telnet es también su amigo. Nótese que arriba he permitido el protocolo telnet (puerto TCP 23). Lo bueno de la utilidad telnet es que nos permite hacer una conexión en cualquier puerto TCP. Sabemos que el puerto 80 es HTTP, por lo que puede probar si el puerto 80 está trabajando: 

# telnet bsdmag.org 80

Trying 79.125.23.174...
Connected to bsdmag.org.
Escape character is '^]'. 

[CTRL + C]  le regresa a la consola. Ahora vamos a intentar conectarnos a algo que nuestro firewall permita, pero que el equipo remoto no. Quedaremos colgados indefinidamente en: 

# telnet bsdmag.org 22
Trying 79.125.23.174... 

Una vez más, [CTRL + C] le regresa la consola. Ahora que sabemos qué esperar de los puertos permitidos, vamos a tratar uno que no esté permitido. Vamos a tratar con TFTP: 

# telnet bsdmag.org 69
Trying 79.125.23.174...
telnet: connect to address 79.125.23.174: No route to host 

Sabemos que si existe conexión con el host, por lo que se deben estar bloqueando las conexiones salientes TFTP con PF. Esa es la clave. Cuando telnet le dice que no hay ruta a un host al que de otra forma puede acceder, entonces debe revisar en /etc/pf.conf

¿Qué pasa si tiene un host remoto, y accidentalmente cierra SSH? 
Pues bien, como digo al final, esa es una buena razón para usar bsdvm.com  como proveedor de hosting. Puedo acceder a la consola de VMware para volver a activar SSH. De lo contrario, sería un cretino que debería permanecer en el anonimato. Para librar responsabilidades: No estoy de ninguna manera afiliado a bsdvm.com. Solo soy un fan. Un gran fan. Tener acceso a consola es endiabladamente conveniente para tantas y tantas tareas. 
En la próxima versión  de OpenBSD,  la 5.0, nos veremos usando el filtro de paquetes para priorizar cierto tipo de tráfico. Más sobre esto luego. Por ahora, ya debes tener alguna comprensión de los fundamentos de PF. Disfruta tu nuevo firewall!...



Referencias: