Cas d'usage de HAProxy dans REDHAT OpenShift
Important
|
En cours Le contenu de cette page est en cours d’édition. Tout bouge en permanence sur cette page et notemment les schémas. |
Cas d’usage de HAProxy dans REDHAT OpenShift
HAProxy comme Routeur/Contrôleur d’Entrée (Ingress Controller)
Rôle Principal :
C’est le cas d’utilisation le plus courant et fondamental.
Le contrôleur d’entrée par défaut d’OpenShift (openshift-router) est basé sur HAProxy.
Fonctionnement :
- Il surveille les ressources Route (spécifiques à OpenShift) ou Ingress (standard Kubernetes) créées par les utilisateurs.
- Lorsqu’une nouvelle route est créée (par exemple, pour exposer une application web à l’extérieur du cluster), le contrôleur reconfigure dynamiquement HAProxy.
- HAProxy écoute sur les ports 80 (HTTP) et 443 (HTTPS) sur les nœuds désignés (souvent des nœuds d’infrastructure ou “infra nodes”).
- Il achemine le trafic externe entrant vers les bons Pods de service à l’intérieur du cluster, en se basant sur le nom d’hôte (hostname) et éventuellement le chemin (path) spécifiés dans la ressource Route/Ingress.
Fonctionnalités Clés dans ce rôle :
- Terminaison SSL/TLS : HAProxy peut gérer le déchiffrement du trafic HTTPS en utilisant les certificats spécifiés dans les Routes, soulageant ainsi les applications.
- Ré-encryption TLS : Il peut re-chiffrer le trafic avant de l’envoyer aux Pods si nécessaire.
- Équilibrage de Charge : Il répartit le trafic entre les différents Pods d’un même service.
- Routage basé sur l’hôte et le chemin : Permet d’héberger plusieurs applications/services derrière la même adresse IP.
- Support des WebSockets.
- Sessions persistantes (Sticky Sessions) : Peut s’assurer qu’un utilisateur est toujours dirigé vers le même Pod applicatif.
Schéma 1 : HAProxy comme Routeur/Contrôleur d’Entrée par Défaut OpenShift
Objectif : Montrer le flux de trafic externe standard via le routeur HAProxy.
1. Réception Req
2. Recherche Route
3. Terminaison TLS
4. Équilibrage Charge"] RouteObject["Objet Route (app.domaine.com)"] Service["Service Kubernetes"] %% AppPods["Pods Applicatifs"] end subgraph "Pods Applicatifs" subgraph "Réseau Interne du Cluster SDN" Pod1["Pod App 1"] Pod2["Pod App 2"] Podn["Pod App n"] end end %% Flux Principal User --> OptExtLB; OptExtLB -->|Port 80/443| RouterPod; User -->|Si pas de LB externe| RouterPod; %% Interactions du Routeur RouterPod <-->|Lit configuration depuis| RouteObject; RouterPod -->|Achemine vers| Service; %% Service -->|Équilibre vers| AppPods; Service -.->|Équilibre vers| Pod1; Service -.->|Équilibre vers| Pod2; Service -.->|Équilibre vers| Podn; %% Style (optionnel) style RouterPod fill:#7bff,stroke:#686f8c,stroke-width:2px
- L’utilisateur accède à l’URL de l’application (ex: app.domaine.com).
- La requête arrive sur l’IP publique pointant vers les nœuds OpenShift hébergeant le routeur (souvent via un LB externe).
- Le Pod Routeur HAProxy reçoit la requête sur le port 80 ou 443.
- HAProxy consulte sa configuration (générée à partir des objets Route OpenShift) pour trouver le service backend correspondant au nom d’hôte demandé.
- Si HTTPS, HAProxy termine la session TLS (déchiffre le trafic) en utilisant le certificat de la Route.
- HAProxy équilibre la charge (load balance) la requête vers l’un des Pods de l’application cible via le Service Kubernetes correspondant.
HAProxy comme Pare-feu Applicatif (WAF) - Fonctionnalités et Limitations
Capacités Intrinsèques de Sécurité (Pas un WAF complet) :
- HAProxy lui-même n’est pas un WAF complet comme ModSecurity, F5 BIG-IP ASM, ou Cloudflare WAF. Il ne dispose pas nativement de bibliothèques complexes de règles pour détecter les attaques type XSS, SQL Injection, etc.
- Cependant, HAProxy offre des fonctionnalités de sécurité importantes qui contribuent à la protection applicative :
- Listes de Contrôle d’Accès (ACLs) : Permettent de filtrer le trafic en fonction de divers critères (adresse IP source, en-têtes HTTP, user-agent, path, etc.). On peut ainsi bloquer des IPs malveillantes connues, restreindre l’accès à certaines zones, etc.
- Limitation de Débit (Rate Limiting) : Protège contre les attaques par déni de service (DoS) ou les tentatives de brute-force en limitant le nombre de requêtes par client sur une période donnée.
- Validation du Protocole HTTP : Rejette les requêtes mal formées.
- Gestion fine de TLS/SSL : Permet d’imposer des versions de TLS et des suites de chiffrement robustes (cipher suites).
- Intégration avec un Moteur WAF :
- Une approche courante pour obtenir une fonctionnalité WAF complète est d’intégrer HAProxy avec un moteur WAF dédié, comme ModSecurity.
- Cela peut se faire via libmodsecurity si HAProxy est compilé avec le support nécessaire, ou en plaçant un service WAF (par exemple, un Pod exécutant ModSecurity avec Nginx/Apache) derrière le HAProxy Router ou devant celui-ci.
- Dans ce scénario, HAProxy gère la connexion, la terminaison TLS et l’équilibrage de charge, tandis que le moteur WAF inspecte le trafic déchiffré pour détecter et bloquer les menaces.
- HAProxy Enterprise : La version entreprise de HAProxy inclut parfois des modules WAF plus avancés ou des intégrations facilitées.
Schéma 2 : HAProxy Routeur avec Fonctionnalités de Sécurité (ACLs, Rate Limiting)
Objectif : Montrer où les fonctionnalités de sécurité de base de HAProxy s’insèrent dans le flux. (Zoom sur le Pod Routeur HAProxy du Schéma 1).
IP, Header, etc.]) C([Limiteur de Débit]) F([Réponse Erreur/Rejet ACL]) D([Traitement Normal ]) G([Réponse Erreur 429]) E([Vers Pods Applicatifs Cibles]) end %% Style (optionnel) style F fill:#f00,stroke:#333,stroke-width:2px,color:#fff style G fill:#f00,stroke:#333,stroke-width:2px,color:#fff
- Description :
- Avant même la terminaison TLS (ou juste après, selon la configuration), HAProxy applique les règles ACL définies (ex: bloquer des IPs spécifiques).
- Ensuite, il vérifie si le client dépasse les limites de débit configurées.
- Si les contrôles de sécurité passent, le traitement normal (terminaison TLS, routage, équilibrage de charge) continue comme dans le Schéma 1.
Schéma 3 : HAProxy Routeur Intégré avec un Moteur WAF (Ex: ModSecurity)
Objectif : Montrer comment un WAF peut être intégré pour inspecter le trafic après le déchiffrement par HAProxy.
ex: ModSecurity]) E([HAProxy: Routage & Équilibrage de Charge]) F([WAF: Blocage/Réponse Erreur]) G([Vers Pods Applicatifs Cibles]) end %% Style (optionnel) style F fill:#f00,color:#fff
- HAProxy reçoit la requête HTTPS et effectue la terminaison TLS.
- Le trafic HTTP déchiffré est passé au moteur WAF (ex: libmodsecurity chargé par HAProxy).
- Le WAF inspecte la requête à la recherche de signatures d’attaques connues.
- Si une attaque est détectée, le WAF bloque la requête.
- Si la requête est jugée légitime, elle est retournée à HAProxy qui effectue alors le routage et l’équilibrage de charge vers les Pods applicatifs.
Autres Cas d’Utilisation (Moins Courants dans le cadre strict du routeur par défaut)
- Load Balancer Externe : Une instance HAProxy (physique ou virtuelle) peut être déployée devant les nœuds OpenShift qui hébergent les pods du routeur openshift-router.
Cela ajoute une couche supplémentaire de haute disponibilité et d’équilibrage de charge pour le trafic entrant vers le cluster. - Proxy/Load Balancer Interne : HAProxy peut être déployé comme un service à l’intérieur du cluster pour des besoins spécifiques d’équilibrage de charge TCP/HTTP entre différents microservices, offrant des fonctionnalités plus avancées que les Services Kubernetes/OpenShift standards.
Schéma 4 (Optionnel) : HAProxy comme Load Balancer Externe Devant OpenShift
Objectif : Montrer HAProxy utilisé en dehors du cluster pour distribuer le trafic vers les routeurs OpenShift.
- Le trafic utilisateur arrive d’abord sur une instance HAProxy externe (ou une paire pour la haute disponibilité).
- Cet HAProxy externe équilibre la charge sur les différents nœuds OpenShift (généralement les nœuds Infra) qui exécutent les Pods du routeur HAProxy par défaut d’OpenShift.
- Ensuite, le flux continue comme dans le Schéma 1 à l’intérieur de chaque Pod Routeur OpenShift.
En résumé :
Dans OpenShift, HAProxy est principalement utilisé comme le moteur du routeur par défaut, gérant tout le trafic externe entrant via les objets Route/Ingress.
Il assure le routage, la terminaison TLS et l’équilibrage de charge vers les applications.
Bien qu’il ne soit pas un WAF complet en soi, il fournit des fonctionnalités de sécurité essentielles (ACLs, rate limiting) et peut être intégré à des solutions WAF dédiées pour une protection applicative renforcée.
Sa robustesse et ses performances en font un choix idéal pour ces rôles critiques.
mise en œuvre d’HAProxy (via l’OpenShift Router) sur un cluster OpenShift avec quatre nœuds et 6 pods applicatifs
-
^Réseau Externe : Le trafic provenant de l’extérieur du cluster OpenShift arrive sur les nœuds physiques via le réseau externe. Les ports d’entrée typiques pour les applications web sont le port 80 (HTTP) et le port 443 (HTTPS).
-
Nœuds Physiques (quatres Nœuds) : Chaque nœud physique possède des interfaces réseau. Généralement, vous aurez au moins une interface connectée au réseau externe (avec une adresse IP accessible de l’extérieur) et une ou plusieurs interfaces pour le réseau interne du cluster.
- Interface Externe (e.g., eth0) : Reçoit le trafic externe sur les ports 80 et 443.
- Interface du Réseau Cluster (e.g., eth1) : Utilisée pour la communication interne entre les nœuds et les pods, gérée par le SDN.
-
SDN (Software-Defined Network) : OpenShift utilise un SDN (comme OVN ou OpenShift SDN) pour créer un réseau virtuel unifié à travers tous les nœuds. Cela permet aux pods de communiquer entre eux indépendamment du nœud physique sur lequel ils s’exécutent. Le SDN gère également l’attribution des adresses IP aux pods et aux services.
-
Pods de Routeur HAProxy (Sur les Nœuds) : Dans un cluster avec trois nœuds, vous aurez probablement un ou plusieurs pods de routeur HAProxy déployés sur ces nœuds. Ces pods écoutent sur les ports 80 et 443 au sein de leur réseau virtuel (fourni par le SDN).
-
Service du Routeur HAProxy : Un service Kubernetes/OpenShift est créé pour exposer les pods de routeur. Ce service peut être de type LoadBalancer (dans les environnements cloud) ou NodePort (dans les environnements on-premise).
- LoadBalancer : Un load balancer externe (provisionné par le cloud provider) achemine le trafic vers les adresses IP des nœuds sur les ports 80 et 443, qui est ensuite dirigé vers les pods de routeur.
- NodePort : Un port spécifique (e.g., 30000-32767) est ouvert sur chaque nœud. Le trafic externe peut être envoyé à n’importe quel nœud sur ce port, et il sera routé vers un pod de routeur.
-
Routage et Équilibrage de Charge : Le service du routeur (via HAProxy) reçoit le trafic et, en fonction des règles définies dans les ressources Route (ou Ingress), achemine le trafic vers les services backend appropriés pour vos applications. HAProxy effectue également l’équilibrage de charge entre les différents pods de l’application.
-
Services des Applications : Les pods applicatifs sont généralement regroupés derrière un ou plusieurs services Kubernetes/OpenShift. Ces services ont une adresse IP virtuelle interne au cluster (ClusterIP) et écoutent sur un port spécifique (par exemple, 8080).
-
Communication Interne : La communication entre les pods de routeur et les services des applications, ainsi qu’entre les services et les pods d’application, se fait via le réseau interne du cluster géré par le SDN.
%%{init: {"flowchart":{'securityLevel': 'loose', 'theme':'base', 'markdownAutoWrap': 'false'}}}%% graph LR subgraph "Réseau Externe" EXT["Trafic ExterneExplication du Schéma:
(Port 80/443)"] end subgraph "Nœud Physique 1" N1_eth0[eth0:
IP Externe] N1_eth1[eth1:
Réseau Cluster] RP1((Routeur Pod 1)) end subgraph "Nœud Physique 2" N2_eth0[eth0:
IP Externe] N2_eth1[eth1:
Réseau Cluster] RP2((Routeur Pod 2)) end subgraph "Nœud Physique 3" N3_eth0[eth0:
IP Externe] N3_eth1[eth1:
Réseau Cluster] RP3((Routeur Pod 3)) end subgraph "Nœud Physique 4" N4_eth0[eth0:
IP Externe] N4_eth1[eth1:
Réseau Cluster] RP4((Routeur Pod 4)) end subgraph "SDN (OVN ou OpenShift SDN)" SDN end subgraph "Cluster OpenShift" RS[Service Routeur LB/NodePort] AS1[Service App 1 Port Ex: 8080] AS2[Service App 2 Port Ex: 8080] AS3[Service App 3 Port Ex: 8080] subgraph "Pods Application" AP1((Pod 1)) AP2((Pod 2)) AP3((Pod 3)) AP4((Pod 4)) AP5((Pod 5)) AP6((Pod 6)) end end %% linkStyle 0,1,2,3 EXT -- Port 80/443 --> N1_eth0 EXT -- Port 80/443 --> N2_eth0 EXT -- Port 80/443 --> N3_eth0 EXT -- Port 80/443 --> N4_eth0 %% linkStyle 4,5,6,7 N1_eth0 -- vers --> RP1 N2_eth0 -- vers --> RP2 N3_eth0 -- vers --> RP3 N4_eth0 -- vers --> RP4 %% linkStyle 8,9,10,11 RP1 -- Port 80/443
(interne) --> RS RP2 -- Port 80/443
(interne) --> RS RP3 -- Port 80/443
(interne) --> RS RP4 -- Port 80/443
(interne) --> RS %% linkStyle 12,13,14,15 %% RP1 -.-> N1_eth1 %% RP2 -.-> N2_eth1 %% RP3 -.-> N3_eth1 %% RP4 -.-> N4_eth1 %% linkStyle 16,17,18 RS -- Routage basé sur Route --> AS1 RS -- Routage basé sur Route --> AS2 RS -- Routage basé sur Route --> AS3 %% linkStyle 19,20,21,22,23,24 AS1 -- Port 8080 (SDN) --> AP1 AS1 -- Port 8080 (SDN) --> AP2 AS2 -- Port 8080 (SDN) --> AP3 AS2 -- Port 8080 (SDN) --> AP4 AS3 -- Port 8080 (SDN) --> AP5 AS3 -- Port 8080 (SDN) --> AP6 %% RP1 -- Communication via --> SDN %% RP2 -- Communication via --> SDN %% RP3 -- Communication via --> SDN %% RP4 -- Communication via --> SDN N1_eth1 <-- Communication via --> SDN N2_eth1 <-- Communication via --> SDN N3_eth1 <-- Communication via --> SDN N4_eth1 <-- Communication via --> SDN AS1 -- Communication via --> SDN AS2 -- Communication via --> SDN AS3 -- Communication via --> SDN AP1 -- Communication via --> SDN AP2 -- Communication via --> SDN AP3 -- Communication via --> SDN AP4 -- Communication via --> SDN AP5 -- Communication via --> SDN AP6 -- Communication via --> SDN %% %% AP1 -- (via Service) --> AS2 %% linkStyle 4 stroke:red,stroke-width:2px,color:red; linkStyle 0,1,2,3 stroke:blue,stroke-width:2px,color:blue,stroke-dasharray: 5 5; linkStyle 4,5,6,7,12,13,14,15 stroke:orange,stroke-width:2px,color:orange,stroke-dasharray: 5 5; linkStyle 8,9,10,11 stroke:green,stroke-width:2px,color:green,stroke-dasharray: 5 5; linkStyle 25,26,28,29,30,31 stroke:purple,stroke-width:2px,color:purple,stroke-dasharray: 5 5; linkStyle 20 stroke:orange,stroke-width:2px,color:orange; linkStyle 21 stroke:green,stroke-width:2px,color:green; linkStyle 24 stroke:blue,stroke-width:2px,color:blue; linkStyle 27 stroke:purple,stroke-width:2px,color:purple; -
Réseau Externe (EXT) : Représente la source du trafic entrant.
-
Nœuds Physiques (N1_eth0, N2_eth0, N3_eth0) : Affichent l’interface externe de chaque nœud recevant le trafic sur les ports 80 et 443.
-
Pods Routeur (RP1, RP2, RP3) : Représentent les instances d’HAProxy s’exécutant sur chaque nœud.
-
SDN : Symbolise le réseau virtuel qui connecte tous les composants à l’intérieur du cluster.
-
Cluster OpenShift : Contient les services et les pods applicatifs.
-
Service Routeur (RS) : Le service qui expose les pods de routeur.
-
Services Application (AS1, AS2) : Les services qui regroupent les pods de vos applications.
-
Pods Application (AP1 à AP6) : Les instances de vos applications.