HAProxy
Load balancer et proxy inverse haute performance pour la gestion du trafic et la répartition de charge.
Architecture et structure
Comprendre l'architecture modulaire de HAProxy et l'organisation des fichiers de configuration
Notre implémentation de HAProxy utilise une architecture modulaire qui sépare les différentes responsabilités en fichiers de configuration distincts. Cette approche facilite la maintenance, permet une meilleure organisation du code, et rend la configuration plus lisible et modulaire.
Cette architecture a été spécifiquement choisie pour faciliter l'ajout d'autres applications plus tard : chaque nouvelle application peut être ajoutée simplement en créant un nouveau fichier ACL dans acls/ et un nouveau fichier backend dans backends/, sans modifier les fichiers de configuration existants.
Cette section explique le flux de trafic, la structure des fichiers, et les exemples de configuration.
HAProxy fonctionne selon un modèle en trois étapes : les Frontends reçoivent les requêtes, les ACLs et le routage déterminent où diriger le trafic, et les Backends traitent les requêtes. Voici comment le trafic circule :
Architecture modulaire HAProxy
Frontend unifié : Un seul frontend (frontend-web-in.cfg) gère à la fois HTTP (port 80) et HTTPS (port 443), simplifiant la configuration.
ACLs & Routage : Règles de routage basées sur le hostname définies dans acls/*.cfg pour diriger le trafic vers les backends appropriés.
Backends : Serveurs applicatifs (127.0.0.1:port) définis dans backends/*.cfg qui traitent les requêtes et retournent les réponses.
Configuration modulaire : Global, Defaults, Frontend unifié, ACLs et Backends sont organisés en fichiers séparés pour faciliter la maintenance et l'ajout de nouvelles applications. Cette architecture permet d'ajouter une nouvelle application en créant simplement deux fichiers (un ACL et un backend) sans toucher aux configurations existantes.
# Flux de trafic HAProxy
#
# 1. Frontend unifié (web-in)
# - HTTP (port 80) : reçoit les requêtes non chiffrées
# - HTTPS (port 443) : reçoit les requêtes chiffrées SSL/TLS
# - Configuration des headers (X-Forwarded-*, HSTS, etc.)
#
# 2. ACLs & Routage (acls/*.cfg)
# - Analyse du hostname (ex: devoups.elyamaje.com)
# - Règles de routage basées sur le domaine
# - Décision de redirection vers le bon backend
#
# 3. Backends (backends/*.cfg)
# - Serveurs locaux (127.0.0.1:port)
# - Traitement des requêtes et retour des réponses
# - default-backend.cfg pour les domaines non configurésLa configuration HAProxy est organisée en fichiers modulaires dans le répertoire /etc/haproxy/conf.d/. Cette structure permet de séparer les responsabilités et facilite la maintenance.
Structure des fichiers de configuration
Chaque fichier a une responsabilité spécifique :
- global.cfg : Paramètres globaux (logging, stats socket, SSL, etc.)
- defaults.cfg : Valeurs par défaut pour tous les frontends/backends
- frontend-web-in.cfg : Frontend unifié gérant HTTP (port 80) et HTTPS (port 443)
- acls/ : ACLs et règles de routage par application
- backends/ : Définitions des backends par application, avec default-backend.cfg en dernier
Avantage de cette structure : Pour ajouter une nouvelle application, il suffit de créer un fichier dans `acls/` (pour le routage) et un fichier dans `backends/` (pour la définition des serveurs), sans modifier les fichiers existants. Le playbook Ansible assemble automatiquement tous les fichiers lors de la génération de haproxy.cfg.
# Structure des fichiers
/etc/haproxy/
├── haproxy.cfg # Fichier principal (assemblé automatiquement)
├── certs/ # Certificats SSL (.pem)
├── errors/ # Pages d'erreur personnalisées
└── conf.d/
├── global.cfg # Configuration globale
├── defaults.cfg # Paramètres par défaut
├── maintenance.cfg # Mode maintenance (optionnel)
├── stats.cfg # Interface statistiques (optionnel)
├── frontend-web-in.cfg # Frontend unifié HTTP+HTTPS
├── acls/ # ACLs par application
│ ├── app1.cfg
│ └── app2.cfg
└── backends/ # Backends par application
├── app1-backend.cfg
├── app2-backend.cfg
└── default-backend.cfg # Backend par défaut (toujours en dernier)Le fichier principal haproxy.cfg est assemblé automatiquement par le playbook Ansible en concaténant les fichiers dans un ordre précis. L'ordre d'assemblage est crucial pour le bon fonctionnement de HAProxy.
Configuration principale (haproxy.cfg)
L'ordre d'assemblage est critique :
- global.cfg : Configuration globale (logging, stats socket, SSL)
- defaults.cfg : Valeurs par défaut pour tous les frontends/backends
- maintenance.cfg et stats.cfg : Configurations spéciales (optionnelles)
- frontend-web-in.cfg : Frontend unifié HTTP+HTTPS (optionnel)
- **acls/*.cfg** : ACLs et règles de routage par application
- **backends/*.cfg** : Backends par application (sauf default-backend.cfg)
- default-backend.cfg : Backend par défaut pour les domaines non configurés (toujours en dernier)
Note : Le fichier haproxy.cfg est généré automatiquement par le playbook Ansible. Ne le modifiez pas manuellement.
# Ordre d'assemblage automatique de haproxy.cfg
# (géré par le playbook Ansible)
# 1. Configuration de base (toujours présents)
global.cfg
defaults.cfg
# 2. Configurations optionnelles (si elles existent)
maintenance.cfg # Optionnel
stats.cfg # Optionnel
frontend-web-in.cfg # Optionnel
# 3. ACLs et routage (par application)
acls/*.cfg
# 4. Backends (par application, sauf default)
backends/*.cfg # Exclut default-backend.cfg
# 5. Backend par défaut (toujours en dernier)
backends/default-backend.cfgNotre architecture utilise un frontend unifié qui gère à la fois HTTP (port 80) et HTTPS (port 443) dans un seul fichier. Les ACLs et le routage sont définis dans les fichiers séparés du répertoire acls/.
Exemple : Configuration du frontend unifié (HTTP + HTTPS)
Points clés de cette configuration :
- **bind *:80** : Écoute sur le port 80 (HTTP) pour toutes les interfaces
- **bind *:443 ssl crt /etc/haproxy/certs/** : Écoute sur le port 443 (HTTPS) avec tous les certificats SSL
- alpn http/1.1 : Support du protocole HTTP/1.1 via ALPN
- Headers X-Forwarded-* : Transmission correcte des informations du client (IP, protocole)
- Strict-Transport-Security : HSTS uniquement sur les connexions HTTPS (condition { ssl_fc })
- default_backend : Backend par défaut pour les domaines non configurés
- Les ACLs et règles de routage sont définies dans les fichiers acls/*.cfg pour une meilleure modularité
# /etc/haproxy/conf.d/frontend-web-in.cfg
frontend web-in
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/ alpn http/1.1
mode http
option httplog
option forwardfor
option http-server-close
# Headers sécurisés: Configuration des en-têtes IP du client
http-request add-header X-Real-IP %[src]
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header HTTPS off if !{ ssl_fc }
http-request set-header HTTPS on if { ssl_fc }
http-request set-header X-Client-IP %[src]
http-request set-header X-Forwarded-For %[src]
# HSTS uniquement sur HTTPS
http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" if { ssl_fc }
# Les ACLs et use_backend sont définis dans acls/*.cfg
default_backend default_error_backendLes ACLs et règles de routage sont définies dans des fichiers séparés dans le répertoire acls/. Chaque fichier correspond généralement à une application et contient les ACLs pour identifier le domaine et les règles use_backend pour diriger le trafic.
Exemple : Configuration d'une ACL et routage
Structure typique d'un fichier ACL :
- acl : Définit une condition (ici, vérification du hostname)
- use_backend : Dirige le trafic vers le backend spécifié si la condition ACL est vraie
- Chaque application peut avoir son propre fichier ACL pour une meilleure organisation
# /etc/haproxy/conf.d/acls/myapp.cfg
# ACL pour identifier le domaine
acl is_myapp hdr(host) -i myapp.example.com
# Routage vers le backend correspondant
use_backend myapp_backend if is_myappLes backends sont définis dans des fichiers séparés dans le répertoire backends/. Chaque backend correspond généralement à une application et définit les serveurs qui traitent les requêtes.
Exemple : Configuration d'un backend
Points clés d'un backend :
- mode http : Mode HTTP (ou tcp pour TCP)
- balance : Algorithme de répartition de charge (roundrobin, leastconn, etc.)
- option httpchk : Vérification de santé HTTP (optionnel)
- server : Définition des serveurs backend avec leur adresse et port
- check : Active la vérification de santé du serveur
- backup : Serveur de secours utilisé uniquement si les serveurs principaux sont indisponibles
# /etc/haproxy/conf.d/backends/myapp-backend.cfg
backend myapp_backend
mode http
balance roundrobin
option httpchk GET /health
server app1 127.0.0.1:8080 check
server app2 127.0.0.1:8081 check backupInstallation et configuration
Guide complet pour installer et configurer HAProxy sur votre serveur
HAProxy est un load balancer et reverse proxy haute performance. Cette section vous guide à travers l'installation complète, la configuration initiale et la vérification du bon fonctionnement du service. Assurez-vous d'avoir les privilèges root (sudo) avant de commencer.
La première étape consiste à mettre à jour la liste des paquets et installer HAProxy ainsi que ses dépendances. Les paquets suivants sont nécessaires :
Installation de HAProxy et dépendances
- haproxy : Le serveur HAProxy principal
- ssl-cert : Utilitaires pour la gestion des certificats SSL
- openssl : Bibliothèque cryptographique
- certbot : Outil pour obtenir des certificats Let's Encrypt
- cron : Pour automatiser le renouvellement des certificats
sudo apt-get update -y
sudo apt-get install -y haproxy ssl-cert openssl certbot cronHAProxy nécessite plusieurs répertoires pour fonctionner correctement. Le répertoire /etc/haproxy/certs contiendra vos certificats SSL, /run/haproxy est utilisé pour les sockets de communication, et /etc/haproxy/errors pour les pages d'erreur personnalisées.
Création des répertoires nécessaires
Les permissions 755 permettent la lecture et l'exécution par tous, mais seule la modification par root. C'est la configuration de sécurité recommandée.
sudo mkdir -p /etc/haproxy/certs /run/haproxy /etc/haproxy/errors && \
sudo chmod 755 /etc/haproxy/certs /run/haproxy /etc/haproxy/errors && \
sudo chown root:root /etc/haproxy/certs /run/haproxy /etc/haproxy/errorsUne fois HAProxy installé, il faut activer le service pour qu'il démarre automatiquement au boot du système, puis le démarrer manuellement.
Activation et démarrage du service
La commande enable configure le service pour démarrer automatiquement. La commande start démarre le service immédiatement.
sudo systemctl enable haproxy
sudo systemctl start haproxyAprès le démarrage, vérifiez que le service fonctionne correctement et consultez la version installée de HAProxy.
Vérification du statut
La première commande affiche l'état détaillé du service (actif, en erreur, etc.). La seconde affiche la version de HAProxy installée.
sudo systemctl status haproxy
sudo haproxy -vAvant de recharger ou redémarrer HAProxy, il est crucial de valider la syntaxe de votre fichier de configuration. Cette commande vérifie que la configuration est correcte sans redémarrer le service.
Validation de la configuration
Si la configuration est valide, vous verrez 'Configuration file is valid'. En cas d'erreur, le message indiquera la ligne et le type d'erreur.
sudo haproxy -c -f /etc/haproxy/haproxy.cfgContrairement à restart, reload permet de recharger la configuration sans interrompre les connexions actives. C'est la méthode recommandée en production.
Recharger la configuration sans coupure
Cette commande est non-bloquante et n'interrompt pas les connexions existantes. Utilisez restart uniquement si reload ne fonctionne pas.
sudo systemctl reload haproxyGestion de la configuration
Commandes essentielles pour gérer et déboguer la configuration HAProxy
La gestion de la configuration HAProxy est un aspect crucial de son administration. Cette section couvre les commandes pour valider, déboguer et maintenir votre configuration. Il est recommandé de toujours valider la configuration avant de la déployer en production.
Cette commande valide la syntaxe de votre fichier de configuration sans modifier l'état du service. Elle est essentielle avant chaque déploiement.
Vérifier la syntaxe de la configuration
Retourne 'Configuration file is valid' si tout est correct, sinon affiche les erreurs de syntaxe avec leur emplacement.
sudo haproxy -c -f /etc/haproxy/haproxy.cfgQuand la validation échoue, cette commande fournit des informations de débogage plus détaillées pour identifier précisément les problèmes.
Voir les erreurs de configuration détaillées
Le mode -db (debug) affiche des messages d'erreur plus verbaux et détaillés pour faciliter le diagnostic.
sudo haproxy -db -f /etc/haproxy/haproxy.cfgContrairement à reload, restart arrête complètement le service puis le redémarre. Cela interrompt toutes les connexions actives.
Redémarrer le service (avec coupure)
Utilisez restart uniquement si reload ne fonctionne pas ou si vous avez modifié des paramètres qui nécessitent un redémarrage complet.
sudo systemctl restart haproxyLes logs sont essentiels pour diagnostiquer les problèmes et surveiller l'activité de HAProxy. Cette commande affiche les logs en temps réel et se met à jour automatiquement.
Voir les logs en temps réel
Appuyez sur Ctrl+C pour quitter le mode suivi. Utilisez -n 100 pour voir les 100 dernières lignes au lieu du suivi en temps réel.
sudo journalctl -u haproxy -fGestion SSL avec Let's Encrypt
Configuration complète des certificats SSL pour HAProxy, avec Let's Encrypt ou certificats auto-signés
La sécurisation des communications avec SSL/TLS est essentielle pour protéger les données en transit. Let's Encrypt offre des certificats gratuits et renouvelables automatiquement. Cette section vous guide à travers l'obtention d'un certificat, sa configuration pour HAProxy, et sa gestion. Notez que pour obtenir un certificat Let's Encrypt, votre domaine doit pointer vers le serveur et les ports 80 et 443 doivent être accessibles.
PRÉREQUIS - Création des répertoires et installation
Préparer l'environnement pour les certificats SSL. Remplacez 'domaine.elyamaje.com' par votre domaine.
sudo mkdir -p /etc/haproxy/certs
sudo apt update && sudo apt install -y certbot
sudo chown -R root:root /etc/haproxy/certs
sudo chmod 755 /etc/haproxy/certsCertbot doit utiliser le port 80 pour valider la propriété du domaine. C'est pourquoi nous arrêtons HAProxy temporairement. Le mode standalone fait que certbot écoute directement sur le port 80.
ÉTAPE 1 : Obtenir un certificat Let's Encrypt (remplacez le domaine)
Important : Remplacez 'domaine.elyamaje.com' par votre domaine réel et l'email par votre adresse. L'email est utilisé pour les notifications de renouvellement. Le certificat sera stocké dans /etc/letsencrypt/live/votre-domaine.com/
sudo systemctl stop haproxy
sudo certbot certonly --standalone --non-interactive --agree-tos --email "equipe2elyamaje@gmail.com" -d "domaine.elyamaje.com"HAProxy nécessite un fichier unique (.pem) contenant à la fois le certificat (fullchain.pem) et la clé privée (privkey.pem). L'ordre est important : d'abord le certificat, puis la clé.
ÉTAPE 2 : Combiner le certificat et la clé privée pour HAProxy
Alternative avec tee (plus sûr pour les permissions) : sudo bash -c 'cat /etc/letsencrypt/live/devoups.elyamaje.com/fullchain.pem /etc/letsencrypt/live/devoups.elyamaje.com/privkey.pem' | sudo tee /etc/haproxy/certs/devoups.elyamaje.com.pem > /dev/null
sudo cat "/etc/letsencrypt/live/domaine.elyamaje.com/fullchain.pem" "/etc/letsencrypt/live/domaine.elyamaje.com/privkey.pem" > "/etc/haproxy/certs/domaine.elyamaje.com.pem"Les certificats SSL contiennent des informations sensibles (clés privées). Il est crucial de restreindre les permissions pour éviter qu'ils soient lus par des utilisateurs non autorisés.
Sécuriser le fichier de certificat
Les permissions 600 (rw-------) permettent uniquement au propriétaire (root) de lire et écrire. Aucun autre utilisateur ne peut y accéder.
sudo chmod 600 "/etc/haproxy/certs/domaine.elyamaje.com.pem"
sudo chown root:root "/etc/haproxy/certs/domaine.elyamaje.com.pem"Avant de configurer le renouvellement automatique, testez-le avec --dry-run pour vérifier que tout fonctionne sans réellement renouveler le certificat.
Tester le renouvellement automatique
Simule le processus de renouvellement sans effectuer de changements réels. Idéal pour valider votre configuration cron.
sudo certbot renew --dry-runLes certificats Let's Encrypt expirent après 90 jours. Cette commande renouvelle tous les certificats qui approchent de l'expiration (moins de 30 jours restants par défaut).
Renouveler le certificat SSL
Attention : avec --force-renew, cette commande renouvellera le certificat même s'il n'est pas encore proche de l'expiration. À utiliser avec précaution.
sudo certbot renewListe tous les certificats Let's Encrypt actuellement installés sur le serveur avec leurs informations de validité.
Voir les certificats installés
Affiche pour chaque certificat : le nom du domaine, le chemin des fichiers, la date d'expiration et le statut.
sudo certbot certificatesCertificats SSL auto-signés (Alternative)
Créer un certificat SSL auto-signé pour le développement ou le test
Les certificats auto-signés sont utiles pour le développement, les tests, ou les environnements internes où vous n'avez pas besoin d'un certificat reconnu publiquement. Attention : les navigateurs afficheront un avertissement de sécurité pour ces certificats car ils ne sont pas signés par une autorité de certification reconnue. Ne les utilisez pas en production pour des sites publics.
Cette commande génère un certificat SSL auto-signé avec OpenSSL. Le certificat sera valide pendant 365 jours. Les paramètres -x509 et -nodes créent un certificat auto-signé sans protection par mot de passe de la clé privée.
Créer un certificat auto-signé (remplacez le domaine)
Paramètres importants :
- -x509 : Génère un certificat auto-signé
- -nodes : Pas de chiffrement de la clé privée (nécessaire pour HAProxy)
- -days 365 : Validité de 1 an
- -newkey rsa:2048 : Clé RSA de 2048 bits
- -subj : Spécifie les informations du certificat (pays, état, organisation, nom commun)
Adaptez le sujet (-subj) selon vos besoins et remplacez 'domaine.elyamaje.com' par votre domaine.
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout "/etc/haproxy/certs/domaine.elyamaje.com.key" -out "/etc/haproxy/certs/domaine.elyamaje.com.crt" -subj "/C=FR/ST=France/L=Paris/O=ElyaMaje/CN=domaine.elyamaje.com"Comme pour les certificats Let's Encrypt, HAProxy nécessite un fichier .pem unique contenant le certificat et la clé privée dans cet ordre.
Combiner le certificat et la clé pour HAProxy
L'ordre est crucial : d'abord le certificat (.crt), puis la clé privée (.key). Un mauvais ordre empêchera HAProxy de charger le certificat.
sudo cat "/etc/haproxy/certs/domaine.elyamaje.com.crt" "/etc/haproxy/certs/domaine.elyamaje.com.key" > "/etc/haproxy/certs/domaine.elyamaje.com.pem"Sécuriser et nettoyer les fichiers temporaires
Supprimer les fichiers temporaires après avoir créé le fichier .pem combiné.
sudo chmod 600 "/etc/haproxy/certs/domaine.elyamaje.com.pem"
sudo chown root:root "/etc/haproxy/certs/domaine.elyamaje.com.pem"
sudo rm "/etc/haproxy/certs/domaine.elyamaje.com.key" "/etc/haproxy/certs/domaine.elyamaje.com.crt"Vérification et test des certificats SSL
Outils et commandes pour vérifier et tester vos certificats SSL
Après avoir configuré un certificat SSL, il est important de vérifier qu'il est correctement installé et fonctionnel. Cette section fournit les outils pour inspecter les informations du certificat, valider la configuration HAProxy, et tester la connexion SSL depuis l'extérieur.
Inspectez les détails d'un certificat pour vérifier qu'il est correctement configuré, identifier son émetteur et vérifier sa période de validité.
Vérifier les informations du certificat
Affiche :
- Subject : Le domaine pour lequel le certificat est émis
- Issuer : L'autorité de certification (Let's Encrypt pour les certificats Let's Encrypt)
- Not Before/After : Les dates de validité du certificat
sudo openssl x509 -in "/etc/haproxy/certs/devoups.elyamaje.com.pem" -text -noout | grep -E "(Subject:|Issuer:|Not Before:|Not After:)"Après avoir configuré un nouveau certificat SSL, il est essentiel de valider la configuration HAProxy avant de redémarrer le service pour éviter une interruption de service.
Vérifier la configuration HAProxy avant redémarrage
Ces trois commandes en séquence :
- Valident la syntaxe de la configuration
- Démarrant HAProxy si la validation réussit
- Affichent le statut détaillé pour confirmer que le service fonctionne
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl start haproxy
sudo systemctl status haproxy --no-pager -lTeste la connexion SSL/TLS depuis l'extérieur pour vérifier que le certificat est correctement configuré et que le serveur répond correctement sur le port 443.
Tester la connexion SSL
Cette commande simule une connexion SSL client et affiche les informations du certificat présenté par le serveur. Remplacez 'domaine.elyamaje.com' par votre domaine. Le paramètre -servername est important pour SNI (Server Name Indication).
openssl s_client -connect domaine.elyamaje.com:443 -servername domaine.elyamaje.com < /dev/null