Contexte
Dans le cadre de la mise en place d’une infrastructure sécurisée répondant aux critères de l’épreuve E5, le critère de redondance était nécessaire. Ainsi, dans la mission de la charge de serveurs web de la société BagdadMediLab, cette société ayant une volonté de résister face aux nombres importants de visites sur son site web. Alors le service mise en place est pensé comme un cluster pour une haute disponibilité avec HAPRoxy.
Installation et configuration des serveurs WEB
Prérequis
Ainsi, dans le cadre de la mise en place d’une infrastructure, il est nécessaire d’avoir :
- Un serveur sous Rocky Linux (9.4 ici)
Installation d’un service WEB (nginx)
- Installation des packages nécessaires au service WEB
sudo dnf install nginx php-fpm mariadb-server php php-mysqlnd -y
- On retrouvera les fichiers de .conf dans /etc/nginx/
sudo ls /etc/nginx/

- Et les logs se trouveront dans le répertoire /var/log/nginx/error.log

- Et par défaut, les fichiers pour le site web sont dans le répertoire /usr/share/nginx/html/
- On ajoute une exception pour les ports 80 (HTTP) et 443 (HTTPS) dans le pare-feu pour que la page par défaut (index.html) s’affiche correctement
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload

- Démarrer et rendre enable le service nginx
sudo systemctl start nginx & sudo systemctl enable nginx
- On peut voir les pages http par défaut (index.html) qui s’affiche dans notre navigateur si on tape http://adresse_ip/

- Et pour vérifier que le service http est autorisé dans le firewall :
sudo firewall-cmd --list-service
- Modification du port d’écoute de nginx (par défaut 80 pour le protocole html), il faut se rendre dans le fichier de configuration nginx et modification des paramètres :
sudo nano /etc/nginx/nginx.conf
sudo systemctl restart nginx

- Que l’on teste avec le port 80 ou 8080, cela nous donne le résultat suivant, en effet le port d’écoute de nginx ayant été modifié, le 80 n’est plus écouté et le firewall-cmd n’a pas été configuré pour effectuer une exception pour le port 8080.

- Modification de la configuration pour la remettre dans son état d’origine (Il faut effectuer la manipulation inverse que celle-ci-dessus)
Installation du moteur de la base de données
- MariaDB ayant été installé, il est nécessaire de le configurer
- TIPS : Il faudra conserver ces logins tout au long du TP
- Lancement et rendre enable au démarrage MariaDB
sudo systemctl enable --now mariadb.service

- Lancement de la configuration de base
sudo mysql_secure_installation

- Connexion
sudo mysql -u root -p
- Création de la base de données
create database bdd_web;
- Création de l’utilisateur
CREATE USER 'WEB'@'localhost' IDENTIFIED BY 'je_suis_le_mot_de_passe';
- Attribution des droits
GRANT ALL PRIVILEGES ON bdd_web.* TO 'WEB'@'localhost';
- Forcer la prise en compte des modifications
FLUSH PRIVILEGES;
- Vérifier la base de données
SHOW DATABASES;

Déploiement du site FR
- Déploiement le site FR, pour cela nous allons créer le répertoire ecommerce.fr/ dans /var/www/
sudo mkdir -p /var/www/ecommerce.fr/
- Avec le package fournis, on déposera l’ensemble des fichiers dans le répertoire ecommerce.fr Astuce : WinSCP permet d’effectuer cette démarche en utilisant le protocole SSH

sudo cp -r /home/ldutour/PricingSubscription/ /var/www/ecommerce.fr/
- Maintenant nous allons modifier les paramètres de php-fpm, se rendre dans /etc/php-fpm.d/www.conf
sudo nano /etc/php-fpm.d/www.conf


- Activation du démarrage automatique et démarrer dès maintenant le service
sudo systemctl start php-fpm & sudo systemctl enable --now php-fpm

- Création du fichier de configuration nginx, à créer dans le répertoire /etc/nginx/conf.d/site_commerce.fr.conf
sudo nano /etc/nginx/conf.d/site_commerce.fr.conf
server {
listen 80;
listen [::]:80;
root /var/www/ecommerce.fr/PricingSubscription/;
index index.html index.htm index.nginx-debian.html sign-up.php;
server_name ecommerce.fr ;
location ~* \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
access_log /var/log/nginx/access_ecommerce.fr.log;
error_log /var/log/nginx/error_ecommerce.fr.log;
location / {
try_files $uri $uri/ =404;
}
}
- Configuration du fichier de configuration php pour établir la connexion avec le moteur de base de données. Pour cela, il faut effectuer une modification du fichier de configuration conf.php et renseigner les informations avec les informations lors de la création de la base de données et de l’utilisateur.
sudo nano /var/www/ecommerce.fr/PricingSubscription/config.php

- Exécution du script SQL database.sql fournit. Pour cela, il faut se connecter sur le moteur de base de données et sélectionner la base.
sudo mysql -u WEB -p
use bdd_web;
source /var/www/ecommerce.fr/PricingSubscription/database.sql

- Relance du service nginx afin de faire des tests.
sudo systemctl restart nginx
- Lorsque l’on tape l’adresse IP, cela fonctionne

- Pour que le nom de domaine fonctionne, il faut modifier les DNS dans sa machine locale Sur Windows, modifier le fichier de configuration suivant en tant qu’administrateur
C:\Windows\System32\drivers\etc\hosts

Sur Linux, modifier le fichier de configuration suivant
/etc/hosts
- Maintenant, si on tape dans la barre de recherche de son navigateur le nom de domaine, on tombe sur notre page

- Un test supplémentaire permet de vérifier si php est correctement opérationnel : Cette commande permet de vérifier la version et information complémentaire de php ainsi que du système d’exploitation utilisé.
echo '<?php phpinfo(); ?>' | sudo tee /var/www/ecommerce.fr/PricingSubscription/info.php
sudo chown nginx:nginx /var/www/ecommerce.fr/PricingSubscription/info.php
sudo chmod 644 /var/www/ecommerce.fr/PricingSubscription/info.php

- Si l’on souhaite modifier à notre guise la page en FR de la page qui s’affiche, alors il faudra modifier le fichier suivant : /var/www/ecommerce.fr/PricingSubscription/sign-up.php
sudo nano /var/www/ecommerce.fr/PricingSubscription/sign-up.php
En effectuant les modifications nécessaires, on se retrouve avec la page suivante :

Déploiement du site UK
Nous allons maintenant déployer le 2ème site UK. En utilisant la démarche précédente à l’exception de quelques étapes :
- La configuration de la base de données n’est pas nécessaire car nous réutiliserons celle du serveur WEB01
sudo mkdir -p /var/www/ecommerce.uk/
sudo cp -r /home/ldutour/PricingSubscription/ /var/www/ecommerce.fr/
sudo nano /etc/nginx/conf.d/site_commerce.uk.conf
server {
listen 80;
listen [::]:80;
root /var/www/ecommerce.fr/PricingSubscription/;
index index.html index.htm index.nginx-debian.html sign-up.php;
server_name ecommerce.uk ;
location ~* \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
access_log /var/log/nginx/access_ecommerce.uk.log;
error_log /var/log/nginx/error_ecommerce.uk.log;
location / {
try_files $uri $uri/ =404;
}
}
sudo nano /var/www/ecommerce.uk/PricingSubscription/config.php
- Ici, lors de l’indication d’où se trouve la base de données, on modifie
localhost
par l’adresse IP du serveur.

sudo systemctl restart nginx
- Et lorsque l’on tape l’adresse IP dans notre navigateur, on retrouve le site.
- Modification du fichier host du client se localisant ici :
C:\Windows\System32\drivers\etc\hosts


echo '<?php phpinfo(); ?>' | sudo tee /var/www/ecommerce.uk/PricingSubscription/info.php
sudo chown nginx:nginx /var/www/ecommerce.uk/PricingSubscription/info.php
sudo chmod 644 /var/www/ecommerce.uk/PricingSubscription/info.php

- Le site ecommerce.uk est fonctionnel.
- Par mesure de prévoyance, il est conseillé d’effectuer des snapshots des machines virtuelles configurées plus tôt.
Sécurisation d’un service WEB (nginx)
Dans le cadre d’une sécurisation des services WEB mise en place précédemment. Cependant dans le cadre de changements sur un système, il existe une gestion des changements. Les actions doivent être en lien avec la mise en place d’un incident ou d’un changement. C’est une recommandation selon la norme ITIL. Ainsi, nous suivrons le processus « type » d’un changement selon la norme ITIL, il est important de prendre en compte, cela est une proposition de processus, chaque entreprise l’adapte selon son besoin.

En lien avec le protocole http, l’ANSSI recommande l’utilisation des protocoles avec chiffrement. En effet, si l’on effectue une analyse Wireshark et que l’on rempli le formulaire du site :

Grâce à Wireshark, on peut observer les trames passer sur le réseau et les informations passent en clair. Ainsi il est urgent de sécuriser cela ! ⚠️ Pour cela, il est nécessaire de mettre en place le protocole HTTPS sur nos serveurs web.
- Création du répertoire suivant et limitation de l’accès à ce répertoire
sudo mkdir /etc/ssl/private
sudo chmod 700 /etc/ssl/private/
- Commande pour la génération des certificats et explication de cette commande
o Openssl : Outil pour la création de certificat
o Req : La commande x509 est un utilitaire de certificat polyvalent. Il peut être utilisé pour afficher des informations de certificat, convertir des certificats en diverses formes, signer des demandes de certificat comme une « mini CA » ou modifier les paramètres de confiance de certificat
o -x509 : Cette Option génère un certificat auto-signe au lieu d’une demande de certificat. Ceci est généralement utilisé pour générer un certificat de test ou une autorité racine auto-signée. Les extensions ajoutées au certificat (le cas échéant) sont spécifiées dans le fichier de configuration.
o -nodes : Cela indique à OpenSSL d’ignorer l’option permettant de sécuriser notre certificat avec une passphrase. Nous avons besoin de nginx pour pouvoir lire le fichier, sans intervention de l’utilisateur, au démarrage du serveur. Une phrase secrète empêcherait que cela se produise car nous devrions la saisir après chaque redémarrage.
o -days 365 : Durée de validité du certificat
o -newkey rsa:2048 : Cela spécifie que nous voulons générer un nouveau certificat et une nouvelle clé en même temps. Nous n’avons pas créé la clé requise pour signer le certificat lors d’une étape précédente, nous devons donc la créer avec le certificat. La partie rsa:2048 lui indique de créer une clé RSA d’une longueur de 2048 bits.
o -keyout /etc/ssl/private/nginx-selfsigned.key :
o -out /etc/ssl/certs/nginx-selfsigned.crt :
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned_fr.key -out /etc/ssl/certs/nginx-selfsigned_fr.crt


- Générer un groupe Diffie-Hellman fort qui permet la négociation de PFS (Perfect Forward Secrecy)
sudo openssl dhparam -out /etc/ssl/certs/dhparam_fr.pem 2048

- Édition des fichiers de configuration /etc/nginx/conf.d de chaque site pour intégrer le protocole HTTPS.
o On va spécifier les ports de fonctionnement de HTTPS (443)
o Spécification du certificat et de la clef
sudo nano /etc/nginx/conf.d/site_commerce.fr.conf
server {
listen 443 http2 ssl;
listen [::]:443 http2 ssl;
ssl_certificate /etc/ssl/certs/nginx-selfsigned_fr.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned_fr.key;
ssl_dhparam /etc/ssl/certs/dhparam_fr.pem;
root /var/www/ecommerce.fr/PricingSubscription/;
index index.html index.htm index.nginx-debian.html sign-up.php;
server_name ecommerce.fr ;
location ~* \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
access_log /var/log/nginx/access_ecommerce.fr.log;
error_log /var/log/nginx/error_ecommerce.fr.log;
location / {
try_files $uri $uri/ =404;
}
}
sudo nginx -t
sudo systemctl reload nginx
- Pour la partie ecommerce.uk :
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned_uk.key -out /etc/ssl/certs/nginx-selfsigned_uk.crt
sudo openssl dhparam -out /etc/ssl/certs/dhparam_uk.pem 2048


sudo nano /etc/nginx/conf.d/site_commerce.uk.conf
server {
listen 443 http2 ssl;
listen [::]:443 http2 ssl;
ssl_certificate /etc/ssl/certs/nginx-selfsigned_uk.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned_uk.key;
ssl_dhparam /etc/ssl/certs/dhparam_uk.pem;
root /var/www/ecommerce.uk/PricingSubscription/;
index index.html index.htm index.nginx-debian.html sign-up.php;
server_name ecommerce.uk ;
location ~* \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
access_log /var/log/nginx/access_ecommerce.uk.log;
error_log /var/log/nginx/error_ecommerce.uk.log;
location / {
try_files $uri $uri/ =404;
}
}
sudo nginx -t
sudo systemctl reload nginx
- Lorsque l’on tente d’accéder au site, nous avons une alerte, faites « Paramètres avancés/Continuer vers le site ecommerce.uk (Dangereux) »
o L’alerte est normale, depuis 2019, les navigateurs signalent les certificats « auto-signés »




- Si on observe les détails du certificat

- Pour être sûr du bon fonctionnement en HTTPS, on lance une petite analyse de trame via WireShark. De plus, en faisant le même exercice avec le formulaire, on remarque que les données sont chiffrées.


- Avant de continuer, il faut que les 2 sites soient consultables via HTTPS et il est conseillé de faire une snapshot des machines virtuelles.
Redirection HTTP vers HTTPS
Cependant, si nous testons d’aller sur le site en http, cela fonctionne encore. Nous allons mettre en place pour nos utilisateurs, une redirection http vers HTTPS. Il faut pour cela ajouter une directive dans la partie serveur http : L’ensemble des requêtes http sont redirigés vers HTTPS.
sudo nano /etc/nginx/conf.d/site_commerce.uk.conf
return 301 https://$host$request_uri; #A ajouter dans le bloc server listen 80
sudo nginx -t
sudo systemctl reload nginx

- Et on effectue de même avec le site ecommerce.fr
sudo nano /etc/nginx/conf.d/site_commerce.fr.conf
return 301 https://$host$request_uri; #A ajouter dans le bloc server listen 80

sudo nginx -t
sudo systemctl reload nginx
- Le port HTTPS peut être ouvert, tandis que le port http peut être fermé
sudo firewall-cmd --remove-service=http && sudo firewall-cmd --add-service=https
firewall-cmd --list-service

Et on effectue la même chose sur WEB02
sudo ls /etc/nginx/
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload
sudo systemctl start nginx & sudo systemctl enable nginx
- Test du serveur nginx dans le navigateur à l’adresse http://adresse_ip/

sudo mkdir -p /var/www/ecommerce.uk/

sudo cp -r /home/ldutour/PricingSubscription/ /var/www/ecommerce.uk/
sudo nano /etc/php-fpm.d/www.conf


sudo systemctl start php-fpm & sudo systemctl enable --now php-fpm

sudo nano /etc/nginx/conf.d/site_ecommerce.uk.conf

Déploiement du service de haute disponibilité WEB grâce à HAProxy
- Installation du package HAProxy
sudo yum install haproxy -y
- Copie du fichier de configuration avant toute modification
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
- Modifications des paramètres suivant pour ajouter nos serveurs :
Bloc permettant d’activer la page de suivi du load-balancing :
defaults
mode tcp
listen stats bind *:8080 # Port d'écoute de l'interface de suivi
mode http
stats enable
stats hide-version
stats uri /stats # URL de l'interface de suivi
stats admin if LOCALHOST
stats auth haproxy:haproxy # Identifiants de connexion (utilisateur:mot de passe)
Bloc permettant de définir le serveur qui va rediriger les requêtes vers le bon serveur WEB :
frontend main
bind *:80 # Port sur lequel HAProxy écoute
acl url_static path_beg /static /images /javascript /stylesheets
acl url_static path_end .jpg .gif .png .css .js
use_backend static if url_static
default_backend app # Redirection vers le backend principal
Bloc permettant de définir nos serveurs selon le nom du backend :
backend app
balance roundrobin
server WEB02 192.168.1.166:443 ssl verify none check
server WEB01 192.168.1.234:443 ssl verify none check
- Activation de Rsyslog
sudo cp /etc/rsyslog.conf /etc/rsyslog.conf.bak
sudo nano /etc/rsyslog.conf
- Décommentez les lignes suivantes :
module(load="imudp") # needs to be done just once
input(type="imudp" port="514")

- Configuration d’une policy pour SELinux car celui-ci surveille tout
sudo setsebool -P haproxy_connect_any 1
- Démarrage de HAProxy et Rsyslog
sudo systemctl enable --now haproxy && sudo systemctl enable --now rsyslog
sudo systemctl reload haproxy
- Ouverture du port 8080 dans le firewall
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
Depuis le HAProxy
- Vérification dans un navigateur WEB, l’accès à la page d’administration


Mise en place d’un cluster de HAProxy
- Dans le cadre de la haute disponibilité, il est recommandé de mettre en place un cluster de HAProxy. Ici, il aura les machines suivantes toutes sous RHEL :
- WEB01
- WEB02
- HA01
- HA02

Il faut que la résolution de noms soit fonctionnelle. Ceci peut-être testé avec curl
.
Installation HAProxy Bis
- Résolution des noms via le fichier
/etc/hosts
et vérification aveccurl
.

- Ouverture du port 80 si nécessaire.
sudo yum install haproxy -y
sudo scp /etc/haproxy/haproxy.cfg ldutour@192.168.1.134:/home/ldutour
sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
sudo cp /home/ldutour/haproxy.cfg /etc/haproxy/
sudo cp /etc/rsyslog.conf /etc/rsyslog.conf.bak
sudo nano /etc/rsyslog.conf
sudo setsebool -P haproxy_connect_any 1
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --reload
sudo openssl req -x509 -nodes -newkey rsa:2048 -keyout /etc/pki/tls/certs/haproxy.pem -out /etc/pki/tls/certs/haproxy.pem -days 365

sudo systemctl enable --now haproxy && sudo systemctl enable --now rsyslog
sudo systemctl reload haproxy
Installation de Pacemaker
- Installation sur les deux proxy du module Pacemaker
sudo yum config-manager --set-enabled highavailability
- Activer le module « highavailability » :
sudo yum config-manager --set-enabled highavailability
sudo dnf install pcs -y
sudo systemctl enable --now pcsd
- Création du cluster avec configuration du mot de passe
sudo passwd hacluster
- Gestion du firewall :
sudo firewall-cmd --add-service=high-availability --permanent
sudo firewall-cmd --reload
- Authentification entre les HAProxy :
sudo pcs host auth HA01 HA02


- Sur HA02 uniquement :
sudo pcs host auth HA01 HA02

- Démarrage et activation du cluster :
sudo pcs cluster start --all
sudo pcs cluster enable --all


- Vérifications :
sudo pcs cluster status

sudo pcs status corosync #Vérifie le statut du service de communication Corosync
pcs status nodes #Liste l’état des nœuds du cluster


– Possibilité de vérifier les erreurs
sudo crm_verify -L -V

Erreurs concernant STONITH car celui-ci n’a pas été configuré voir à Configuration de STONITH
- Vérification des versions
sudo pcs property

Configuration de STONITH
sudo pcs property set stonith-enabled=false
sudo pcs property set no-quorum-policy=ignore
sudo crm_verify -L -V
Configuration d’une VIP (Virtual IP)
sudo pcs resource create virtual_ip ocf:heartbeat:IPaddr2 ip=192.168.1.135 cidr_netmask=24 op monitor interval=30s
sudo pcs status resources
Celle-ci a bien été configuré

sudo pcs status resources

Ressource de maintenance
Sur les deux serveurs :
- Installation de l’agent HAProxy :
sudo curl -O https://raw.githubusercontent.com/thisismitch/cluster-agents/master/haproxy
sudo chmod +x haproxy
sudo mv haproxy /usr/lib/ocf/resource.d/heartbeat/
- Création et intégration de la ressource :
Création du cluster
sudo pcs resource create haproxy ocf:heartbeat:haproxy binpath=/usr/sbin/haproxy conffile=/etc/haproxy/haproxy.cfg op monitor interval=10s
– Savoir quels agents sont disponibles sur le serveur
sudo pcs resource agents ocf:heartbeat

#Affectation de la ressource au cluster
sudo pcs resource group add HAproxyGroup virtual_ip haproxy
#Ajout d’une contrainte pour que l’IP virtuelle et le HAProxy soit opérationnel sur le même nœud en même temps
sudo pcs constraint order virtual_ip then haproxy
- Vérification globale :
sudo pcs status

- Logs de Corosync :
cd /var/log/cluster
ls

- Vérification de la redirection via la VIP.

Vérification de la continuité de service du HAProxy
En effet, si l’un des serveurs est éteint, le second récupère la VIP pour réceptionner les requêtes.
Donc, dans le cadre d’un test, si on effectue une extinction du serveur HA01, le HA02 récupère la VIP comme on le voit ci-dessous.

Et si on regarde le statut, on peut voir que le service détecte comme OFFLINE, éteint le HA01.

Et si nous effectuons la même manœuvre avec l’extinction de HA02, le serveur HA01 récupère la VIP.

Et si on regarde le statut, on peut voir qu’il détecte comme OFFLINE le HA02.
Ainsi la vérification de la continuité de service informatique est effectuée.
Sources
Si cela vous intéresse, vous trouverez ci-dessous le compte-rendu de cette réalisation professionnelle :
🔒Se connecter pour accéder à la ressource