Explicamos de forma rápida y sencilla cómo abrir un número de puerto o bien un servicio (http, ftp, ssh, …) en el cortafuegos (firewall) de Linux CentOS 8. Lo mostramos desde la línea de comandos en un equipo sin modo gráfico, con Linux CentOS 8 Minimal. Aunque para realizar este artículo hemos usado Linux CentOS 8.0, todo lo que explicamos servirá para cualquier distribución de Linux que use firewalld.

Requisitos para abrir puertos y servicios en cortafuegos de Linux CentOS 8

Únicamente necesitaremos un equipo o máquina virtual con Linux CentOS 8 como sistema operativo. Deberemos ejecutar unos comandos, por lo que necesitaremos acceso a la línea de comandos (shell o terminal) y un usuario y contraseña con permisos suficientes para ejecutar estos comandos.

En instalaciones estándar de Linux CentOS 8, el servicio SSH (número de puerto 22) vendrá abierto en el cortafuegos por defecto. De esta forma podremos acceder a la consola/terminal desde otro equipo remotamente, por ejemplo usando PuTTY. Para conectarnos únicamente necesitaremos saber la dirección IP del equipo Linux, un usuario y una contraseña. Podremos conectarnos desde otros equipos Linux o bien desde equipos Windows o MAC OS:

Requisitos para abrir puertos y servicios en cortafuegos de Linux CentOS 8

¿Para qué abrir un puerto o servicio en equipo Linux CentOS 8?

Por defecto y por seguridad, en las instalaciones estándar de Linux CentOS 8, todos los puertos estarán cerrados salvo los servicios: cockpit (herramienta de monitorización Linux, estará el servicio abierto si la hemos elegido en la instalación), dhcpv6-client (para DHCP en IPv6) sshel (servicio SSH para conexión por terminal remota al equipo).

Cuando necesitemos acceso externo (desde otros equipos de la misma red o bien desde equipos de Internet o de otras redes) a algún servicio de nuestro equipo Linux CentOS 8, necesitaremos saber qué número de puerto usa dicho servicio para abrirlo en el cortafuegos.

Por ejemplo, si hemos instalado una base de datos MySQL en nuestro equipo Linux CentOS 8 y queremos permitir el acceso desde otros equipos de la red a esta base de datos, necesitaremos abrir el puerto correspondiente (por defecto el 3306) en el cortafuegos. Otro ejemplo sería cuando hemos montado un servidor web con Apache y PHP en nuestro Linux, en este caso, para que se pueda mostrar la web desde otros equipos de la red o incluso desde Internet, tendremos que abrir el servicio http (puerto 80) y, tal vez, el https (puerto 443).

Herramienta de gestión firewalld en Linux CentOS 8

Antes de continuar, conviene indicar que en Linux CentOS 8 y en instalaciones estándar, el cortafuegos que viene instalado por defecto es firewalld. Se trata de una herramienta de gestión de firewall para sistemas operativos Linux. Proporciona funciones de firewall al actuar como un front-end para el marco de netfilter del kernel de Linux a través de la utilidad nftables userspace, que actúa como una alternativa al programa de línea de comando nft.

No necesitamos entrar más en detalle sobre firewalld y netfilter, lo importante es que sepamos que Linux CentOS 8, en una instalación estándar, incorpora firewalld como herramienta de gestión del cortafuegos. Esto nos será de mucha utilidad para saber qué comandos podemos ejecutar posteriormente para abrir puertos y comprobar el estado del cortafuegos.

Las zonas en el firewalld de Linux CentOS 8

Un concepto que hay que conocer de firewalld, al menos de forma general, es el de zona. Las zonas son conjuntos de reglas predefinidos que especifican qué tráfico debe permitirse, según los niveles de confianza para las conexiones de red. Por ejemplo, puede haber zonas para el hogar, públicas, de confianza, DMZ, etc.. Las zonas funcionan en una relación de uno a varios, por lo que una conexión solo puede ser parte de una sola zona, pero una zona puede usarse para muchas conexiones de red. Se pueden asignar diferentes fuentes e interfaces de red a zonas específicas.

Esto es útil, por ejemplo, para equipos que puedan cambiar de red con frecuencia, como equipos portátiles. Al usar zonas se podrán cambiar las reglas a aplicar de forma dinámica, al cambiar de adaptador. Por ejemplo, si el portátil se conecta a una red wifi «desconocida» se le podría aplicar una zona restrictiva, en cambio, si se conecta a la red de su organización, podría aplicársele una zona menos restrictiva.

En el caso de equipos que no vayan a cambiar de red, el concepto de zona no es tan importante, porque siempre se les aplicará la misma. Desde la línea de comandos de Linux podemos ver cuál es la zona por defecto que se aplica a cada adaptador de red del equipo (si tiene varios puede aplicarse una zona diferente o la misma a cada adaptador). Por un lado para ver la zona por defecto:

El resultado del comando anterior, en una instalación estándar, será: public.

Y por el otro, la zona que se aplica a cada adaptador:

El resultado del comando anterior, en una instalación estándar, será:

public
interfaces: ens160

Donde «ens160» será la interfaz de red a la que se le aplicarán las reglas de la zona public.

Las zonas en el firewalld de Linux CentOS 8

Estos comandos nos resultarán necesarios porque así sabremos, a continuación, a qué zona aplicar las reglas que queramos implementar en el equipo Linux CentOS 8. En nuestro caso, como hemos visto, a la zona public.

Las zonas disponibles en firewalld, a título informativo, ordenadas de menor a mayor confiabilidad:

  • drop: todas las conexiones entrantes se descartan sin enviar respuesta al solicitante, mientras que todas las conexiones salientes se permiten.
  • block: todas las conexiones entrantes se rechazan con un mensaje ICMP de icmp-host-prohibited, mientras que todas las conexiones salientes se permiten.
  • public: esta zona está destinada a ser utilizada en las zonas comunes que no son de confianza. No se confía en otros equipos de la red, pero se pueden permitir ciertas conexiones entrantes (si así se establece por comando).
  • external: esta zona está destinada a ser utilizada en redes externas, cuando se usa el firewall como puerta de enlace. Está configurada para enmascaramiento de NAT, para que su red interna permanezca privada, pero sea accesible.
  • internal: esta zona está destinada a ser utilizada en las redes internas cuando el sistema actúa como una puerta de enlace o router. Otros sistemas en esta red son generalmente confiables.
  • dmz: esta zona está destinada a ser utilizada para los equipos situados en su zona desmilitarizada (DMZ), que tendrán acceso limitado al resto de la red.
  • work: esta zona está destinada a ser utilizada para equipos en el entorno de trabajo. Otros equipos de la misma red serán generalmente confiables.
  • home: esta zona está destinada a ser utilizada para las equipos de casa. Otros equipos en esta red son generalmente confiables.
  • trusted: todas las conexiones de red son aceptados y otros equipos de cualquier red son de confianza. Es la zona más abierta y la más insegura.

Podremos consultarlas en firewalld con el comando:

Devolverá: block dmz drop external home internal public trusted work.

Las zonas en el firewalld de Linux CentOS 8

Comprobar estado, instalar, activar, mostrar reglas de una zona en firewalld

Es conveniente comprobar el estado del cortafuegos antes de aplicar reglas. Lo primero que haremos será verificar que está instalado e iniciado, con el comando:

Si el firewalld está instalado y activo, nos mostrará el siguiente resultado:

Comprobar estado, instalar, activar, mostrar  reglas de una zona en firewalld

En caso de que no estuviera instalado podríamos hacerlo con el comando:

Y habilitarlo y activarlo en el inicio con los comandos:

También se puede comprobar que está activo firewalld con el comando:

Nos devolverá «running» si está activo:

Comprobar estado, instalar, activar, mostrar  reglas de una zona en firewalld

Para consultar las reglas que hay aplicadas a una determinada zona de firewalld ejecutaremos el siguiente comando, por ejemplo, para mostrar las de la zona public:

Nos devolverá, en una instalación «limpia»:

public (active)
target: default
icmp-block-inversion: no
interfaces: ens160
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

Comprobar estado, instalar, activar, mostrar  reglas de una zona en firewalld

Abrir un número de puerto en el firewalld de Linux

Imaginemos que tenemos una base de datos MySQL/MariaDB en nuestro equipo Linux, que usa su puerto estándar 3306. Queremos permitir el acceso externo de equipos de la red a esta base de datos. Si intentamos acceder sin abrir el puerto correspondiente, recibiremos el error: Unable to connect to IP_Servidor_Linux:3306.

Abrir un número de puerto en el firewalld de Linux

También podremos recibir el error: Can’t connect to MySQL server on ‘IP_Servidor_Linux’ (10061): Server did not respond within the specified timeout interval.

Para permitir el acceso a MySQL/MariaDB por el puerto 3306 de equipos de nuestra red, ejecutaremos el siguiente comando (aplicando la regla a la zona public que es la que tiene asignada el adaptador de red del equipo) y para el protocolo tcp:

Si la orden es correcta devolverá «success».

Abrir un número de puerto en el firewalld de Linux

Para aplicar la regla, ejecutaremos el comando:

Abrir un número de puerto en el firewalld de Linux

El comando anterior agregará el puerto 3306 en conexión tcp a la zona public, que es la asignada al adaptador de red. Por lo tanto, ya podremos probar a volver a conectar con el servidor MySQL desde otro equipo de la red y, ahora sí, conectará a través del puerto 3306 abierto:

Abrir un número de puerto en el firewalld de Linux

Vemos que la conexión a MySQL devuelve un error, pero ya no es de apertura de puerto en el firewall. El error que indica «Host «pcton» is not alloweb to connect to this MySQL server» se debe a que hay que configurar MySQL para permitir conexiones externas, como indicamos en este artículo:

Podremos comprobar que se ha agregado la regla, también, con el comando:

Y también desde:

En «ports» nos mostrará el 3306/tcp que hemos agregado.

Abrir un número de puerto en el firewalld de Linux

Al indicar «–permanet» en el comando para crear la regla, quedará permanente aunque reiniciemos el equipo.

Abrir o permitir un servicio en firewalld de Linux

Al igual que para abrir un puerto, firewalld, también permite abrir servicios. Los servicios disponibles se encuentran en:

/usr/lib/firewalld/services

En realidad son ficheros XML que contienen información del puerto que abren. Por ejemplo, el fichero http.xml contiene:

Vemos que lo único que especifica es el protocolo y uno o varios números de puerto a abrir en el firewall. Para el caso de http, el protocolo tcp y puerto 80, un nombre corto y una descripción.

Por ejemplo, si hemos montado un servidor web en nuestro equipo Linux, necesitaremos abrir los servicios http y https, para ello ejecutaremos:

Para aplicar los cambios ejecutaremos:

Y para comprobar que el servicio se ha agregado a las reglas de la zona public ejecutaremos:

Abrir o permitir un servicio en firewalld de Linux

En realidad, habilitar un servicio es lo mismo que abrir el número de puerto de dicho servicio.

Eliminar un puerto abierto en el firewalld de Linux

Para eliminar un puerto abierto, por ejemplo el 3306/tcp, ejecutaremos:

Para aplicar los cambios ejecutaremos:

Y para comprobar que el puerto ha desaparecido de la regla:

Eliminar un puerto abierto en el firewalld

Eliminar servicio de firewalld en Linux

Para eliminar un servicio que hayamos habilitado/abierto en el firewalld, ejecutaremos el comando:

Cambiando «http» por el nombre del servicio que queramos eliminar. Para aplicar los cambios ejecutaremos:

Eliminar servicio de firewalld en Linux

Definir nuevo servicio para firewalld

Podemos definir nuevos servicios inexistentes para usarlos en firewalld. Esto es útil, por ejemplo, cuando tenemos varios administradores de sistemas en una organización y, por otro lado, cuando alguna aplicación puede cambiar de puerto. En este caso, definimos un servicio con el puerto actual de la aplicación y cuando cambie, en lugar de modificar la regla del cortafuegos, se modificará el puerto en el fichero xml del servicio, como explicamos a continuación.

Para definir un nuevo servicio accederemos a la carpeta /usr/lib/firewalld/services con el comando:

A continuación crearemos el fichero XML correspondiente al servicio, como nombre del fichero podemos usar el nombre del servicio, por ejemplo, para crear un nuevo servicio para MySQL, llamaremos al fichero mysql.xml:

Eliminar un puerto abierto en el firewalld de Linux

Introduciremos el siguiente texto en formato XML:

En el texto anterior indicaremos el nombre corto del servicio, en «short», en nuestro caso «MySQL». Indicaremos también el protocolo en «protocol», en nuestro caso «tcp» y el número de puerto en «port», en nuestro caso «3306»:

Eliminar un puerto abierto en el firewalld de Linux

Guardaremos los cambios pulsando en Control + O y saldremos pulsando en Control + X.

Y ya tendremos disponible el servicio, llamado «mysql», que podremos agregar al cortafuegos como hemos explicado anteriormente. Si el número de puerto de esta aplicación cambia, solo tendremos que editar el fichero xml y modificar el valor de «port».

Otra de las ventajas de usar servicios predefinidos es que podemos añadir varios puertos para un mismo servicio, como por ejemplo el que ya se incluye con Linux CentOS 8, samba-dc.xml:

Si agregamos una regla para el servicio samba-dc, se abrirán todos los puertos indicados en el fichero xml anterior.