Intro
Todo comenzó con la necesidad de filtrar el puerto 111 en nuestros servidores.
En el caso de servidores Linux empleamos la opción de iptables. Sin embargo, los servidores basados en FreeBSD, como los FreeNAS, que son los que sirven los volúmenes NFS no tienen iptables. Como podríamos filtrar el puerto 111 para evitar que sirva para lanzar ataques de DDoS?
Entonces hicimos lo que todo administrador de sistemas debe de hacer: Googleamos y… voilá!, encontramos la opción de packet filtering (pf para los amigos) en un artículo (sigue el link si te interesa acceder a la fuente). Personalmente ya conocía packet filtering, pero eso de dejar los servidores sin acceso a internet por una configuración defectuosa no me apetecía demasiado.
Para los curiosos, dejo un enlace a la documentación de packet filtering web de OpenBSD en la sección de enlaces.
Filtrando el puerto 111 en FreeNAS
Generar el archivo de configuración
Generar el archivo de configuración no es complicado. Lo complicado es hacer que éste se mantenga en FreeNAS tras un reboot. Podríamos guardarlo en uno de los volúmenes montados, pero en ese caso podría perderse al sustituir el volumen donde se encuentra. Decidimos guardarlo en el directorio /root. Sin embargo, todos sabemos que FreeNAS monta el sistema de archivos raiz (/) como readonly. Por eso, lo primero que hemos de hacer es montarlo para escritura. Para ello empleamos la instrucción:
# mount -uw /
Entonces con nano creamos el archivo pf.conf. En principio no nos interesa hacer un filtrado de todo el tráfico de red en FreeNAS, sencillamente queremos evitar que los malos puedan acceder al puerto 111 y emplearlo para lanzar ataques de DDoS. El archivo pf.conf sería el siguiente:
# pf config file ext_if="vtnet0" my_ip="XXX.XXX.XXX.XXX" table <bruteforce> persist set skip on lo0 # lo0 y ipfw0 son el resto de interfaces distintas de vtnet0 que aparecen cuando hacemos un ifconfig. Queremos que solamente filtre en esta interfaz e ignore el resto set skip on ipfw0 set block-policy return # logging set loginterface $ext_if scrub in all block quick from <bruteforce> # Allow rpcbind from UV pass in quick on $ext_if proto tcp from XXX.XXX.0.0/16 to $my_ip flags S/SA keep state pass in quick on $ext_if proto udp from XXX.XXX.0.0/16 to $my_ip # Block rpcbind from any block in on $ext_if proto tcp from any to any port 111 block in on $ext_if proto udp from any to any port 111 pass out on $ext_if from any to any keep state
Una vez finalizado, volvemos a poner el sistema de archivos como solo lectura:
# mount -ur /
Evitar ataques bruteforce en el puerto ssh
En el artículo que tenemos en la sección enlaces dan una explicación más detallada. Aquí nos limitaremos a indicar la línea que hemos introducido en pf.conf para evitar los ataques por fuerza bruta al puerto ssh. La línea es:
# Avoid ssh bruteforce attacks
pass quick log proto tcp from any to any port ssh flags S/SA keep state (max-src-conn 15, max-src-conn-rate 5/3, overload <bruteforce> flush global)
En esencia, añadimos a la tabla <bruteforce>, definida previamente en el archivo de configuración (overload <bruteforce>) la ip de cualquier equipo que acceda al puerto ssh con más de 15 conexiones simultáneas (max-src-conn 15) o trate de acceder al puerto más de 5 veces en 3 (max-src-conn-rate 5/3) segundos. Por último, desconecta (flush) al host que alcance los límites. El valor global indica que se tienen en cuenta conexiones referidas también a otras reglas. El log hace que el sistema registre los accesos.
Arrancar pf al inicio
En un sistema FreeBSD se activaría al inicio con las siguientes líneas en el archivo /etc/rc.conf:
pf_enable="YES"
pf_rules="/root/pf.conf"
Sin embargo, por lo que hemos dicho antes, el sistema restaura el archivo /etc/rc.conf en cada inicio. Para que se mantengan, hemos de recurrir a los ‘Tunables’ de FreeNAS. Añadiremos los siguientes:
Reiniciamos para comprobar que todo está correcto.
Visualizar logs de PF
Para visualizar los contenidos del fichero de log de pf (/var/log/pflog) empleamos el comando:
# tcpdump -n -e -ttt -r /var/log/pflog
Visualizar contenido de la tabla bruteforce
Una vez tenemos el pf funcionando queremos comprobar que todo está correcto. La curiosidad nos corroe y queremos ver quien ha caido en nuestra trampa. Para listar el contenido de la tabla bruteforce deberemos emplear el siguiente comando:
# pfctl -t bruteforce -T show
Eliminar una IP de la tabla bruteforce
Podemos eliminar una IP de la tabla bruteforce con el siguiente comando:
# pfctl -t bruteforce -T delete <IP>
Comandos interesantes
# pfctl -f /etc/pf.conf
Load the pf.conf file
# pfctl -nf /etc/pf.conf
Parse the file, but don’t load it
# pfctl -sr
Show the current ruleset
# pfctl -ss
Show the current state table
# pfctl -si
Show filter stats and counters
# pfctl -sa
Show EVERYTHING it can show
Enlaces