Introducción
En este laboratorio, aprenderás cómo asegurar un servidor web Apache (httpd) en Red Hat Enterprise Linux (RHEL) mediante la gestión de políticas de SELinux y reglas de firewall. Trabajarás en un escenario práctico donde configurarás httpd para escuchar en un puerto no estándar y explorarás cómo los sistemas SELinux y firewall gestionan la seguridad para dichas configuraciones. Este ejercicio proporciona experiencia práctica con tareas comunes de administración de seguridad en un entorno RHEL.
Comenzarás configurando el servicio httpd para que se ejecute en un puerto personalizado y observarás cómo se comporta bajo la aplicación de políticas de SELinux. Utilizarás el comando semanage para comprender y gestionar las etiquetas de puerto de SELinux, asegurando el cumplimiento de la seguridad. Luego, usarás firewall-cmd para abrir este puerto personalizado en el firewall del sistema. Finalmente, verificarás que el servidor web sea accesible, confirmando que tus configuraciones de seguridad se han aplicado correctamente.
Configurar httpd en un puerto personalizado y comprender el contexto de SELinux
En este paso, aprenderás cómo configurar el servidor web Apache (httpd) para que se ejecute en un puerto no estándar y comprenderás cómo SELinux gestiona el acceso a los puertos. Trabajaremos con el puerto 8081 y exploraremos la gestión de puertos de SELinux, incluso si el servicio se inicia correctamente en algunas configuraciones.
Los paquetes necesarios (httpd, policycoreutils-python-utils y firewalld) ya han sido instalados en la fase de configuración. El paquete policycoreutils-python-utils proporciona el comando semanage, que utilizarás en un paso posterior.
Comencemos modificando la configuración predeterminada de httpd para que escuche en un puerto no estándar, el 8081. El archivo de configuración principal de 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, usa las teclas de flecha para desplazarte hacia abajo y encontrar la línea que dice Listen 80. Cambia esta línea por:
Listen 8081
Para guardar el archivo y salir de nano, presiona 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 contenedorizado, systemctl no está disponible. Iniciaremos el demonio httpd directamente.
La fase de configuración ya deshabilita el host virtual SSL predeterminado, por lo que este laboratorio de HTTP simple puede iniciarse sin errores relacionados con archivos de certificados.
sudo /usr/sbin/httpd
Es posible que veas un mensaje de advertencia sobre el nombre de dominio totalmente calificado del servidor, pero esto es normal y puede ignorarse.
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 comprobando los procesos de httpd.
ps aux | grep httpd
Deberías ver múltiples procesos de httpd ejecutándose, 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
Revisemos también los registros de errores de httpd para ver qué sucedió durante el inicio.
sudo tail /var/log/httpd/error_log
Deberías 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 problemas de SELinux. Comprobemos 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ó el servicio httpd para que se vinculara al puerto 8081. Esto podría deberse a que:
- El puerto 8081 podría estar permitido para servicios HTTP de forma predeterminada en algunas configuraciones.
- El proceso httpd podría estar ejecutándose en un contexto no confinado (unconfined).
- El puerto 8081 puede estar ya definido en la política de SELinux.
Comprobemos el modo actual de SELinux:
getenforce
Deberías ver que SELinux está en modo "Enforcing", lo que significa que está aplicando políticas activamente. El hecho de que httpd se iniciara correctamente indica que el puerto 8081 puede tener ya la etiqueta de SELinux adecuada, o que el servicio se está ejecutando en un contexto no confinado, como se muestra en los mensajes de registro. Para los fines de este ejercicio de aprendizaje, continuemos con el siguiente paso, donde exploraremos la gestión de puertos de SELinux y garantizaremos una configuración adecuada.
Comprender y gestionar etiquetas de puerto de SELinux con semanage
En este paso, aprenderás cómo gestionar las etiquetas de puerto de SELinux utilizando el comando semanage. Aunque el servicio httpd se está ejecutando actualmente en el puerto 8081, es importante entender cómo configurar correctamente las políticas de puerto de SELinux para garantizar la seguridad y el cumplimiento. Explorarás la configuración actual del puerto y aprenderás cómo asignar explícitamente el tipo de SELinux correcto a los puertos personalizados.
Primero, necesitas encontrar el tipo de SELinux correcto para los puertos del servidor web. El comando semanage port -l enumera todas las definiciones de puertos conocidas por SELinux. Podemos enviar esta salida a grep para encontrar tipos relacionados con http.
sudo semanage port -l | grep http
La salida muestra varios tipos de puertos. 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 puedes ver, http_port_t está asignado a puertos HTTP/HTTPS estándar como 80 y 443. La política de SELinux permite que los procesos con el tipo httpd_t (nuestro servidor web) se vinculen a cualquier puerto etiquetado con http_port_t. Comprobemos si el puerto 8081 ya está en esta lista.
Observa que el puerto 8081 no aparece actualmente bajo http_port_t. Sin embargo, en algunas configuraciones de RHEL, este puerto puede estar ya definido en la política de SELinux. Intentemos añadirlo explícitamente para un cumplimiento adecuado de SELinux utilizando el comando semanage port -a.
- La opción
-asignifica "add" (añadir). - La opción
-t http_port_tespecifica el tipo a asignar. - La opción
-p tcpespecifica el protocolo.
sudo semanage port -a -t http_port_t -p tcp 8081
Es posible que veas 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ó correctamente en el paso anterior. Para verificar la configuración actual, enumera las definiciones de http_port_t nuevamente.
sudo semanage port -l | grep '^http_port_t'
Ahora deberías 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 de SELinux actualizada explícitamente, el puerto 8081 ahora se reconoce formalmente como un puerto HTTP. El servicio httpd debería seguir ejecutándose sin problemas, y has garantizado el cumplimiento adecuado de SELinux.
Verifiquemos que el proceso sigue ejecutándose:
ps aux | grep httpd
Deberías seguir viendo múltiples procesos de httpd, lo que indica que el servidor web se está ejecutando correctamente con la etiqueta de puerto de SELinux adecuada.
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
Has configurado con éxito la política de SELinux para permitir explícitamente que el servicio httpd se ejecute en el puerto 8081, asegurando el cumplimiento de la seguridad.
Abrir un puerto personalizado en el firewall con firewall-cmd
En este paso, configurarás el firewall del sistema para permitir conexiones externas a tu servidor web en el puerto personalizado 8081. Aunque el servicio httpd se está ejecutando correctamente gracias al cambio en la política de SELinux, el servicio firewalld, que gestiona las reglas de tráfico de red, probablemente esté bloqueando las solicitudes entrantes en este puerto no estándar de forma predeterminada.
El paquete firewalld ya ha sido instalado en la fase de configuración. Sin embargo, primero debemos iniciar el servicio firewalld. Comprobemos el estado actual e iniciémoslo si es necesario.
sudo firewall-cmd --list-all
Si ves "FirewallD is not running", debemos 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 &
Espera un momento a que el servicio se inicialice y luego verifica que se esté ejecutando:
sudo firewall-cmd --list-all
Ahora deberías ver la configuración actual del firewall 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ías ver el contenido HTML de tu página de prueba, lo que significa que el servidor web es accesible localmente. Esto es esperado porque firewalld normalmente permite el tráfico de localhost de forma predeterminada.
Sin embargo, para el acceso externo y una configuración de seguridad adecuada, todavía necesitamos configurar el firewall correctamente para nuestro puerto personalizado. Aunque las conexiones de localhost suelen funcionar independientemente de las reglas del firewall, las conexiones externas desde otras máquinas se bloquearían sin la configuración de firewall adecuada.
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, añade una nueva regla para permitir el tráfico TCP en el puerto 8081. Asegúrate de que firewalld se esté ejecutando antes de ejecutar este comando.
--add-port=8081/tcpespecifica el puerto y el protocolo a abrir.--permanentasegura que la regla persista después de un reinicio o una recarga del firewall.
sudo firewall-cmd --permanent --add-port=8081/tcp
Si ves "FirewallD is not running", asegúrate de haber iniciado el demonio firewalld en el paso anterior y espera 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 firewall hasta que se recarga. Recarguemos el firewall para aplicar nuestra nueva regla.
sudo firewall-cmd --reload
Este comando también debería devolver success.
success
Verifiquemos que el puerto esté ahora abierto enumerando las reglas nuevamente.
sudo firewall-cmd --list-all
Ahora deberías 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:
Has configurado el firewall con éxito. El paso final es probar si puedes acceder al servidor web.
Verificar el acceso a los puertos estándar y personalizados del servidor web
En este paso final, verificarás que todos los cambios que has realizado aseguren que tu servidor web esté configurado correctamente tanto para el acceso local como para el externo. Has configurado la política de SELinux y abierto el puerto necesario en el firewall. Ahora, realizarás 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 del documento predeterminada para httpd es /var/www/html. Crearemos un archivo index.html en ese directorio. Necesitarás privilegios de 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 de sudo mientras usamos una tubería (pipe). Deberías 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 el 8081, esta solicitud debería fallar.
curl http://localhost:80
Como era de esperar, la conexión es rechazada porque no hay ningún servicio escuchando en ese puerto.
curl: (7) Failed to connect to localhost port 80: Connection refused
Esto confirma que tu servidor se está ejecutando exclusivamente en el puerto personalizado que configuraste. A través de este laboratorio, has aprendido un flujo de trabajo de resolución de problemas crítico para servicios en RHEL:
- Comprobar el estado del servicio y los registros.
- Investigar las denegaciones de SELinux en el registro de auditoría.
- Corregir las políticas de SELinux usando
semanage. - Configurar las reglas del firewall usando
firewall-cmd. - Verificar la conectividad.
Resumen
En este laboratorio, aprendiste cómo configurar un servidor web en un puerto personalizado y gestionar las políticas de seguridad de SELinux. Con los paquetes Apache web server (httpd), policycoreutils-python-utils y firewalld preinstalados, te centraste en comprender la gestión de puertos de SELinux y la configuración del firewall. Modificaste el archivo httpd.conf para cambiar el puerto de escucha del servidor web a un puerto no estándar, el 8081.
Descubriste que el servicio httpd se inició correctamente en el puerto personalizado porque el puerto 8081 ya estaba configurado correctamente en la política de SELinux. Esto brindó la oportunidad de explorar la gestión de puertos de SELinux y comprender cómo funciona semanage para mantener un etiquetado de puertos adecuado. También aprendiste a usar firewall-cmd para gestionar las reglas del firewall, garantizando tanto el cumplimiento de la seguridad como la accesibilidad. Aunque httpd se ejecutó en un contexto no confinado, este laboratorio demostró la importancia de una configuración adecuada de SELinux y del firewall para entornos de producción.



