Cómo configurar "FirewallD" o "IPtables" en Red Hat/CentOS 7 y Fedora 21

Net-filter es un firewall en Linux, aquellos usuarios medio o avanzados lo conocen muy bien. Firewalld es un daemon dinámico para administrar cortafuegos con soporte para zonas de redes. En la versión anterior, RHEL y CentOS 6 se usó  iptables como un daemon para el marco de filtrado de paquetes. En RHEL / CentOS 7 y Fedora 21 la interfaz de iptables está siendo reemplazada por firewalld.

Es muy recomendable comenzar a utilizar Firewalld en lugar de iptables, ya que el soporte puede verse interrumpido en el futuro.

Sin embargo, iptables todavía es compatible y se puede instalar con el comando YUM. No podemos mantener Firewalld e iptables en el mismo sistema, lo  que puede llevar a conflictos.

En iptables, usamos para configurar INPUT, OUTPUT & FORWARD CHAINS pero en Firewalld, el concepto que usa es Zones. De forma predeterminada, hay diferentes zonas disponibles en firewalld que discutiremos en este artículo.

La zona básica que normalmente son pública y la zona privada,  ojo aqui estoy partiendo del hecho de que usted no es un usuario medio o experto. Para hacer que las cosas funciones correctamente a nivel de redes con estas zonas, necesitamos agregar la interfaz con el soporte de zona especifico y luego podemos agregar los servicios a firewalld.

Por defecto, hay muchos servicios disponibles, una de las mejores características de Firewalld es, que viene con servicios predefinidos y podemos tomar estos servicios como ejemplos para agregar los nuestros propios, simplemente copiandolos.

Firewalld funciona muy bien con puentes tipo IPv4, IPv6 y Ethernet también. Podemos tener la configuración de tiempo de ejecución y permanente en firewalld. Vamos a empezar a trabajar con zonas y crear nuestros propios servicios y otros usos mucho más emocionante de firewalld.

Les recomiendo los siguiente videos
https://www.youtube.com/watch?v=TyMallqnWiw


FirewallD

Se trata de un cortafuegos dinámico con soporte para IPv4, IPv6 y puentes de red, que nos permite definir en las interfaces de red ciertas zonas de confianza, a parte de las tradicionales reglas de reenvío, denegación, enmascaramiento, etc…
Al ser dinámico podremos cargar nuevas reglas o modificar las existentes sin necesidad de reiniciar el servicio de cortafuegos, lo que implicaría entre otras cosas, romper las conexiones y, descargar y cargar módulos del kernel. Otra ventaja de firewalld es la de crear reglas de una forma sencilla, basta con seleccionar un servicio (combinación de puerto y protocolo) y elegir a que zona queremos añadirlo. De la misma manera añadiremos interfaces de red, redes, etc…
La desventaja es que “nos obliga” a tener que utilizar exclusivamente firewalld, ya que este no permite la modificación de reglas mediante los tradicionales comandos IPtables. Cierto es, que es nuestra decisión el activar el tradicional IPtables o firewalld pero nunca los dos de forma simultánea.
Nota: Podemos ver a firewalld como el hermano de ufw de Debian, una capa de abstracción para facilitarnos la vida a la hora de configurar el cortafuegos usando de fondo iptables/netfilter.

Manos a la obra

Estamos ante uno de los sistemas que implementan firewalld, bien… ¿como empezamos?, pues viendo si el cortafuegos se encuentra activado o no:
# systemctl status firewalld
ó
# firewall-cmd --state
Para interactuar con firewalld podremos utilizar las herramientas firewall-config (GUI) o firewall-cmd (CLI). Nosotros en esta entrada aprenderemos firewall-cmd.
Activar firewalld en caso de encontrarse desactivado:
# systemctl start firewalld
¿Como instalar firewalld si no viene instalado?
# yum install firewalld
Si además queremos la interfaz gráfica:
# yum install firewall-config

¿Zonas de confianza?

Al inicio, hemos comentado la “gran” novedad, la de definir zonas de confianza.
¿Que zona tenemos actualmente definida?
# firewall-cmd --get-default-zone
¿Que interfaz de red tenemos asignada a esta zona?
# firewall-cmd --get-active-zones
¿De que otras zonas dispongo?
# firewall-cmd --get-zones
 
 
Breve descripción de las zonas:

block: Se rechaza cualquier conexión de entrada emitiendo una respuesta ICMP avisando al origen de la denegación de la conexión.

drop: Se deniega cualquier conexión de entrada sin emitir paquete que informe del rechazo.

dmz: Zona desmilitarizada. Solo serán aceptadas aquellas conexiones preseleccionadas. Una especie de acceso público pero en el que se acaba limitando las conexiones.

external: Redes externas con enmascaramiento habilitado. Solo las conexiones de entrada preseleccionada podrán accesar.

internal: Redes internas (privadas)

home: Área del hogar. Conocido por el mundo MS Windows.

work: Área de trabajo

public: Redes públicas. Las conexiones no son de confianza.

trusted: Toda conexión es aceptada

¿Como cambiar la zona por defecto?
# firewall-cmd --set-default-zone=work
 
¿Como añadir una interfaz de red a una zona concreta de forma temporal?
Info: Cuando añadimos una regla en firewalld esta puede usarse de forma temporal (se perderá al reinicio) o de forma permanente
# firewall-cmd --zone=internal --change-interface=eth0
¿Y para que perdure tras el reinicio del servicio?
# firewall-cmd --permanent --zone=internal --change-interface=eth0
¿Como averiguar a que otras zonas pertenece por ejemplo eth0?
# firewall-cmd --get-zone-of-interface=eth0
¿Como listar la configuración de una zona?
# firewall-cmd --zone=public --list-all
Nota: Esto mostrará la configuración que se encuentra en ejecución, quizás diferente a la que podría tener si reiniciáramos.

¿Listar la configuración permanente de una zona? 
Esto es, la que tendrá aun cuando reiniciemos el servicio:
# firewall-cmd --zone=public --permanent --list-all
 
¿Como listar solo las redes asignadas a una determinada zona?
# firewall-cmd --zone=trusted --list-sources
 
¿Como crear mi propia zona, por ejemplo llamada secureme?
# firewall-cmd --permanent --new-zone=secureme
 
¿Como añado una red (source) a mi nueva zona de forma permanente?
# firewall-cmd --permanent --zone=secureme --add-source=192.168.1.0/24
 
¿Como recargamos el servicio para que el cambio se haga efectivo?
# firewall-cmd --reload
 
 
IMPORTANTE: Si queremos por ejemplo añadir una red (source) a una zona pero de forma temporal, bastaría con no pasar el parámetro –permanent y no recargar el servicio, de lo contrario cancelaríamos la operación.
Con el anterior comando podemos también, eliminar el source si aplicamos –remove-source en vez de –add-source o cambiarla de zona si hubiésemos utilizado –change-source y una nueva zona.

Añadiendo servicios (puertos y protocolos)

Ahora que hemos finalizado creando nuestra propia zona de confianza (secureme) le hemos asignado nuestra source (192.168.1.0/24), vamos a agregarle algunas reglas de conexiones, por ejemplo:
 # firewall-cmd --permanent --zone=secureme --add-service=samba
 
Añadimos el acceso a samba en la zona secureme. Ahora habrá que recargar el servicio:
# firewall-cmd --reload
 
Ahora vamos a desactivar temporalmente el servicio http de nuestra zona secureme:
# firewall-cmd --zone=secureme --remove-service=http
 
Nota: Para los principales servicios existen definiciones en los archivos /usr/lib/firewalld/services y /etc/firewalld/services (este último tiene preferencia en caso de existir una definición para un servicio concreto en ambos archivos). Podremos crear nuestras propias definiciones para aquellos servicios que no vengan predefinido.
¿Como ver los servicios que vienen predefinido?

# ls /usr/lib/firewalld/services/
¿Como ver los servicios definidos por el usuario?

# ls /etc/sysconfig/iptables
Permitir el tráfico por el puerto 443 en nuestra zona secureme de forma permanente:

# firewall-cmd --zone=internal --add-port=443/tcp
 
Info: Podemos ver los servicios y puertos habilitados en una zona concreta (en este caso secureme) de la siguiente manera:

# firewall-cmd --zone=secureme --list-services
# firewall-cmd --zone=secureme --list-ports
 
Crear masquerading desde una zona external a la default que tenemos seteada (secureme):
# firewall-cmd --permanent  --zone=external --add-masquerade
 
Nota: –remove-masquerade para eliminar el masquerading

¿Como ver si tenemos activo el masquerading?

# firewall-cmd --query-masquerade
 
¿Como reenviar desde y hacia un puerto?

# firewall-cmd --permanent --zone=external --add-forward-port=port=22:proto=tcp:toport=2222
 
Nota: Esto reenviará el trafico entrante desde la zona external por el puerto 22 al puerto 2222 de nuestra zona secureme (activa como default). Podemos ver los reenvíos de puertos con la opción –query-forward-port y eliminarlo con –remove-forward-port

¿Como habilitar IPtables en sistemas que activan FirewallD como cortafuegos predefinido?

Si queremos utilizar IPtables en un sistema que activa por defecto firewalld (Fedora 21 en adelante y Red Hat 7, lo que incluye entre otras distribuciones a CentOS) bastará con desactivar el servicio:
# systemctl mask firewalld.service
# systemctl stop firewalld.service
 
Instalar, habilitar y activar IPtables IPv4 e IPv6:

# yum install iptables-services
# systemctl enable iptables.service
# systemctl enable ip6tables.service
# systemctl start iptables.service
# systemctl start ip6tables.service
 
Listo, de ahora en adelante podemos usar nuestro conocido IPtables. Definiendo las reglas como ya sabemos, bien mediante los comandos, o en sus archivos estáticos (/etc/sysconfig/iptables y /etc/sysconfig/ip6tables). Podremos además instalar system-config-firewal para crear reglas de una forma cómoda.

Ahora bien, muy interesante, pero que pasa si quiero utilizar iptables en lugar del firewalld, a pesar de que en cualquier momento dejara de tener soporte......

En este mundo teconlogico existen siempre este tipo de preguntas y excepciones, así que para cubrir el tema de forma completo...... jejejejejejejeje adoro escribir


Reglas IPtables

IPtables permite realizar diferentes configuración mediante el uso de las reglas que afectan al sistema de filtrado, ya sea generación de logs, acciones de pre y post routing de paquetes, NAT o forwarding.

IPtables se constituye en tres tablas: filter (para el sistema de filtrado), nat (enmascaramiento y reenvío) y mangled (configuración de opciones de paquetes). Estas tablas a su vez contienen una serie de cadenas que agruparán determinadas reglas según su función. 

Por ejemplo para la tabla NAT contamos con PREROUTING que permitirá modificar paquetes entrantes antes de su enrutamiento, POSTROUTING los modificará antes de que salgan al destino y OUTPUT que modifica los paquetes generados una vez se hayan enrutado, mientras que en la tabla FILTER podemos añadir reglas a las cadenas (chains) INPUT para los paquetes que entran, OUTPUT para los que salen y FORWARD si quisiéramos realizar un reenvío.


Importante: Cuando queremos hacer forwarding de paquetes, por defecto GNU/Linux no trae habilitada la opción por lo que deberemos de activarla nosotros. Podemos hacerlo de forma temporal (será volátil) a través del sistema de ficheros /proc o bien de forma estática:
  • Volátil:
echo 1 > /proc/sys/net/ipv4/ip_forward
  • Permanecerá a reinicios: deberemos de editar el archivo /etc/sysctl.conf y añadir:
net.ipv4.ip_forward = 1
 
Los paquetes son analizados primeramente por la tabla NAT, a continuación la tabla FILTER decidirá si pasarán (en caso de que vayan destinado a nosotros) o si hay que reenviarlos a otro destino.

No podemos abarcar ni 1% de lo que supone IPtables por lo que se recomienda acudir a su página man. No obstante se va a explicar como crear algunas reglas básicas para las tablas FILTER y NAT.

Para comenzar a utilizar IPtables deberemos de tener el servicio corriendo. Esto ya sabremos como hacerlo, en función del sistema de inicialización que estemos usando. Para sysV bastará con /etc/init.d/iptables start (stop para pararlo).

Sería interesante comprobar de que reglas dispone la configuración actual de IPtables:
$ sudo iptables -L

Crear reglas en la tabla FILTER

Para crear una regla básica en la tabla FILTER y en la cadena INPUT, podríamos utilizar la siguiente sintaxis:
$ sudo iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
Con -s <ip> indicamos el origen (source) con -j la acción (en este caso aceptar) y podríamos haber utilizado -d para indicar un destino.
El orden de las reglas es importante, por lo que deberemos de colocar siempre las menos restrictivas en las primeras posiciones, podemos hacerlo directamente desde la línea de comandos, tal que así:
$ sudo iptables -I INPUT 3 -s 192.168.1.0/24 -j ACCEPT
Esto haría que la regla se colocara en la tercera posición. La opción -A simplemente añade, -I inserta en una determinada posición.
Podremos eliminar por ejemplo esta misma regla si pasamos la opción -D
$ sudo iptables -D INPUT 3
o
$ sudo iptables -D INPUTS -s 192.168.1.0/24 - ACCEPT
Una regla mas elaborada podría quedar así:
$ sudo iptables -A INPUT -p tcp --dport 80 -s 0.0.0.0 -d 192.168.1.23 -j ACCEPT
Con esta regla indicamos que cualquier conexión proveniente (-s) de cualquier origen con destino (-d) al equipo con IP 192.168.1.23 concretamente por el puerto 80 (–dport, puerto destino) con protocolo tcp (-p) sea (-j) aceptada.
Y con alguna opción:
$ sudo iptables - A INPUT -p tcp --dport 80 -s 0.0.0.0 -d 192.168.1.23 -j REJECT --reject-with tcp-reset
Aquí rechazamos las conexiones (REJECT) y ademas emitimos una respuesta del tipo tcp-reset
Cuando modificamos las reglas deberemos de salvarlas. Para hacerlo en Red Hat bastaría con pasarle el parámetro ‘save‘ (service iptables save o /etc/init.d/iptables save y estas se guardarán en /etc/sysconfig/iptables.
Si estamos usando una distribución Debian o derivado además de ‘save‘ deberemos de pasarle un nombre por lo que acabarán guardándose en /var/log/iptables/<nombre-reglas>
Aviso: Si el directorio no existe deberemos de crearlo.
Para cargar las reglas podremos pasar el parámetro ‘load‘ en Red Hat y ‘load nombre-reglas‘ en Debian.

Crear reglas en la tabla NAT

Podemos ver las reglas para una determinada tabla con el parámetro -t y en nombre de la tabla:
$ sudo -t nat -L
Si queremos ser mas meticulosos y ver las reglas de una cadena concreta y ademas con detalles:
$ sudo -t nat -L PREROUTING -n -v
La opción -n da resultados numéricos y -v detalla información
Podemos eliminar todas las reglas de una tabla:
$ sudo -t nat -F
O concretar a solo las de una determinada cadena de una tabla concreta:
$ sudo -t nat -F OUTPUT
Podemos, además de eliminar todas las reglas, poner los contadores a cero (útil cuando vamos a comenzar a definir reglas desde 0):
$ sudo -t nat -F
$ sudo -t nat -Z
 
Nota: Podemos omitir la tabla para que afecte de forma global.
Crear la regla de oro, es decir, conectar todos los ordenadores de una red privada con Internet a través de un dispositivo que posee dos interfaces de red, una conectada hacia Internet y la otra hacia el switch de la red privada. Esto recibe el nombre de Source NAT o SNAT (cambia la dirección IP de origen, en este caso para convertirla en la IP pública de nuestro ISP):
$ sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 88.23.144.210
Añadimos esta regla a la cadena POSTROUTING indicando el origen (-s) nuestra red privada. Solo se aplicará a los paquetes que salgan (-o, output) por la interfaz de red ‘eth0‘, la acción (-j) será SNAT y la nueva IP es 88.23.144.210 (la ofrecida por nuestro ISP). Existen diferentes formas de conocer nuestra IP pública, por ejemplo a través del router o de Internet, accediendo a direcciones como http://www.cualesmiip.com

Aviso: Este tipo de regla es configurada de esta manera cuando la IP que nos ofrece nuestro ISP es estática. Suele ser un servicio extra ofrecido por la compañía mediante pago.
Ahora vamos a crear la misma regla pero para una IP dinámica, es decir, lo común en cuanto a las IP ofrecidas por los ISP.

$ sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
 
Como vemos solo cambia la acción, que en este caso usamos MASQUERADE que lo que hace es usar la IP que tiene en esos momentos configurada nuestra interfaz eth0

Para terminar con la configuración de reglas básicas de IPtables vamos a crear una regla común, que por lo general se suele hacer a nivel ‘casero‘ desde el propio firewall del router ofrecido por nuestro ISP, y es la de direccionar peticiones de acceso a un determinado servicio que escucha en un puerto concreto.

 El circuito típico sería, una conexión que entra desde la IP pública y que debe ser encaminada hacia una dirección IP privada específica en la cual puede haber corriendo varios servicios pero en concreto queremos configurar el servidor web que por defecto escucha en el puerto 80. Para conseguir esto deberemos de aplicar la regla a la cadena PREROUTING ya que el paquete acaba de entrar y seremos nosotros quien le cree la ruta de encaminamiento.

$ sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 192.168.1.52
Nuevas opciones serían la -i (input) y la acción DNAT que es equivalente a –to-destination con la que se modifica la IP de destino.

Comentarios

Entradas populares