Asegurar con firewalld y SELinux en RHEL

Red Hat Enterprise LinuxBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderá a asegurar un servidor web Apache (httpd) en Red Hat Enterprise Linux (RHEL) mediante la gestión de políticas SELinux y reglas de firewall. Trabajará a través de un escenario práctico donde configurará httpd para que escuche en un puerto no estándar y explorará cómo los sistemas SELinux y firewall gestionan la seguridad para tales configuraciones. Este ejercicio proporciona experiencia práctica con tareas comunes de administración de seguridad en un entorno RHEL.

Comenzará configurando el servicio httpd para que se ejecute en un puerto personalizado y observando cómo se comporta bajo la aplicación de SELinux. Utilizará el comando semanage para comprender y gestionar las etiquetas de puerto SELinux, asegurando el cumplimiento adecuado de la seguridad. Luego, utilizará firewall-cmd para abrir este puerto personalizado en el firewall del sistema. Finalmente, verificará que el servidor web sea accesible, confirmando que sus configuraciones de seguridad se aplican correctamente.

Configurar httpd en un Puerto Personalizado y Comprender el Contexto SELinux

En este paso, aprenderá a configurar el servidor web Apache (httpd) para que se ejecute en un puerto no estándar y a comprender cómo SELinux gestiona el acceso a los puertos. Trabajaremos con el puerto 8081 y exploraremos la gestión de puertos SELinux, incluso si el servicio se inicia con éxito en algunas configuraciones.

Los paquetes necesarios (httpd, policycoreutils-python-utils y firewalld) ya se han instalado en la fase de configuración. El paquete policycoreutils-python-utils proporciona el comando semanage, que utilizará en un paso posterior.

Comencemos modificando la configuración predeterminada de httpd para que escuche en un puerto no estándar, 8081. El archivo de configuración principal para httpd se encuentra en /etc/httpd/conf/httpd.conf. Usaremos el editor nano para cambiar el puerto de escucha.

sudo nano /etc/httpd/conf/httpd.conf

Dentro del editor nano, use las teclas de flecha para desplazarse hacia abajo y encontrar la línea que dice Listen 80. Cambie esta línea a:

Listen 8081

Para guardar el archivo y salir de nano, presione Ctrl+X, luego Y para confirmar los cambios y, finalmente, Enter para escribir en el archivo.

Ahora, con la configuración cambiada, intentemos iniciar el servicio httpd. En este entorno en contenedores, systemctl no está disponible. Iniciaremos el demonio httpd directamente.

sudo /usr/sbin/httpd

Puede ver un mensaje de advertencia sobre el nombre de dominio completo del servidor, pero esto es normal y se puede ignorar.

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::216:3eff:fe02:1a1e%eth0. Set the 'ServerName' directive globally to suppress this message

Verifiquemos si el servicio se está ejecutando buscando procesos httpd.

ps aux | grep httpd

Debería ver múltiples procesos httpd en ejecución, lo que indica que el servidor web se inició correctamente.

root        4813  0.0  0.2  23364  7736 ?        Ss   09:32   0:00 /usr/sbin/httpd
apache      4814  0.0  0.1  23020  5092 ?        S    09:32   0:00 /usr/sbin/httpd
apache      4815  0.0  0.4 1441064 14620 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4816  0.0  0.5 1441064 18736 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4837  0.0  0.4 1572200 16872 ?       Sl   09:32   0:00 /usr/sbin/httpd
labex       4996  0.0  0.0   6408  2176 pts/3    S+   09:32   0:00 grep --color=auto httpd

También verifiquemos los registros de errores de httpd para ver qué sucedió durante el inicio.

sudo tail /var/log/httpd/error_log

Debería ver mensajes de inicio normales que indican que el servidor se está ejecutando correctamente.

[Tue Jun 17 09:32:46.374275 2025] [core:notice] [pid 4812:tid 4812] SELinux policy enabled; httpd running as context system_u:system_r:unconfined_service_t:s0
[Tue Jun 17 09:32:46.377265 2025] [suexec:notice] [pid 4812:tid 4812] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Tue Jun 17 09:32:46.394284 2025] [lbmethod_heartbeat:notice] [pid 4813:tid 4813] AH02282: No slotmem from mod_heartmonitor
[Tue Jun 17 09:32:46.399433 2025] [mpm_event:notice] [pid 4813:tid 4813] AH00489: Apache/2.4.62 (Red Hat Enterprise Linux) configured -- resuming normal operations
[Tue Jun 17 09:32:46.399458 2025] [core:notice] [pid 4813:tid 4813] AH00094: Command line: '/usr/sbin/httpd'

Curiosamente, el servicio httpd se inició sin ningún problema de SELinux. Verifiquemos si hubo alguna denegación de SELinux en el registro de auditoría.

sudo grep AVC /var/log/audit/audit.log | grep httpd

Si no hay resultados, significa que SELinux no bloqueó al servicio httpd para que se vinculara al puerto 8081. Esto podría deberse a:

  1. El puerto 8081 ya podría estar permitido para los servicios HTTP de forma predeterminada en algunas configuraciones.
  2. El proceso httpd podría estar ejecutándose en un contexto no restringido.
  3. El puerto 8081 ya puede estar definido en la política SELinux.

Verifiquemos el modo SELinux actual:

getenforce

Debería ver que SELinux está en modo "Enforcing", lo que significa que está aplicando activamente las políticas. El hecho de que httpd se iniciara con éxito indica que el puerto 8081 ya puede tener la etiqueta SELinux adecuada, o el servicio se está ejecutando en un contexto no restringido, como se muestra en los mensajes del registro. Para el propósito de este ejercicio de aprendizaje, continuemos con el siguiente paso donde exploraremos la gestión de puertos SELinux y aseguraremos la configuración adecuada.

Comprender y Gestionar las Etiquetas de Puerto SELinux con semanage

En este paso, aprenderá a gestionar las etiquetas de puerto SELinux utilizando el comando semanage. Aunque el servicio httpd se está ejecutando actualmente en el puerto 8081, es importante comprender cómo configurar correctamente las políticas de puerto SELinux para garantizar la seguridad y el cumplimiento. Explorará la configuración actual del puerto y aprenderá a asignar explícitamente el tipo SELinux correcto a los puertos personalizados.

Primero, necesita encontrar el tipo SELinux correcto para los puertos del servidor web. El comando semanage port -l enumera todas las definiciones de puerto conocidas por SELinux. Podemos canalizar esta salida a grep para encontrar tipos relacionados con http.

sudo semanage port -l | grep http

La salida muestra varios tipos de puerto. El más relevante para un servidor web estándar es http_port_t.

http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988
pegasus_https_port_t           tcp      5989

Como puede ver, http_port_t se asigna a los puertos HTTP/HTTPS estándar como 80 y 443. La política SELinux permite que los procesos con el tipo httpd_t (nuestro servidor web) se vinculen a cualquier puerto etiquetado con http_port_t. Verifiquemos si el puerto 8081 ya está en esta lista.

Observe que el puerto 8081 no está actualmente listado bajo http_port_t. Sin embargo, en algunas configuraciones de RHEL, este puerto ya puede estar definido en la política SELinux. Intentemos agregarlo explícitamente para un cumplimiento adecuado de SELinux utilizando el comando semanage port -a.

  • La opción -a significa "agregar" (add).
  • La opción -t http_port_t especifica el tipo a asignar.
  • La opción -p tcp especifica el protocolo.
sudo semanage port -a -t http_port_t -p tcp 8081

Puede ver un mensaje que indica "Port tcp/8081 already defined, modifying instead", lo que significa que el puerto ya estaba configurado. Esto explica por qué httpd se inició con éxito en el paso anterior. Para verificar la configuración actual, enumere las definiciones de http_port_t nuevamente.

sudo semanage port -l | grep '^http_port_t'

Ahora debería ver el puerto 8081 incluido en la lista.

http_port_t                    tcp      8081, 80, 81, 443, 488, 8008, 8009, 8443, 9000

Con la política SELinux explícitamente actualizada, el puerto 8081 ahora se reconoce formalmente como un puerto HTTP. El servicio httpd debería continuar ejecutándose sin problemas, y ha garantizado el cumplimiento adecuado de SELinux.

Verifiquemos que el proceso aún se está ejecutando:

ps aux | grep httpd

Debería seguir viendo múltiples procesos httpd, lo que indica que el servidor web se está ejecutando correctamente con el etiquetado de puerto SELinux adecuado.

root        4813  0.0  0.2  23364  7736 ?        Ss   09:32   0:00 /usr/sbin/httpd
apache      4814  0.0  0.1  23020  5092 ?        S    09:32   0:00 /usr/sbin/httpd
apache      4815  0.0  0.4 1441064 14620 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4816  0.0  0.5 1441064 18736 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4837  0.0  0.4 1572200 16872 ?       Sl   09:32   0:00 /usr/sbin/httpd
labex       5215  0.0  0.0   6408  2176 pts/3    S+   09:33   0:00 grep --color=auto httpd

Ha configurado con éxito la política SELinux para permitir explícitamente que el servicio httpd se ejecute en el puerto 8081, garantizando el cumplimiento adecuado de la seguridad.

Abrir un Puerto Personalizado en el Firewall con firewall-cmd

En este paso, configurará el cortafuegos del sistema para permitir conexiones externas a su servidor web en el puerto personalizado 8081. Aunque el servicio httpd ahora se está ejecutando correctamente gracias al cambio de política de SELinux, es probable que el servicio firewalld, que gestiona las reglas de tráfico de red, esté bloqueando las solicitudes entrantes en este puerto no estándar de forma predeterminada.

El paquete firewalld ya se ha instalado en la fase de configuración. Sin embargo, necesitamos iniciar el servicio firewalld primero. Verifiquemos el estado actual e iniciémoslo si es necesario.

sudo firewall-cmd --list-all

Si ve "FirewallD is not running", necesitamos iniciar el demonio firewalld. En este entorno de contenedor, iniciamos el demonio firewalld directamente. El & al final ejecuta el proceso en segundo plano.

sudo /usr/sbin/firewalld &

Espere un momento a que el servicio se inicialice, luego verifique que se esté ejecutando:

sudo firewall-cmd --list-all

Ahora debería ver la configuración actual del cortafuegos para la zona predeterminada (public).

Probemos el acceso al servidor web desde la línea de comandos usando curl. Este comando intenta conectarse a localhost en el puerto 8081.

curl http://localhost:8081

Debería ver el contenido HTML de su página de prueba, lo que significa que el servidor web es accesible localmente. Esto es lo esperado porque firewalld normalmente permite el tráfico de localhost de forma predeterminada.

Sin embargo, para el acceso externo y la configuración de seguridad adecuada, aún necesitamos configurar el cortafuegos correctamente para nuestro puerto personalizado. Si bien las conexiones de localhost suelen funcionar independientemente de las reglas del cortafuegos, las conexiones externas desde otras máquinas se bloquearían sin la configuración adecuada del cortafuegos.

Primero, inspeccionemos las reglas actuales para la zona predeterminada (public):

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

Ahora, agregue una nueva regla para permitir el tráfico TCP en el puerto 8081. Asegúrese de que firewalld se esté ejecutando antes de ejecutar este comando.

  • --add-port=8081/tcp especifica el puerto y el protocolo a abrir.
  • --permanent asegura que la regla persista después de un reinicio o una recarga del cortafuegos.
sudo firewall-cmd --permanent --add-port=8081/tcp

Si ve "FirewallD is not running", asegúrese de haber iniciado el demonio firewalld en el paso anterior y espere un momento a que se inicialice.

El comando debería devolver success cuando firewalld se está ejecutando correctamente.

success

Las reglas permanentes no se aplican a la configuración activa del cortafuegos hasta que se recarga. Recarguemos el cortafuegos para aplicar nuestra nueva regla.

sudo firewall-cmd --reload

Este comando también debería devolver success.

success

Verifiquemos que el puerto ahora está abierto enumerando las reglas nuevamente.

sudo firewall-cmd --list-all

Ahora debería ver 8081/tcp en la sección ports:.

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources:
  services: cockpit dhcpv6-client ssh
  ports: 8081/tcp
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

Ha configurado correctamente el cortafuegos. El paso final es probar si puede acceder al servidor web.

Verificar el Acceso a Puertos de Servidor Web Estándar y Personalizados

En este paso final, verificará que todos los cambios que ha realizado aseguren que su servidor web esté configurado correctamente tanto para el acceso local como para el externo. Ha configurado la política de SELinux y ha abierto el puerto necesario en el cortafuegos. Ahora, realizará pruebas exhaustivas para confirmar la configuración.

Primero, creemos una página de prueba simple para que, cuando nos conectemos, obtengamos un mensaje personalizado. La raíz de documentos predeterminada para httpd es /var/www/html. Crearemos un archivo index.html en ese directorio. Necesitará privilegios sudo para escribir en esta ubicación.

echo "Success! Web server on custom port 8081 is working." | sudo tee /var/www/html/index.html

Este comando coloca el mensaje de éxito en el archivo index.html. El comando tee se utiliza aquí porque nos permite escribir en un archivo que requiere privilegios sudo mientras se usa una tubería (pipe). Debería ver el mensaje reflejado en la terminal como confirmación.

Success! Web server on custom port 8081 is working.

Para completar el ejercicio, demostremos el contraste intentando acceder al puerto HTTP estándar 80. Dado que nuestro servidor está configurado para escuchar solo en 8081, esta solicitud debería fallar.

curl http://localhost:80

Como se esperaba, la conexión es rechazada porque ningún servicio está escuchando en ese puerto.

curl: (7) Failed to connect to localhost port 80: Connection refused

Esto confirma que su servidor se está ejecutando exclusivamente en el puerto personalizado que configuró. A través de este laboratorio, ha aprendido un flujo de trabajo de solución de problemas crítico para los servicios en RHEL:

  1. Verificar el estado y los registros del servicio.
  2. Investigar las denegaciones de SELinux en el registro de auditoría.
  3. Corregir las políticas de SELinux usando semanage.
  4. Configurar las reglas del cortafuegos usando firewall-cmd.
  5. Verificar la conectividad.

Resumen

En este laboratorio, aprendió a configurar un servidor web en un puerto personalizado y a gestionar las políticas de seguridad de SELinux. Con el servidor web Apache (httpd), los paquetes policycoreutils-python-utils y firewalld preinstalados, se centró en comprender la gestión de puertos de SELinux y la configuración del cortafuegos. Modificó el archivo httpd.conf para cambiar el puerto de escucha del servidor web a un puerto no estándar, el 8081.

Descubrió que el servicio httpd se inició con éxito en el puerto personalizado porque el puerto 8081 ya estaba configurado correctamente en la política de SELinux. Esto proporcionó una oportunidad para explorar la gestión de puertos de SELinux y comprender cómo funciona semanage para mantener el etiquetado adecuado de los puertos. También aprendió a usar firewall-cmd para gestionar las reglas del cortafuegos, asegurando tanto el cumplimiento de la seguridad como la accesibilidad. Aunque httpd se ejecutó en un contexto no confinado, este laboratorio demostró la importancia de la configuración adecuada de SELinux y el cortafuegos para entornos de producción.