Soy amante de la filosofía KISS (Keep It Simple Stupid) y del principio de no cambiar algo que funciona perfectamente. ¿Por qué Slackware es la distribución más antigua aún con vida? Porque ha seguido esta línea de pensamiento.

En esta oportunidad les voy a hablar de FirewallD, el firewall desarrollado por Fedora para reemplazar al viejo y querido (por pocos, y odiado por algunos) iptables.



Si hay algo que funciona muy bien en GNU/Linux (desde 1998), eso es iptables, entonces ¡¿por qué reemplazarlo?! Supongo que porque es viejo, o porque los nuevos administradores de sistemas no tienen ganas de aprender sus reglas. Sea cual sea la razón (poco me importa) los muchachos de Fedora decidieron implementar su propio firewall: FirewallD.

FirewallD es un firewall administrado dinámicamente que soporta zonas de confianza... STOP. ¿Zonas de confianza? Esto me trae malos recuerdos:


Esto se llama copiar malas ideas de malos sistemas.

En realidad FirewallD es una capa de abstracción de iptables (sí, de fondo usa iptables) para que los administradores vagos no tengan que lidiar con sus reglas, sino con reglas más simples (no son más simples, son distintas). No gracias, me quedo con iptables.

FirewallD consta de un demonio (firewalld) que gestiona las reglas de iptables/netfilter en tiempo de ejecución, y el cual puede ser manejado por las herramientas firewall-cmd (línea de comandos) y firewall-config (GUI).

Me había olvidado que esta era una de las nuevas mierdas que venían junto con SystemD, hasta que tuve la necesidad de abrir un puerto por primera vez en mi workstation con CentOS 7. En este caso necesitaba abrir los puertos 139 y 445 para poder acceder a un recurso compartido mediante samba, desde una de mis máquinas virtuales:

[root@hal9000 ~]# netstat -tulpn | grep smb
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      9258/smbd           
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      9258/smbd           
tcp6       0      0 :::445                  :::*                    LISTEN      9258/smbd           
tcp6       0      0 :::139                  :::*                    LISTEN      9258/smbd           

¿Qué hice entonces? Como el tiempo urgía, busqué rápido en la guía de seguridad oficial de Red Hat:

Security Guide - 4.5. Using Firewalls.

Donde pude descubrir que es posible configurar el FirewallD ejecutando la herramienta firewall-config:

La configuración se divide en dos tipos: de tiempo de ejecución, y permanente. Para salir del paso decidí habilitar el servicio samba para la zona "public" en tiempo de ejecución, con un simple clic:

Volcando rápidamente las reglas de iptables se observa que el demonio abrió los puertos 137, 138, 139 y 445, cuando sólo era necesario abrir los puertos 139 y 445:

[root@hal9000 ~]# iptables -nL | grep ACCEPT | grep NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 ctstate NEW
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:137 ctstate NEW
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:138 ctstate NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:139 ctstate NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:445 ctstate NEW

Esto se considera un fallo de seguridad. Permitiría a un atacante que logra explotar una vulnerabilidad levantar un proceso escuchando en estos puertos. Es lo que pasa cuando se utilizan estas bonitas herramientas de entorno gráfico. Después los fanboys de Fedora se llenan la boca hablando de seguridad y cgroups, para después terminar con un firewall que abre cualquier puerto, por las dudas, al mejor estilo Windows.

En lugar de esto, hubiera sido suficiente con simplemente ejecutar:

iptables -A INPUT -p tcp -m state --state NEW -m tcp -s 192.168.1.0/24 --dport 139 -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW -m tcp -s 192.168.1.0/24 --dport 445 -j ACCEPT

Lo que hubiera resultado mucho más seguro (porque además estaría filtrando por dirección IP fuente, para que sólo se pueda acceder desde la red asignada a las máquinas virtuales).

¿Entonces FirewallD es una mierda? En principio diría que sí, porque está pensado para administradores idiotas o vagos (que no desean aprender iptables). Aunque esta apertura indiscriminada de puertos no es culpa del demonio firewalld, sino del cliente firewall-config.

A ver qué sucede utilizando firewall-cmd. Primero, abrir nuevamente firewall-config y destildar samba de la zona "public" en la configuración de tiempo de ejecución. Al hacer esto se cierran los puertos mencionados anteriormente:

[root@hal9000 ~]# iptables -nL | grep ACCEPT | grep NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 ctstate NEW

Ahora, utilizando el cliente de línea de comandos, abrir los puertos 139 y 445:

[root@hal9000 ~]# firewall-cmd --zone=public --add-port=139/tcp6
success
[root@hal9000 ~]# firewall-cmd --zone=public --add-port=445/tcp6
success

También es posible utilizar los nombres de los servicios, en lugar de los números de puertos, tal como se definen en el archivo /etc/services:

# firewall-cmd --zone=public --add-port=microsoft-ds/tcp6
# firewall-cmd --zone=public --add-port=netbios-ssn/tcp6

El resultado es el siguiente:

[root@hal9000 ~]# iptables -nL | grep ACCEPT | grep NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 ctstate NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:445 ctstate NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:139 ctstate NEW

Tal como sospechaba, sólo se abrieron los puertos indicados, lo cual resulta más seguro que utilizando la herramienta firewall-config.

Ahora bien, para que estos puertos queden abiertos permanentemente, se debe utilizar la opción --permanent:

[root@hal9000 ~]# firewall-cmd --zone=public --add-port=139/tcp --permanent
success
[root@hal9000 ~]# firewall-cmd --zone=public --add-port=445/tcp --permanent
success

Entonces, lo que antes se hacía con los siguientes comandos:

iptables -A INPUT -p tcp -m state --state NEW -m tcp -s 192.168.1.0/24 --dport 139 -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW -m tcp -s 192.168.1.0/24 --dport 445 -j ACCEPT
service iptables save

Ahora se hace con los siguientes:

firewall-cmd --zone=public --add-port=139/tcp6
firewall-cmd --zone=public --add-port=139/tcp6 --permanent
firewall-cmd --zone=public --add-port=445/tcp
firewall-cmd --zone=public --add-port=445/tcp --permanent

Por favor díganme dónde está la simplificación, porque no la veo. Y para colmo pierdo flexibilidad.

Cómo reemplazar FirewallD por iptables en CentOS 7

Posiblemente la mayoría de los administradores de red preferirán trabajar directamente con iptables, por su mayor flexibilidad y por estar familiarizados con la configuración de dispositivos de firewall físicos, como por ejemplo los PIX y ASA de Cisco. Si son de aquellos que prefieren quedarse con iptables, es factible reemplazar FirewallD y recuperar el servicio iptables tradicional. La realidad es que no nos queda otra que acostumbrarnos al nuevo FirewallD. Sabemos que quien pisa fuerte y marca tendencia en la comunidad, lamentablemente es Red Hat (mal que le pese a Debian). Por ello seguramente en el futuro tendremos problemas al deshabilitar FirewallD. Si de todas formas deseamos quitar FirewallD del medio, se deben realizar las siguientes modificaciones en el sistema:

Instalar el servicio iptables:

yum install iptables-services

Deshabilitar el demonio firewalld y habilitar el servicio iptables:

systemctl mask firewalld
systemctl enable iptables

Detener el demonio firewalld e iniciar el servicio iptables:

systemctl stop firewalld
systemctl start iptables

Configurar las reglas del firewall con iptables (puede ser utilizando un script Bash, tal como expliqué en el artículo Cómo configurar el cortafuegos en Debian).

Guardar las reglas ejecutando:

service iptables save

Similar a lo que se hace en Debian (service iptables-persistent save).

Documentación sobre FirewallD

FirewallD - Fedora Project.

Red Hat Enterprise Linux 7 - Security Guide - 4.5. Using Firewalls.

$ man firewalld
$ man firewalld.conf
$ man firewalld.service
$ man firewalld.zone
$ man firewalld.zones
$ man firewall-cmd
$ man firewalld-config


Tal vez pueda interesarte


Compartí este artículo y dejá tu comentario