Nous tenterons dans cet article de survoler les différentes approches permettant d’accroître la fiabilité des applications web hébergées grâce à la mise en œuvre d’un répartiteur de charge tel que HAProxy.
1. Qu’est-ce que HAProxy ?
HAProxy [1] est un répartiteur de charge (en anglais « load balancer ») né début 2001 dans des environnements très exigeants en matière de fiabilité, et qui depuis n'a eu de cesse de toujours accroître la fiabilité des infrastructures au cœur desquelles il s'intègre. Son utilisation principale le place en frontal des serveurs d'applications web bien que de nombreux autres usages soient fréquemment rencontrés.
Cette longue expérience en environnements hostiles et sa notoriété de produit extrêmement fiable lui ont fait gagner peu à peu une place de premier rang parmi les grands acteurs de la répartition de charge, et le fait qu'il ait su rester un logiciel libre a bien évidemment eu une forte incidence sur sa capacité à se répandre sur les serveurs du monde entier à travers les distributions de systèmes d'exploitation libres, tout comme ses compères assurant le rôle de serveur web et que l'on retrouve bien souvent connectés juste derrière.
2. Un répartiteur de charge ? Pourquoi ?
Tout site web marchand, toute application impactant directement ou indirectement l'activité de celui qui l'opère cible en premier lieu la satisfaction de son utilisateur. Cela passe bien entendu par le respect de temps de réponse satisfaisants, mais aussi par la fiabilité ressentie par l'utilisateur. Les applications contiennent des bugs, les matériels tombent en panne, les systèmes nécessitent des mises à jour suivies de redémarrages. Mais on ne veut pas que les utilisateurs subissent les interruptions de service. Quoi de plus efficace pour faire fuir définitivement un client que de lui présenter une trace Java ou PHP dans son navigateur au milieu d'un processus de commande en ligne ? Pour éviter cela, l'intuition conduit souvent certains décideurs à rajouter des serveurs sans toutefois savoir très bien qu'en faire, voire ne pas comprendre pourquoi cela fonctionne encore plus mal après.
2.1 Calculer la disponibilité
Tout d'abord, parlons un peu de statistiques et de cas pratiques. La disponibilité, c'est ce qui reste quand on a décompté les pannes. Ici nous parlons de pannes visibles du client. Avec un taux de panne fixe par serveur, on augmente le taux de panne global en ajoutant des serveurs. Étonnant, non ? Faisons un calcul simple. Si un serveur présente un taux de disponibilité moyen de 99%, cela veut dire qu'il passe 1% de son temps dans un état inutilisable. Formulé autrement, chaque utilisateur a une probabilité de 1% de solliciter un serveur indisponible. Un algorithme de répartition de charge naïf (aléatoire ou à tour de rôle) mis en œuvre par des mécanismes simplistes tels que le DNS ou le routage aura pour effet de promener le client sur l'ensemble des serveurs au fil de ses clics. Avec 10 serveurs, la probabilité que tous les serveurs soient disponibles en même temps n’est plus que de 99% élevé à la puissance 10, soit seulement 90%. Pour un service pour lequel une seule requête est nécessaire, 10% des utilisateurs seront alors impactés. Si chaque utilisateur effectue de nombreuses requêtes et que celles-ci se font à chaque fois sur un serveur différent, 100% des utilisateurs rencontreront un problème à un moment ou un autre. Ce n'était pas vraiment le but recherché au départ ! C'est pour cela que l'on dit quela répartition de charge effectuée naïvement aggrave l'indisponibilité en augmentant le risque de présenter une anomalie à un visiteur.
Le décideur qui a acheté les 10 serveurs ci-dessus n'acceptera pas longtemps cette démonstration comme excuse pour la baisse de son chiffre d'affaires en ligne. Sa réaction immédiate sera certainement « mais pourquoi diable envoie-t-on des requêtes vers un serveur qui a planté ? ».
2.2 Vérifier en permanence la bonne santé des serveurs
Et bien le rôle principal du répartiteur de charge se situe justement là : s'intercaler entre le client et les serveurs dont il vérifie en permanence la bonne santé pour ne délivrer le trafic qu'à ceux qui sont pleinement opérationnels. Ces tests périodiques fréquents (typiquement chaque seconde) parfois appelés « tests de vie » sont plus couramment désignés par le terme anglais « health checks », c'est-à-dire « contrôles de bonne santé ». Une multitude de méthodes existent pour effectuer ces contrôles, avec un niveau de fiabilité plus ou moins élevé et un coût plus ou moins élevé pour le répartiteur de charge comme pour l'application.
Contre les pannes matérielles, un simple test de connectivité IP (« ping ») suffit souvent. Contre les plantages logiciels, il est indispensable d'effectuer des requêtes auxquelles seule une application en bonne santé saura répondre. Toute la subtilité se situe là, il faut coller au plus près du métier. Un site de vente de vêtements peut par exemple décider de lancer périodiquement une recherche des articles répondant à la description de « chaussettes » et s'assurer que des réponses valides sont fournies. Cela fait souvent peur au départ, et c'est pourquoi les tests de santé ont tendance à être déployés initialement de manière simple et facile à comprendre, comme un simple test de connectivité au port TCP du serveur web, et qu'au fil du temps ces tests s'affinent pour détecter les cas résiduels. Il s'agit en fait souvent d'une tentative de détection automatique du dernier échec rencontré, qui se transforme peu à peu en une forme d'addiction à la fiabilité occultant bien souvent les autres cas de pannes. Il faut en général comprendre que si le répartiteur de charge n'échoue plus que dans les cas où le serveur est tombé en panne dans la dernière seconde, le taux de disponibilité du service peut très rapidement remonter à 99.999% même avec des serveurs de très mauvaise qualité et des applications plantant tout le temps. Souvent déjà à 99.9% on ne se préoccupe plus des 0.1% de pertes potentielles de revenus ni des risques d'atteinte à l'image de marque. En outre, on constate sur le terrain que les tests de bonne santé sont souvent dénaturés pour prendre en compte les besoins d’arrêt en douceur des serveurs pour effectuer des maintenances à chaud, souvent via la mise en place d’agents sur les serveurs ou de code spécifique dans l’application.
2.3 Le facteur humain
Tous les hébergeurs pratiquant un gel des opérations non critiques à certaines périodes de l'année le diront : ces périodes où il est interdit de toucher aux équipements sont celles où le nombre de pannes est de très loin le plus faible. Comme les répartiteurs de charge sont souvent beaucoup moins manipulés que les autres composants, que ce soit par peur (tout le trafic passe par eux), par méconnaissance, ou plus simplement par absence de besoin d'y toucher (pas de mises à jour à appliquer), ils sont bien moins sujets aux erreurs humaines que le reste de l'infrastructure, et cela contribue grandement à leur forte disponibilité. Regardez d'ailleurs depuis combien de temps votre routeur frontal n'a pas été redémarré, vous serez sans doute surpris.
2.4 La fiabilité du répartiteur en question
Malgré tout le soin apporté à la fiabilité, les répartiteurs de charge aussi contiennent des bugs, tombent en panne, ont besoin de mises à jour et sont tributaires du matériel. C'est pourquoi il est primordial d'utiliser des produits réputés et éprouvés, et surtout de ne jamais essayer d'improviser son propre répartiteur de charge. Les éditeurs de répartiteurs de charge sont (au moins pour les plus sérieux) transparents sur le niveau de fiabilité des versions qu'ils proposent et ne poussent jamais à utiliser la toute dernière version, car ils savent que chaque bug rapporté porte atteinte à l'image de leur produit. Les versions commerciales [2] dérivées de HAProxy attendent généralement 6 mois avant de commencer à l'intégrer dans les produits et les clients non pressés n'adoptent ces versions qu'au bout d'un an. Pendant ce temps, des centaines de milliers de sites auront eu l'opportunité de rapporter d'éventuels problèmes qui se verront corrigés. Il faut bien voir que les clients veulent souvent pouvoir déployer le produit, le configurer et l'oublier définitivement. Il n'est pas rare de rencontrer sur le terrain de tels produits n'ayant pas été relancés une seule fois en 3 ans. Du point de vue des mises à jour de sécurité, cela peut être perçu comme un désastre, mais tout dépend de l'environnement dans lequel le produit opère, car le plus souvent un produit comme HAProxy est installé sur un système débarrassé de tout composant inutile et auquel très peu de gens ont accès, ce qui le rend peu sensible aux vulnérabilités nécessitant des redémarrages. Au final, cette approche porte ses fruits : les pages de statistiques fournies par HAProxy montrent très souvent des dizaines à des centaines de pertes de serveurs couvertes par mois pendant lesquelles pas une seule panne du répartiteur n'est survenue.
2.5 Gérer la panne du répartiteur
Afin de couvrir les cas résiduels où le répartiteur de charge est lui-même à l'origine de la panne, on applique souvent la technique consistant à le redonder. Contrairement aux apparences, cela est souvent bien plus simple que de redonder les serveurs. En effet, un répartiteur de charge ne possède normalement aucun contexte stocké, si bien qu'il ne dépend pas de la machine sur laquelle il tourne et ne nécessite pas de migrer de données vers une autre machine en cas de bascule. En fait, il peut être amené à stocker des informations en mémoire comme des associations entre des cookies de session et des identifiants de serveurs, mais il faut éviter cela à tout prix justement pour faciliter les bascules. HAProxy sait échanger ses tables de correspondances avec d'autres nœuds, donc ce n'est pas un critère rédhibitoire, mais cela reste une bonne pratique que de n'avoir besoin de rien partager. Des mécanismes tels qu'un mode actif/passif basé sur le protocole VRRP [3] sont tout à fait appropriés pour migrer l'adresse IP du répartiteur d'une machine vers une autre au sein du même réseau local et déclencher ainsi une bascule du trafic. Le composant « Keepalived » [4] est couramment utilisé conjointement à HAProxy pour cela (et c'est lui aussi un produit français né sur le terrain, preuve s'il en est que les opérateurs d’infrastructure français restent préoccupés par la qualité de service). Grâce à la directive « vrrp_script » [5], il sait même surveiller le processus HAProxy et faire des tests complémentaires pour déclencher des bascules immédiates (une seconde) en cas de dysfonctionnement. On voit encore parfois à tort des mécanismes de type cluster avec migration de systèmes de fichiers et redémarrage de service à froid sur ce genre de composant, et c'est une grave erreur. Ces mécanismes sont adaptés pour les systèmes partageant des données en écriture tels que les serveurs de bases de données, où l'on veut s'assurer que plus d'un nœud aura accès à la ressource à la fois. Aussi, un service redémarré va devoir découvrir les serveurs opérationnels derrière lui et perdre du temps à envoyer le trafic au mauvais endroit. À l'inverse, les mécanismes de redondance d'adresse virtuelle comme VRRP garantissent qu'au moins un nœud sera présent, quitte à provoquer une situation où les deux le sont (« split brain ») dans certains cas de panne, mais assurant quand même le bon fonctionnement du service pour l'utilisateur. Point important à noter, il faut toujours prévoir une adresse de service distincte de l'adresse du serveur lorsqu'on met en place un répartiteur de charge, c'est cela qui permet de migrer facilement le service d'un nœud à l'autre et de conserver une bonne flexibilité. Des approches complémentaires à base de routage existent, comme ECMP (Equal-Cost Multi-Path routing), qui sont plus souvent déployées dans les environnements à base de commutateurs de niveau 3 ou bien en multisite. Le principe général est alors d'avoir un service d'injection de routes (« RHI » pour Route Health Injection) sur chaque nœud de répartition de charge annonçant via les protocoles BGP ou OSPF la disponibilité du répartiteur de charge et de ses serveurs vers les routeurs et/ou commutateurs frontaux. Ces options sont peu représentées, ou du moins limitées dans le monde libre, mais souvent proposées dans les offres commerciales. Les solutions uniquement à base de DNS sont à bannir, car elles ne laissent aucun contrôle sur la vitesse de bascule et l'on ne converge jamais totalement vers les 100%, donc on doit se résoudre à couper du trafic au bout d'un certain temps lorsque la bascule est inévitable.
3. Passage en multisite
Si la mise en place d'une répartition de charge est une chose simple sur un seul site, il en est toute autre chose dès que l'on parle de plusieurs sites. L'existence même de plusieurs sites découle souvent de choix stratégiques motivés par des enjeux très différents d'une entreprise à l'autre, mais au bout du compte on retrouve souvent les quatre catégories suivantes constituant en réalité des étapes successives dans l'évolution de l'infrastructure vers le multisite :
- PRA : Plan de Reprise d’Activité - on cherche juste à limiter la casse en cas d'incident peu probable, mais grave comme l'incendie d'un datacenter ;
- PCA : Plan de Continuité d’Activité - on ne veut pas disparaître à cause d'une double panne des réseaux opérateurs ou d'une panne électrique prolongée sur un datacenter ;
- délestage actif-actif : on utilise les ressources du PCA pour répartir la production sur les différents sites ;
- géolocalisation : on optimise le placement des visiteurs sur les datacenters les plus proches.
3.1 Le PRA : simplicité, limites et opportunités
Dans la pratique, un PRA simple nécessite assez peu de moyens matériels, car souvent les serveurs ne suivent pas les évolutions du site de production et se retrouvent sous-dimensionnés, ce qui n'est pas considéré comme un problème grave dans la mesure où l'on souhaite uniquement assurer sa présence sur le net à court terme, juste le temps de rétablir le mode nominal. Un bon répartiteur de charge saura lisser la charge infligée aux serveurs pour leur éviter de tomber, quitte à ralentir légèrement le site. Au minimum, il faut définir les deux procédures suivantes :
- la synchronisation des configurations du site de production vers le site de PRA ;
- l'assurance que l'on saura basculer sur le site de PRA en ne changeant que des entrées DNS.
Attention cependant, le site de secours n'étant pas utilisé en temps normal, les oublis ou erreurs de synchronisation de configuration restent souvent non détectés avant d'en avoir réellement besoin. Et comme les tests sont souvent difficiles à réaliser, on a parfois tendance à reposer simplement sur les tests de bonne santé effectués par les répartiteurs de charge pour valider que la chaîne applicative fonctionne comme prévu et que les configurations sont bien à jour. Même si une telle validation semble un peu légère, elle permet en fait de s'assurer qu'en cas de bascule, la connectivité sera déjà bonne et que peu d'ajustements auront besoin d'être effectués à la dernière minute. C'est pour gagner cette visibilité confortable que certains administrateurs n'hésitent pas à déployer des tests de bonne santé avancés, et à faire tester tout ce qu’ils peuvent par les répartiteurs de charge, y compris des serveurs qui n'ont rien à voir avec le service couvert.
3.2 Le PCA : plus cher, mais tellement mieux
En général, suite à une panne de réseau opérateur au cours de laquelle on a jugé que le coût de bascule en PRA était plus élevé que celui de l'attente du rétablissement du mode nominal, on décide de convertir le PRA en PCA en se disant qu'à la prochaine panne, on pourra basculer en effectuant simplement une bascule DNS. L'impact technique est important, car il convient alors de dimensionner le site de secours suffisamment pour que les utilisateurs ne soient pas perturbés par une telle bascule. Il faut aussi en général mettre en place plusieurs chemins de communication entre les sites afin de synchroniser des informations et/ou des bases de données. Ces liaisons peuvent être dédiées et perdurer lors de la perte d'un accès frontal, ou bien être réalisées à l'aide de VPN passant par les accès publics. Dans tous les cas, ces liaisons coûtent cher et il convient d'en limiter le nombre et la capacité.
Une approche permettant de respecter ces contraintes consiste à configurer les répartiteurs de charge de chaque site avec la liste des serveurs locaux et distants, mais avec une préférence pour les locaux. On couple à cela un mécanisme de persistance, de préférence par insertion de cookie, permettant au client d'indiquer dans ses requêtes sur quel site sa session a été établie. Le répartiteur recevant ces requêtes saura ainsi aiguiller certaines d'entre elles sur l'ancien site s'il est toujours joignable, et les nouvelles sur son propre site. Cela assure que le trafic intersite reste limité aux sessions en cours et disparaisse rapidement. Dans le cas de HAProxy, cela se fait simplement en déclarant les serveurs distants avec le mot-clé « backup » [6], indiquant qu'on ne les utilisera pas pour de nouveaux visiteurs. Le réel avantage de cette méthode est qu'elle assure que le retour en mode nominal se passe de manière totalement transparente, même dans le cas où les liaisons intersites sont réalisées à l'aide d'un VPN empruntant les accès publics. Lors d'une panne opérateur, une bascule « douloureuse » a lieu vu qu'il n'y a plus du tout d'accès au site nominal, mais lors du retour à la normale, les deux sites sont accessibles et le retour à la normale se fait en douceur, car le répartiteur du site principal continue d’avoir accès aux serveurs du site de secours pour assurer les sessions existantes.
Lorsque le PCA commence à bien fonctionner et à être bien maîtrisé par l'ensemble des personnes, le besoin de pouvoir l'utiliser pour opérer à tout moment sur le site nominal se fait sentir. La seule contrainte reste alors le critère du choix du site. Le DNS n'assure jamais une convergence de 100% du trafic sur un site ou l'autre, et la propagation prend du temps. On peut avoir par exemple 90% du trafic basculé en 1 minute, mais seulement 99% en une heure. Deux approches existent contre cela. La première, souvent coûteuse, consiste à gérer son propre AS BGP et d'annoncer ses propres adresses IP via différents chemins. Cette approche est fiable, bien maîtrisée par les opérateurs réseau, permet une bascule de site en quelques secondes, mais engendre une surconsommation d'adresses IP, ce qui n'est plus vraiment à la mode, surtout pour des sites utilisant moins d'une centaine d'adresses IP publiques. Une autre approche consiste à placer le répartiteur de charge en tête de réseau, devant toute l'infrastructure. C'est alors à lui qu'incombera la tâche de rerouter le trafic vers l'autre site lorsque le site local sera rendu inopérant. Cette approche se combine très bien avec les bascules DNS, car le répartiteur n'aura à rerouter qu'un faible pourcentage de trafic résiduel. Et comme dans le cas du simple site, les pannes de répartiteurs de charge sont rares d'autant que c'est un composant peu manipulé, donc ce risque est généralement considéré comme tout à fait acceptable lorsqu'il impacte au plus un très faible pourcentage de trafic résiduel. Cette approche permet aussi de déclencher des bascules complètes de site en journée de manière totalement transparente pour effectuer des opérations de maintenance.
3.3 Le PCA jusqu’au bout en actif-actif
Le lecteur avisé aura remarqué que si l'on place des répartiteurs de charge en frontal de l'infrastructure avec une possibilité de rerouter du trafic sur l'autre site, rien n'empêche d'utiliser les deux sites actifs et d'augmenter ainsi la capacité globale de traitement sans ajouter de matériel. Bon nombre de directions informatiques font le même choix lorsque le besoin d'augmenter la capacité même ponctuellement se fait sentir et que l'on comprend mal l'intérêt d'avoir autant de matériel dormant. Il faut toutefois prendre quelques précautions d'usage :
- limiter les échanges intersite qui peuvent coûter cher en bande passante ainsi qu'en latence si les sites sont éloignés. Les redirections HTTP sont assez efficaces contre cela. Le répartiteur frontal du site 1 redirigera alors les clients vers site1.example.org tandis que celui du site 2 les redirigera vers site2.example.org, et les adresses pointeront vers celles des sites respectifs. Cette approche est surtout utilisée lorsque les sites d'hébergement se trouvent dans différents pays, car la redirection impacte le ressenti utilisateur, surtout dans les environnements mobiles. Une approche plus complexe, mais plus optimale consiste à faire en sorte que l'application construise elle-même des liens référençant son propre site dans les réponses délivrées ;
- faire attention à ce que la capacité de traitement résultant de la panne d'un site suffise toujours à rendre le service de manière fiable, quitte à dégrader les performances. Ici encore le répartiteur de charge joue un rôle crucial. C'est à lui seul que revient la responsabilité de réguler intelligemment le trafic pour ne jamais surcharger un serveur. Correctement configuré, il lui est possible de faire fonctionner un serveur à 100% de sa capacité moyennant une légère dégradation des temps de réponse. Cette approche permet en fonctionnement nominal de ne jamais dépasser 50 à 80% de charge par site, d'effectuer des maintenances planifiées pendant les périodes calmes et de supporter la panne d'un site même en pleine charge ;
- bien faire attention à nommer différemment les équipements des différents sites et à journaliser les événements au maximum. En effet, les dysfonctionnements intermittents augmentent avec le nombre de sites et deviennent très difficiles à comprendre lorsqu'on ne sait pas avec certitude par où le trafic passe.
Lorsque ces principes sont respectés, rien n'empêche de dépasser deux sites pour peu que les applications le supportent. Les applications subissent en effet souvent une contrainte liée aux possibilités de réplication des données entre les sites, et pour y faire face, certaines détournent les possibilités de modes actif/passifs de certains serveurs de bases de données.
3.4 Répartition géographique
Lorsque ces contraintes sont levées par les choix d'architectures et de technologies applicatives, il devient parfois intéressant de pouvoir placer les sites physiques au plus près des utilisateurs afin d'optimiser les temps de réponse. Les sites internationaux cherchent souvent à couvrir au moins 4 fuseaux horaires en plaçant des serveurs sur les côtes Est et Ouest des États Unis, d'autres en Europe et d'autres en Asie. On réutilise alors le fonctionnement décrit ci-dessus en combinaison avec de la géolocalisation d'adresse IP, méthode consistant à deviner dans quelle ville, quel pays ou continent un visiteur se trouve, et à choisir parmi une liste de services disponibles, celui dont il est le plus proche. Il existe principalement deux méthodes. La première consiste à utiliser des serveurs DNS capables de présenter des réponses différentes en fonction de l'adresse qui les requête. Certains fournisseurs de services DNS sont capables d'assurer eux-mêmes cette fonction. L'une des principales critiques envers cette méthode est qu'elle détecte réellement l'emplacement du serveur intermédiaire requêtant le serveur DNS final plutôt que celle du client lui-même et qu'elle est donc imprécise face à certains gros fournisseurs d'accès. L'autre méthode consiste à laisser le répartiteur frontal effectuer la redirection lui-même en fonction de l'adresse IP du client, comme dans le cas du choix du site actif ou passif. Cette méthode est plus simple et plus fiable, mais elle induit une latence initiale supplémentaire que le DNS aurait pu éviter. La solution optimale se situe ici aussi dans la combinaison des deux mécanismes de sorte que seule une petite partie de la population ait à subir cette latence initiale.
Acheminement du trafic sur le bon site après une bascule ou un retour à la normale. Le répartiteur de charge détermine le site cible d'après le nom du serveur indiqué par le cookie.
4. Apports en terme de sécurité
Les infrastructures d'hébergement de sites web engendrent des revenus et sont à ce titre la cible de bon nombre d'attaques, à la base desquelles on retrouve des tentatives d'extorsion, des tentatives de détournement de clients par un concurrent, des tentatives de collectes d'identifiants de paiement monnayables, et même de la simple malveillance.
4.1 Isolation protocolaire totale
Un répartiteur de charge fonctionnant en mode proxy comme HAProxy apporte naturellement une très bonne protection aux serveurs web. En effet, il s'agit déjà d'un proxy, donc il dispose de deux connexions TCP distinctes et totalement indépendantes l'une de l'autre vers le client et vers le serveur. Cela veut dire que les attaques protocolaires employant par exemple des paquets malformés ou de l'usurpation d'adresse IP (IP spoofing) ne seront jamais relayées aux serveurs. Cela veut dire également que les serveurs peuvent être hébergés sur un réseau privé non accessible d'Internet, ce qui limite très fortement les risques d'intrusions, de vol de données, de récupération de codes malveillants à l'extérieur, ou de rebonds pour attaquer d'autres sites, vu que le seul trafic qui passe est celui pour lequel des règles précises ont été configurées sur le répartiteur de charge. Ensuite, le répartiteur de charge peut aussi traiter lui-même le déchiffrement SSL/TLS et éviter ainsi d'exposer les vulnérabilités d'implémentations vieillissantes des serveurs applicatifs se trouvant derrière. Seul le répartiteur aura besoin d'être maintenu à jour pour protéger tout le parc. Enfin, le répartiteur ne laisse passer que des requêtes HTTP qu'il a su comprendre, c'est-à-dire qu'elles sont complètes et valides. Les requêtes malformées seront bloquées à l'entrée. Les attaques comme Slowloris visant à saturer les serveurs avec des connexions lentes seront sans effet, car le répartiteur de charge est conçu pour supporter des charges de 100 à 1000 fois supérieures à celle d'un serveur web classique.
4.2 Fonctionnalités avancées
Au-delà des bénéfices indirects liés uniquement à la conception du produit, on va trouver des fonctionnalités propres à certains produits. HAProxy par exemple sait maintenir des statistiques avancées de trafic en fonction de nombreux critères tels que l'adresse IP source, des URL, des cookies, etc., qui peuvent même être partagées avec les autres sites. Il devient alors possible de programmer des décisions automatiques de traitements spécifiques sur comportements anormaux (répétition excessive d'une même URL pour une adresse IP donnée, etc.). Certains hébergeurs vont très loin dans ce niveau de programmation et parviennent à intégrer de la logique métier dans le produit pour résister à peu près à toutes les attaques. L'intégration récente du langage de programmation Lua laisse présager des configurations plus riches encore. Il faut tout de même savoir rester raisonnable et se dire qu'à tout moment un répartiteur de charge doit pouvoir être remplacé sans perte de fonctionnalités essentielles. C'est pour cette raison qu'HAProxy n'intègre pas de WAF (Web Application Firewall = filtrage applicatif Web) : le remplacement d'un WAF est incroyablement plus complexe que celui d'un répartiteur de charge et il faut toujours se réserver la possibilité de remplacer l'un sans devoir remplacer l'autre.
4.3 Prévoir de rajouter facilement des répartiteurs
Le répartiteur de charge pourra lui aussi devenir un point critique de l'infrastructure d'hébergement. Tout d'abord, il pourra atteindre des limites de capacité, notamment en terme de traitements SSL/TLS sur les très gros sites. Ces limites sont facilement contournables par la mise en place de plusieurs répartiteurs sur la même adresse de service, ce qui est souvent réalisé en utilisant le protocole ECMP vers les commutateurs frontaux. Un nouveau problème survient alors, qui est que l'on ne veut pas que chaque connexion engendre une renégociation TLS dès qu'elle tombe sur un autre nœud que la précédente, cas fréquent lorsque le trafic est réparti de manière aléatoire entre plusieurs terminaisons TLS. Une répartition frontale basée sur l'adresse IP source répond généralement assez bien à ce cas de figure. Sinon la mise en place d’un partage des secrets utilisés pour émettre les tickets TLS évite également ce problème.
4.4 Le répartiteur doit se protéger
Le répartiteur frontal sera le premier rempart contre les attaques distribuées de déni de service (DDoS), dont il protégera également l'éventuel firewall placé derrière lui. Ces attaques de type SYN flood[7] ou de réflexion (DNS, NTP...) visant à saturer sa pile TCP/IP n'auront d'effet que sur l'OS du répartiteur de charge, qui devra se défendre lui-même sous peine de causer l'effondrement de la totalité du site. La première protection consiste ici à configurer convenablement le système d'exploitation. Mais au-delà du gigabit/s d'attaque, c'est peine perdue, ou bien il faudra déployer de multiples répartiteurs frontaux. Des boîtiers anti-DDoS externes peuvent alors s'avérer intéressants comparés au coût d'une ferme de répartiteurs de charge. Autrement il existe des extensions purement logicielles (telles que PacketShield qui équipe les versions commerciales d'HAProxy) qui permettent de tenir des niveaux de charge très élevés sur un faible nombre d'équipements et qui lèvent ainsi tout goulot d'étranglement. Il faut aussi garder à l'esprit qu'à partir du moment où le lien internet frontal est saturé par le trafic d'attaque, seul le fournisseur d'accès internet pourra faire quelque chose. Enfin, la répartition multisite à base de géolocalisation permet parfois de circonscrire l'attaque dans certaines zones géographiques seulement et faire en sorte que les visiteurs d'autres pays ne se rendent compte de rien.
5. Le mot de la fin
En conclusion, on retiendra que même si un répartiteur de charge ne fait pas tout, il fait beaucoup plus que de la simple répartition de charge, et il apporte surtout une très grande flexibilité qui permet de s'adapter rapidement et efficacement à tous les cas de figure qui se présentent, qu'il s'agisse de croissance rapide, de pannes graves ou d'attaques. C’est pour cela que ces produits se comparent toujours aux fonctionnalités rendues. C'est un très bon poste d'observation de l'activité générale de l'infrastructure et de son état de santé. C'est un composant fiable et performant, mais qu'il ne faut pas négliger, car même s'il a tendance à être le dernier élément opérationnel quand tous les autres ont déjà échoué, on n'est jamais prêt à accepter qu'il puisse être responsable de la moindre panne.
Références
[1] HAProxy communautaire : http://www.haproxy.org/
[2] HAProxy commercial : http://www.haproxy.com/
[3] VRRP : https://www.ietf.org/rfc/rfc2338.txt
[4] Keepalived : http://keepalived.org/
[5] https://github.com/acassen/keepalived/blob/master/doc/samples/keepalived.conf.vrrp.localcheck
[6] http://cbonte.github.io/haproxy-dconv/configuration-1.6.html#5.2-backup
[7] SYN flood : https://fr.wikipedia.org/wiki/SYN_flood