Sécuriser avec firewalld et SELinux sur RHEL

Red Hat Enterprise LinuxBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, vous apprendrez à sécuriser un serveur web Apache (httpd) sur Red Hat Enterprise Linux (RHEL) en gérant les politiques SELinux et les règles du pare-feu. Vous travaillerez à travers un scénario pratique où vous configurerez httpd pour écouter sur un port non standard et explorerez comment SELinux et les systèmes de pare-feu gèrent la sécurité pour de telles configurations. Cet exercice offre une expérience pratique des tâches courantes d'administration de la sécurité dans un environnement RHEL.

Vous commencerez par configurer le service httpd pour qu'il s'exécute sur un port personnalisé et observerez son comportement sous l'application de SELinux. Vous utiliserez la commande semanage pour comprendre et gérer les étiquettes de port SELinux, assurant ainsi une conformité de sécurité appropriée. Vous utiliserez ensuite firewall-cmd pour ouvrir ce port personnalisé dans le pare-feu du système. Enfin, vous vérifierez que le serveur web est accessible, confirmant que vos configurations de sécurité sont correctement appliquées.

Configurer httpd sur un port personnalisé et comprendre le contexte SELinux

Dans cette étape, vous apprendrez à configurer le serveur web Apache (httpd) pour qu'il s'exécute sur un port non standard et à comprendre comment SELinux gère l'accès aux ports. Nous travaillerons avec le port 8081 et explorerons la gestion des ports SELinux, même si le service démarre avec succès dans certaines configurations.

Les paquets nécessaires (httpd, policycoreutils-python-utils et firewalld) ont déjà été installés lors de la phase de configuration. Le paquet policycoreutils-python-utils fournit la commande semanage, que vous utiliserez dans une étape ultérieure.

Commençons par modifier la configuration par défaut de httpd pour qu'il écoute sur un port non standard, 8081. Le fichier de configuration principal pour httpd se trouve à /etc/httpd/conf/httpd.conf. Nous utiliserons l'éditeur nano pour modifier le port d'écoute.

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

À l'intérieur de l'éditeur nano, utilisez les touches fléchées pour faire défiler et trouver la ligne qui dit Listen 80. Remplacez cette ligne par :

Listen 8081

Pour enregistrer le fichier et quitter nano, appuyez sur Ctrl+X, puis sur Y pour confirmer les modifications, et enfin sur Entrée pour écrire dans le fichier.

Maintenant, avec la configuration modifiée, essayons de démarrer le service httpd. Dans cet environnement conteneurisé, systemctl n'est pas disponible. Nous allons démarrer le démon httpd directement.

sudo /usr/sbin/httpd

Vous pouvez voir un message d'avertissement concernant le nom de domaine complet du serveur, mais c'est normal et peut être ignoré.

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

Vérifions si le service est en cours d'exécution en recherchant les processus httpd.

ps aux | grep httpd

Vous devriez voir plusieurs processus httpd en cours d'exécution, ce qui indique que le serveur web a démarré avec succès.

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

Vérifions également les journaux d'erreurs httpd pour voir ce qui s'est passé pendant le démarrage.

sudo tail /var/log/httpd/error_log

Vous devriez voir des messages de démarrage normaux indiquant que le serveur fonctionne correctement.

[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'

Il est intéressant de noter que le service httpd a démarré sans aucun problème SELinux. Vérifions s'il y a eu des refus SELinux dans le journal d'audit.

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

S'il n'y a pas de résultats, cela signifie que SELinux n'a pas bloqué le service httpd de se lier au port 8081. Cela pourrait être dû au fait que :

  1. Le port 8081 pourrait déjà être autorisé pour les services HTTP par défaut dans certaines configurations
  2. Le processus httpd pourrait s'exécuter dans un contexte non confiné
  3. Le port 8081 peut déjà être défini dans la politique SELinux

Vérifions le mode SELinux actuel :

getenforce

Vous devriez voir que SELinux est en mode "Enforcing", ce qui signifie qu'il applique activement les politiques. Le fait que httpd ait démarré avec succès indique que le port 8081 peut déjà avoir une étiquette SELinux appropriée, ou que le service s'exécute dans un contexte non confiné, comme le montrent les messages du journal. Pour les besoins de cet exercice d'apprentissage, passons à l'étape suivante où nous explorerons la gestion des ports SELinux et assurerons une configuration appropriée.

Comprendre et gérer les étiquettes de port SELinux avec semanage

Dans cette étape, vous apprendrez à gérer les étiquettes de port SELinux à l'aide de la commande semanage. Même si le service httpd est actuellement en cours d'exécution sur le port 8081, il est important de comprendre comment configurer correctement les politiques de port SELinux pour garantir la sécurité et la conformité. Vous explorerez la configuration actuelle des ports et apprendrez à attribuer explicitement le type SELinux correct aux ports personnalisés.

Tout d'abord, vous devez trouver le type SELinux correct pour les ports du serveur web. La commande semanage port -l répertorie toutes les définitions de port connues de SELinux. Nous pouvons diriger cette sortie vers grep pour trouver les types liés à http.

sudo semanage port -l | grep http

La sortie affiche plusieurs types de ports. Le plus pertinent pour un serveur web standard est 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

Comme vous pouvez le voir, http_port_t est attribué aux ports HTTP/HTTPS standard comme 80 et 443. La politique SELinux permet aux processus de type httpd_t (notre serveur web) de se lier à tout port étiqueté avec http_port_t. Vérifions si le port 8081 est déjà dans cette liste.

Notez que le port 8081 n'est pas actuellement répertorié sous http_port_t. Cependant, dans certaines configurations RHEL, ce port peut déjà être défini dans la politique SELinux. Essayons de l'ajouter explicitement pour une conformité SELinux appropriée à l'aide de la commande semanage port -a.

  • L'option -a signifie "ajouter" (add).
  • L'option -t http_port_t spécifie le type à attribuer.
  • L'option -p tcp spécifie le protocole.
sudo semanage port -a -t http_port_t -p tcp 8081

Vous pouvez voir un message indiquant "Port tcp/8081 already defined, modifying instead", ce qui signifie que le port était déjà configuré. Cela explique pourquoi httpd a démarré avec succès à l'étape précédente. Pour vérifier la configuration actuelle, répertoriez à nouveau les définitions http_port_t.

sudo semanage port -l | grep '^http_port_t'

Vous devriez maintenant voir le port 8081 inclus dans la liste.

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

Avec la politique SELinux explicitement mise à jour, le port 8081 est désormais formellement reconnu comme un port HTTP. Le service httpd devrait continuer à fonctionner sans aucun problème, et vous avez assuré une conformité SELinux appropriée.

Vérifions que le processus est toujours en cours d'exécution :

ps aux | grep httpd

Vous devriez continuer à voir plusieurs processus httpd, indiquant que le serveur web fonctionne avec succès avec un étiquetage de port SELinux approprié.

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

Vous avez configuré avec succès la politique SELinux pour autoriser explicitement le service httpd à s'exécuter sur le port 8081, garantissant ainsi une conformité de sécurité appropriée.

Ouvrir un port personnalisé dans le pare-feu avec firewall-cmd

Dans cette étape, vous configurerez le pare-feu du système pour autoriser les connexions externes à votre serveur web sur le port personnalisé 8081. Bien que le service httpd fonctionne désormais correctement grâce à la modification de la politique SELinux, le service firewalld, qui gère les règles de trafic réseau, bloque probablement par défaut les requêtes entrantes sur ce port non standard.

Le paquet firewalld a déjà été installé lors de la phase de configuration. Cependant, nous devons d'abord démarrer le service firewalld. Vérifions l'état actuel et démarrons-le si nécessaire.

sudo firewall-cmd --list-all

Si vous voyez "FirewallD is not running", nous devons démarrer le démon firewalld. Dans cet environnement conteneurisé, nous démarrons le démon firewalld directement. Le & à la fin exécute le processus en arrière-plan.

sudo /usr/sbin/firewalld &

Attendez un instant que le service s'initialise, puis vérifiez qu'il est en cours d'exécution :

sudo firewall-cmd --list-all

Vous devriez maintenant voir la configuration actuelle du pare-feu pour la zone par défaut (public).

Testons l'accès au serveur web à partir de la ligne de commande en utilisant curl. Cette commande tente de se connecter à localhost sur le port 8081.

curl http://localhost:8081

Vous devriez voir le contenu HTML de votre page de test, ce qui signifie que le serveur web est accessible localement. C'est normal car firewalld autorise généralement le trafic localhost par défaut.

Cependant, pour l'accès externe et une configuration de sécurité appropriée, nous devons toujours configurer correctement le pare-feu pour notre port personnalisé. Bien que les connexions localhost fonctionnent généralement quel que soit le pare-feu, les connexions externes provenant d'autres machines seraient bloquées sans la configuration appropriée du pare-feu.

Tout d'abord, inspectons les règles actuelles pour la zone par défaut (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:

Maintenant, ajoutez une nouvelle règle pour autoriser le trafic TCP sur le port 8081. Assurez-vous que firewalld est en cours d'exécution avant d'exécuter cette commande.

  • --add-port=8081/tcp spécifie le port et le protocole à ouvrir.
  • --permanent garantit que la règle persiste après un redémarrage ou un rechargement du pare-feu.
sudo firewall-cmd --permanent --add-port=8081/tcp

Si vous voyez "FirewallD is not running", assurez-vous d'avoir démarré le démon firewalld à l'étape précédente et attendez un instant qu'il s'initialise.

La commande doit renvoyer success lorsque firewalld est en cours d'exécution correctement.

success

Les règles permanentes ne sont pas appliquées à la configuration active du pare-feu tant qu'il n'est pas rechargé. Rechargeons le pare-feu pour appliquer notre nouvelle règle.

sudo firewall-cmd --reload

Cette commande doit également renvoyer success.

success

Vérifions que le port est maintenant ouvert en répertoriant à nouveau les règles.

sudo firewall-cmd --list-all

Vous devriez maintenant voir 8081/tcp dans la section 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:

Vous avez configuré avec succès le pare-feu. La dernière étape consiste à tester si vous pouvez accéder au serveur web.

Vérifier l'accès aux ports de serveur web standard et personnalisés

Dans cette dernière étape, vous vérifierez que toutes les modifications que vous avez apportées garantissent que votre serveur web est correctement configuré pour un accès local et externe. Vous avez configuré la politique SELinux et ouvert le port nécessaire dans le pare-feu. Maintenant, vous effectuerez des tests complets pour confirmer la configuration.

Tout d'abord, créons une simple page de test afin que, lorsque nous nous connectons, nous obtenions un message personnalisé. La racine de documents par défaut pour httpd est /var/www/html. Nous allons créer un fichier index.html dans ce répertoire. Vous aurez besoin des privilèges sudo pour écrire à cet emplacement.

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

Cette commande place le message de succès dans le fichier index.html. La commande tee est utilisée ici car elle nous permet d'écrire dans un fichier qui nécessite des privilèges sudo tout en utilisant un pipe. Vous devriez voir le message renvoyé dans le terminal comme confirmation.

Success! Web server on custom port 8081 is working.

Pour terminer l'exercice, démontrons le contraste en tentant d'accéder au port HTTP standard 80. Étant donné que notre serveur est configuré pour écouter uniquement sur 8081, cette requête devrait échouer.

curl http://localhost:80

Comme prévu, la connexion est refusée car aucun service n'écoute sur ce port.

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

Cela confirme que votre serveur s'exécute exclusivement sur le port personnalisé que vous avez configuré. Grâce à ce lab, vous avez appris un flux de travail de dépannage essentiel pour les services sur RHEL :

  1. Vérifier l'état et les journaux du service.
  2. Enquêter sur les refus SELinux dans le journal d'audit.
  3. Corriger les politiques SELinux à l'aide de semanage.
  4. Configurer les règles du pare-feu à l'aide de firewall-cmd.
  5. Vérifier la connectivité.

Résumé

Dans ce lab, vous avez appris à configurer un serveur web sur un port personnalisé et à gérer les politiques de sécurité SELinux. Avec le serveur web Apache (httpd), les paquets policycoreutils-python-utils et firewalld préinstallés, vous vous êtes concentré sur la compréhension de la gestion des ports SELinux et de la configuration du pare-feu. Vous avez modifié le fichier httpd.conf pour changer le port d'écoute du serveur web en un port non standard, 8081.

Vous avez découvert que le service httpd démarrait avec succès sur le port personnalisé car le port 8081 était déjà correctement configuré dans la politique SELinux. Cela a permis d'explorer la gestion des ports SELinux et de comprendre comment semanage fonctionne pour maintenir un étiquetage correct des ports. Vous avez également appris à utiliser firewall-cmd pour gérer les règles du pare-feu, garantissant à la fois la conformité en matière de sécurité et l'accessibilité. Même si httpd s'est exécuté dans un contexte non confiné, ce lab a démontré l'importance d'une configuration appropriée de SELinux et du pare-feu pour les environnements de production.